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 c154df9d2c
commit fbe613c209
33 changed files with 568 additions and 182 deletions

View file

@ -97,7 +97,7 @@ public final class ContactTransferApproveFlow implements TransactionalFlow {
ofy().save().<Object>entities(newContact, historyEntry, gainingPollMessage);
// Delete the billing event and poll messages that were written in case the transfer would have
// been implicitly server approved.
ofy().delete().keys(existingContact.getTransferData().getServerApproveEntities());
tm().delete(existingContact.getTransferData().getServerApproveEntities());
return responseBuilder
.setResData(createTransferResponse(targetId, newContact.getTransferData()))
.build();

View file

@ -93,7 +93,7 @@ public final class ContactTransferCancelFlow implements TransactionalFlow {
ofy().save().<Object>entities(newContact, historyEntry, losingPollMessage);
// Delete the billing event and poll messages that were written in case the transfer would have
// been implicitly server approved.
ofy().delete().keys(existingContact.getTransferData().getServerApproveEntities());
tm().delete(existingContact.getTransferData().getServerApproveEntities());
return responseBuilder
.setResData(createTransferResponse(targetId, newContact.getTransferData()))
.build();

View file

@ -90,7 +90,7 @@ public final class ContactTransferRejectFlow implements TransactionalFlow {
ofy().save().<Object>entities(newContact, historyEntry, gainingPollMessage);
// Delete the billing event and poll messages that were written in case the transfer would have
// been implicitly server approved.
ofy().delete().keys(existingContact.getTransferData().getServerApproveEntities());
tm().delete(existingContact.getTransferData().getServerApproveEntities());
return responseBuilder
.setResData(createTransferResponse(targetId, newContact.getTransferData()))
.build();

View file

@ -126,12 +126,14 @@ public final class ContactTransferRequestFlow implements TransactionalFlow {
// If the transfer is server approved, this message will be sent to the gaining registrar. */
PollMessage serverApproveGainingPollMessage =
createGainingTransferPollMessage(targetId, serverApproveTransferData, historyEntry);
TransferData pendingTransferData = serverApproveTransferData.asBuilder()
TransferData pendingTransferData =
serverApproveTransferData
.asBuilder()
.setTransferStatus(TransferStatus.PENDING)
.setServerApproveEntities(
ImmutableSet.of(
Key.create(serverApproveGainingPollMessage),
Key.create(serverApproveLosingPollMessage)))
serverApproveGainingPollMessage.createVKey(),
serverApproveLosingPollMessage.createVKey()))
.build();
// When a transfer is requested, a poll message is created to notify the losing registrar.
PollMessage requestPollMessage =

View file

@ -214,7 +214,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
ofy().save().entities(entitiesToSave.build());
// Delete the billing event and poll messages that were written in case the transfer would have
// been implicitly server approved.
ofy().delete().keys(existingDomain.getTransferData().getServerApproveEntities());
tm().delete(existingDomain.getTransferData().getServerApproveEntities());
return responseBuilder
.setResData(createTransferResponse(
targetId, newDomain.getTransferData(), newDomain.getRegistrationExpirationTime()))

View file

@ -110,7 +110,7 @@ public final class DomainTransferCancelFlow implements TransactionalFlow {
updateAutorenewRecurrenceEndTime(existingDomain, END_OF_TIME);
// Delete the billing event and poll messages that were written in case the transfer would have
// been implicitly server approved.
ofy().delete().keys(existingDomain.getTransferData().getServerApproveEntities());
tm().delete(existingDomain.getTransferData().getServerApproveEntities());
return responseBuilder
.setResData(createTransferResponse(targetId, newDomain.getTransferData(), null))
.build();

View file

@ -112,7 +112,7 @@ public final class DomainTransferRejectFlow implements TransactionalFlow {
updateAutorenewRecurrenceEndTime(existingDomain, END_OF_TIME);
// Delete the billing event and poll messages that were written in case the transfer would have
// been implicitly server approved.
ofy().delete().keys(existingDomain.getTransferData().getServerApproveEntities());
tm().delete(existingDomain.getTransferData().getServerApproveEntities());
return responseBuilder
.setResData(createTransferResponse(targetId, newDomain.getTransferData(), null))
.build();

View file

@ -20,7 +20,6 @@ import static google.registry.util.DateTimeUtils.END_OF_TIME;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
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;
@ -37,6 +36,7 @@ import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferData.TransferServerApproveEntity;
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import java.util.Optional;
import javax.annotation.Nullable;
import org.joda.money.Money;
@ -52,37 +52,34 @@ public final class DomainTransferUtils {
TransferData.Builder transferDataBuilder,
ImmutableSet<TransferServerApproveEntity> serverApproveEntities,
Period transferPeriod) {
ImmutableSet.Builder<Key<? extends TransferServerApproveEntity>> serverApproveEntityKeys =
ImmutableSet.Builder<VKey<? extends TransferServerApproveEntity>> serverApproveEntityKeys =
new ImmutableSet.Builder<>();
for (TransferServerApproveEntity entity : serverApproveEntities) {
serverApproveEntityKeys.add(Key.create(entity));
serverApproveEntityKeys.add(entity.createVKey());
}
if (transferPeriod.getValue() != 0) {
// Unless superuser sets period to 0, add a transfer billing event.
transferDataBuilder.setServerApproveBillingEvent(
Key.create(
serverApproveEntities
.stream()
serverApproveEntities.stream()
.filter(BillingEvent.OneTime.class::isInstance)
.map(BillingEvent.OneTime.class::cast)
.collect(onlyElement())));
.collect(onlyElement())
.createVKey());
}
return transferDataBuilder
.setTransferStatus(TransferStatus.PENDING)
.setServerApproveAutorenewEvent(
Key.create(
serverApproveEntities
.stream()
serverApproveEntities.stream()
.filter(BillingEvent.Recurring.class::isInstance)
.map(BillingEvent.Recurring.class::cast)
.collect(onlyElement())))
.collect(onlyElement())
.createVKey())
.setServerApproveAutorenewPollMessage(
Key.create(
serverApproveEntities
.stream()
serverApproveEntities.stream()
.filter(PollMessage.Autorenew.class::isInstance)
.map(PollMessage.Autorenew.class::cast)
.collect(onlyElement())))
.collect(onlyElement())
.createVKey())
.setServerApproveEntities(serverApproveEntityKeys.build())
.setTransferPeriod(transferPeriod)
.build();

View file

@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@ -114,7 +115,7 @@ public final class ResourceTransferUtils {
R resource, R newResource, DateTime now, HistoryEntry historyEntry) {
if (resource.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) {
TransferData oldTransferData = resource.getTransferData();
ofy().delete().keys(oldTransferData.getServerApproveEntities());
tm().delete(oldTransferData.getServerApproveEntities());
ofy()
.save()
.entity(

View file

@ -345,6 +345,7 @@ public abstract class BillingEvent extends ImmutableObject
return Optional.ofNullable(allocationToken);
}
@Override
public VKey<OneTime> createVKey() {
return VKey.createOfy(getClass(), Key.create(this));
}
@ -482,6 +483,7 @@ public abstract class BillingEvent extends ImmutableObject
return recurrenceTimeOfYear;
}
@Override
public VKey<Recurring> createVKey() {
return VKey.createOfy(getClass(), Key.create(this));
}
@ -603,6 +605,7 @@ public abstract class BillingEvent extends ImmutableObject
return builder.build();
}
@Override
public VKey<Cancellation> createVKey() {
return VKey.createOfy(getClass(), Key.create(this));
}
@ -682,6 +685,11 @@ public abstract class BillingEvent extends ImmutableObject
return new Builder(clone(this));
}
@Override
public VKey<Modification> createVKey() {
return VKey.createOfy(this.getClass(), Key.create(this));
}
/**
* Create a new Modification billing event which is a refund of the given OneTime billing event
* and that is parented off the given HistoryEntry.

View file

@ -41,7 +41,6 @@ import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Transient;
import javax.xml.bind.annotation.XmlElement;
import org.joda.time.DateTime;
@ -171,8 +170,7 @@ public class ContactResource extends EppResource
ContactAuthInfo authInfo;
/** Data about any pending or past transfers on this contact. */
// TODO(b/153363295): Figure out how to persist transfer data
@Transient TransferData transferData;
TransferData transferData;
/**
* The time that this resource was last transferred.

View file

@ -253,7 +253,7 @@ public class DomainBase extends EppResource
String smdId;
/** Data about any pending or past transfers on this domain. */
@Transient TransferData transferData;
TransferData transferData;
/**
* The time that this resource was last transferred.
@ -438,8 +438,14 @@ public class DomainBase extends EppResource
.setRegistrationExpirationTime(expirationDate)
// Set the speculatively-written new autorenew events as the domain's autorenew
// events.
.setAutorenewBillingEvent(transferData.getServerApproveAutorenewEvent())
.setAutorenewPollMessage(transferData.getServerApproveAutorenewPollMessage());
.setAutorenewBillingEvent(
transferData.getServerApproveAutorenewEvent() == null
? null
: transferData.getServerApproveAutorenewEvent().getOfyKey())
.setAutorenewPollMessage(
transferData.getServerApproveAutorenewPollMessage() == null
? null
: transferData.getServerApproveAutorenewPollMessage().getOfyKey());
if (transferData.getTransferPeriod().getValue() == 1) {
// Set the grace period using a key to the prescheduled transfer billing event. Not using
// GracePeriod.forBillingEvent() here in order to avoid the actual Datastore fetch.
@ -450,7 +456,9 @@ public class DomainBase extends EppResource
transferExpirationTime.plus(
Registry.get(getTld()).getTransferGracePeriodLength()),
transferData.getGainingClientId(),
transferData.getServerApproveBillingEvent())));
transferData.getServerApproveBillingEvent() == null
? null
: transferData.getServerApproveBillingEvent().getOfyKey())));
} else {
// There won't be a billing event, so we don't need a grace period
builder.setGracePeriods(ImmutableSet.of());

View file

@ -16,6 +16,8 @@ package google.registry.model.domain;
import com.googlecode.objectify.annotation.Embed;
import google.registry.model.ImmutableObject;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlValue;
@ -25,6 +27,7 @@ import javax.xml.bind.annotation.XmlValue;
@javax.persistence.Embeddable
public class Period extends ImmutableObject {
@Enumerated(EnumType.STRING)
@XmlAttribute
Unit unit;

View file

@ -43,6 +43,7 @@ import google.registry.model.transfer.TransferData.TransferServerApproveEntity;
import google.registry.model.transfer.TransferResponse;
import google.registry.model.transfer.TransferResponse.ContactTransferResponse;
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
import google.registry.persistence.VKey;
import google.registry.persistence.WithLongVKey;
import java.util.List;
import java.util.Optional;
@ -150,6 +151,9 @@ public abstract class PollMessage extends ImmutableObject
public abstract ImmutableList<ResponseData> getResponseData();
@Override
public abstract VKey<? extends PollMessage> createVKey();
/** Override Buildable.asBuilder() to give this method stronger typing. */
@Override
public abstract Builder<?, ?> asBuilder();
@ -291,6 +295,11 @@ public abstract class PollMessage extends ImmutableObject
@Column(name = "transfer_response_contact_id")
String contactId;
@Override
public VKey<OneTime> createVKey() {
return VKey.createOfy(this.getClass(), Key.create(this));
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));
@ -387,6 +396,11 @@ public abstract class PollMessage extends ImmutableObject
return autorenewEndTime;
}
@Override
public VKey<Autorenew> createVKey() {
return VKey.createOfy(this.getClass(), Key.create(this));
}
@Override
public ImmutableList<ResponseData> getResponseData() {
// Note that the event time is when the auto-renew occured, so the expiration time in the

View file

@ -16,6 +16,7 @@ package google.registry.model.transfer;
import google.registry.model.Buildable.GenericBuilder;
import google.registry.model.ImmutableObject;
import javax.persistence.Column;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.MappedSuperclass;
@ -38,6 +39,7 @@ public abstract class BaseTransferObject extends ImmutableObject {
/** The gaining registrar of the current or last transfer. Can be null if never transferred. */
@XmlElement(name = "reID")
@Column(name = "transfer_gaining_registrar_id")
String gainingClientId;
/** The time that the last transfer was requested. Can be null if never transferred. */
@ -46,6 +48,7 @@ public abstract class BaseTransferObject extends ImmutableObject {
/** The losing registrar of the current or last transfer. Can be null if never transferred. */
@XmlElement(name = "acID")
@Column(name = "transfer_losing_registrar_id")
String losingClientId;
/**
@ -54,6 +57,7 @@ public abstract class BaseTransferObject extends ImmutableObject {
* this holds the time that the last pending transfer ended. Can be null if never transferred.
*/
@XmlElement(name = "acDate")
@Column(name = "transfer_pending_expiration_time")
DateTime pendingTransferExpirationTime;
public TransferStatus getTransferStatus() {

View file

@ -17,8 +17,8 @@ package google.registry.model.transfer;
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Embed;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.IgnoreSave;
import com.googlecode.objectify.annotation.Unindex;
import com.googlecode.objectify.condition.IfNull;
@ -29,10 +29,14 @@ import google.registry.model.domain.Period;
import google.registry.model.domain.Period.Unit;
import google.registry.model.eppcommon.Trid;
import google.registry.model.poll.PollMessage;
import google.registry.persistence.VKey;
import java.util.Set;
import javax.annotation.Nullable;
import javax.persistence.ElementCollection;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Transient;
import org.joda.time.DateTime;
/**
@ -47,7 +51,16 @@ public class TransferData extends BaseTransferObject implements Buildable {
public static final TransferData EMPTY = new TransferData();
/** The transaction id of the most recent transfer request (or null if there never was one). */
@Embedded Trid transferRequestTrid;
@Embedded
@AttributeOverrides({
@AttributeOverride(
name = "serverTransactionId",
column = @Column(name = "transfer_server_txn_id")),
@AttributeOverride(
name = "clientTransactionId",
column = @Column(name = "transfer_client_txn_id"))
})
Trid transferRequestTrid;
/**
* The period to extend the registration upon completion of the transfer.
@ -55,15 +68,20 @@ public class TransferData extends BaseTransferObject implements Buildable {
* <p>By default, domain transfers are for one year. This can be changed to zero by using the
* superuser EPP extension.
*/
@Embedded Period transferPeriod = Period.create(1, Unit.YEARS);
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "unit", column = @Column(name = "transfer_renew_period_unit")),
@AttributeOverride(name = "value", column = @Column(name = "transfer_renew_period_value"))
})
Period transferPeriod = Period.create(1, Unit.YEARS);
/**
* The registration expiration time resulting from the approval - speculative or actual - of the
* most recent transfer request, applicable for domains only.
*
* <p>For pending transfers, this is the expiration time that will take effect under a projected
* server approval. For approved transfers, this is the actual expiration time of the domain as
* of the moment of transfer completion. For rejected or cancelled transfers, this field will be
* server approval. For approved transfers, this is the actual expiration time of the domain as of
* the moment of transfer completion. For rejected or cancelled transfers, this field will be
* reset to null.
*
* <p>Note that even when this field is set, it does not necessarily mean that the post-transfer
@ -72,6 +90,7 @@ public class TransferData extends BaseTransferObject implements Buildable {
* bundled renewal simply subsumes the recent autorenewal, resulting in the same expiration time.
*/
// TODO(b/36405140): backfill this field for existing domains to which it should apply.
@Column(name = "transfer_registration_expiration_time")
DateTime transferredRegistrationExpirationTime;
/**
@ -83,18 +102,35 @@ public class TransferData extends BaseTransferObject implements Buildable {
* pending transfer is explicitly approved, rejected or cancelled, the referenced entities should
* be deleted.
*/
@Transient
@IgnoreSave(IfNull.class)
@ElementCollection
Set<Key<? extends TransferServerApproveEntity>> serverApproveEntities;
Set<VKey<? extends TransferServerApproveEntity>> serverApproveEntities;
// The following 3 fields are the replacement for serverApproveEntities in Cloud SQL.
// TODO(shicong): Add getter/setter for these 3 fields and use them in the application code.
@Ignore
@Column(name = "transfer_gaining_poll_message_id")
Long gainingTransferPollMessageId;
@Ignore
@Column(name = "transfer_losing_poll_message_id")
Long losingTransferPollMessageId;
@Ignore
@Column(name = "transfer_billing_cancellation_id")
Long billingCancellationId;
/**
* The regular one-time billing event that will be charged for a server-approved transfer.
*
* <p>This field should be null if there is not currently a pending transfer or if the object
* being transferred is not a domain.
*
* <p>TODO(b/158230654) Remove unused columns for TransferData in Contact table.
*/
@IgnoreSave(IfNull.class)
Key<BillingEvent.OneTime> serverApproveBillingEvent;
@Column(name = "transfer_billing_event_id")
VKey<BillingEvent.OneTime> serverApproveBillingEvent;
/**
* The autorenew billing event that should be associated with this resource after the transfer.
@ -103,7 +139,8 @@ public class TransferData extends BaseTransferObject implements Buildable {
* being transferred is not a domain.
*/
@IgnoreSave(IfNull.class)
Key<BillingEvent.Recurring> serverApproveAutorenewEvent;
@Column(name = "transfer_billing_recurrence_id")
VKey<BillingEvent.Recurring> serverApproveAutorenewEvent;
/**
* The autorenew poll message that should be associated with this resource after the transfer.
@ -112,7 +149,8 @@ public class TransferData extends BaseTransferObject implements Buildable {
* being transferred is not a domain.
*/
@IgnoreSave(IfNull.class)
Key<PollMessage.Autorenew> serverApproveAutorenewPollMessage;
@Column(name = "transfer_autorenew_poll_message_id")
VKey<PollMessage.Autorenew> serverApproveAutorenewPollMessage;
@Nullable
public Trid getTransferRequestTrid() {
@ -128,22 +166,22 @@ public class TransferData extends BaseTransferObject implements Buildable {
return transferredRegistrationExpirationTime;
}
public ImmutableSet<Key<? extends TransferServerApproveEntity>> getServerApproveEntities() {
public ImmutableSet<VKey<? extends TransferServerApproveEntity>> getServerApproveEntities() {
return nullToEmptyImmutableCopy(serverApproveEntities);
}
@Nullable
public Key<BillingEvent.OneTime> getServerApproveBillingEvent() {
public VKey<BillingEvent.OneTime> getServerApproveBillingEvent() {
return serverApproveBillingEvent;
}
@Nullable
public Key<BillingEvent.Recurring> getServerApproveAutorenewEvent() {
public VKey<BillingEvent.Recurring> getServerApproveAutorenewEvent() {
return serverApproveAutorenewEvent;
}
@Nullable
public Key<PollMessage.Autorenew> getServerApproveAutorenewPollMessage() {
public VKey<PollMessage.Autorenew> getServerApproveAutorenewPollMessage() {
return serverApproveAutorenewPollMessage;
}
@ -202,25 +240,25 @@ public class TransferData extends BaseTransferObject implements Buildable {
}
public Builder setServerApproveEntities(
ImmutableSet<Key<? extends TransferServerApproveEntity>> serverApproveEntities) {
ImmutableSet<VKey<? extends TransferServerApproveEntity>> serverApproveEntities) {
getInstance().serverApproveEntities = serverApproveEntities;
return this;
}
public Builder setServerApproveBillingEvent(
Key<BillingEvent.OneTime> serverApproveBillingEvent) {
VKey<BillingEvent.OneTime> serverApproveBillingEvent) {
getInstance().serverApproveBillingEvent = serverApproveBillingEvent;
return this;
}
public Builder setServerApproveAutorenewEvent(
Key<BillingEvent.Recurring> serverApproveAutorenewEvent) {
VKey<BillingEvent.Recurring> serverApproveAutorenewEvent) {
getInstance().serverApproveAutorenewEvent = serverApproveAutorenewEvent;
return this;
}
public Builder setServerApproveAutorenewPollMessage(
Key<PollMessage.Autorenew> serverApproveAutorenewPollMessage) {
VKey<PollMessage.Autorenew> serverApproveAutorenewPollMessage) {
getInstance().serverApproveAutorenewPollMessage = serverApproveAutorenewPollMessage;
return this;
}
@ -230,5 +268,7 @@ public class TransferData extends BaseTransferObject implements Buildable {
* Marker interface for objects that are written in anticipation of a server approval, and
* therefore need to be deleted under any other outcome.
*/
public interface TransferServerApproveEntity {}
public interface TransferServerApproveEntity {
VKey<? extends TransferServerApproveEntity> createVKey();
}
}

View file

@ -17,6 +17,7 @@ package google.registry.persistence;
import static com.google.common.base.Preconditions.checkState;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.googlecode.objectify.Key;
import google.registry.model.ImmutableObject;
import java.util.Optional;
@ -57,6 +58,23 @@ public class VKey<T> extends ImmutableObject {
return new VKey(kind, ofyKey, null);
}
/**
* Creates a {@link VKey} which only contains the ofy primary key by specifying the id of the
* {@link Key}.
*/
public static <T> VKey<T> createOfy(Class<? extends T> kind, long id) {
return createOfy(kind, Key.create(kind, id));
}
/**
* Creates a {@link VKey} which only contains the ofy primary key by specifying the name of the
* {@link Key}.
*/
public static <T> VKey<T> createOfy(Class<? extends T> kind, String name) {
checkArgumentNotNull(kind, "name must not be null");
return createOfy(kind, Key.create(kind, name));
}
/** Creates a {@link VKey} which only contains both sql and ofy primary key. */
public static <T> VKey<T> create(
Class<? extends T> kind, Object sqlKey, com.googlecode.objectify.Key ofyKey) {

View file

@ -0,0 +1,37 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import google.registry.model.transfer.TransferData.TransferServerApproveEntity;
import google.registry.persistence.VKey;
import java.util.Set;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
/** {@link AttributeConverter} for {@link Set}. */
@Converter(autoApply = true)
public class TransferServerApproveEntitySetConverter
extends StringSetConverterBase<VKey<? extends TransferServerApproveEntity>> {
@Override
String toString(VKey<? extends TransferServerApproveEntity> element) {
return String.valueOf(element.getSqlKey());
}
@Override
VKey<? extends TransferServerApproveEntity> fromString(String value) {
return VKey.createSql(TransferServerApproveEntity.class, Long.parseLong(value));
}
}

View file

@ -56,15 +56,18 @@
<class>google.registry.persistence.converter.StringListConverter</class>
<class>google.registry.persistence.converter.StringSetConverter</class>
<class>google.registry.persistence.converter.TldStateTransitionConverter</class>
<class>google.registry.persistence.converter.TransferServerApproveEntitySetConverter</class>
<class>google.registry.persistence.converter.UpdateAutoTimestampConverter</class>
<class>google.registry.persistence.converter.ZonedDateTimeConverter</class>
<!-- Generated converters for VKey -->
<class>google.registry.model.billing.VKeyConverter_BillingEvent</class>
<class>google.registry.model.domain.VKeyConverter_DomainBase</class>
<class>google.registry.model.contact.VKeyConverter_ContactResource</class>
<class>google.registry.model.domain.token.VKeyConverter_AllocationToken</class>
<class>google.registry.model.host.VKeyConverter_HostResource</class>
<class>google.registry.model.contact.VKeyConverter_ContactResource</class>
<class>google.registry.model.poll.VKeyConverter_Autorenew</class>
<class>google.registry.model.poll.VKeyConverter_OneTime</class>
<!-- TODO(weiminyu): check out application-layer validation. -->
<validation-mode>NONE</validation-mode>

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,9 +332,8 @@ 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(
new BillingEvent.Recurring.Builder()
.setReason(Reason.RENEW)
@ -344,9 +343,9 @@ public class DomainBaseToXjcConverterTest {
.setEventTime(END_OF_TIME)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(historyEntry)
.build())))
.build())
.createVKey())
.setServerApproveAutorenewPollMessage(
Key.create(
persistResource(
new Autorenew.Builder()
.setTargetId("example.xn--q9jyb4c")
@ -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,9 +174,8 @@ 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(
new BillingEvent.Recurring.Builder()
.setReason(Reason.RENEW)
@ -186,9 +185,9 @@ final class RdeFixtures {
.setEventTime(END_OF_TIME)
.setRecurrenceEndTime(END_OF_TIME)
.setParent(historyEntry)
.build())))
.build())
.createVKey())
.setServerApproveAutorenewPollMessage(
Key.create(
persistResource(
new Autorenew.Builder()
.setTargetId("example." + tld)
@ -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,31 +443,36 @@ 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(
persistResource(
createPollMessageForImplicitTransfer(
contact,
historyEntryContactTransfer,
"NewRegistrar",
requestTime,
expirationTime,
null))),
Key.create(persistResource(
null))
.createVKey(),
persistResource(
createPollMessageForImplicitTransfer(
contact,
historyEntryContactTransfer,
"TheRegistrar",
requestTime,
expirationTime,
null)))))
.setTransferRequestTrid(Trid.create("transferClient-trid", "transferServer-trid"))
null))
.createVKey()))
.setTransferRequestTrid(
Trid.create("transferClient-trid", "transferServer-trid"))
.build())
.build());
}
@ -585,36 +590,44 @@ public class DatastoreHelper {
}
TransferData.Builder transferDataBuilder =
createTransferDataBuilder(requestTime, expirationTime);
return persistResource(domain.asBuilder()
return persistResource(
domain
.asBuilder()
.setPersistedCurrentSponsorClientId("TheRegistrar")
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(transferDataBuilder
.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(
.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))),
Key.create(persistResource(
extendedRegistrationExpirationTime))
.createVKey(),
persistResource(
createPollMessageForImplicitTransfer(
domain,
historyEntryDomainTransfer,
"TheRegistrar",
requestTime,
expirationTime,
extendedRegistrationExpirationTime)))))
.setTransferRequestTrid(Trid.create("transferClient-trid", "transferServer-trid"))
extendedRegistrationExpirationTime))
.createVKey()))
.setTransferRequestTrid(
Trid.create("transferClient-trid", "transferServer-trid"))
.build())
.build());
}

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;

View file

@ -0,0 +1,84 @@
-- Copyright 2020 The Nomulus Authors. All Rights Reserved.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
alter table "Contact"
add column transfer_gaining_poll_message_id int8,
add column transfer_losing_poll_message_id int8,
add column transfer_billing_cancellation_id int8,
add column transfer_billing_event_id int8,
add column transfer_billing_recurrence_id int8,
add column transfer_autorenew_poll_message_id int8,
add column transfer_renew_period_unit text,
add column transfer_renew_period_value int4,
add column transfer_client_txn_id text,
add column transfer_server_txn_id text,
add column transfer_registration_expiration_time timestamptz,
add column transfer_gaining_registrar_id text,
add column transfer_losing_registrar_id text,
add column transfer_pending_expiration_time timestamptz,
add column transfer_request_time timestamptz,
add column transfer_status text;
alter table "Domain"
add column transfer_gaining_poll_message_id int8,
add column transfer_losing_poll_message_id int8,
add column transfer_billing_cancellation_id int8,
add column transfer_billing_event_id int8,
add column transfer_billing_recurrence_id int8,
add column transfer_autorenew_poll_message_id int8,
add column transfer_renew_period_unit text,
add column transfer_renew_period_value int4,
add column transfer_client_txn_id text,
add column transfer_server_txn_id text,
add column transfer_registration_expiration_time timestamptz,
add column transfer_gaining_registrar_id text,
add column transfer_losing_registrar_id text,
add column transfer_pending_expiration_time timestamptz,
add column transfer_request_time timestamptz,
add column transfer_status text;
alter table if exists "Contact"
add constraint fk_contact_transfer_gaining_registrar_id
foreign key (transfer_gaining_registrar_id)
references "Registrar";
alter table if exists "Contact"
add constraint fk_contact_transfer_losing_registrar_id
foreign key (transfer_losing_registrar_id)
references "Registrar";
alter table if exists "Domain"
add constraint fk_domain_transfer_gaining_registrar_id
foreign key (transfer_gaining_registrar_id)
references "Registrar";
alter table if exists "Domain"
add constraint fk_domain_transfer_losing_registrar_id
foreign key (transfer_losing_registrar_id)
references "Registrar";
alter table if exists "Domain"
add constraint fk_domain_transfer_billing_cancellation_id
foreign key (transfer_billing_cancellation_id)
references "BillingCancellation";
alter table if exists "Domain"
add constraint fk_domain_transfer_billing_event_id
foreign key (transfer_billing_event_id)
references "BillingEvent";
alter table if exists "Domain"
add constraint fk_domain_transfer_billing_recurrence_id
foreign key (transfer_billing_recurrence_id)
references "BillingRecurrence";

View file

@ -118,6 +118,22 @@
addr_local_org text,
addr_local_type text,
search_name text,
transfer_billing_cancellation_id int8,
transfer_gaining_poll_message_id int8,
transfer_losing_poll_message_id int8,
transfer_billing_recurrence_id int8,
transfer_autorenew_poll_message_id int8,
transfer_billing_event_id int8,
transfer_renew_period_unit text,
transfer_renew_period_value int4,
transfer_client_txn_id text,
transfer_server_txn_id text,
transfer_registration_expiration_time timestamptz,
transfer_gaining_registrar_id text,
transfer_losing_registrar_id text,
transfer_pending_expiration_time timestamptz,
transfer_request_time timestamptz,
transfer_status text,
voice_phone_extension text,
voice_phone_number text,
primary key (repo_id)
@ -165,6 +181,22 @@
subordinate_hosts text[],
tech_contact text,
tld text,
transfer_billing_cancellation_id int8,
transfer_gaining_poll_message_id int8,
transfer_losing_poll_message_id int8,
transfer_billing_recurrence_id int8,
transfer_autorenew_poll_message_id int8,
transfer_billing_event_id int8,
transfer_renew_period_unit text,
transfer_renew_period_value int4,
transfer_client_txn_id text,
transfer_server_txn_id text,
transfer_registration_expiration_time timestamptz,
transfer_gaining_registrar_id text,
transfer_losing_registrar_id text,
transfer_pending_expiration_time timestamptz,
transfer_request_time timestamptz,
transfer_status text,
primary key (repo_id)
);

View file

@ -241,7 +241,23 @@ CREATE TABLE public."Contact" (
addr_local_type text,
search_name text,
voice_phone_extension text,
voice_phone_number text
voice_phone_number text,
transfer_gaining_poll_message_id bigint,
transfer_losing_poll_message_id bigint,
transfer_billing_cancellation_id bigint,
transfer_billing_event_id bigint,
transfer_billing_recurrence_id bigint,
transfer_autorenew_poll_message_id bigint,
transfer_renew_period_unit text,
transfer_renew_period_value integer,
transfer_client_txn_id text,
transfer_server_txn_id text,
transfer_registration_expiration_time timestamp with time zone,
transfer_gaining_registrar_id text,
transfer_losing_registrar_id text,
transfer_pending_expiration_time timestamp with time zone,
transfer_request_time timestamp with time zone,
transfer_status text
);
@ -286,7 +302,23 @@ CREATE TABLE public."Domain" (
admin_contact text,
billing_contact text,
registrant_contact text,
tech_contact text
tech_contact text,
transfer_gaining_poll_message_id bigint,
transfer_losing_poll_message_id bigint,
transfer_billing_cancellation_id bigint,
transfer_billing_event_id bigint,
transfer_billing_recurrence_id bigint,
transfer_autorenew_poll_message_id bigint,
transfer_renew_period_unit text,
transfer_renew_period_value integer,
transfer_client_txn_id text,
transfer_server_txn_id text,
transfer_registration_expiration_time timestamp with time zone,
transfer_gaining_registrar_id text,
transfer_losing_registrar_id text,
transfer_pending_expiration_time timestamp with time zone,
transfer_request_time timestamp with time zone,
transfer_status text
);
@ -1127,6 +1159,22 @@ ALTER TABLE ONLY public."BillingRecurrence"
ADD CONSTRAINT fk_billing_recurrence_client_id FOREIGN KEY (client_id) REFERENCES public."Registrar"(client_id);
--
-- Name: Contact fk_contact_transfer_gaining_registrar_id; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Contact"
ADD CONSTRAINT fk_contact_transfer_gaining_registrar_id FOREIGN KEY (transfer_gaining_registrar_id) REFERENCES public."Registrar"(client_id);
--
-- Name: Contact fk_contact_transfer_losing_registrar_id; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Contact"
ADD CONSTRAINT fk_contact_transfer_losing_registrar_id FOREIGN KEY (transfer_losing_registrar_id) REFERENCES public."Registrar"(client_id);
--
-- Name: Domain fk_domain_admin_contact; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -1159,6 +1207,46 @@ ALTER TABLE ONLY public."Domain"
ADD CONSTRAINT fk_domain_tech_contact FOREIGN KEY (tech_contact) REFERENCES public."Contact"(repo_id);
--
-- Name: Domain fk_domain_transfer_billing_cancellation_id; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Domain"
ADD CONSTRAINT fk_domain_transfer_billing_cancellation_id FOREIGN KEY (transfer_billing_cancellation_id) REFERENCES public."BillingCancellation"(billing_cancellation_id);
--
-- Name: Domain fk_domain_transfer_billing_event_id; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Domain"
ADD CONSTRAINT fk_domain_transfer_billing_event_id FOREIGN KEY (transfer_billing_event_id) REFERENCES public."BillingEvent"(billing_event_id);
--
-- Name: Domain fk_domain_transfer_billing_recurrence_id; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Domain"
ADD CONSTRAINT fk_domain_transfer_billing_recurrence_id FOREIGN KEY (transfer_billing_recurrence_id) REFERENCES public."BillingRecurrence"(billing_recurrence_id);
--
-- Name: Domain fk_domain_transfer_gaining_registrar_id; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Domain"
ADD CONSTRAINT fk_domain_transfer_gaining_registrar_id FOREIGN KEY (transfer_gaining_registrar_id) REFERENCES public."Registrar"(client_id);
--
-- Name: Domain fk_domain_transfer_losing_registrar_id; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public."Domain"
ADD CONSTRAINT fk_domain_transfer_losing_registrar_id FOREIGN KEY (transfer_losing_registrar_id) REFERENCES public."Registrar"(client_id);
--
-- Name: DomainHost fk_domainhost_host_valid; Type: FK CONSTRAINT; Schema: public; Owner: -
--