Remove ofy support from PollMessage (#1732)

Also deletes the autorenew poll message history revision id field in
Domain, which is only needed to recreate the ofy key for the poll
message. The column already contains null values in it, making it
impossible to depend on it. The column itself will be deleted from the
schema after this PR is deployed.

The logic to update autorenew recurrence end time is changed
accordingly: When a poll message already exists, we simply update the
endtime, but when it no longer exists, i. e. when it's deleted
speculatively after a transfer request, we recreate one using the
history entry id that resulted in its creation (e. g. cancelled or rejected
transfer).

This should fix b/240984498. Though the exact reason for that bug is
still unclear to me. Namely, it throws an NPE at this line during an
explicit domain transfer approval:

https://cs.opensource.google/nomulus/nomulus/+/master:core/src/main/java/google/registry/flows/domain/DomainFlowUtils.java;l=603;bpv=1;bpt=0;drc=ede919d7dcdb7f209b074563b3d449ebee19118a

The domain in question has a null autorenewPollMessageHistoryId, but
that in itself should not have caused an NPE because we are not
operating on the null pointer. On that line the only possible way to
throw an NPE is for the domain itself to be null, but if that were the
case, the NPE would have been thrown at line 599 where we called a
method on the domain object.

Regardless of the cause, with this PR we are using an explicitly
provided history id and checking for its nullness before using it. If a
similar issue arises again, we should have a better idea why.

Lastly, the way poll message id is constructed is largely simplified in
PollMessageExternalKeyConverter as a result of the removal ofy parent
keys in PollMessage. This does present a possibility of failure when
immediately before deployment, a registrar requests a poll message and
received the old id, but by the time the registrar acks the id, the new
version is deployed and therefore does not recognize the old key. The
likelihood of this happening should be slim, and we could have prevented
it by letting the converter recognize both the old and the new key.
However, we would like to eventually phase out the old key, and in
theory a registrar could ack a poll message at any time after it was
requested. So, there is not a safe time by which all the old ids are
acked, lest we develop some elaborate scheme to keep track of which
messages were sent with an old id when requested and which of these old
ids are acked. Only then can we be truly safe to phase out the old id.
The benefit does not seem to warrant the effort. If a registrar does
encounter a situation like this, they could open a support bug to have
us manually ack the poll message for them.
This commit is contained in:
Lai Jiang
2022-08-19 14:24:03 -04:00
committed by GitHub
parent dda9a3ef7e
commit 6e201450f0
46 changed files with 188 additions and 512 deletions
@@ -179,8 +179,7 @@ class DeleteExpiredDomainsActionTest {
.asBuilder()
.setAutorenewEndTime(Optional.of(clock.nowUtc().minusDays(10)))
.setAutorenewBillingEvent(autorenewBillingEvent.createVKey())
.setAutorenewPollMessage(
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
.build());
return pendingExpirationDomain;
@@ -95,7 +95,7 @@ class EppLifecycleContactTest extends EppTestCase {
.hasCommandName("PollRequest")
.and()
.hasStatus(SUCCESS_WITH_ACK_MESSAGE);
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "2-1-ROID-3-6-2000"))
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "6-2000"))
.atTime("2000-06-08T22:02:00Z")
.hasResponse("poll_ack_response_empty.xml");
assertThat(getRecordedEppMetric())
@@ -747,11 +747,11 @@ class EppLifecycleDomainTest extends EppTestCase {
.hasResponse(
"poll_response_autorenew.xml",
ImmutableMap.of(
"ID", "1-B-EXAMPLE-12-15-2002",
"ID", "15-2002",
"QDATE", "2002-06-01T00:04:00Z",
"DOMAIN", "fakesite.example",
"EXDATE", "2003-06-01T00:04:00Z"));
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-B-EXAMPLE-12-15-2002"))
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "15-2002"))
.atTime("2002-07-01T00:02:00Z")
.hasResponse("poll_ack_response_empty.xml");
@@ -765,13 +765,13 @@ class EppLifecycleDomainTest extends EppTestCase {
.hasResponse(
"poll_response_autorenew.xml",
ImmutableMap.of(
"ID", "1-B-EXAMPLE-12-15-2003", // Note -- Year is different from previous ID.
"ID", "15-2003", // Note -- Year is different from previous ID.
"QDATE", "2003-06-01T00:04:00Z",
"DOMAIN", "fakesite.example",
"EXDATE", "2004-06-01T00:04:00Z"));
// Ack the second poll message and verify that none remain.
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-B-EXAMPLE-12-15-2003"))
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "15-2003"))
.atTime("2003-07-01T00:05:05Z")
.hasResponse("poll_ack_response_empty.xml");
assertThatCommand("poll.xml")
@@ -801,7 +801,7 @@ class EppLifecycleDomainTest extends EppTestCase {
// As the losing registrar, read the request poll message, and then ack it.
assertThatLoginSucceeds("NewRegistrar", "foo-BAR2");
String messageId = "1-B-EXAMPLE-18-24-2001";
String messageId = "24-2001";
assertThatCommand("poll.xml")
.atTime("2001-01-01T00:01:00Z")
.hasResponse("poll_response_domain_transfer_request.xml", ImmutableMap.of("ID", messageId));
@@ -810,7 +810,7 @@ class EppLifecycleDomainTest extends EppTestCase {
.hasResponse("poll_ack_response_empty.xml");
// Five days in the future, expect a server approval poll message to the loser, and ack it.
messageId = "1-B-EXAMPLE-18-23-2001";
messageId = "23-2001";
assertThatCommand("poll.xml")
.atTime("2001-01-06T00:01:00Z")
.hasResponse(
@@ -822,7 +822,7 @@ class EppLifecycleDomainTest extends EppTestCase {
assertThatLogoutSucceeds();
// Also expect a server approval poll message to the winner, with the transfer request trid.
messageId = "1-B-EXAMPLE-18-22-2001";
messageId = "22-2001";
assertThatLoginSucceeds("TheRegistrar", "password2");
assertThatCommand("poll.xml")
.atTime("2001-01-06T00:02:00Z")
@@ -147,8 +147,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
domain
.asBuilder()
.setAutorenewBillingEvent(autorenewBillingEvent.createVKey())
.setAutorenewPollMessage(
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
.build());
assertTransactionalFlow(true);
@@ -214,8 +213,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
"TheRegistrar",
autorenewBillingEvent.createVKey())))
.setAutorenewBillingEvent(autorenewBillingEvent.createVKey())
.setAutorenewPollMessage(
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
.build());
assertTransactionalFlow(true);
}
@@ -181,9 +181,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
.setRegistrationExpirationTime(expirationTime)
.setStatusValues(ImmutableSet.copyOf(statusValues))
.setAutorenewBillingEvent(autorenewEvent.createVKey())
.setAutorenewPollMessage(
autorenewPollMessage.createVKey(),
autorenewPollMessage.getHistoryRevisionId())
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
.build();
persistResources(
ImmutableSet.of(
@@ -162,7 +162,7 @@ class DomainTransferCancelFlowTest
.setEventTime(originalExpirationTime)
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(getOnlyHistoryEntryOfType(domain, DOMAIN_CREATE))
.setHistoryEntry(getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_CANCEL))
.build(),
new PollMessage.OneTime.Builder()
.setRegistrarId("TheRegistrar")
@@ -47,7 +47,7 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
@BeforeEach
void setUp() {
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2011"));
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-2011"));
clock.setTo(DateTime.parse("2011-01-02T01:01:01Z"));
setRegistrarIdForFlow("NewRegistrar");
createTld("example");
@@ -87,7 +87,7 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
@Test
void testSuccess_contactPollMessage() throws Exception {
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3-2011"));
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-2011"));
persistResource(
new PollMessage.OneTime.Builder()
.setId(MESSAGE_ID)
@@ -102,7 +102,7 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
@Test
void testFailure_contactPollMessage_withIncorrectYearField() throws Exception {
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3-1999"));
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-1999"));
persistResource(
new PollMessage.OneTime.Builder()
.setId(MESSAGE_ID)
@@ -124,7 +124,7 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
@Test
void testSuccess_recentActiveAutorenew() throws Exception {
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2010"));
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-2010"));
persistAutorenewPollMessage(clock.nowUtc().minusMonths(6), END_OF_TIME);
assertTransactionalFlow(true);
runFlowAssertResponse(loadFile("poll_ack_response_empty.xml"));
@@ -132,7 +132,7 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
@Test
void testSuccess_oldActiveAutorenew() throws Exception {
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2009"));
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-2009"));
persistAutorenewPollMessage(clock.nowUtc().minusYears(2), END_OF_TIME);
// Create three other messages to be queued for retrieval to get our count right, since the poll
// ack response wants there to be 4 messages in the queue when the ack comes back.
@@ -141,14 +141,12 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
}
assertTransactionalFlow(true);
runFlowAssertResponse(
loadFile(
"poll_ack_response.xml",
ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2009", "COUNT", "4")));
loadFile("poll_ack_response.xml", ImmutableMap.of("MSGID", "3-2009", "COUNT", "4")));
}
@Test
void testSuccess_oldInactiveAutorenew() throws Exception {
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2010"));
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-2010"));
persistAutorenewPollMessage(clock.nowUtc().minusMonths(6), clock.nowUtc());
assertTransactionalFlow(true);
runFlowAssertResponse(loadFile("poll_ack_response_empty.xml"));
@@ -162,35 +160,33 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
}
assertTransactionalFlow(true);
runFlowAssertResponse(
loadFile(
"poll_ack_response.xml",
ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2011", "COUNT", "4")));
loadFile("poll_ack_response.xml", ImmutableMap.of("MSGID", "3-2011", "COUNT", "4")));
}
@Test
void testFailure_noSuchMessage() throws Exception {
assertTransactionalFlow(true);
Exception e = assertThrows(MessageDoesNotExistException.class, this::runFlow);
assertThat(e).hasMessageThat().contains(String.format("(1-3-EXAMPLE-4-%d-2011)", MESSAGE_ID));
assertThat(e).hasMessageThat().contains(String.format("(%d-2011)", MESSAGE_ID));
}
@Test
void testFailure_invalidId_tooFewComponents() throws Exception {
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-2-3"));
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1"));
assertTransactionalFlow(true);
assertThrows(InvalidMessageIdException.class, this::runFlow);
}
@Test
void testFailure_invalidId_tooManyComponents() throws Exception {
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3-1999-2007"));
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-1999-2007"));
assertTransactionalFlow(true);
assertThrows(InvalidMessageIdException.class, this::runFlow);
}
@Test
void testFailure_contactPollMessage_withMissingYearField() throws Exception {
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3"));
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3"));
persistResource(
new PollMessage.OneTime.Builder()
.setId(MESSAGE_ID)
@@ -210,13 +206,6 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
assertThrows(InvalidMessageIdException.class, this::runFlow);
}
@Test
void testFailure_invalidEppResourceClassId() throws Exception {
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "999-1-1-1"));
assertTransactionalFlow(true);
assertThrows(InvalidMessageIdException.class, this::runFlow);
}
@Test
void testFailure_missingId() throws Exception {
setEppInput("poll_ack_missing_id.xml");
@@ -250,6 +239,6 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
.build());
assertTransactionalFlow(true);
Exception e = assertThrows(MessageDoesNotExistException.class, this::runFlow);
assertThat(e).hasMessageThat().contains(String.format("(1-3-EXAMPLE-4-%d-2011)", MESSAGE_ID));
assertThat(e).hasMessageThat().contains(String.format("(%d-2011)", MESSAGE_ID));
}
}
@@ -27,7 +27,6 @@ import google.registry.model.index.EppResourceIndexBucket;
import google.registry.model.index.ForeignKeyIndex.ForeignKeyContactIndex;
import google.registry.model.index.ForeignKeyIndex.ForeignKeyDomainIndex;
import google.registry.model.index.ForeignKeyIndex.ForeignKeyHostIndex;
import google.registry.model.poll.PollMessage;
import google.registry.model.rde.RdeRevision;
import google.registry.model.registrar.Registrar;
import google.registry.model.reporting.HistoryEntry;
@@ -63,7 +62,6 @@ public class ClassPathManagerTest {
assertThat(ClassPathManager.getClass("Lock")).isEqualTo(Lock.class);
assertThat(ClassPathManager.getClass("Domain")).isEqualTo(Domain.class);
assertThat(ClassPathManager.getClass("HistoryEntry")).isEqualTo(HistoryEntry.class);
assertThat(ClassPathManager.getClass("PollMessage")).isEqualTo(PollMessage.class);
assertThat(ClassPathManager.getClass("ForeignKeyHostIndex"))
.isEqualTo(ForeignKeyHostIndex.class);
assertThat(ClassPathManager.getClass("ServerSecret")).isEqualTo(ServerSecret.class);
@@ -117,7 +115,6 @@ public class ClassPathManagerTest {
assertThat(ClassPathManager.getClassName(Lock.class)).isEqualTo("Lock");
assertThat(ClassPathManager.getClassName(Domain.class)).isEqualTo("Domain");
assertThat(ClassPathManager.getClassName(HistoryEntry.class)).isEqualTo("HistoryEntry");
assertThat(ClassPathManager.getClassName(PollMessage.class)).isEqualTo("PollMessage");
assertThat(ClassPathManager.getClassName(ForeignKeyHostIndex.class))
.isEqualTo("ForeignKeyHostIndex");
assertThat(ClassPathManager.getClassName(ServerSecret.class)).isEqualTo("ServerSecret");
@@ -15,7 +15,6 @@
package google.registry.model.domain;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.flows.domain.DomainTransferUtils.createPendingTransferData;
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
import static google.registry.model.domain.token.AllocationToken.TokenStatus.NOT_STARTED;
import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE;
@@ -40,11 +39,8 @@ import com.googlecode.objectify.Key;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Flag;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.billing.BillingEvent.Recurring;
import google.registry.model.common.EntityGroupRoot;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.DesignatedContact.Type;
import google.registry.model.domain.Period.Unit;
import google.registry.model.domain.launch.LaunchNotice;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.domain.secdns.DelegationSignerData;
@@ -52,7 +48,6 @@ import google.registry.model.domain.token.AllocationToken;
import google.registry.model.domain.token.AllocationToken.TokenStatus;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.host.Host;
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
@@ -503,8 +498,7 @@ public class DomainSqlTest {
domain
.asBuilder()
.setAutorenewBillingEvent(billEvent.createVKey())
.setAutorenewPollMessage(
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
.setDeletePollMessage(deletePollMessage.createVKey())
.setTransferData(transferData)
.setGracePeriods(gracePeriods)
@@ -549,147 +543,10 @@ public class DomainSqlTest {
assertThat(persisted.getGracePeriods()).isEqualTo(gracePeriods);
}
@Test
void persistDomainWithLegacyVKeys() {
createTld("com");
historyEntry =
new DomainHistory.Builder()
.setId(100L)
.setType(HistoryEntry.Type.DOMAIN_CREATE)
.setPeriod(Period.create(1, Period.Unit.YEARS))
.setModificationTime(DateTime.now(UTC))
.setDomainRepoId("4-COM")
.setRegistrarId("registrar1")
// These are non-null, but I don't think some tests set them.
.setReason("felt like it")
.setRequestedByRegistrar(false)
.setXmlBytes(new byte[0])
.build();
BillingEvent.Recurring billEvent =
new BillingEvent.Recurring.Builder()
.setId(200L)
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
.setTargetId("example.com")
.setRegistrarId("registrar1")
.setEventTime(DateTime.now(UTC).plusYears(1))
.setRecurrenceEndTime(END_OF_TIME)
.setDomainHistory(historyEntry)
.build();
PollMessage.Autorenew autorenewPollMessage =
new PollMessage.Autorenew.Builder()
.setId(300L)
.setRegistrarId("registrar1")
.setEventTime(DateTime.now(UTC).plusYears(1))
.setHistoryEntry(historyEntry)
.build();
PollMessage.OneTime deletePollMessage =
new PollMessage.OneTime.Builder()
.setId(400L)
.setRegistrarId("registrar1")
.setEventTime(DateTime.now(UTC).plusYears(1))
.setHistoryEntry(historyEntry)
.build();
BillingEvent.OneTime oneTimeBillingEvent =
new BillingEvent.OneTime.Builder()
.setId(500L)
// Use SERVER_STATUS so we don't have to add a period.
.setReason(Reason.SERVER_STATUS)
.setTargetId("example.com")
.setRegistrarId("registrar1")
.setBillingTime(DateTime.now(UTC))
.setCost(Money.of(USD, 100))
.setEventTime(DateTime.now(UTC).plusYears(1))
.setDomainHistory(historyEntry)
.build();
DomainTransferData transferData =
createPendingTransferData(
domain.getRepoId(),
historyEntry.getId(),
new DomainTransferData.Builder()
.setTransferRequestTrid(Trid.create("foo", "bar"))
.setTransferRequestTime(fakeClock.nowUtc())
.setGainingRegistrarId("registrar2")
.setLosingRegistrarId("registrar1")
.setPendingTransferExpirationTime(fakeClock.nowUtc().plusDays(1)),
ImmutableSet.of(oneTimeBillingEvent, billEvent, autorenewPollMessage),
Period.create(0, Unit.YEARS));
gracePeriods =
ImmutableSet.of(
GracePeriod.create(
GracePeriodStatus.ADD,
"4-COM",
END_OF_TIME,
"registrar1",
oneTimeBillingEvent.createVKey()),
GracePeriod.createForRecurring(
GracePeriodStatus.AUTO_RENEW,
"4-COM",
END_OF_TIME,
"registrar1",
billEvent.createVKey()));
domain =
domain
.asBuilder()
.setAutorenewBillingEvent(Recurring.createVKey(billEvent.getId()))
.setAutorenewPollMessage(
createLegacyVKey(PollMessage.Autorenew.class, autorenewPollMessage.getId()),
autorenewPollMessage.getHistoryRevisionId())
.setDeletePollMessage(
createLegacyVKey(PollMessage.OneTime.class, deletePollMessage.getId()))
.setTransferData(transferData)
.setGracePeriods(gracePeriods)
.build();
historyEntry = historyEntry.asBuilder().setDomain(domain).build();
insertInDb(
contact,
contact2,
host,
historyEntry,
autorenewPollMessage,
billEvent,
deletePollMessage,
oneTimeBillingEvent,
domain);
// Store the existing BillingRecurrence VKey. This happens after the event has been persisted.
Domain persisted = loadByKey(domain.createVKey());
// Verify that the domain data has been persisted.
// dsData still isn't persisted. gracePeriods appears to have the same values but for some
// reason is showing up as different.
assertEqualDomainExcept(persisted, "creationTime", "dsData", "gracePeriods");
// Verify that the DomainBase object from the history record sets the fields correctly.
DomainHistory persistedHistoryEntry = loadByKey(historyEntry.createVKey());
assertThat(persistedHistoryEntry.getDomainBase().get().getAutorenewPollMessage())
.isEqualTo(domain.getAutorenewPollMessage());
assertThat(persistedHistoryEntry.getDomainBase().get().getAutorenewBillingEvent())
.isEqualTo(domain.getAutorenewBillingEvent());
assertThat(persistedHistoryEntry.getDomainBase().get().getDeletePollMessage())
.isEqualTo(domain.getDeletePollMessage());
DomainTransferData persistedTransferData =
persistedHistoryEntry.getDomainBase().get().getTransferData();
DomainTransferData originalTransferData = domain.getTransferData();
assertThat(persistedTransferData.getServerApproveBillingEvent())
.isEqualTo(originalTransferData.getServerApproveBillingEvent());
assertThat(persistedTransferData.getServerApproveAutorenewEvent())
.isEqualTo(originalTransferData.getServerApproveAutorenewEvent());
assertThat(persistedTransferData.getServerApproveAutorenewPollMessage())
.isEqualTo(originalTransferData.getServerApproveAutorenewPollMessage());
assertThat(domain.getGracePeriods()).isEqualTo(gracePeriods);
}
private <T> VKey<T> createKey(Class<T> clazz, String name) {
return VKey.create(clazz, name, Key.create(clazz, name));
}
private <T> VKey<T> createLegacyVKey(Class<T> clazz, long id) {
return VKey.create(
clazz, id, Key.create(Key.create(EntityGroupRoot.class, "per-tld"), clazz, id));
}
private void assertEqualDomainExcept(Domain thatDomain, String... excepts) {
ImmutableList<String> moreExcepts =
new ImmutableList.Builder<String>()
@@ -41,7 +41,6 @@ import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Ordering;
import com.google.common.collect.Streams;
import com.googlecode.objectify.Key;
import google.registry.model.ImmutableObject;
import google.registry.model.ImmutableObjectSubject;
import google.registry.model.billing.BillingEvent;
@@ -114,7 +113,7 @@ public class DomainTest {
oneTimeBillKey =
persistResource(
new BillingEvent.OneTime.Builder()
// Use SERVER_STATUS so we don't have to add a period.
// Use SERVER_STATUS, so we don't have to add a period.
.setReason(Reason.SERVER_STATUS)
.setTargetId(domain.getDomainName())
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
@@ -140,7 +139,7 @@ public class DomainTest {
BillingEvent.OneTime oneTimeBill =
new BillingEvent.OneTime.Builder()
.setId(500L)
// Use SERVER_STATUS so we don't have to add a period.
// Use SERVER_STATUS, so we don't have to add a period.
.setReason(Reason.SERVER_STATUS)
.setTargetId("example.com")
.setRegistrarId("registrar1")
@@ -163,10 +162,8 @@ public class DomainTest {
.build();
insertInDb(historyEntry, oneTimeBill, recurringBill);
recurringBillKey = recurringBill.createVKey();
VKey<PollMessage.Autorenew> autorenewPollKey =
VKey.from(Key.create(Key.create(domainHistory), PollMessage.Autorenew.class, 3));
VKey<PollMessage.OneTime> onetimePollKey =
VKey.from(Key.create(Key.create(domainHistory), PollMessage.OneTime.class, 1));
VKey<PollMessage.Autorenew> autorenewPollKey = VKey.createSql(PollMessage.Autorenew.class, 3L);
VKey<PollMessage.OneTime> onetimePollKey = VKey.createSql(PollMessage.OneTime.class, 1L);
// Set up a new persisted domain entity.
domain =
persistResource(
@@ -215,7 +212,7 @@ public class DomainTest {
.build())
.setDeletePollMessage(onetimePollKey)
.setAutorenewBillingEvent(recurringBillKey)
.setAutorenewPollMessage(autorenewPollKey, historyEntry.getId())
.setAutorenewPollMessage(autorenewPollKey)
.setSmdId("smdid")
.addGracePeriod(
GracePeriod.create(
@@ -849,7 +846,7 @@ public class DomainTest {
@Test
void testClone_transferDuringAutorenew() {
// When the domain is an an autorenew grace period, we should not extend the registration
// When the domain is an autorenew grace period, we should not extend the registration
// expiration by a further year--it should just be whatever the autorenew was
DateTime now = DateTime.now(UTC);
DateTime transferExpirationTime = now.minusDays(1);
@@ -46,7 +46,7 @@ public class PollMessageExternalKeyConverterTest {
public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build();
private HistoryEntry historyEntry;
private FakeClock clock = new FakeClock(DateTime.parse("2007-07-07T01:01:01Z"));
private final FakeClock clock = new FakeClock(DateTime.parse("2007-07-07T01:01:01Z"));
@BeforeEach
void beforeEach() {
@@ -77,8 +77,8 @@ public class PollMessageExternalKeyConverterTest {
.setMsg("Test poll message")
.setHistoryEntry(historyEntry)
.build());
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("1-2-FOOBAR-4-5-2007");
assertVKeysEqual(parsePollMessageExternalId("1-2-FOOBAR-4-5-2007"), pollMessage.createVKey());
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("5-2007");
assertVKeysEqual(parsePollMessageExternalId("5-2007"), pollMessage.createVKey());
}
@Test
@@ -94,8 +94,8 @@ public class PollMessageExternalKeyConverterTest {
.setMsg("Test poll message")
.setHistoryEntry(historyEntry)
.build());
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("2-5-ROID-6-7-2007");
assertVKeysEqual(parsePollMessageExternalId("2-5-ROID-6-7-2007"), pollMessage.createVKey());
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("7-2007");
assertVKeysEqual(parsePollMessageExternalId("7-2007"), pollMessage.createVKey());
}
@Test
@@ -111,46 +111,25 @@ public class PollMessageExternalKeyConverterTest {
.setMsg("Test poll message")
.setHistoryEntry(historyEntry)
.build());
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("3-5-ROID-6-7-2007");
assertVKeysEqual(parsePollMessageExternalId("3-5-ROID-6-7-2007"), pollMessage.createVKey());
}
@Test
void testFailure_missingYearField() {
assertThrows(
PollMessageExternalKeyParseException.class,
() -> parsePollMessageExternalId("1-2-FOOBAR-4-5"));
}
@Test
void testFailure_invalidEppResourceTypeId() {
// Populate the testdata correctly as for 1-2-FOOBAR-4-5 so we know that the only thing that
// is wrong here is the EppResourceTypeId.
testSuccess_domain();
assertThrows(
PollMessageExternalKeyParseException.class,
() -> parsePollMessageExternalId("4-2-FOOBAR-4-5-2007"));
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("7-2007");
assertVKeysEqual(parsePollMessageExternalId("7-2007"), pollMessage.createVKey());
}
@Test
void testFailure_tooFewComponentParts() {
assertThrows(
PollMessageExternalKeyParseException.class,
() -> parsePollMessageExternalId("1-3-EXAMPLE"));
assertThrows(PollMessageExternalKeyParseException.class, () -> parsePollMessageExternalId("1"));
}
@Test
void testFailure_tooManyComponentParts() {
assertThrows(
PollMessageExternalKeyParseException.class,
() -> parsePollMessageExternalId("1-3-EXAMPLE-4-5-2007-2009"));
PollMessageExternalKeyParseException.class, () -> parsePollMessageExternalId("1-3-2009"));
}
@Test
void testFailure_nonNumericIds() {
assertThrows(
PollMessageExternalKeyParseException.class,
() -> parsePollMessageExternalId("A-B-FOOBAR-D-E-F"));
PollMessageExternalKeyParseException.class, () -> parsePollMessageExternalId("A-2007"));
}
// We may have VKeys of slightly varying types, e.g. VKey<PollMessage> (superclass) and
@@ -18,16 +18,13 @@ import static com.google.common.truth.Truth.assertThat;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Cancellation;
import google.registry.model.billing.BillingEvent.OneTime;
import google.registry.model.billing.BillingEvent.Recurring;
import google.registry.model.domain.Domain;
import google.registry.model.domain.Period;
import google.registry.model.eppcommon.Trid;
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.persistence.VKey;
import google.registry.testing.AppEngineExtension;
import org.joda.time.DateTime;
@@ -51,21 +48,11 @@ public class TransferDataTest {
@BeforeEach
void beforeEach() {
Key<HistoryEntry> historyEntryKey =
Key.create(Key.create(Domain.class, "4-TLD"), HistoryEntry.class, 1356L);
transferBillingEventKey = OneTime.createVKey(12345L);
otherServerApproveBillingEventKey = Cancellation.createVKey(2468L);
recurringBillingEventKey = Recurring.createVKey(13579L);
autorenewPollMessageKey =
VKey.create(
PollMessage.Autorenew.class,
67890L,
Key.create(historyEntryKey, PollMessage.Autorenew.class, 67890L));
otherServerApprovePollMessageKey =
VKey.create(
PollMessage.OneTime.class,
314159L,
Key.create(historyEntryKey, PollMessage.OneTime.class, 314159L));
autorenewPollMessageKey = VKey.createSql(PollMessage.Autorenew.class, 67890L);
otherServerApprovePollMessageKey = VKey.createSql(PollMessage.OneTime.class, 314159L);
}
@Test
@@ -334,8 +334,7 @@ public class DomainToXjcConverterTest {
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(domainHistory)
.build())
.createVKey(),
domainHistory.getId())
.createVKey())
.setTransferData(
new DomainTransferData.Builder()
.setGainingRegistrarId("NewRegistrar")
@@ -175,8 +175,7 @@ final class RdeFixtures {
.setMsg("Domain was auto-renewed.")
.setHistoryEntry(historyEntry)
.build())
.createVKey(),
historyEntry.getId())
.createVKey())
.setTransferData(
new DomainTransferData.Builder()
.setGainingRegistrarId("gaining")
@@ -667,8 +667,7 @@ public class DatabaseHelper {
domain
.asBuilder()
.setAutorenewBillingEvent(autorenewEvent.createVKey())
.setAutorenewPollMessage(
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
.build());
}
@@ -77,10 +77,10 @@ public class AckPollMessagesCommandTest extends CommandTestCase<AckPollMessagesC
assertThat(loadByKeysIfPresent(ImmutableList.of(pm1, pm2, pm3, pm4)).values())
.containsExactly(futurePollMessage);
assertInStdout(
"1-FSDGS-TLD-2406-624-2013,2013-05-01T22:33:44.000Z,ninelives",
"1-FSDGS-TLD-2406-316-2014,2014-01-01T22:33:44.000Z,foobar",
"1-FSDGS-TLD-2406-791-2015,2015-01-08T22:33:44.000Z,ginger");
assertNotInStdout("1-FSDGS-TLD-2406-123-2015,2015-09-01T22:33:44.000Z,notme");
"624-2013,2013-05-01T22:33:44.000Z,ninelives",
"316-2014,2014-01-01T22:33:44.000Z,foobar",
"791-2015,2015-01-08T22:33:44.000Z,ginger");
assertNotInStdout("123-2015,2015-09-01T22:33:44.000Z,notme");
}
@Test
@@ -105,9 +105,9 @@ public class AckPollMessagesCommandTest extends CommandTestCase<AckPollMessagesC
assertThat(loadByKeysIfPresent(ImmutableList.of(pm1, pm2, pm3)).values())
.containsExactly(resaved);
assertInStdout(
"1-FSDGS-TLD-2406-625-2011,2011-04-15T22:33:44.000Z,autorenew",
"1-FSDGS-TLD-2406-624-2013,2013-05-01T22:33:44.000Z,ninelives",
"1-FSDGS-TLD-2406-316-2014,2014-01-01T22:33:44.000Z,foobar");
"625-2011,2011-04-15T22:33:44.000Z,autorenew",
"624-2013,2013-05-01T22:33:44.000Z,ninelives",
"316-2014,2014-01-01T22:33:44.000Z,foobar");
}
@Test
@@ -130,9 +130,9 @@ public class AckPollMessagesCommandTest extends CommandTestCase<AckPollMessagesC
runCommand("-c", "TheRegistrar");
assertThat(loadByKeysIfPresent(ImmutableList.of(pm1, pm2, pm3))).isEmpty();
assertInStdout(
"1-FSDGS-TLD-2406-625-2011,2011-04-15T22:33:44.000Z,autorenew",
"1-FSDGS-TLD-2406-624-2013,2013-05-01T22:33:44.000Z,ninelives",
"1-FSDGS-TLD-2406-316-2014,2014-01-01T22:33:44.000Z,foobar");
"625-2011,2011-04-15T22:33:44.000Z,autorenew",
"624-2013,2013-05-01T22:33:44.000Z,ninelives",
"316-2014,2014-01-01T22:33:44.000Z,foobar");
}
@Test
@@ -115,7 +115,7 @@ class EppLifecycleToolsTest extends EppTestCase {
.atTime("2001-06-08T00:00:00Z")
.hasResponse("poll_response_unrenew.xml");
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-7-TLD-20-21-2001"))
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "21-2001"))
.atTime("2001-06-08T00:00:01Z")
.hasResponse("poll_ack_response_empty.xml");
@@ -136,7 +136,7 @@ class EppLifecycleToolsTest extends EppTestCase {
.hasResponse(
"poll_response_autorenew.xml",
ImmutableMap.of(
"ID", "1-7-TLD-20-23-2003",
"ID", "23-2003",
"QDATE", "2003-06-01T00:02:00Z",
"DOMAIN", "example.tld",
"EXDATE", "2004-06-01T00:02:00Z"));
@@ -155,7 +155,6 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
.build()));
// Check that fields on domain were updated correctly.
assertThat(domain.getAutorenewPollMessageHistoryId()).isEqualTo(synthetic.getId());
assertThat(domain.getRegistrationExpirationTime()).isEqualTo(newExpirationTime);
assertThat(domain.getLastEppUpdateTime()).isEqualTo(unrenewTime);
assertThat(domain.getLastEppUpdateRegistrarId()).isEqualTo("TheRegistrar");
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
<msgQ count="1" id="6-2011">
<qDate>2011-01-02T01:01:01Z</qDate>
<msg>Domain test.example was deleted by registry administrator with final deletion effective: 2011-01-02T00:56:01.008Z</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
<msgQ count="1" id="6-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Domain was auto-renewed.</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="2-2-ROID-5-6-2011">
<msgQ count="1" id="6-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Deleted contact jd1234</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="2-2-ROID-5-3-2010">
<msgQ count="1" id="3-2010">
<qDate>2010-12-28T01:01:01Z</qDate>
<msg>Transfer requested.</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
<msgQ count="1" id="6-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Domain deleted.</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
<msgQ count="1" id="6-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Transfer approved.</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
<msgQ count="1" id="6-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Transfer approved.</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="3-4-ROID-5-6-2011">
<msgQ count="1" id="6-2011">
<qDate>2011-01-01T01:01:01Z</qDate>
<msg>Deleted host ns1.test.example</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="2-1-ROID-3-6-2000">
<msgQ count="1" id="6-2000">
<qDate>2000-06-08T22:00:00Z</qDate>
<msg>Transfer requested.</msg>
</msgQ>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-7-TLD-14-16-2000">
<msgQ count="1" id="16-2000">
<qDate>2000-06-02T13:00:00Z</qDate>
<msg>The registry administrator has added the status(es) [serverHold].
</msg>
@@ -3,7 +3,7 @@
<result code="1301">
<msg>Command completed successfully; ack to dequeue</msg>
</result>
<msgQ count="1" id="1-7-TLD-20-21-2001">
<msgQ count="1" id="21-2001">
<qDate>2001-06-07T00:00:00Z</qDate>
<msg>Domain example.tld was unrenewed by 3 years; now expires at 2003-06-01T00:02:00.000Z.</msg>
</msgQ>
@@ -359,26 +359,6 @@ class google.registry.model.index.ForeignKeyIndex$ForeignKeyHostIndex {
google.registry.persistence.VKey<E> topReference;
org.joda.time.DateTime deletionTime;
}
class google.registry.model.poll.PollMessage {
@Id java.lang.Long id;
java.lang.String clientId;
java.lang.String msg;
org.joda.time.DateTime eventTime;
}
class google.registry.model.poll.PollMessage$Autorenew {
@Id java.lang.Long id;
java.lang.String clientId;
java.lang.String msg;
java.lang.String targetId;
org.joda.time.DateTime autorenewEndTime;
org.joda.time.DateTime eventTime;
}
class google.registry.model.poll.PollMessage$OneTime {
@Id java.lang.Long id;
java.lang.String clientId;
java.lang.String msg;
org.joda.time.DateTime eventTime;
}
class google.registry.model.rde.RdeRevision {
@Id java.lang.String id;
int revision;