Add columns for TransferData in Domain and Contact (#577)

* Add columns for TransferData in Domain and Contact

* Rename flyway file and foreign key

* Rebase on master and address comment

* Compileable commit

* Fix unit test

* Refactor TransferServerApproveEntity

* Use tm().delete(vkeys)

* Rename transfer_period fields

* Rename client_id to registrar_id

* Rebase on master

* Resolve comment

* Rebase on master
This commit is contained in:
Shicong Huang 2020-06-09 16:39:55 -04:00 committed by GitHub
parent f0765dc893
commit fdac686250
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 568 additions and 182 deletions

View file

@ -52,6 +52,7 @@ 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 google.registry.persistence.VKey;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
@ -129,9 +130,13 @@ public class ContactTransferRequestFlowTest
// poll messages, the approval notice ones for gaining and losing registrars.
assertPollMessagesEqual(
Iterables.filter(
ofy().load()
ofy()
.load()
// Use toArray() to coerce the type to something keys() will accept.
.keys(contact.getTransferData().getServerApproveEntities().toArray(new Key<?>[]{}))
.keys(
contact.getTransferData().getServerApproveEntities().stream()
.map(VKey::getOfyKey)
.toArray(Key[]::new))
.values(),
PollMessage.class),
ImmutableList.of(gainingApproveMessage, losingApproveMessage));

View file

@ -93,6 +93,7 @@ import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferResponse;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import java.util.Map;
import org.joda.money.Money;
@ -668,13 +669,24 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
.setPendingTransferExpirationTime(clock.nowUtc())
.build());
// The server-approve entities should all be deleted.
assertThat(ofy().load().key(oldTransferData.getServerApproveBillingEvent()).now()).isNull();
assertThat(ofy().load().key(oldTransferData.getServerApproveAutorenewEvent()).now()).isNull();
assertThat(ofy().load().key(oldTransferData.getServerApproveAutorenewPollMessage()).now())
assertThat(ofy().load().key(oldTransferData.getServerApproveBillingEvent().getOfyKey()).now())
.isNull();
assertThat(ofy().load().key(oldTransferData.getServerApproveAutorenewEvent().getOfyKey()).now())
.isNull();
assertThat(
ofy()
.load()
.key(oldTransferData.getServerApproveAutorenewPollMessage().getOfyKey())
.now())
.isNull();
assertThat(oldTransferData.getServerApproveEntities()).isNotEmpty(); // Just a sanity check.
assertThat(
ofy().load().keys(oldTransferData.getServerApproveEntities().toArray(new Key<?>[] {})))
ofy()
.load()
.keys(
oldTransferData.getServerApproveEntities().stream()
.map(VKey::getOfyKey)
.toArray(Key[]::new)))
.isEmpty();
}

View file

@ -27,6 +27,7 @@ import static google.registry.model.registry.Registry.TldState.QUIET_PERIOD;
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.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatastoreHelper.assertBillingEvents;
import static google.registry.testing.DatastoreHelper.assertBillingEventsEqual;
import static google.registry.testing.DatastoreHelper.assertPollMessagesEqual;
@ -290,13 +291,13 @@ public class DomainTransferRequestFlowTest
// Assert that the domain's TransferData server-approve billing events match the above.
if (expectTransferBillingEvent) {
assertBillingEventsEqual(
ofy().load().key(domain.getTransferData().getServerApproveBillingEvent()).now(),
tm().load(domain.getTransferData().getServerApproveBillingEvent()),
optionalTransferBillingEvent.get());
} else {
assertThat(domain.getTransferData().getServerApproveBillingEvent()).isNull();
}
assertBillingEventsEqual(
ofy().load().key(domain.getTransferData().getServerApproveAutorenewEvent()).now(),
tm().load(domain.getTransferData().getServerApproveAutorenewEvent()),
gainingClientAutorenew);
// Assert that the full set of server-approve billing events is exactly the extra ones plus
// the transfer billing event (if present) and the gaining client autorenew.
@ -309,7 +310,10 @@ public class DomainTransferRequestFlowTest
ofy()
.load()
// Use toArray() to coerce the type to something keys() will accept.
.keys(domain.getTransferData().getServerApproveEntities().toArray(new Key<?>[] {}))
.keys(
domain.getTransferData().getServerApproveEntities().stream()
.map(VKey::getOfyKey)
.toArray(Key[]::new))
.values(),
BillingEvent.class),
Sets.union(expectedServeApproveBillingEvents, extraBillingEvents));
@ -410,7 +414,7 @@ public class DomainTransferRequestFlowTest
// Assert that the poll messages show up in the TransferData server approve entities.
assertPollMessagesEqual(
ofy().load().key(domain.getTransferData().getServerApproveAutorenewPollMessage()).now(),
tm().load(domain.getTransferData().getServerApproveAutorenewPollMessage()),
autorenewPollMessage);
// Assert that the full set of server-approve poll messages is exactly the server approve
// OneTime messages to gaining and losing registrars plus the gaining client autorenew.
@ -419,7 +423,10 @@ public class DomainTransferRequestFlowTest
ofy()
.load()
// Use toArray() to coerce the type to something keys() will accept.
.keys(domain.getTransferData().getServerApproveEntities().toArray(new Key<?>[] {}))
.keys(
domain.getTransferData().getServerApproveEntities().stream()
.map(VKey::getOfyKey)
.toArray(Key[]::new))
.values(),
PollMessage.class),
ImmutableList.of(

View file

@ -29,7 +29,6 @@ import static org.junit.Assert.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import google.registry.model.EntityTestCase;
import google.registry.model.billing.BillingEvent;
import google.registry.model.contact.Disclose.PostalInfoChoice;
@ -114,7 +113,7 @@ public class ContactResourceTest extends EntityTestCase {
.setLosingClientId("losing")
.setPendingTransferExpirationTime(fakeClock.nowUtc())
.setServerApproveEntities(
ImmutableSet.of(Key.create(BillingEvent.OneTime.class, 1)))
ImmutableSet.of(VKey.createOfy(BillingEvent.OneTime.class, 1)))
.setTransferRequestTime(fakeClock.nowUtc())
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.setTransferRequestTrid(Trid.create("client-trid", "server-trid"))
@ -134,6 +133,8 @@ public class ContactResourceTest extends EntityTestCase {
saveRegistrar("registrar1");
saveRegistrar("registrar2");
saveRegistrar("registrar3");
saveRegistrar("gaining");
saveRegistrar("losing");
jpaTm().transact(() -> jpaTm().saveNew(originalContact));
ContactResource persisted =
jpaTm()
@ -141,15 +142,17 @@ public class ContactResourceTest extends EntityTestCase {
() ->
jpaTm()
.load(VKey.createSql(ContactResource.class, originalContact.getRepoId())));
// TODO(b/153378849): Remove the hard code for postal info after resolving the issue that
// @PostLoad doesn't work in Address
ContactResource fixed =
originalContact
.asBuilder()
.setCreationTime(persisted.getCreationTime())
.setInternationalizedPostalInfo(persisted.getInternationalizedPostalInfo())
.setLocalizedPostalInfo(persisted.getLocalizedPostalInfo())
.setTransferData(null)
.setTransferData(
originalContact
.getTransferData()
.asBuilder()
.setServerApproveEntities(null)
.build())
.build();
assertThat(persisted).isEqualTo(fixed);
}

View file

@ -138,10 +138,16 @@ public class DomainBaseTest extends EntityTestCase {
.setLosingClientId("losing")
.setPendingTransferExpirationTime(fakeClock.nowUtc())
.setServerApproveEntities(
ImmutableSet.of(oneTimeBillKey, recurringBillKey, autorenewPollKey))
.setServerApproveBillingEvent(oneTimeBillKey)
.setServerApproveAutorenewEvent(recurringBillKey)
.setServerApproveAutorenewPollMessage(autorenewPollKey)
ImmutableSet.of(
VKey.createOfy(BillingEvent.OneTime.class, oneTimeBillKey),
VKey.createOfy(BillingEvent.Recurring.class, recurringBillKey),
VKey.createOfy(PollMessage.Autorenew.class, autorenewPollKey)))
.setServerApproveBillingEvent(
VKey.createOfy(BillingEvent.OneTime.class, oneTimeBillKey))
.setServerApproveAutorenewEvent(
VKey.createOfy(BillingEvent.Recurring.class, recurringBillKey))
.setServerApproveAutorenewPollMessage(
VKey.createOfy(PollMessage.Autorenew.class, autorenewPollKey))
.setTransferRequestTime(fakeClock.nowUtc().plusDays(1))
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.setTransferRequestTrid(Trid.create("client-trid", "server-trid"))
@ -363,8 +369,8 @@ public class DomainBaseTest extends EntityTestCase {
.setTransferRequestTime(fakeClock.nowUtc().minusDays(4))
.setPendingTransferExpirationTime(fakeClock.nowUtc().plusDays(1))
.setGainingClientId("winner")
.setServerApproveBillingEvent(Key.create(transferBillingEvent))
.setServerApproveEntities(ImmutableSet.of(Key.create(transferBillingEvent)))
.setServerApproveBillingEvent(transferBillingEvent.createVKey())
.setServerApproveEntities(ImmutableSet.of(transferBillingEvent.createVKey()))
.build())
.addGracePeriod(
// Okay for billing event to be null since the point of this grace period is just
@ -375,7 +381,7 @@ public class DomainBaseTest extends EntityTestCase {
DomainBase afterTransfer = domain.cloneProjectedAtTime(fakeClock.nowUtc().plusDays(1));
DateTime newExpirationTime = oldExpirationTime.plusYears(1);
Key<BillingEvent.Recurring> serverApproveAutorenewEvent =
domain.getTransferData().getServerApproveAutorenewEvent();
domain.getTransferData().getServerApproveAutorenewEvent().getOfyKey();
assertTransferred(afterTransfer, newExpirationTime, serverApproveAutorenewEvent);
assertThat(afterTransfer.getGracePeriods())
.containsExactly(
@ -746,8 +752,10 @@ public class DomainBaseTest extends EntityTestCase {
.setPendingTransferExpirationTime(transferExpirationTime)
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("TheRegistrar")
.setServerApproveAutorenewEvent(recurringBillKey)
.setServerApproveBillingEvent(oneTimeBillKey)
.setServerApproveAutorenewEvent(
VKey.createOfy(BillingEvent.Recurring.class, recurringBillKey))
.setServerApproveBillingEvent(
VKey.createOfy(BillingEvent.OneTime.class, oneTimeBillKey))
.build();
domain =
persistResource(

View file

@ -26,7 +26,6 @@ import static org.junit.Assert.assertThrows;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.InetAddresses;
import com.googlecode.objectify.Key;
import google.registry.model.EntityTestCase;
import google.registry.model.billing.BillingEvent;
import google.registry.model.domain.DomainBase;
@ -34,6 +33,7 @@ import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
@ -63,7 +63,7 @@ public class HostResourceTest extends EntityTestCase {
.setLosingClientId("losing")
.setPendingTransferExpirationTime(fakeClock.nowUtc())
.setServerApproveEntities(
ImmutableSet.of(Key.create(BillingEvent.OneTime.class, 1)))
ImmutableSet.of(VKey.createOfy(BillingEvent.OneTime.class, 1)))
.setTransferRequestTime(fakeClock.nowUtc())
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.setTransferRequestTrid(Trid.create("client-trid", "server-trid"))

View file

@ -18,11 +18,11 @@ 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.domain.Period;
import google.registry.model.eppcommon.Trid;
import google.registry.model.poll.PollMessage;
import google.registry.persistence.VKey;
import google.registry.testing.AppEngineRule;
import org.joda.time.DateTime;
import org.junit.Before;
@ -40,19 +40,19 @@ public class TransferDataTest {
private final DateTime now = DateTime.now(UTC);
private Key<BillingEvent.OneTime> transferBillingEventKey;
private Key<BillingEvent.Cancellation> otherServerApproveBillingEventKey;
private Key<BillingEvent.Recurring> recurringBillingEventKey;
private Key<PollMessage.Autorenew> autorenewPollMessageKey;
private Key<PollMessage.OneTime> otherServerApprovePollMessageKey;
private VKey<BillingEvent.OneTime> transferBillingEventKey;
private VKey<BillingEvent.Cancellation> otherServerApproveBillingEventKey;
private VKey<BillingEvent.Recurring> recurringBillingEventKey;
private VKey<PollMessage.Autorenew> autorenewPollMessageKey;
private VKey<PollMessage.OneTime> otherServerApprovePollMessageKey;
@Before
public void setUp() {
transferBillingEventKey = Key.create(BillingEvent.OneTime.class, 12345);
otherServerApproveBillingEventKey = Key.create(BillingEvent.Cancellation.class, 2468);
recurringBillingEventKey = Key.create(BillingEvent.Recurring.class, 13579);
autorenewPollMessageKey = Key.create(PollMessage.Autorenew.class, 67890);
otherServerApprovePollMessageKey = Key.create(PollMessage.OneTime.class, 314159);
transferBillingEventKey = VKey.createOfy(BillingEvent.OneTime.class, 12345);
otherServerApproveBillingEventKey = VKey.createOfy(BillingEvent.Cancellation.class, 2468);
recurringBillingEventKey = VKey.createOfy(BillingEvent.Recurring.class, 13579);
autorenewPollMessageKey = VKey.createOfy(PollMessage.Autorenew.class, 67890);
otherServerApprovePollMessageKey = VKey.createOfy(PollMessage.OneTime.class, 314159);
}
@Test
@ -67,7 +67,8 @@ public class TransferDataTest {
.setTransferPeriod(Period.create(5, Period.Unit.YEARS))
.build();
TransferData fullTransferData =
constantTransferData.asBuilder()
constantTransferData
.asBuilder()
.setPendingTransferExpirationTime(now)
.setTransferStatus(TransferStatus.PENDING)
.setServerApproveEntities(

View file

@ -332,10 +332,9 @@ public class DomainBaseToXjcConverterTest {
.setGainingClientId("gaining")
.setLosingClientId("losing")
.setPendingTransferExpirationTime(DateTime.parse("1925-04-20T00:00:00Z"))
.setServerApproveBillingEvent(Key.create(billingEvent))
.setServerApproveBillingEvent(billingEvent.createVKey())
.setServerApproveAutorenewEvent(
Key.create(
persistResource(
persistResource(
new BillingEvent.Recurring.Builder()
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
@ -344,10 +343,10 @@ public class DomainBaseToXjcConverterTest {
.setEventTime(END_OF_TIME)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(historyEntry)
.build())))
.build())
.createVKey())
.setServerApproveAutorenewPollMessage(
Key.create(
persistResource(
persistResource(
new Autorenew.Builder()
.setTargetId("example.xn--q9jyb4c")
.setClientId("TheRegistrar")
@ -355,8 +354,9 @@ public class DomainBaseToXjcConverterTest {
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setParent(historyEntry)
.build())))
.setServerApproveEntities(ImmutableSet.of(Key.create(billingEvent)))
.build())
.createVKey())
.setServerApproveEntities(ImmutableSet.of(billingEvent.createVKey()))
.setTransferRequestTime(DateTime.parse("1919-01-01T00:00:00Z"))
.setTransferStatus(TransferStatus.PENDING)
.setTransferredRegistrationExpirationTime(

View file

@ -174,10 +174,9 @@ final class RdeFixtures {
.setGainingClientId("gaining")
.setLosingClientId("losing")
.setPendingTransferExpirationTime(DateTime.parse("1993-04-20T00:00:00Z"))
.setServerApproveBillingEvent(Key.create(billingEvent))
.setServerApproveBillingEvent(billingEvent.createVKey())
.setServerApproveAutorenewEvent(
Key.create(
persistResource(
persistResource(
new BillingEvent.Recurring.Builder()
.setReason(Reason.RENEW)
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
@ -186,10 +185,10 @@ final class RdeFixtures {
.setEventTime(END_OF_TIME)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(historyEntry)
.build())))
.build())
.createVKey())
.setServerApproveAutorenewPollMessage(
Key.create(
persistResource(
persistResource(
new Autorenew.Builder()
.setTargetId("example." + tld)
.setClientId("TheRegistrar")
@ -197,8 +196,9 @@ final class RdeFixtures {
.setAutorenewEndTime(END_OF_TIME)
.setMsg("Domain was auto-renewed.")
.setParent(historyEntry)
.build())))
.setServerApproveEntities(ImmutableSet.of(Key.create(billingEvent)))
.build())
.createVKey())
.setServerApproveEntities(ImmutableSet.of(billingEvent.createVKey()))
.setTransferRequestTime(DateTime.parse("1991-01-01T00:00:00Z"))
.setTransferStatus(TransferStatus.PENDING)
.setTransferredRegistrationExpirationTime(

View file

@ -443,32 +443,37 @@ public class DatastoreHelper {
.setParent(contact)
.build());
return persistResource(
contact.asBuilder()
contact
.asBuilder()
.setPersistedCurrentSponsorClientId("TheRegistrar")
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(createTransferDataBuilder(requestTime, expirationTime)
.setTransferData(
createTransferDataBuilder(requestTime, expirationTime)
.setPendingTransferExpirationTime(now.plus(getContactAutomaticTransferLength()))
.setServerApproveEntities(
ImmutableSet.of(
// Pretend it's 3 days since the request
Key.create(persistResource(
createPollMessageForImplicitTransfer(
contact,
historyEntryContactTransfer,
"NewRegistrar",
requestTime,
expirationTime,
null))),
Key.create(persistResource(
createPollMessageForImplicitTransfer(
contact,
historyEntryContactTransfer,
"TheRegistrar",
requestTime,
expirationTime,
null)))))
.setTransferRequestTrid(Trid.create("transferClient-trid", "transferServer-trid"))
.build())
.setServerApproveEntities(
ImmutableSet.of(
// Pretend it's 3 days since the request
persistResource(
createPollMessageForImplicitTransfer(
contact,
historyEntryContactTransfer,
"NewRegistrar",
requestTime,
expirationTime,
null))
.createVKey(),
persistResource(
createPollMessageForImplicitTransfer(
contact,
historyEntryContactTransfer,
"TheRegistrar",
requestTime,
expirationTime,
null))
.createVKey()))
.setTransferRequestTrid(
Trid.create("transferClient-trid", "transferServer-trid"))
.build())
.build());
}
@ -585,38 +590,46 @@ public class DatastoreHelper {
}
TransferData.Builder transferDataBuilder =
createTransferDataBuilder(requestTime, expirationTime);
return persistResource(domain.asBuilder()
.setPersistedCurrentSponsorClientId("TheRegistrar")
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(transferDataBuilder
.setPendingTransferExpirationTime(expirationTime)
.setTransferredRegistrationExpirationTime(extendedRegistrationExpirationTime)
.setServerApproveBillingEvent(Key.create(transferBillingEvent))
.setServerApproveAutorenewEvent(Key.create(gainingClientAutorenewEvent))
.setServerApproveAutorenewPollMessage(Key.create(gainingClientAutorenewPollMessage))
.setServerApproveEntities(ImmutableSet.of(
Key.create(transferBillingEvent),
Key.create(gainingClientAutorenewEvent),
Key.create(gainingClientAutorenewPollMessage),
Key.create(persistResource(
createPollMessageForImplicitTransfer(
domain,
historyEntryDomainTransfer,
"NewRegistrar",
requestTime,
expirationTime,
extendedRegistrationExpirationTime))),
Key.create(persistResource(
createPollMessageForImplicitTransfer(
domain,
historyEntryDomainTransfer,
"TheRegistrar",
requestTime,
expirationTime,
extendedRegistrationExpirationTime)))))
.setTransferRequestTrid(Trid.create("transferClient-trid", "transferServer-trid"))
.build())
.build());
return persistResource(
domain
.asBuilder()
.setPersistedCurrentSponsorClientId("TheRegistrar")
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(
transferDataBuilder
.setPendingTransferExpirationTime(expirationTime)
.setTransferredRegistrationExpirationTime(extendedRegistrationExpirationTime)
.setServerApproveBillingEvent(transferBillingEvent.createVKey())
.setServerApproveAutorenewEvent(gainingClientAutorenewEvent.createVKey())
.setServerApproveAutorenewPollMessage(
gainingClientAutorenewPollMessage.createVKey())
.setServerApproveEntities(
ImmutableSet.of(
transferBillingEvent.createVKey(),
gainingClientAutorenewEvent.createVKey(),
gainingClientAutorenewPollMessage.createVKey(),
persistResource(
createPollMessageForImplicitTransfer(
domain,
historyEntryDomainTransfer,
"NewRegistrar",
requestTime,
expirationTime,
extendedRegistrationExpirationTime))
.createVKey(),
persistResource(
createPollMessageForImplicitTransfer(
domain,
historyEntryDomainTransfer,
"TheRegistrar",
requestTime,
expirationTime,
extendedRegistrationExpirationTime))
.createVKey()))
.setTransferRequestTrid(
Trid.create("transferClient-trid", "transferServer-trid"))
.build())
.build());
}
/** Persists and returns a {@link Registrar} with the specified attributes. */

View file

@ -716,15 +716,15 @@ class google.registry.model.tmch.TmchCrl {
org.joda.time.DateTime updated;
}
class google.registry.model.transfer.TransferData {
com.googlecode.objectify.Key<google.registry.model.billing.BillingEvent$OneTime> serverApproveBillingEvent;
com.googlecode.objectify.Key<google.registry.model.billing.BillingEvent$Recurring> serverApproveAutorenewEvent;
com.googlecode.objectify.Key<google.registry.model.poll.PollMessage$Autorenew> serverApproveAutorenewPollMessage;
google.registry.model.domain.Period transferPeriod;
google.registry.model.eppcommon.Trid transferRequestTrid;
google.registry.model.transfer.TransferStatus transferStatus;
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$OneTime> serverApproveBillingEvent;
google.registry.persistence.VKey<google.registry.model.billing.BillingEvent$Recurring> serverApproveAutorenewEvent;
google.registry.persistence.VKey<google.registry.model.poll.PollMessage$Autorenew> serverApproveAutorenewPollMessage;
java.lang.String gainingClientId;
java.lang.String losingClientId;
java.util.Set<com.googlecode.objectify.Key<? extends google.registry.model.transfer.TransferData$TransferServerApproveEntity>> serverApproveEntities;
java.util.Set<google.registry.persistence.VKey<? extends google.registry.model.transfer.TransferData$TransferServerApproveEntity>> serverApproveEntities;
org.joda.time.DateTime pendingTransferExpirationTime;
org.joda.time.DateTime transferRequestTime;
org.joda.time.DateTime transferredRegistrationExpirationTime;