Refactor TransferData to remove unused fields in Contact table (#623)

* Add DomainTransferData and ContactTransferData

* Refactor TransferData to remove unused fields in Contact table

* Add scope for TransferData's type parameter
This commit is contained in:
Shicong Huang 2020-06-16 10:42:57 -04:00 committed by GitHub
parent 3a3adcde0c
commit 56c9e81bcd
38 changed files with 491 additions and 324 deletions

View file

@ -46,7 +46,7 @@ import google.registry.model.eppoutput.EppResponse;
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.ContactTransferData;
import google.registry.model.transfer.TransferStatus;
import java.util.Optional;
import javax.inject.Inject;
@ -112,7 +112,8 @@ public final class ContactTransferRequestFlow implements TransactionalFlow {
.setParent(Key.create(existingContact))
.build();
DateTime transferExpirationTime = now.plus(automaticTransferLength);
TransferData serverApproveTransferData = new TransferData.Builder()
ContactTransferData serverApproveTransferData =
new ContactTransferData.Builder()
.setTransferRequestTime(now)
.setTransferRequestTrid(trid)
.setGainingClientId(gainingClientId)
@ -126,7 +127,7 @@ 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 =
ContactTransferData pendingTransferData =
serverApproveTransferData
.asBuilder()
.setTransferStatus(TransferStatus.PENDING)

View file

@ -58,7 +58,7 @@ import google.registry.model.registry.Registry;
import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import java.util.Optional;
import javax.inject.Inject;
@ -112,7 +112,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
if (!isSuperuser) {
checkAllowedAccessToTld(clientId, tld);
}
TransferData transferData = existingDomain.getTransferData();
DomainTransferData transferData = existingDomain.getTransferData();
String gainingClientId = transferData.getGainingClientId();
Registry registry = Registry.get(existingDomain.getTld());
HistoryEntry historyEntry = buildHistoryEntry(existingDomain, registry, now, gainingClientId);

View file

@ -32,7 +32,7 @@ import google.registry.model.domain.DomainBase;
import google.registry.model.eppcommon.AuthInfo;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.util.Clock;
import java.util.Optional;
@ -74,7 +74,7 @@ public final class DomainTransferQueryFlow implements Flow {
verifyOptionalAuthInfo(authInfo, domain);
// Most of the fields on the transfer response are required, so there's no way to return valid
// XML if the object has never been transferred (and hence the fields aren't populated).
TransferData transferData = domain.getTransferData();
DomainTransferData transferData = domain.getTransferData();
if (transferData.getTransferStatus() == null) {
throw new NoTransferHistoryToQueryException();
}

View file

@ -69,7 +69,7 @@ import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferData.TransferServerApproveEntity;
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
import google.registry.model.transfer.TransferStatus;
@ -198,9 +198,9 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
feesAndCredits.map(FeesAndCredits::getTotalCost),
now);
// Create the transfer data that represents the pending transfer.
TransferData pendingTransferData =
DomainTransferData pendingTransferData =
createPendingTransferData(
new TransferData.Builder()
new DomainTransferData.Builder()
.setTransferRequestTrid(trid)
.setTransferRequestTime(now)
.setGainingClientId(gainingClientId)

View file

@ -32,6 +32,7 @@ import google.registry.model.poll.PendingActionNotificationResponse.DomainPendin
import google.registry.model.poll.PollMessage;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferData.TransferServerApproveEntity;
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
@ -48,8 +49,8 @@ import org.joda.time.DateTime;
public final class DomainTransferUtils {
/** Sets up {@link TransferData} for a domain with links to entities for server approval. */
public static TransferData createPendingTransferData(
TransferData.Builder transferDataBuilder,
public static DomainTransferData createPendingTransferData(
DomainTransferData.Builder transferDataBuilder,
ImmutableSet<TransferServerApproveEntity> serverApproveEntities,
Period transferPeriod) {
ImmutableSet.Builder<VKey<? extends TransferServerApproveEntity>> serverApproveEntityKeys =
@ -110,8 +111,8 @@ public final class DomainTransferUtils {
DateTime now) {
String targetId = existingDomain.getFullyQualifiedDomainName();
// Create a TransferData for the server-approve case to use for the speculative poll messages.
TransferData serverApproveTransferData =
new TransferData.Builder()
DomainTransferData serverApproveTransferData =
new DomainTransferData.Builder()
.setTransferRequestTrid(trid)
.setTransferRequestTime(now)
.setGainingClientId(gainingClientId)

View file

@ -193,8 +193,8 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
public interface ForeignKeyedEppResource {}
/** An interface for resources that have transfer data. */
public interface ResourceWithTransferData {
TransferData getTransferData();
public interface ResourceWithTransferData<T extends TransferData> {
T getTransferData();
/**
* The time that this resource was last transferred.
@ -205,8 +205,9 @@ public abstract class EppResource extends BackupGroupRoot implements Buildable {
}
/** An interface for builders of resources that have transfer data. */
public interface BuilderWithTransferData<B extends BuilderWithTransferData<B>> {
B setTransferData(TransferData transferData);
public interface BuilderWithTransferData<
T extends TransferData, B extends BuilderWithTransferData<T, B>> {
B setTransferData(T transferData);
/** Set the time when this resource was transferred. */
B setLastTransferTime(DateTime lastTransferTime);

View file

@ -39,6 +39,7 @@ import google.registry.model.index.ForeignKeyIndex;
import google.registry.model.ofy.CommitLogManifest;
import google.registry.model.ofy.CommitLogMutation;
import google.registry.model.registry.Registry;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import java.util.List;
@ -222,17 +223,23 @@ public final class EppResourceUtils {
}
/** Process an automatic transfer on a resource. */
public static <B extends EppResource.Builder<?, B> & BuilderWithTransferData<B>>
public static <
T extends TransferData,
B extends EppResource.Builder<?, B> & BuilderWithTransferData<T, B>>
void setAutomaticTransferSuccessProperties(B builder, TransferData transferData) {
checkArgument(TransferStatus.PENDING.equals(transferData.getTransferStatus()));
builder.removeStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(transferData.asBuilder()
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.setServerApproveEntities(null)
TransferData.Builder transferDataBuilder = transferData.asBuilder();
transferDataBuilder.setTransferStatus(TransferStatus.SERVER_APPROVED);
transferDataBuilder.setServerApproveEntities(null);
if (transferData instanceof DomainTransferData) {
((DomainTransferData.Builder) transferDataBuilder)
.setServerApproveBillingEvent(null)
.setServerApproveAutorenewEvent(null)
.setServerApproveAutorenewPollMessage(null)
.build())
.setServerApproveAutorenewPollMessage(null);
}
builder
.removeStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData((T) transferDataBuilder.build())
.setLastTransferTime(transferData.getPendingTransferExpirationTime())
.setPersistedCurrentSponsorClientId(transferData.getGainingClientId());
}
@ -245,10 +252,11 @@ public final class EppResourceUtils {
* </ul>
*/
public static <
T extends EppResource & ResourceWithTransferData,
B extends EppResource.Builder<?, B> & BuilderWithTransferData<B>>
void projectResourceOntoBuilderAtTime(T resource, B builder, DateTime now) {
TransferData transferData = resource.getTransferData();
T extends TransferData,
E extends EppResource & ResourceWithTransferData<T>,
B extends EppResource.Builder<?, B> & BuilderWithTransferData<T, B>>
void projectResourceOntoBuilderAtTime(E resource, B builder, DateTime now) {
T transferData = resource.getTransferData();
// If there's a pending transfer that has expired, process it.
DateTime expirationTime = transferData.getPendingTransferExpirationTime();
if (TransferStatus.PENDING.equals(transferData.getTransferStatus())

View file

@ -36,6 +36,7 @@ import google.registry.model.poll.PendingActionNotificationResponse.ContactPendi
import google.registry.model.poll.PendingActionNotificationResponse.DomainPendingActionNotificationResponse;
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferResponse;
import google.registry.model.transfer.TransferResponse.ContactTransferResponse;
@ -63,12 +64,13 @@ public final class ResourceTransferUtils {
if (eppResource instanceof ContactResource) {
builder = new ContactTransferResponse.Builder().setContactId(eppResource.getForeignKey());
} else {
DomainTransferData domainTransferData = (DomainTransferData) transferData;
builder =
new DomainTransferResponse.Builder()
.setFullyQualifiedDomainName(eppResource.getForeignKey())
.setExtendedRegistrationExpirationTime(
ADD_EXDATE_STATUSES.contains(transferData.getTransferStatus())
? transferData.getTransferredRegistrationExpirationTime()
ADD_EXDATE_STATUSES.contains(domainTransferData.getTransferStatus())
? domainTransferData.getTransferredRegistrationExpirationTime()
: null);
}
builder.setGainingClientId(transferData.getGainingClientId())
@ -142,20 +144,22 @@ public final class ResourceTransferUtils {
*/
private static <
R extends EppResource & ResourceWithTransferData,
B extends EppResource.Builder<R, B> & BuilderWithTransferData<B>>
B extends EppResource.Builder<R, B> & BuilderWithTransferData<TransferData, B>>
B resolvePendingTransfer(R resource, TransferStatus transferStatus, DateTime now) {
checkArgument(
resource.getStatusValues().contains(StatusValue.PENDING_TRANSFER),
"Resource is not in pending transfer status.");
checkArgument(
!TransferData.EMPTY.equals(resource.getTransferData()),
"No old transfer data to resolve.");
checkArgument(!resource.getTransferData().isEmpty(), "No old transfer data to resolve.");
@SuppressWarnings("unchecked")
B builder = (B) resource.asBuilder();
return builder
.removeStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(
resource.getTransferData().copyConstantFieldsToBuilder()
(TransferData)
resource
.getTransferData()
.copyConstantFieldsToBuilder()
.setTransferStatus(transferStatus)
.setPendingTransferExpirationTime(checkNotNull(now))
.build());
@ -171,7 +175,7 @@ public final class ResourceTransferUtils {
*/
public static <
R extends EppResource & ResourceWithTransferData,
B extends EppResource.Builder<R, B> & BuilderWithTransferData<B>>
B extends EppResource.Builder<R, B> & BuilderWithTransferData<TransferData, B>>
R approvePendingTransfer(R resource, TransferStatus transferStatus, DateTime now) {
checkArgument(transferStatus.isApproved(), "Not an approval transfer status");
B builder = resolvePendingTransfer(resource, transferStatus, now);

View file

@ -30,7 +30,7 @@ import google.registry.model.EppResource.ResourceWithTransferData;
import google.registry.model.annotations.ExternalMessagingName;
import google.registry.model.annotations.ReportedOn;
import google.registry.model.contact.PostalInfo.Type;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.ContactTransferData;
import google.registry.persistence.VKey;
import google.registry.persistence.WithStringVKey;
import google.registry.schema.replay.DatastoreAndSqlEntity;
@ -170,7 +170,7 @@ public class ContactResource extends EppResource
ContactAuthInfo authInfo;
/** Data about any pending or past transfers on this contact. */
TransferData transferData;
ContactTransferData transferData;
/**
* The time that this resource was last transferred.
@ -242,8 +242,8 @@ public class ContactResource extends EppResource
}
@Override
public final TransferData getTransferData() {
return Optional.ofNullable(transferData).orElse(TransferData.EMPTY);
public final ContactTransferData getTransferData() {
return Optional.ofNullable(transferData).orElse(ContactTransferData.EMPTY);
}
@Override
@ -285,7 +285,7 @@ public class ContactResource extends EppResource
/** A builder for constructing {@link ContactResource}, since it is immutable. */
public static class Builder extends EppResource.Builder<ContactResource, Builder>
implements BuilderWithTransferData<Builder> {
implements BuilderWithTransferData<ContactTransferData, Builder> {
public Builder() {}
@ -350,7 +350,7 @@ public class ContactResource extends EppResource
}
@Override
public Builder setTransferData(TransferData transferData) {
public Builder setTransferData(ContactTransferData transferData) {
getInstance().transferData = transferData;
return this;
}
@ -380,7 +380,7 @@ public class ContactResource extends EppResource
public ContactResource build() {
ContactResource instance = getInstance();
// If TransferData is totally empty, set it to null.
if (TransferData.EMPTY.equals(instance.transferData)) {
if (ContactTransferData.EMPTY.equals(instance.transferData)) {
setTransferData(null);
}
// Set the searchName using the internationalized and localized postal info names.

View file

@ -63,7 +63,7 @@ import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.model.poll.PollMessage;
import google.registry.model.registry.Registry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import google.registry.persistence.WithStringVKey;
@ -110,7 +110,9 @@ import org.joda.time.Interval;
@WithStringVKey
@ExternalMessagingName("domain")
public class DomainBase extends EppResource
implements DatastoreAndSqlEntity, ForeignKeyedEppResource, ResourceWithTransferData {
implements DatastoreAndSqlEntity,
ForeignKeyedEppResource,
ResourceWithTransferData<DomainTransferData> {
/** The max number of years that a domain can be registered for, as set by ICANN policy. */
public static final int MAX_REGISTRATION_YEARS = 10;
@ -253,7 +255,7 @@ public class DomainBase extends EppResource
String smdId;
/** Data about any pending or past transfers on this domain. */
TransferData transferData;
DomainTransferData transferData;
/**
* The time that this resource was last transferred.
@ -322,8 +324,8 @@ public class DomainBase extends EppResource
}
@Override
public TransferData getTransferData() {
return Optional.ofNullable(transferData).orElse(TransferData.EMPTY);
public DomainTransferData getTransferData() {
return Optional.ofNullable(transferData).orElse(DomainTransferData.EMPTY);
}
@Override
@ -402,7 +404,7 @@ public class DomainBase extends EppResource
@Override
public DomainBase cloneProjectedAtTime(final DateTime now) {
TransferData transferData = getTransferData();
DomainTransferData transferData = getTransferData();
DateTime transferExpirationTime = transferData.getPendingTransferExpirationTime();
// If there's a pending transfer that has expired, handle it.
@ -644,7 +646,7 @@ public class DomainBase extends EppResource
/** A builder for constructing {@link DomainBase}, since it is immutable. */
public static class Builder extends EppResource.Builder<DomainBase, Builder>
implements BuilderWithTransferData<Builder> {
implements BuilderWithTransferData<DomainTransferData, Builder> {
public Builder() {}
@ -656,7 +658,7 @@ public class DomainBase extends EppResource
public DomainBase build() {
DomainBase instance = getInstance();
// If TransferData is totally empty, set it to null.
if (TransferData.EMPTY.equals(getInstance().transferData)) {
if (DomainTransferData.EMPTY.equals(getInstance().transferData)) {
setTransferData(null);
}
// A DomainBase has status INACTIVE if there are no nameservers.
@ -830,7 +832,7 @@ public class DomainBase extends EppResource
}
@Override
public Builder setTransferData(TransferData transferData) {
public Builder setTransferData(DomainTransferData transferData) {
getInstance().transferData = transferData;
return thisCastToDerived();
}

View file

@ -121,5 +121,10 @@ public abstract class BaseTransferObject extends ImmutableObject {
getInstance().pendingTransferExpirationTime = pendingTransferExpirationTime;
return thisCastToDerived();
}
@Override
public T build() {
return super.build();
}
}
}

View file

@ -0,0 +1,48 @@
// 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.model.transfer;
import com.googlecode.objectify.annotation.Embed;
import com.googlecode.objectify.annotation.Unindex;
import javax.persistence.Embeddable;
/** Transfer data for contact. */
@Embed
@Unindex
@Embeddable
public class ContactTransferData extends TransferData<ContactTransferData.Builder> {
public static final ContactTransferData EMPTY = new ContactTransferData();
@Override
public boolean isEmpty() {
return EMPTY.equals(this);
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));
}
public static class Builder
extends TransferData.Builder<ContactTransferData, ContactTransferData.Builder> {
/** Create a {@link ContactTransferData.Builder} wrapping a new instance. */
public Builder() {}
/** Create a {@link ContactTransferData.Builder} wrapping the given instance. */
private Builder(ContactTransferData instance) {
super(instance);
}
}
}

View file

@ -0,0 +1,186 @@
// 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.model.transfer;
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;
import google.registry.model.billing.BillingEvent;
import google.registry.model.domain.Period;
import google.registry.model.domain.Period.Unit;
import google.registry.model.poll.PollMessage;
import google.registry.persistence.VKey;
import javax.annotation.Nullable;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Embedded;
import org.joda.time.DateTime;
/** Transfer data for domain. */
@Embed
@Unindex
@Embeddable
public class DomainTransferData extends TransferData<DomainTransferData.Builder> {
public static final DomainTransferData EMPTY = new DomainTransferData();
/**
* The period to extend the registration upon completion of the transfer.
*
* <p>By default, domain transfers are for one year. This can be changed to zero by using the
* superuser EPP extension.
*/
@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
* reset to null.
*
* <p>Note that even when this field is set, it does not necessarily mean that the post-transfer
* domain has a new expiration time. Superuser transfers may not include a bundled 1 year renewal
* at all, or even when a renewal is bundled, for a transfer during the autorenew grace period the
* 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;
@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)
@Column(name = "transfer_billing_event_id")
VKey<BillingEvent.OneTime> serverApproveBillingEvent;
/**
* The autorenew billing event that should be associated with this resource after the 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.
*/
@IgnoreSave(IfNull.class)
@Column(name = "transfer_billing_recurrence_id")
VKey<BillingEvent.Recurring> serverApproveAutorenewEvent;
/**
* The autorenew poll message that should be associated with this resource after the 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.
*/
@IgnoreSave(IfNull.class)
@Column(name = "transfer_autorenew_poll_message_id")
VKey<PollMessage.Autorenew> serverApproveAutorenewPollMessage;
@Override
public Builder copyConstantFieldsToBuilder() {
return super.copyConstantFieldsToBuilder().setTransferPeriod(this.transferPeriod);
}
public Period getTransferPeriod() {
return transferPeriod;
}
@Nullable
public DateTime getTransferredRegistrationExpirationTime() {
return transferredRegistrationExpirationTime;
}
@Nullable
public VKey<BillingEvent.OneTime> getServerApproveBillingEvent() {
return serverApproveBillingEvent;
}
@Nullable
public VKey<BillingEvent.Recurring> getServerApproveAutorenewEvent() {
return serverApproveAutorenewEvent;
}
@Nullable
public VKey<PollMessage.Autorenew> getServerApproveAutorenewPollMessage() {
return serverApproveAutorenewPollMessage;
}
@Override
public boolean isEmpty() {
return EMPTY.equals(this);
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));
}
public static class Builder extends TransferData.Builder<DomainTransferData, Builder> {
/** Create a {@link DomainTransferData.Builder} wrapping a new instance. */
public Builder() {}
/** Create a {@link Builder} wrapping the given instance. */
private Builder(DomainTransferData instance) {
super(instance);
}
public Builder setTransferPeriod(Period transferPeriod) {
getInstance().transferPeriod = transferPeriod;
return this;
}
public Builder setTransferredRegistrationExpirationTime(
DateTime transferredRegistrationExpirationTime) {
getInstance().transferredRegistrationExpirationTime = transferredRegistrationExpirationTime;
return this;
}
public Builder setServerApproveBillingEvent(
VKey<BillingEvent.OneTime> serverApproveBillingEvent) {
getInstance().serverApproveBillingEvent = serverApproveBillingEvent;
return this;
}
public Builder setServerApproveAutorenewEvent(
VKey<BillingEvent.Recurring> serverApproveAutorenewEvent) {
getInstance().serverApproveAutorenewEvent = serverApproveAutorenewEvent;
return this;
}
public Builder setServerApproveAutorenewPollMessage(
VKey<PollMessage.Autorenew> serverApproveAutorenewPollMessage) {
getInstance().serverApproveAutorenewPollMessage = serverApproveAutorenewPollMessage;
return this;
}
}
}

View file

@ -17,38 +17,31 @@ package google.registry.model.transfer;
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import com.google.common.collect.ImmutableSet;
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;
import google.registry.model.Buildable;
import google.registry.model.EppResource;
import google.registry.model.billing.BillingEvent;
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 google.registry.util.TypeUtils.TypeInstantiator;
import java.util.Set;
import javax.annotation.Nullable;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import org.joda.time.DateTime;
/**
* Common transfer data for {@link EppResource} types. Only applies to domains and contacts; hosts
* are implicitly transferred with their superordinate domain.
*/
@Embed
@Unindex
@javax.persistence.Embeddable
public class TransferData extends BaseTransferObject implements Buildable {
public static final TransferData EMPTY = new TransferData();
@MappedSuperclass
public abstract class TransferData<
B extends TransferData.Builder<? extends TransferData, ? extends TransferData.Builder>>
extends BaseTransferObject implements Buildable {
/** The transaction id of the most recent transfer request (or null if there never was one). */
@Embedded
@ -62,37 +55,6 @@ public class TransferData extends BaseTransferObject implements Buildable {
})
Trid transferRequestTrid;
/**
* The period to extend the registration upon completion of the transfer.
*
* <p>By default, domain transfers are for one year. This can be changed to zero by using the
* superuser EPP extension.
*/
@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
* reset to null.
*
* <p>Note that even when this field is set, it does not necessarily mean that the post-transfer
* domain has a new expiration time. Superuser transfers may not include a bundled 1 year renewal
* at all, or even when a renewal is bundled, for a transfer during the autorenew grace period the
* 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;
/**
* The billing event and poll messages associated with a server-approved transfer.
*
@ -116,85 +78,26 @@ public class TransferData extends BaseTransferObject implements Buildable {
@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)
@Column(name = "transfer_billing_event_id")
VKey<BillingEvent.OneTime> serverApproveBillingEvent;
/**
* The autorenew billing event that should be associated with this resource after the 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.
*/
@IgnoreSave(IfNull.class)
@Column(name = "transfer_billing_recurrence_id")
VKey<BillingEvent.Recurring> serverApproveAutorenewEvent;
/**
* The autorenew poll message that should be associated with this resource after the 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.
*/
@IgnoreSave(IfNull.class)
@Column(name = "transfer_autorenew_poll_message_id")
VKey<PollMessage.Autorenew> serverApproveAutorenewPollMessage;
public abstract boolean isEmpty();
@Nullable
public Trid getTransferRequestTrid() {
return transferRequestTrid;
}
public Period getTransferPeriod() {
return transferPeriod;
}
@Nullable
public DateTime getTransferredRegistrationExpirationTime() {
return transferredRegistrationExpirationTime;
}
public ImmutableSet<VKey<? extends TransferServerApproveEntity>> getServerApproveEntities() {
return nullToEmptyImmutableCopy(serverApproveEntities);
}
@Nullable
public VKey<BillingEvent.OneTime> getServerApproveBillingEvent() {
return serverApproveBillingEvent;
}
@Nullable
public VKey<BillingEvent.Recurring> getServerApproveAutorenewEvent() {
return serverApproveAutorenewEvent;
}
@Nullable
public VKey<PollMessage.Autorenew> getServerApproveAutorenewPollMessage() {
return serverApproveAutorenewPollMessage;
}
@Override
public Builder asBuilder() {
return new Builder(clone(this));
}
public abstract Builder asBuilder();
/**
* Returns a fresh Builder populated only with the constant fields of this TransferData, i.e.
* those that are fixed and unchanging throughout the transfer process.
*
* <p>These fields are:
*
* <ul>
* <li>transferRequestTrid
* <li>transferRequestTime
@ -203,64 +106,43 @@ public class TransferData extends BaseTransferObject implements Buildable {
* <li>transferPeriod
* </ul>
*/
public Builder copyConstantFieldsToBuilder() {
return new Builder()
public B copyConstantFieldsToBuilder() {
B newBuilder = new TypeInstantiator<B>(getClass()) {}.instantiate();
newBuilder
// .setTransferPeriod(this.transferPeriod)
.setTransferRequestTrid(this.transferRequestTrid)
.setTransferRequestTime(this.transferRequestTime)
.setGainingClientId(this.gainingClientId)
.setLosingClientId(this.losingClientId)
.setTransferPeriod(this.transferPeriod);
.setLosingClientId(this.losingClientId);
return newBuilder;
}
/** Builder for {@link TransferData} because it is immutable. */
public static class Builder extends BaseTransferObject.Builder<TransferData, Builder> {
public abstract static class Builder<T extends TransferData, B extends Builder<T, B>>
extends BaseTransferObject.Builder<T, B> {
/** Create a {@link Builder} wrapping a new instance. */
public Builder() {}
/** Create a {@link Builder} wrapping the given instance. */
private Builder(TransferData instance) {
protected Builder(T instance) {
super(instance);
}
public Builder setTransferRequestTrid(Trid transferRequestTrid) {
public B setTransferRequestTrid(Trid transferRequestTrid) {
getInstance().transferRequestTrid = transferRequestTrid;
return this;
return thisCastToDerived();
}
public Builder setTransferPeriod(Period transferPeriod) {
getInstance().transferPeriod = transferPeriod;
return this;
}
public Builder setTransferredRegistrationExpirationTime(
DateTime transferredRegistrationExpirationTime) {
getInstance().transferredRegistrationExpirationTime = transferredRegistrationExpirationTime;
return this;
}
public Builder setServerApproveEntities(
public B setServerApproveEntities(
ImmutableSet<VKey<? extends TransferServerApproveEntity>> serverApproveEntities) {
getInstance().serverApproveEntities = serverApproveEntities;
return this;
return thisCastToDerived();
}
public Builder setServerApproveBillingEvent(
VKey<BillingEvent.OneTime> serverApproveBillingEvent) {
getInstance().serverApproveBillingEvent = serverApproveBillingEvent;
return this;
}
public Builder setServerApproveAutorenewEvent(
VKey<BillingEvent.Recurring> serverApproveAutorenewEvent) {
getInstance().serverApproveAutorenewEvent = serverApproveAutorenewEvent;
return this;
}
public Builder setServerApproveAutorenewPollMessage(
VKey<PollMessage.Autorenew> serverApproveAutorenewPollMessage) {
getInstance().serverApproveAutorenewPollMessage = serverApproveAutorenewPollMessage;
return this;
@Override
public T build() {
return super.build();
}
}

View file

@ -36,7 +36,6 @@ import google.registry.xjc.eppcom.XjcEppcomTrStatusType;
import google.registry.xjc.rdecontact.XjcRdeContact;
import google.registry.xjc.rdecontact.XjcRdeContactElement;
import google.registry.xjc.rdecontact.XjcRdeContactTransferDataType;
import java.util.Objects;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
@ -102,7 +101,7 @@ final class ContactResourceToXjcConverter {
// required before an automated response action will be taken by
// the registry. For all other status types, the value identifies
// the date and time when the request was completed.
if (!Objects.equals(model.getTransferData(), TransferData.EMPTY)) {
if (!model.getTransferData().isEmpty()) {
bean.setTrnData(convertTransferData(model.getTransferData()));
}

View file

@ -28,6 +28,7 @@ import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.rde.RdeMode;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferData;
import google.registry.persistence.VKey;
import google.registry.util.Idn;
@ -234,7 +235,7 @@ final class DomainBaseToXjcConverter {
// * An OPTIONAL <exDate> element that contains the end of the
// domain name object's validity period (expiry date) if the
// transfer caused or causes a change in the validity period.
if (!model.getTransferData().equals(TransferData.EMPTY)) {
if (!model.getTransferData().isEmpty()) {
// Temporary check to make sure that there really was a transfer. A bug caused spurious
// empty transfer records to get generated for deleted domains.
// TODO(b/33289763): remove the hasGainingAndLosingRegistrars check in February 2017
@ -258,7 +259,7 @@ final class DomainBaseToXjcConverter {
}
/** Converts {@link TransferData} to {@link XjcRdeDomainTransferDataType}. */
private static XjcRdeDomainTransferDataType convertTransferData(TransferData model) {
private static XjcRdeDomainTransferDataType convertTransferData(DomainTransferData model) {
XjcRdeDomainTransferDataType bean = new XjcRdeDomainTransferDataType();
bean.setTrStatus(
XjcEppcomTrStatusType.fromValue(model.getTransferStatus().getXmlName()));

View file

@ -87,6 +87,7 @@ import google.registry.model.poll.PollMessage.OneTime;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.server.Lock;
import google.registry.model.transfer.ContactTransferData;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferResponse;
import google.registry.model.transfer.TransferStatus;
@ -303,7 +304,7 @@ public class DeleteContactsAndHostsActionTest
false);
runMapreduce();
ContactResource contactAfterDeletion = ofy().load().entity(contact).now();
assertThat(contactAfterDeletion.getTransferData()).isEqualTo(TransferData.EMPTY);
assertThat(contactAfterDeletion.getTransferData()).isEqualTo(ContactTransferData.EMPTY);
}
@Test

View file

@ -43,14 +43,12 @@ import google.registry.flows.exceptions.ObjectAlreadySponsoredException;
import google.registry.flows.exceptions.ResourceStatusProhibitsOperationException;
import google.registry.model.contact.ContactAuthInfo;
import google.registry.model.contact.ContactResource;
import google.registry.model.domain.Period;
import google.registry.model.domain.Period.Unit;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.ContactTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import org.joda.time.DateTime;
@ -95,13 +93,11 @@ public class ContactTransferRequestFlowTest
contact.getTransferData().getTransferRequestTrid().getServerTransactionId());
assertThat(contact.getTransferData())
.isEqualTo(
new TransferData.Builder()
new ContactTransferData.Builder()
.setTransferRequestTrid(expectedTrid)
.setTransferRequestTime(clock.nowUtc())
.setGainingClientId("NewRegistrar")
.setLosingClientId("TheRegistrar")
// Period is meaningless for contact transfers, but this is the default.
.setTransferPeriod(Period.create(1, Unit.YEARS))
.setTransferStatus(TransferStatus.PENDING)
.setPendingTransferExpirationTime(afterTransfer)
// Make the server-approve entities field a no-op comparison; it's easier to

View file

@ -90,7 +90,7 @@ import google.registry.model.registry.Registry;
import google.registry.model.registry.Registry.TldType;
import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferResponse;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
@ -595,7 +595,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
clock.advanceOneMilli();
runFlowAssertResponse(loadFile("domain_delete_response_pending.xml"));
DomainBase domain = reloadResourceByForeignKey();
assertThat(domain.getTransferData()).isEqualTo(TransferData.EMPTY);
assertThat(domain.getTransferData()).isEqualTo(DomainTransferData.EMPTY);
}
@Test
@ -603,7 +603,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
setClientIdForFlow("TheRegistrar");
setUpSuccessfulTest();
// Modify the domain we are testing to include a pending transfer.
TransferData oldTransferData =
DomainTransferData oldTransferData =
persistWithPendingTransfer(reloadResourceByForeignKey()).getTransferData();
clock.advanceOneMilli();
runFlowAssertResponse(loadFile("domain_delete_response_pending.xml"));

View file

@ -68,7 +68,7 @@ import google.registry.model.poll.PollMessage;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferResponse.DomainTransferResponse;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
@ -109,7 +109,7 @@ public class DomainTransferApproveFlowTest
clock.advanceOneMilli();
}
private void assertTransferApproved(DomainBase domain, TransferData oldTransferData) {
private void assertTransferApproved(DomainBase domain, DomainTransferData oldTransferData) {
assertAboutDomains()
.that(domain)
.hasCurrentSponsorClientId("NewRegistrar")
@ -178,7 +178,7 @@ public class DomainTransferApproveFlowTest
assertThat(getPollMessages(domain, "NewRegistrar", clock.nowUtc().plusMonths(1))).hasSize(1);
assertThat(getPollMessages(domain, "TheRegistrar", clock.nowUtc().plusMonths(1))).hasSize(1);
// Setup done; run the test.
TransferData originalTransferData = domain.getTransferData();
DomainTransferData originalTransferData = domain.getTransferData();
assertTransactionalFlow(true);
runFlowAssertResponse(loadFile(expectedXmlFilename));
// Transfer should have succeeded. Verify correct fields were set.
@ -616,7 +616,7 @@ public class DomainTransferApproveFlowTest
@Test
public void testSuccess_superuserExtension_transferPeriodZero() throws Exception {
domain = reloadResourceByForeignKey();
TransferData.Builder transferDataBuilder = domain.getTransferData().asBuilder();
DomainTransferData.Builder transferDataBuilder = domain.getTransferData().asBuilder();
persistResource(
domain
.asBuilder()
@ -641,7 +641,7 @@ public class DomainTransferApproveFlowTest
// active autorenew grace period spanning the entire transfer window.
DateTime autorenewTime = clock.nowUtc().minusDays(1);
DateTime expirationTime = autorenewTime.plusYears(1);
TransferData.Builder transferDataBuilder = domain.getTransferData().asBuilder();
DomainTransferData.Builder transferDataBuilder = domain.getTransferData().asBuilder();
domain =
persistResource(
domain

View file

@ -98,7 +98,7 @@ import google.registry.model.registrar.Registrar.State;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.DomainTransactionRecord;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferResponse;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
@ -213,7 +213,7 @@ public class DomainTransferRequestFlowTest
domain.getTransferData().getTransferRequestTrid().getServerTransactionId());
assertThat(domain.getTransferData())
.isEqualTo(
new TransferData.Builder()
new DomainTransferData.Builder()
.setGainingClientId("NewRegistrar")
.setLosingClientId("TheRegistrar")
.setTransferRequestTrid(expectedTrid)

View file

@ -44,7 +44,7 @@ import google.registry.model.eppcommon.Trid;
import google.registry.model.host.HostResource;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import org.joda.time.DateTime;
import org.junit.Before;
@ -226,7 +226,7 @@ public class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, Hos
.setPersistedCurrentSponsorClientId("NewRegistrar") // Shouldn't hurt.
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(
new TransferData.Builder()
new DomainTransferData.Builder()
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("NewRegistrar")
.setTransferRequestTime(requestTime)
@ -259,7 +259,7 @@ public class HostDeleteFlowTest extends ResourceFlowTestCase<HostDeleteFlow, Hos
.setPersistedCurrentSponsorClientId("NewRegistrar") // Shouldn't help.
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(
new TransferData.Builder()
new DomainTransferData.Builder()
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("TheRegistrar")
.setTransferRequestTime(requestTime)

View file

@ -74,7 +74,7 @@ import google.registry.model.host.HostResource;
import google.registry.model.index.ForeignKeyIndex;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import javax.annotation.Nullable;
@ -117,7 +117,7 @@ public class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, Hos
.setPersistedCurrentSponsorClientId("TheRegistrar")
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(
new TransferData.Builder()
new DomainTransferData.Builder()
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("NewRegistrar")
.setTransferRequestTime(requestTime)

View file

@ -37,7 +37,7 @@ import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.PresenceMarker;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.ContactTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import org.junit.jupiter.api.BeforeEach;
@ -108,7 +108,7 @@ public class ContactResourceTest extends EntityTestCase {
.build())
.setStatusValues(ImmutableSet.of(StatusValue.OK))
.setTransferData(
new TransferData.Builder()
new ContactTransferData.Builder()
.setGainingClientId("gaining")
.setLosingClientId("losing")
.setPendingTransferExpirationTime(fakeClock.nowUtc())
@ -205,7 +205,8 @@ public class ContactResourceTest extends EntityTestCase {
@Test
public void testEmptyTransferDataBecomesNull() {
ContactResource withNull = new ContactResource.Builder().setTransferData(null).build();
ContactResource withEmpty = withNull.asBuilder().setTransferData(TransferData.EMPTY).build();
ContactResource withEmpty =
withNull.asBuilder().setTransferData(ContactTransferData.EMPTY).build();
assertThat(withNull).isEqualTo(withEmpty);
assertThat(withEmpty.transferData).isNull();
}

View file

@ -29,7 +29,7 @@ import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.ContactTransferData;
import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
@ -191,7 +191,7 @@ public class DomainBaseSqlTest {
return new ContactResource.Builder()
.setRepoId(repoId)
.setCreationClientId("registrar1")
.setTransferData(new TransferData.Builder().build())
.setTransferData(new ContactTransferData.Builder().build())
.setPersistedCurrentSponsorClientId("registrar1")
.build();
}

View file

@ -52,7 +52,7 @@ import google.registry.model.host.HostResource;
import google.registry.model.poll.PollMessage;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import org.joda.money.Money;
@ -133,7 +133,7 @@ public class DomainBaseTest extends EntityTestCase {
.setLaunchNotice(
LaunchNotice.create("tcnid", "validatorId", START_OF_TIME, START_OF_TIME))
.setTransferData(
new TransferData.Builder()
new DomainTransferData.Builder()
.setGainingClientId("gaining")
.setLosingClientId("losing")
.setPendingTransferExpirationTime(fakeClock.nowUtc())
@ -267,7 +267,7 @@ public class DomainBaseTest extends EntityTestCase {
@Test
public void testEmptyTransferDataBecomesNull() {
DomainBase withNull = newDomainBase("example.com").asBuilder().setTransferData(null).build();
DomainBase withEmpty = withNull.asBuilder().setTransferData(TransferData.EMPTY).build();
DomainBase withEmpty = withNull.asBuilder().setTransferData(DomainTransferData.EMPTY).build();
assertThat(withNull).isEqualTo(withEmpty);
assertThat(withEmpty.transferData).isNull();
}
@ -478,7 +478,7 @@ public class DomainBaseTest extends EntityTestCase {
domain
.asBuilder()
.setRegistrationExpirationTime(oldExpirationTime)
.setTransferData(TransferData.EMPTY)
.setTransferData(DomainTransferData.EMPTY)
.setGracePeriods(ImmutableSet.of())
.setLastEppUpdateTime(null)
.setLastEppUpdateClientId(null)
@ -666,8 +666,8 @@ public class DomainBaseTest extends EntityTestCase {
DateTime transferExpirationTime = now.minusDays(1);
DateTime previousExpiration = now.minusDays(2);
TransferData transferData =
new TransferData.Builder()
DomainTransferData transferData =
new DomainTransferData.Builder()
.setPendingTransferExpirationTime(transferExpirationTime)
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("TheRegistrar")
@ -694,8 +694,8 @@ public class DomainBaseTest extends EntityTestCase {
DateTime transferExpirationTime = now.minusDays(1);
DateTime previousExpiration = now.plusWeeks(2);
TransferData transferData =
new TransferData.Builder()
DomainTransferData transferData =
new DomainTransferData.Builder()
.setPendingTransferExpirationTime(transferExpirationTime)
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("TheRegistrar")
@ -721,8 +721,8 @@ public class DomainBaseTest extends EntityTestCase {
DateTime transferExpirationTime = now.plusDays(1);
DateTime previousExpiration = now.plusWeeks(2);
TransferData transferData =
new TransferData.Builder()
DomainTransferData transferData =
new DomainTransferData.Builder()
.setPendingTransferExpirationTime(transferExpirationTime)
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("TheRegistrar")
@ -747,8 +747,8 @@ public class DomainBaseTest extends EntityTestCase {
DateTime transferExpirationTime = now.minusDays(1);
DateTime previousExpiration = now.minusDays(2);
TransferData transferData =
new TransferData.Builder()
DomainTransferData transferData =
new DomainTransferData.Builder()
.setPendingTransferExpirationTime(transferExpirationTime)
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("TheRegistrar")

View file

@ -31,7 +31,7 @@ import google.registry.model.billing.BillingEvent;
import google.registry.model.domain.DomainBase;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
import org.joda.time.DateTime;
@ -58,7 +58,7 @@ public class HostResourceTest extends EntityTestCase {
.asBuilder()
.setRepoId("1-COM")
.setTransferData(
new TransferData.Builder()
new DomainTransferData.Builder()
.setGainingClientId("gaining")
.setLosingClientId("losing")
.setPendingTransferExpirationTime(fakeClock.nowUtc())

View file

@ -57,8 +57,8 @@ public class TransferDataTest {
@Test
public void test_copyConstantFieldsToBuilder() {
TransferData constantTransferData =
new TransferData.Builder()
DomainTransferData constantTransferData =
new DomainTransferData.Builder()
.setTransferRequestTrid(Trid.create("server-trid", "client-trid"))
.setTransferRequestTime(now)
.setGainingClientId("NewRegistrar")
@ -66,7 +66,7 @@ public class TransferDataTest {
// Test must use a non-1-year period, since that's the default value.
.setTransferPeriod(Period.create(5, Period.Unit.YEARS))
.build();
TransferData fullTransferData =
DomainTransferData fullTransferData =
constantTransferData
.asBuilder()
.setPendingTransferExpirationTime(now)

View file

@ -39,7 +39,7 @@ import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarContact;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.rdap.RdapJsonFormatter.OutputDataType;
import google.registry.rdap.RdapObjectClasses.BoilerplateType;
@ -170,7 +170,7 @@ public class RdapJsonFormatterTest {
.asBuilder()
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(
new TransferData.Builder()
new DomainTransferData.Builder()
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("NewRegistrar")
.setTransferRequestTime(clock.nowUtc().minusDays(1))

View file

@ -31,7 +31,7 @@ import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.PresenceMarker;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.eppcommon.Trid;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.ContactTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.testing.AppEngineRule;
import google.registry.xjc.contact.XjcContactPostalInfoEnumType;
@ -297,14 +297,16 @@ public class ContactResourceToXjcConverterTest {
.setLastTransferTime(DateTime.parse("1925-04-20TZ"))
.setLastEppUpdateTime(DateTime.parse("1930-04-20TZ"))
.setEmailAddress("justine@crr.com")
.setStatusValues(ImmutableSet.of(
StatusValue.CLIENT_DELETE_PROHIBITED,
StatusValue.SERVER_UPDATE_PROHIBITED))
.setInternationalizedPostalInfo(new PostalInfo.Builder()
.setStatusValues(
ImmutableSet.of(
StatusValue.CLIENT_DELETE_PROHIBITED, StatusValue.SERVER_UPDATE_PROHIBITED))
.setInternationalizedPostalInfo(
new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName("Dipsy Doodle")
.setOrg("Charleston Road Registry Incorporated")
.setAddress(new ContactAddress.Builder()
.setAddress(
new ContactAddress.Builder()
.setStreet(ImmutableList.of("123 Charleston Road", "Suite 123"))
.setCity("Mountain View")
.setState("CA")
@ -317,11 +319,9 @@ public class ContactResourceToXjcConverterTest {
.setPhoneNumber("+1.2126660000")
.setExtension("123")
.build())
.setFaxNumber(
new ContactPhoneNumber.Builder()
.setPhoneNumber("+1.2126660001")
.build())
.setTransferData(new TransferData.Builder()
.setFaxNumber(new ContactPhoneNumber.Builder().setPhoneNumber("+1.2126660001").build())
.setTransferData(
new ContactTransferData.Builder()
.setGainingClientId("TheRegistrar")
.setLosingClientId("NewRegistrar")
.setTransferRequestTime(DateTime.parse("1925-04-19TZ"))
@ -329,12 +329,15 @@ public class ContactResourceToXjcConverterTest {
.setTransferStatus(TransferStatus.SERVER_APPROVED)
.setTransferRequestTrid(Trid.create("client-trid", "server-trid"))
.build())
.setDisclose(new Disclose.Builder()
.setDisclose(
new Disclose.Builder()
.setFlag(true)
.setEmail(new PresenceMarker())
.setAddrs(ImmutableList.of(
.setAddrs(
ImmutableList.of(
Disclose.PostalInfoChoice.create(PostalInfo.Type.INTERNATIONALIZED)))
.setNames(ImmutableList.of(
.setNames(
ImmutableList.of(
Disclose.PostalInfoChoice.create(PostalInfo.Type.INTERNATIONALIZED)))
.build())
.build();

View file

@ -53,7 +53,7 @@ import google.registry.model.poll.PollMessage;
import google.registry.model.poll.PollMessage.Autorenew;
import google.registry.model.rde.RdeMode;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
@ -328,7 +328,7 @@ public class DomainBaseToXjcConverterTest {
.setParent(historyEntry)
.build())))
.setTransferData(
new TransferData.Builder()
new DomainTransferData.Builder()
.setGainingClientId("gaining")
.setLosingClientId("losing")
.setPendingTransferExpirationTime(DateTime.parse("1925-04-20T00:00:00Z"))

View file

@ -47,7 +47,7 @@ import google.registry.model.host.HostResource;
import google.registry.model.poll.PollMessage;
import google.registry.model.poll.PollMessage.Autorenew;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.testing.FakeClock;
import google.registry.util.Idn;
@ -170,7 +170,7 @@ final class RdeFixtures {
.setParent(historyEntry)
.build())))
.setTransferData(
new TransferData.Builder()
new DomainTransferData.Builder()
.setGainingClientId("gaining")
.setLosingClientId("losing")
.setPendingTransferExpirationTime(DateTime.parse("1993-04-20T00:00:00Z"))

View file

@ -91,6 +91,8 @@ import google.registry.model.registry.label.PremiumList.PremiumListEntry;
import google.registry.model.registry.label.PremiumList.PremiumListRevision;
import google.registry.model.registry.label.ReservedList;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.transfer.ContactTransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.persistence.VKey;
@ -384,9 +386,19 @@ public class DatastoreHelper {
registrar.asBuilder().setAllowedTlds(difference(registrar.getAllowedTlds(), tld)).build());
}
private static TransferData.Builder createTransferDataBuilder(
private static DomainTransferData.Builder createDomainTransferDataBuilder(
DateTime requestTime, DateTime expirationTime) {
return new TransferData.Builder()
return new DomainTransferData.Builder()
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("NewRegistrar")
.setTransferRequestTime(requestTime)
.setLosingClientId("TheRegistrar")
.setPendingTransferExpirationTime(expirationTime);
}
private static ContactTransferData.Builder createContactTransferDataBuilder(
DateTime requestTime, DateTime expirationTime) {
return new ContactTransferData.Builder()
.setTransferStatus(TransferStatus.PENDING)
.setGainingClientId("NewRegistrar")
.setTransferRequestTime(requestTime)
@ -402,7 +414,7 @@ public class DatastoreHelper {
DateTime expirationTime,
@Nullable DateTime extendedRegistrationExpirationTime) {
TransferData transferData =
createTransferDataBuilder(requestTime, expirationTime)
createDomainTransferDataBuilder(requestTime, expirationTime)
.setTransferredRegistrationExpirationTime(extendedRegistrationExpirationTime)
.build();
return new PollMessage.OneTime.Builder()
@ -448,7 +460,7 @@ public class DatastoreHelper {
.setPersistedCurrentSponsorClientId("TheRegistrar")
.addStatusValue(StatusValue.PENDING_TRANSFER)
.setTransferData(
createTransferDataBuilder(requestTime, expirationTime)
createContactTransferDataBuilder(requestTime, expirationTime)
.setPendingTransferExpirationTime(now.plus(getContactAutomaticTransferLength()))
.setServerApproveEntities(
ImmutableSet.of(
@ -588,8 +600,8 @@ public class DatastoreHelper {
} else {
deleteResource(autorenewPollMessage);
}
TransferData.Builder transferDataBuilder =
createTransferDataBuilder(requestTime, expirationTime);
DomainTransferData.Builder transferDataBuilder =
createDomainTransferDataBuilder(requestTime, expirationTime);
return persistResource(
domain
.asBuilder()

View file

@ -51,7 +51,7 @@ import google.registry.model.host.HostResource;
import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar;
import google.registry.model.registry.Registry;
import google.registry.model.transfer.TransferData;
import google.registry.model.transfer.DomainTransferData;
import google.registry.model.transfer.TransferStatus;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
@ -178,7 +178,7 @@ public class WhoisActionTest {
makeDomainBaseWithRegistrar(registrar)
.asBuilder()
.setTransferData(
new TransferData.Builder()
new DomainTransferData.Builder()
.setGainingClientId("TheRegistrar")
.setLosingClientId("NewRegistrar")
.setTransferRequestTime(DateTime.parse("2009-05-29T20:13:00Z"))

View file

@ -114,7 +114,7 @@ class google.registry.model.contact.ContactResource {
google.registry.model.contact.Disclose disclose;
google.registry.model.contact.PostalInfo internationalizedPostalInfo;
google.registry.model.contact.PostalInfo localizedPostalInfo;
google.registry.model.transfer.TransferData transferData;
google.registry.model.transfer.ContactTransferData transferData;
java.lang.String contactId;
java.lang.String creationClientId;
java.lang.String currentSponsorClientId;
@ -171,7 +171,7 @@ class google.registry.model.domain.DomainBase {
google.registry.model.UpdateAutoTimestamp updateTimestamp;
google.registry.model.domain.DomainAuthInfo authInfo;
google.registry.model.domain.launch.LaunchNotice launchNotice;
google.registry.model.transfer.TransferData transferData;
google.registry.model.transfer.DomainTransferData transferData;
java.lang.String creationClientId;
java.lang.String currentSponsorClientId;
java.lang.String fullyQualifiedDomainName;
@ -715,7 +715,16 @@ class google.registry.model.tmch.TmchCrl {
java.lang.String url;
org.joda.time.DateTime updated;
}
class google.registry.model.transfer.TransferData {
class google.registry.model.transfer.ContactTransferData {
google.registry.model.eppcommon.Trid transferRequestTrid;
google.registry.model.transfer.TransferStatus transferStatus;
java.lang.String gainingClientId;
java.lang.String losingClientId;
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;
}
class google.registry.model.transfer.DomainTransferData {
google.registry.model.domain.Period transferPeriod;
google.registry.model.eppcommon.Trid transferRequestTrid;
google.registry.model.transfer.TransferStatus transferStatus;

View file

@ -0,0 +1,21 @@
-- 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" DROP COLUMN transfer_billing_cancellation_id;
ALTER TABLE "Contact" DROP COLUMN transfer_billing_recurrence_id;
ALTER TABLE "Contact" DROP COLUMN transfer_autorenew_poll_message_id;
ALTER TABLE "Contact" DROP COLUMN transfer_billing_event_id;
ALTER TABLE "Contact" DROP COLUMN transfer_renew_period_unit;
ALTER TABLE "Contact" DROP COLUMN transfer_renew_period_value;
ALTER TABLE "Contact" DROP COLUMN transfer_registration_expiration_time;

View file

@ -118,17 +118,10 @@
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,
@ -182,16 +175,16 @@
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_registration_expiration_time timestamptz,
transfer_gaining_poll_message_id int8,
transfer_losing_poll_message_id int8,
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,

View file

@ -244,15 +244,8 @@ CREATE TABLE public."Contact" (
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,