mirror of
https://github.com/google/nomulus
synced 2026-07-08 17:16:54 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e201450f0 | |||
| dda9a3ef7e | |||
| 8c1fb6bf00 | |||
| 4e21152f04 |
@@ -377,8 +377,7 @@ public final class DomainCreateFlow implements TransactionalFlow {
|
||||
.setIdnTableName(validateDomainNameWithIdnTables(domainName))
|
||||
.setRegistrationExpirationTime(registrationExpirationTime)
|
||||
.setAutorenewBillingEvent(autorenewBillingEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.setLaunchNotice(hasClaimsNotice ? launchCreate.get().getNotice() : null)
|
||||
.setSmdId(signedMarkId)
|
||||
.setDsData(secDnsCreate.map(SecDnsCreateExtension::getDsData).orElse(null))
|
||||
|
||||
@@ -263,7 +263,8 @@ public final class DomainDeleteFlow implements TransactionalFlow {
|
||||
// the updated recurring billing event, we'll need it later and can't reload it.
|
||||
Recurring existingRecurring = tm().loadByKey(existingDomain.getAutorenewBillingEvent());
|
||||
BillingEvent.Recurring recurringBillingEvent =
|
||||
updateAutorenewRecurrenceEndTime(existingDomain, existingRecurring, now);
|
||||
updateAutorenewRecurrenceEndTime(
|
||||
existingDomain, existingRecurring, now, domainHistory.getDomainHistoryId());
|
||||
// If there's a pending transfer, the gaining client's autorenew billing
|
||||
// event and poll message will already have been deleted in
|
||||
// ResourceDeleteFlow since it's listed in serverApproveEntities.
|
||||
|
||||
@@ -591,7 +591,10 @@ public class DomainFlowUtils {
|
||||
* <p>Returns the new autorenew recurring billing event.
|
||||
*/
|
||||
public static Recurring updateAutorenewRecurrenceEndTime(
|
||||
Domain domain, Recurring existingRecurring, DateTime newEndTime) {
|
||||
Domain domain,
|
||||
Recurring existingRecurring,
|
||||
DateTime newEndTime,
|
||||
@Nullable DomainHistoryId historyId) {
|
||||
Optional<PollMessage.Autorenew> autorenewPollMessage =
|
||||
tm().loadByKeyIfPresent(domain.getAutorenewPollMessage());
|
||||
|
||||
@@ -599,20 +602,25 @@ public class DomainFlowUtils {
|
||||
// create a new one at the same id. This can happen if a transfer was requested on a domain
|
||||
// where all autorenew poll messages had already been delivered (this would cause the poll
|
||||
// message to be deleted), and then subsequently the transfer was canceled, rejected, or deleted
|
||||
// (which would cause the poll message to be recreated here).
|
||||
PollMessage.Autorenew updatedAutorenewPollMessage =
|
||||
autorenewPollMessage.isPresent()
|
||||
? autorenewPollMessage.get().asBuilder().setAutorenewEndTime(newEndTime).build()
|
||||
: newAutorenewPollMessage(domain)
|
||||
.setId((Long) domain.getAutorenewPollMessage().getSqlKey())
|
||||
.setAutorenewEndTime(newEndTime)
|
||||
.setDomainHistoryId(
|
||||
new DomainHistoryId(
|
||||
domain.getRepoId(), domain.getAutorenewPollMessageHistoryId()))
|
||||
.build();
|
||||
// (which would cause the poll message to be recreated here). In the latter case, the history id
|
||||
// of the event that created the new poll message will also be used.
|
||||
PollMessage.Autorenew updatedAutorenewPollMessage;
|
||||
if (autorenewPollMessage.isPresent()) {
|
||||
updatedAutorenewPollMessage =
|
||||
autorenewPollMessage.get().asBuilder().setAutorenewEndTime(newEndTime).build();
|
||||
} else {
|
||||
checkNotNull(
|
||||
historyId, "Cannot create a new autorenew poll message without a domain history id");
|
||||
updatedAutorenewPollMessage =
|
||||
newAutorenewPollMessage(domain)
|
||||
.setId((Long) domain.getAutorenewPollMessage().getSqlKey())
|
||||
.setAutorenewEndTime(newEndTime)
|
||||
.setDomainHistoryId(historyId)
|
||||
.build();
|
||||
}
|
||||
|
||||
// If the resultant autorenew poll message would have no poll messages to deliver, then just
|
||||
// delete it. Otherwise save it with the new end time.
|
||||
// delete it. Otherwise, save it with the new end time.
|
||||
if (isAtOrAfter(updatedAutorenewPollMessage.getEventTime(), newEndTime)) {
|
||||
autorenewPollMessage.ifPresent(autorenew -> tm().delete(autorenew));
|
||||
} else {
|
||||
|
||||
@@ -223,7 +223,11 @@ public final class DomainRenewFlow implements TransactionalFlow {
|
||||
.build();
|
||||
// End the old autorenew billing event and poll message now. This may delete the poll message.
|
||||
Recurring existingRecurring = tm().loadByKey(existingDomain.getAutorenewBillingEvent());
|
||||
updateAutorenewRecurrenceEndTime(existingDomain, existingRecurring, now);
|
||||
updateAutorenewRecurrenceEndTime(
|
||||
existingDomain,
|
||||
existingRecurring,
|
||||
now,
|
||||
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()));
|
||||
Domain newDomain =
|
||||
existingDomain
|
||||
.asBuilder()
|
||||
@@ -231,9 +235,7 @@ public final class DomainRenewFlow implements TransactionalFlow {
|
||||
.setLastEppUpdateRegistrarId(registrarId)
|
||||
.setRegistrationExpirationTime(newExpirationTime)
|
||||
.setAutorenewBillingEvent(newAutorenewEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
newAutorenewPollMessage.createVKey(),
|
||||
newAutorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(newAutorenewPollMessage.createVKey())
|
||||
.addGracePeriod(
|
||||
GracePeriod.forBillingEvent(
|
||||
GracePeriodStatus.RENEW, existingDomain.getRepoId(), explicitRenewEvent))
|
||||
|
||||
@@ -251,8 +251,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
|
||||
.setGracePeriods(null)
|
||||
.setDeletePollMessage(null)
|
||||
.setAutorenewBillingEvent(autorenewEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
// Clear the autorenew end time so if it had expired but is now explicitly being restored,
|
||||
// it won't immediately be deleted again.
|
||||
.setAutorenewEndTime(Optional.empty())
|
||||
|
||||
@@ -194,7 +194,11 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
||||
}
|
||||
// Close the old autorenew event and poll message at the transfer time (aka now). This may end
|
||||
// up deleting the poll message.
|
||||
updateAutorenewRecurrenceEndTime(existingDomain, existingRecurring, now);
|
||||
updateAutorenewRecurrenceEndTime(
|
||||
existingDomain,
|
||||
existingRecurring,
|
||||
now,
|
||||
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()));
|
||||
DateTime newExpirationTime =
|
||||
computeExDateForApprovalTime(existingDomain, now, transferData.getTransferPeriod());
|
||||
// Create a new autorenew event starting at the expiration time.
|
||||
@@ -240,9 +244,7 @@ public final class DomainTransferApproveFlow implements TransactionalFlow {
|
||||
.build())
|
||||
.setRegistrationExpirationTime(newExpirationTime)
|
||||
.setAutorenewBillingEvent(autorenewEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
gainingClientAutorenewPollMessage.createVKey(),
|
||||
gainingClientAutorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(gainingClientAutorenewPollMessage.createVKey())
|
||||
// Remove all the old grace periods and add a new one for the transfer.
|
||||
.setGracePeriods(
|
||||
billingEvent
|
||||
|
||||
@@ -116,7 +116,8 @@ public final class DomainTransferCancelFlow implements TransactionalFlow {
|
||||
// Reopen the autorenew event and poll message that we closed for the implicit transfer. This
|
||||
// may recreate the autorenew poll message if it was deleted when the transfer request was made.
|
||||
Recurring existingRecurring = tm().loadByKey(existingDomain.getAutorenewBillingEvent());
|
||||
updateAutorenewRecurrenceEndTime(existingDomain, existingRecurring, END_OF_TIME);
|
||||
updateAutorenewRecurrenceEndTime(
|
||||
existingDomain, existingRecurring, END_OF_TIME, domainHistory.getDomainHistoryId());
|
||||
// Delete the billing event and poll messages that were written in case the transfer would have
|
||||
// been implicitly server approved.
|
||||
tm().delete(existingDomain.getTransferData().getServerApproveEntities());
|
||||
|
||||
@@ -117,7 +117,8 @@ public final class DomainTransferRejectFlow implements TransactionalFlow {
|
||||
// Reopen the autorenew event and poll message that we closed for the implicit transfer. This
|
||||
// may end up recreating the poll message if it was deleted upon the transfer request.
|
||||
Recurring existingRecurring = tm().loadByKey(existingDomain.getAutorenewBillingEvent());
|
||||
updateAutorenewRecurrenceEndTime(existingDomain, existingRecurring, END_OF_TIME);
|
||||
updateAutorenewRecurrenceEndTime(
|
||||
existingDomain, existingRecurring, END_OF_TIME, domainHistory.getDomainHistoryId());
|
||||
// Delete the billing event and poll messages that were written in case the transfer would have
|
||||
// been implicitly server approved.
|
||||
tm().delete(existingDomain.getTransferData().getServerApproveEntities());
|
||||
|
||||
@@ -57,6 +57,7 @@ import google.registry.model.billing.BillingEvent.Recurring;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.DomainCommand.Transfer;
|
||||
import google.registry.model.domain.DomainHistory;
|
||||
import google.registry.model.domain.DomainHistory.DomainHistoryId;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.domain.fee.FeeTransferCommandExtension;
|
||||
import google.registry.model.domain.fee.FeeTransformResponseExtension;
|
||||
@@ -260,7 +261,11 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
|
||||
// the poll message if it has no events left. Note that if the automatic transfer succeeds, then
|
||||
// cloneProjectedAtTime() will replace these old autorenew entities with the server approve ones
|
||||
// that we've created in this flow and stored in pendingTransferData.
|
||||
updateAutorenewRecurrenceEndTime(existingDomain, existingRecurring, automaticTransferTime);
|
||||
updateAutorenewRecurrenceEndTime(
|
||||
existingDomain,
|
||||
existingRecurring,
|
||||
automaticTransferTime,
|
||||
new DomainHistoryId(domainHistoryKey.getParent().getName(), domainHistoryKey.getId()));
|
||||
Domain newDomain =
|
||||
existingDomain
|
||||
.asBuilder()
|
||||
|
||||
@@ -28,7 +28,6 @@ import google.registry.model.host.HostHistory;
|
||||
import google.registry.model.index.EppResourceIndex;
|
||||
import google.registry.model.index.EppResourceIndexBucket;
|
||||
import google.registry.model.index.ForeignKeyIndex;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.rde.RdeRevision;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
@@ -58,9 +57,6 @@ public final class EntityClasses {
|
||||
Host.class,
|
||||
HostHistory.class,
|
||||
Lock.class,
|
||||
PollMessage.class,
|
||||
PollMessage.Autorenew.class,
|
||||
PollMessage.OneTime.class,
|
||||
RdeRevision.class,
|
||||
Registrar.class,
|
||||
ServerSecret.class);
|
||||
|
||||
@@ -90,13 +90,13 @@ public class Domain extends DomainBase implements ForeignKeyedEppResource {
|
||||
@Access(AccessType.PROPERTY)
|
||||
@Column(name = "host_repo_id")
|
||||
public Set<VKey<Host>> getNsHosts() {
|
||||
return super.nsHosts;
|
||||
return nsHosts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of {@link GracePeriod} associated with the domain.
|
||||
*
|
||||
* <p>This is the getter method specific for Hibernate to access the field so it is set to
|
||||
* <p>This is the getter method specific for Hibernate to access the field, so it is set to
|
||||
* private. The caller can use the public {@link #getGracePeriods()} to get the grace periods.
|
||||
*
|
||||
* <p>Note that we need to set `insertable = false, updatable = false` for @JoinColumn, otherwise
|
||||
@@ -104,10 +104,7 @@ public class Domain extends DomainBase implements ForeignKeyedEppResource {
|
||||
* deleting the whole entry from the table when the {@link GracePeriod} is removed from the set.
|
||||
*/
|
||||
@Access(AccessType.PROPERTY)
|
||||
@OneToMany(
|
||||
cascade = {CascadeType.ALL},
|
||||
fetch = FetchType.EAGER,
|
||||
orphanRemoval = true)
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
|
||||
@JoinColumn(
|
||||
name = "domainRepoId",
|
||||
referencedColumnName = "repoId",
|
||||
@@ -121,7 +118,7 @@ public class Domain extends DomainBase implements ForeignKeyedEppResource {
|
||||
/**
|
||||
* Returns the set of {@link DelegationSignerData} associated with the domain.
|
||||
*
|
||||
* <p>This is the getter method specific for Hibernate to access the field so it is set to
|
||||
* <p>This is the getter method specific for Hibernate to access the field, so it is set to
|
||||
* private. The caller can use the public {@link #getDsData()} to get the DS data.
|
||||
*
|
||||
* <p>Note that we need to set `insertable = false, updatable = false` for @JoinColumn, otherwise
|
||||
@@ -130,10 +127,7 @@ public class Domain extends DomainBase implements ForeignKeyedEppResource {
|
||||
* the set.
|
||||
*/
|
||||
@Access(AccessType.PROPERTY)
|
||||
@OneToMany(
|
||||
cascade = {CascadeType.ALL},
|
||||
fetch = FetchType.EAGER,
|
||||
orphanRemoval = true)
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
|
||||
@JoinColumn(
|
||||
name = "domainRepoId",
|
||||
referencedColumnName = "repoId",
|
||||
@@ -182,10 +176,9 @@ public class Domain extends DomainBase implements ForeignKeyedEppResource {
|
||||
}
|
||||
|
||||
public Builder copyFrom(DomainBase domainBase) {
|
||||
this.getInstance().copyUpdateTimestamp(domainBase);
|
||||
return this.setAuthInfo(domainBase.getAuthInfo())
|
||||
.setAutorenewPollMessage(
|
||||
domainBase.getAutorenewPollMessage(), domainBase.getAutorenewPollMessageHistoryId())
|
||||
getInstance().copyUpdateTimestamp(domainBase);
|
||||
return setAuthInfo(domainBase.getAuthInfo())
|
||||
.setAutorenewPollMessage(domainBase.getAutorenewPollMessage())
|
||||
.setAutorenewBillingEvent(domainBase.getAutorenewBillingEvent())
|
||||
.setAutorenewEndTime(domainBase.getAutorenewEndTime())
|
||||
.setContacts(domainBase.getContacts())
|
||||
|
||||
@@ -216,13 +216,6 @@ public class DomainBase extends EppResource
|
||||
@Column(name = "autorenew_poll_message_id")
|
||||
VKey<PollMessage.Autorenew> autorenewPollMessage;
|
||||
|
||||
/**
|
||||
* History record for the autorenew poll message.
|
||||
*
|
||||
* <p>Here so we can restore the original ofy key from sql.
|
||||
*/
|
||||
@Ignore Long autorenewPollMessageHistoryId;
|
||||
|
||||
/** The unexpired grace periods for this domain (some of which may not be active yet). */
|
||||
@Transient Set<GracePeriod> gracePeriods;
|
||||
|
||||
@@ -322,10 +315,6 @@ public class DomainBase extends EppResource
|
||||
return autorenewPollMessage;
|
||||
}
|
||||
|
||||
public Long getAutorenewPollMessageHistoryId() {
|
||||
return autorenewPollMessageHistoryId;
|
||||
}
|
||||
|
||||
public ImmutableSet<GracePeriod> getGracePeriods() {
|
||||
return nullToEmptyImmutableCopy(gracePeriods);
|
||||
}
|
||||
@@ -509,9 +498,7 @@ public class DomainBase extends EppResource
|
||||
// Set the speculatively-written new autorenew events as the domain's autorenew
|
||||
// events.
|
||||
.setAutorenewBillingEvent(transferData.getServerApproveAutorenewEvent())
|
||||
.setAutorenewPollMessage(
|
||||
transferData.getServerApproveAutorenewPollMessage(),
|
||||
transferData.getServerApproveAutorenewPollMessageHistoryId());
|
||||
.setAutorenewPollMessage(transferData.getServerApproveAutorenewPollMessage());
|
||||
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.
|
||||
@@ -886,11 +873,8 @@ public class DomainBase extends EppResource
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
public B setAutorenewPollMessage(
|
||||
@Nullable VKey<PollMessage.Autorenew> autorenewPollMessage,
|
||||
@Nullable Long autorenewPollMessageHistoryId) {
|
||||
public B setAutorenewPollMessage(@Nullable VKey<PollMessage.Autorenew> autorenewPollMessage) {
|
||||
getInstance().autorenewPollMessage = autorenewPollMessage;
|
||||
getInstance().autorenewPollMessageHistoryId = autorenewPollMessageHistoryId;
|
||||
return thisCastToDerived();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,18 +20,12 @@ import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.googlecode.objectify.Key;
|
||||
import com.googlecode.objectify.annotation.Entity;
|
||||
import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import com.googlecode.objectify.annotation.Id;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import com.googlecode.objectify.annotation.Index;
|
||||
import google.registry.model.Buildable;
|
||||
import google.registry.model.EppResource;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.UnsafeSerializable;
|
||||
import google.registry.model.annotations.ExternalMessagingName;
|
||||
import google.registry.model.annotations.ReportedOn;
|
||||
import google.registry.model.annotations.OfyIdAllocation;
|
||||
import google.registry.model.contact.ContactHistory;
|
||||
import google.registry.model.contact.ContactHistory.ContactHistoryId;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
@@ -55,16 +49,19 @@ import google.registry.persistence.VKey;
|
||||
import google.registry.persistence.WithLongVKey;
|
||||
import google.registry.util.NullIgnoringCollectionBuilder;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.AttributeOverride;
|
||||
import javax.persistence.AttributeOverrides;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.DiscriminatorColumn;
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.PostLoad;
|
||||
import javax.persistence.Table;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
@@ -76,10 +73,10 @@ import org.joda.time.DateTime;
|
||||
* retained for historical purposes, poll messages are truly deleted once they have been delivered
|
||||
* and ACKed.
|
||||
*
|
||||
* <p>Poll messages are parented off of the {@link HistoryEntry} that resulted in their creation.
|
||||
* This means that poll messages are contained in the Datastore entity group of the parent {@link
|
||||
* EppResource} (which can be a domain, contact, or host). It is thus possible to perform a strongly
|
||||
* consistent query to find all poll messages associated with a given EPP resource.
|
||||
* <p>Poll messages have a reference to the revision id of the {@link HistoryEntry} that resulted in
|
||||
* their creation or re-creation, in case of transfer cancellation/rejection. The revision ids are
|
||||
* not used directly by the Java code, but their presence in the database makes it easier to
|
||||
* diagnose potential issues related to poll messages.
|
||||
*
|
||||
* <p>Poll messages are identified externally by registrars using the format defined in {@link
|
||||
* PollMessageExternalKeyConverter}.
|
||||
@@ -88,16 +85,10 @@ import org.joda.time.DateTime;
|
||||
* Command</a>
|
||||
*/
|
||||
@Entity
|
||||
@ReportedOn
|
||||
@ExternalMessagingName("message")
|
||||
@javax.persistence.Entity
|
||||
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||
@DiscriminatorColumn(name = "type")
|
||||
@javax.persistence.Table(
|
||||
indexes = {
|
||||
@javax.persistence.Index(columnList = "registrar_id"),
|
||||
@javax.persistence.Index(columnList = "eventTime")
|
||||
})
|
||||
@Table(indexes = {@Index(columnList = "registrar_id"), @Index(columnList = "eventTime")})
|
||||
public abstract class PollMessage extends ImmutableObject
|
||||
implements Buildable, TransferServerApproveEntity, UnsafeSerializable {
|
||||
|
||||
@@ -108,9 +99,9 @@ public abstract class PollMessage extends ImmutableObject
|
||||
HOST(3L, Host.class);
|
||||
|
||||
private final long id;
|
||||
private final Class<?> clazz;
|
||||
private final Class<? extends EppResource> clazz;
|
||||
|
||||
Type(long id, Class<?> clazz) {
|
||||
Type(long id, Class<? extends EppResource> clazz) {
|
||||
this.id = id;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
@@ -124,58 +115,40 @@ public abstract class PollMessage extends ImmutableObject
|
||||
}
|
||||
|
||||
/** Returns the class of the underlying resource for the poll message type. */
|
||||
public Class<?> getResourceClass() {
|
||||
public Class<? extends EppResource> getResourceClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type specified by the identifer, {@code Optional.empty()} if the id is out of
|
||||
* range.
|
||||
*/
|
||||
public static Optional<Type> fromId(long id) {
|
||||
for (Type val : values()) {
|
||||
if (val.id == id) {
|
||||
return Optional.of(val);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
/** Entity id. */
|
||||
@Id
|
||||
@javax.persistence.Id
|
||||
@OfyIdAllocation
|
||||
@Column(name = "poll_message_id")
|
||||
Long id;
|
||||
|
||||
/** The registrar that this poll message will be delivered to. */
|
||||
@Index
|
||||
@Column(name = "registrar_id", nullable = false)
|
||||
String clientId;
|
||||
|
||||
/** The time when the poll message should be delivered. May be in the future. */
|
||||
@Index
|
||||
@Column(nullable = false)
|
||||
DateTime eventTime;
|
||||
|
||||
/** Human readable message that will be returned with this poll message. */
|
||||
/** Human-readable message that will be returned with this poll message. */
|
||||
@Column(name = "message")
|
||||
String msg;
|
||||
|
||||
// TODO(b/456803336): Replace these fields with {Domain,Contact,Host}HistoryId objects.
|
||||
String domainRepoId;
|
||||
|
||||
@Ignore String domainRepoId;
|
||||
String contactRepoId;
|
||||
|
||||
@Ignore String contactRepoId;
|
||||
String hostRepoId;
|
||||
|
||||
@Ignore String hostRepoId;
|
||||
Long domainHistoryRevisionId;
|
||||
|
||||
@Ignore Long domainHistoryRevisionId;
|
||||
Long contactHistoryRevisionId;
|
||||
|
||||
@Ignore Long contactHistoryRevisionId;
|
||||
|
||||
@Ignore Long hostHistoryRevisionId;
|
||||
Long hostHistoryRevisionId;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
@@ -228,32 +201,22 @@ public abstract class PollMessage extends ImmutableObject
|
||||
* the resource.
|
||||
*/
|
||||
public String getResourceName() {
|
||||
return domainRepoId != null
|
||||
? domainRepoId
|
||||
: (contactRepoId != null ? contactRepoId : hostRepoId);
|
||||
return domainRepoId != null ? domainRepoId : contactRepoId != null ? contactRepoId : hostRepoId;
|
||||
}
|
||||
|
||||
/** Gets the underlying history revision id, regardless of the type of the resource. */
|
||||
public Long getHistoryRevisionId() {
|
||||
return domainHistoryRevisionId != null
|
||||
? domainHistoryRevisionId
|
||||
: (contactHistoryRevisionId != null ? contactHistoryRevisionId : hostHistoryRevisionId);
|
||||
: contactHistoryRevisionId != null ? contactHistoryRevisionId : hostHistoryRevisionId;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return domainRepoId != null ? Type.DOMAIN : (contactRepoId != null ? Type.CONTACT : Type.HOST);
|
||||
return domainRepoId != null ? Type.DOMAIN : contactRepoId != null ? Type.CONTACT : Type.HOST;
|
||||
}
|
||||
|
||||
public abstract ImmutableList<ResponseData> getResponseData();
|
||||
|
||||
@Override
|
||||
public abstract VKey<? extends PollMessage> createVKey();
|
||||
|
||||
/** Static VKey factory method for use by VKeyTranslatorFactory. */
|
||||
public static VKey<PollMessage> createVKey(Key<PollMessage> key) {
|
||||
return VKey.create(PollMessage.class, key.getId(), key);
|
||||
}
|
||||
|
||||
/** Override Buildable.asBuilder() to give this method stronger typing. */
|
||||
@Override
|
||||
public abstract Builder<?, ?> asBuilder();
|
||||
@@ -318,9 +281,11 @@ public abstract class PollMessage extends ImmutableObject
|
||||
// Set the appropriate field based on the history entry type.
|
||||
if (history instanceof DomainHistory) {
|
||||
return setDomainHistoryId(((DomainHistory) history).getDomainHistoryId());
|
||||
} else if (history instanceof ContactHistory) {
|
||||
}
|
||||
if (history instanceof ContactHistory) {
|
||||
return setContactHistoryId(((ContactHistory) history).getContactHistoryId());
|
||||
} else if (history instanceof HostHistory) {
|
||||
}
|
||||
if (history instanceof HostHistory) {
|
||||
return setHostHistoryId(((HostHistory) history).getHostHistoryId());
|
||||
}
|
||||
return thisCastToDerived();
|
||||
@@ -330,7 +295,7 @@ public abstract class PollMessage extends ImmutableObject
|
||||
* Given an array containing pairs of objects, verifies that both members of exactly one of the
|
||||
* pairs is non-null.
|
||||
*/
|
||||
private boolean exactlyOnePairNonNull(Object... pairs) {
|
||||
private static boolean exactlyOnePairNonNull(Object... pairs) {
|
||||
int count = 0;
|
||||
checkArgument(pairs.length % 2 == 0, "Odd number of arguments provided.");
|
||||
for (int i = 0; i < pairs.length; i += 2) {
|
||||
@@ -360,9 +325,9 @@ public abstract class PollMessage extends ImmutableObject
|
||||
instance.contactHistoryRevisionId,
|
||||
instance.hostRepoId,
|
||||
instance.hostHistoryRevisionId),
|
||||
"the repo id and history revision id must be defined for exactly one of domain, "
|
||||
+ "contact or host: "
|
||||
+ instance);
|
||||
"The repo id and history revision id must be defined for exactly one of domain, "
|
||||
+ "contact or host: %s",
|
||||
instance);
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
@@ -372,13 +337,11 @@ public abstract class PollMessage extends ImmutableObject
|
||||
*
|
||||
* <p>One-time poll messages are deleted from Datastore once they have been delivered and ACKed.
|
||||
*/
|
||||
@EntitySubclass(index = false)
|
||||
@javax.persistence.Entity
|
||||
@Entity
|
||||
@DiscriminatorValue("ONE_TIME")
|
||||
@WithLongVKey(compositeKey = true)
|
||||
public static class OneTime extends PollMessage {
|
||||
|
||||
@Ignore
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(
|
||||
@@ -399,7 +362,6 @@ public abstract class PollMessage extends ImmutableObject
|
||||
})
|
||||
PendingActionNotificationResponse pendingActionNotificationResponse;
|
||||
|
||||
@Ignore
|
||||
@Embedded
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(
|
||||
@@ -420,35 +382,21 @@ public abstract class PollMessage extends ImmutableObject
|
||||
})
|
||||
TransferResponse transferResponse;
|
||||
|
||||
@Ignore
|
||||
@Column(name = "transfer_response_domain_name")
|
||||
String fullyQualifiedDomainName;
|
||||
|
||||
@Ignore
|
||||
@Column(name = "transfer_response_domain_expiration_time")
|
||||
DateTime extendedRegistrationExpirationTime;
|
||||
|
||||
@Ignore
|
||||
@Column(name = "transfer_response_contact_id")
|
||||
String contactId;
|
||||
|
||||
@Ignore
|
||||
@Column(name = "transfer_response_host_id")
|
||||
String hostId;
|
||||
|
||||
@Override
|
||||
public VKey<OneTime> createVKey() {
|
||||
return VKey.create(OneTime.class, getId(), Key.create(this));
|
||||
}
|
||||
|
||||
/** Converts an unspecialized VKey<PollMessage> to a VKey of the derived class. */
|
||||
public static @Nullable VKey<OneTime> convertVKey(@Nullable VKey<? extends PollMessage> key) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
Key<OneTime> ofyKey =
|
||||
Key.create(key.getOfyKey().getParent(), OneTime.class, key.getOfyKey().getId());
|
||||
return VKey.create(OneTime.class, key.getSqlKey(), ofyKey);
|
||||
return VKey.createSql(OneTime.class, getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -525,8 +473,7 @@ public abstract class PollMessage extends ImmutableObject
|
||||
/** A builder for {@link OneTime} since it is immutable. */
|
||||
public static class Builder extends PollMessage.Builder<OneTime, Builder> {
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
public Builder() {}
|
||||
|
||||
private Builder(OneTime instance) {
|
||||
super(instance);
|
||||
@@ -587,14 +534,13 @@ public abstract class PollMessage extends ImmutableObject
|
||||
}
|
||||
|
||||
/**
|
||||
* An auto-renew poll message which recurs annually.
|
||||
* An autorenew poll message which recurs annually.
|
||||
*
|
||||
* <p>Auto-renew poll messages are not deleted until the registration of their parent domain has
|
||||
* been canceled, because there will always be a speculative renewal for next year until that
|
||||
* happens.
|
||||
*/
|
||||
@EntitySubclass(index = false)
|
||||
@javax.persistence.Entity
|
||||
@Entity
|
||||
@DiscriminatorValue("AUTORENEW")
|
||||
@WithLongVKey(compositeKey = true)
|
||||
public static class Autorenew extends PollMessage {
|
||||
@@ -604,7 +550,6 @@ public abstract class PollMessage extends ImmutableObject
|
||||
String targetId;
|
||||
|
||||
/** The autorenew recurs annually between {@link #eventTime} and this time. */
|
||||
@Index
|
||||
DateTime autorenewEndTime;
|
||||
|
||||
public String getTargetId() {
|
||||
@@ -617,25 +562,14 @@ public abstract class PollMessage extends ImmutableObject
|
||||
|
||||
@Override
|
||||
public VKey<Autorenew> createVKey() {
|
||||
return VKey.create(Autorenew.class, getId(), Key.create(this));
|
||||
}
|
||||
|
||||
/** Converts an unspecialized VKey<PollMessage> to a VKey of the derived class. */
|
||||
public static @Nullable VKey<Autorenew> convertVKey(VKey<? extends PollMessage> key) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
Key<Autorenew> ofyKey =
|
||||
Key.create(key.getOfyKey().getParent(), Autorenew.class, key.getOfyKey().getId());
|
||||
return VKey.create(Autorenew.class, key.getSqlKey(), ofyKey);
|
||||
return VKey.createSql(Autorenew.class, getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<ResponseData> getResponseData() {
|
||||
// Note that the event time is when the auto-renew occured, so the expiration time in the
|
||||
// Note that the event time is when the autorenew occurred, so the expiration time in the
|
||||
// response should be 1 year past that, since it denotes the new expiration time.
|
||||
return ImmutableList.of(
|
||||
DomainRenewData.create(getTargetId(), getEventTime().plusYears(1)));
|
||||
return ImmutableList.of(DomainRenewData.create(getTargetId(), getEventTime().plusYears(1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+16
-39
@@ -14,48 +14,38 @@
|
||||
|
||||
package google.registry.model.poll;
|
||||
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A converter between external key strings for {@link PollMessage}s (i.e. what registrars use to
|
||||
* identify and ACK them) and Datastore keys to the resource.
|
||||
* identify and ACK them) and {@link VKey}s to the resource.
|
||||
*
|
||||
* <p>The format of the key string is A-B-C-D-E-F as follows:
|
||||
* <p>The format of the key string is A-B as follows:
|
||||
*
|
||||
* <pre>
|
||||
* A = EppResource.typeId (decimal)
|
||||
* B = EppResource.repoId prefix (STRING)
|
||||
* C = EppResource.repoId suffix (STRING)
|
||||
* D = HistoryEntry.id (decimal)
|
||||
* E = PollMessage.id (decimal)
|
||||
* F = PollMessage.eventTime (decimal, year only)
|
||||
* A = PollMessage.id (decimal)
|
||||
* B = PollMessage.eventTime (decimal, year only)
|
||||
* </pre>
|
||||
*
|
||||
* <p>A typical poll message ID might thus look like: 1-FE0F22-TLD-10071463070-10072612074-2018
|
||||
* <p>A typical poll message ID might thus look like: 10072612074-2018
|
||||
*/
|
||||
public class PollMessageExternalKeyConverter {
|
||||
public final class PollMessageExternalKeyConverter {
|
||||
|
||||
/** An exception thrown when an external key cannot be parsed. */
|
||||
public static class PollMessageExternalKeyParseException extends RuntimeException {}
|
||||
public static class PollMessageExternalKeyParseException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 9026397649048831777L;
|
||||
}
|
||||
|
||||
/** Returns an external poll message ID for the given poll message. */
|
||||
public static String makePollMessageExternalId(PollMessage pollMessage) {
|
||||
return String.format(
|
||||
"%d-%s-%d-%d-%d",
|
||||
pollMessage.getType().getId(),
|
||||
pollMessage.getResourceName(),
|
||||
pollMessage.getHistoryRevisionId(),
|
||||
pollMessage.getId(),
|
||||
pollMessage.getEventTime().getYear());
|
||||
return String.format("%d-%d", pollMessage.getId(), pollMessage.getEventTime().getYear());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Objectify Key to a PollMessage corresponding with the external ID.
|
||||
* Returns a {@link VKey} to a {@link PollMessage} corresponding with the external ID.
|
||||
*
|
||||
* <p>Note that the year field that is included at the end of the poll message isn't actually used
|
||||
* for anything; it exists solely to create unique externally visible IDs for autorenews. We thus
|
||||
@@ -66,26 +56,13 @@ public class PollMessageExternalKeyConverter {
|
||||
*/
|
||||
public static VKey<PollMessage> parsePollMessageExternalId(String externalKey) {
|
||||
List<String> idComponents = Splitter.on('-').splitToList(externalKey);
|
||||
if (idComponents.size() != 6) {
|
||||
if (idComponents.size() != 2) {
|
||||
throw new PollMessageExternalKeyParseException();
|
||||
}
|
||||
try {
|
||||
Class<?> resourceClazz =
|
||||
PollMessage.Type.fromId(Long.parseLong(idComponents.get(0)))
|
||||
.orElseThrow(() -> new PollMessageExternalKeyParseException())
|
||||
.getResourceClass();
|
||||
return VKey.from(
|
||||
Key.create(
|
||||
Key.create(
|
||||
Key.create(
|
||||
null,
|
||||
resourceClazz,
|
||||
String.format("%s-%s", idComponents.get(1), idComponents.get(2))),
|
||||
HistoryEntry.class,
|
||||
Long.parseLong(idComponents.get(3))),
|
||||
PollMessage.class,
|
||||
Long.parseLong(idComponents.get(4))));
|
||||
// Note that idComponents.get(5) is entirely ignored; we never use the year field internally.
|
||||
Long id = Long.parseLong(idComponents.get(0));
|
||||
return VKey.createSql(PollMessage.class, id);
|
||||
// Note that idComponents.get(1) is entirely ignored; we never use the year field internally.
|
||||
} catch (NumberFormatException e) {
|
||||
throw new PollMessageExternalKeyParseException();
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ import org.joda.time.DateTime;
|
||||
* <p>This removes years off a domain's registration period. Note that the expiration time cannot be
|
||||
* set to prior than the present. Reversal of the charges for these years (if desired) must happen
|
||||
* out of band, as they may already have been billed out and thus cannot and won't be reversed in
|
||||
* Datastore.
|
||||
* the database.
|
||||
*/
|
||||
@Parameters(separators = " =", commandDescription = "Unrenew a domain.")
|
||||
@NonFinalForTesting
|
||||
@@ -217,7 +217,8 @@ class UnrenewDomainCommand extends ConfirmingCommand implements CommandWithRemot
|
||||
.build();
|
||||
// End the old autorenew billing event and poll message now.
|
||||
Recurring existingRecurring = tm().loadByKey(domain.getAutorenewBillingEvent());
|
||||
updateAutorenewRecurrenceEndTime(domain, existingRecurring, now);
|
||||
updateAutorenewRecurrenceEndTime(
|
||||
domain, existingRecurring, now, domainHistory.getDomainHistoryId());
|
||||
Domain newDomain =
|
||||
domain
|
||||
.asBuilder()
|
||||
@@ -225,9 +226,7 @@ class UnrenewDomainCommand extends ConfirmingCommand implements CommandWithRemot
|
||||
.setLastEppUpdateTime(now)
|
||||
.setLastEppUpdateRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||
.setAutorenewBillingEvent(newAutorenewEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
newAutorenewPollMessage.createVKey(),
|
||||
newAutorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(newAutorenewPollMessage.createVKey())
|
||||
.build();
|
||||
// In order to do it'll need to write out a new HistoryEntry (likely of type SYNTHETIC), a new
|
||||
// autorenew billing event and poll message, and a new one time poll message at the present time
|
||||
|
||||
@@ -179,8 +179,7 @@ class DeleteExpiredDomainsActionTest {
|
||||
.asBuilder()
|
||||
.setAutorenewEndTime(Optional.of(clock.nowUtc().minusDays(10)))
|
||||
.setAutorenewBillingEvent(autorenewBillingEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.build());
|
||||
|
||||
return pendingExpirationDomain;
|
||||
|
||||
@@ -95,7 +95,7 @@ class EppLifecycleContactTest extends EppTestCase {
|
||||
.hasCommandName("PollRequest")
|
||||
.and()
|
||||
.hasStatus(SUCCESS_WITH_ACK_MESSAGE);
|
||||
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "2-1-ROID-3-6-2000"))
|
||||
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "6-2000"))
|
||||
.atTime("2000-06-08T22:02:00Z")
|
||||
.hasResponse("poll_ack_response_empty.xml");
|
||||
assertThat(getRecordedEppMetric())
|
||||
|
||||
@@ -747,11 +747,11 @@ class EppLifecycleDomainTest extends EppTestCase {
|
||||
.hasResponse(
|
||||
"poll_response_autorenew.xml",
|
||||
ImmutableMap.of(
|
||||
"ID", "1-B-EXAMPLE-12-15-2002",
|
||||
"ID", "15-2002",
|
||||
"QDATE", "2002-06-01T00:04:00Z",
|
||||
"DOMAIN", "fakesite.example",
|
||||
"EXDATE", "2003-06-01T00:04:00Z"));
|
||||
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-B-EXAMPLE-12-15-2002"))
|
||||
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "15-2002"))
|
||||
.atTime("2002-07-01T00:02:00Z")
|
||||
.hasResponse("poll_ack_response_empty.xml");
|
||||
|
||||
@@ -765,13 +765,13 @@ class EppLifecycleDomainTest extends EppTestCase {
|
||||
.hasResponse(
|
||||
"poll_response_autorenew.xml",
|
||||
ImmutableMap.of(
|
||||
"ID", "1-B-EXAMPLE-12-15-2003", // Note -- Year is different from previous ID.
|
||||
"ID", "15-2003", // Note -- Year is different from previous ID.
|
||||
"QDATE", "2003-06-01T00:04:00Z",
|
||||
"DOMAIN", "fakesite.example",
|
||||
"EXDATE", "2004-06-01T00:04:00Z"));
|
||||
|
||||
// Ack the second poll message and verify that none remain.
|
||||
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-B-EXAMPLE-12-15-2003"))
|
||||
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "15-2003"))
|
||||
.atTime("2003-07-01T00:05:05Z")
|
||||
.hasResponse("poll_ack_response_empty.xml");
|
||||
assertThatCommand("poll.xml")
|
||||
@@ -801,7 +801,7 @@ class EppLifecycleDomainTest extends EppTestCase {
|
||||
|
||||
// As the losing registrar, read the request poll message, and then ack it.
|
||||
assertThatLoginSucceeds("NewRegistrar", "foo-BAR2");
|
||||
String messageId = "1-B-EXAMPLE-18-24-2001";
|
||||
String messageId = "24-2001";
|
||||
assertThatCommand("poll.xml")
|
||||
.atTime("2001-01-01T00:01:00Z")
|
||||
.hasResponse("poll_response_domain_transfer_request.xml", ImmutableMap.of("ID", messageId));
|
||||
@@ -810,7 +810,7 @@ class EppLifecycleDomainTest extends EppTestCase {
|
||||
.hasResponse("poll_ack_response_empty.xml");
|
||||
|
||||
// Five days in the future, expect a server approval poll message to the loser, and ack it.
|
||||
messageId = "1-B-EXAMPLE-18-23-2001";
|
||||
messageId = "23-2001";
|
||||
assertThatCommand("poll.xml")
|
||||
.atTime("2001-01-06T00:01:00Z")
|
||||
.hasResponse(
|
||||
@@ -822,7 +822,7 @@ class EppLifecycleDomainTest extends EppTestCase {
|
||||
assertThatLogoutSucceeds();
|
||||
|
||||
// Also expect a server approval poll message to the winner, with the transfer request trid.
|
||||
messageId = "1-B-EXAMPLE-18-22-2001";
|
||||
messageId = "22-2001";
|
||||
assertThatLoginSucceeds("TheRegistrar", "password2");
|
||||
assertThatCommand("poll.xml")
|
||||
.atTime("2001-01-06T00:02:00Z")
|
||||
|
||||
@@ -40,6 +40,7 @@ import google.registry.model.tmch.ClaimsList;
|
||||
import google.registry.model.tmch.ClaimsListDao;
|
||||
import google.registry.testing.DatabaseHelper;
|
||||
import google.registry.testing.TaskQueueHelper.TaskMatcher;
|
||||
import google.registry.testing.TestCacheExtension;
|
||||
import google.registry.util.JdkLoggerConfig;
|
||||
import google.registry.util.TypeUtils.TypeInstantiator;
|
||||
import java.util.logging.Level;
|
||||
@@ -48,6 +49,7 @@ import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
import org.json.simple.JSONValue;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
/**
|
||||
* Base class for resource flow unit tests.
|
||||
@@ -60,6 +62,10 @@ public abstract class ResourceFlowTestCase<F extends Flow, R extends EppResource
|
||||
|
||||
private final TestLogHandler logHandler = new TestLogHandler();
|
||||
|
||||
@RegisterExtension
|
||||
public final TestCacheExtension testCacheExtension =
|
||||
new TestCacheExtension.Builder().withClaimsListCache(java.time.Duration.ofHours(6)).build();
|
||||
|
||||
@BeforeEach
|
||||
void beforeResourceFlowTestCase() {
|
||||
// Attach TestLogHandler to the root logger so it has access to all log messages.
|
||||
|
||||
@@ -147,8 +147,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
domain
|
||||
.asBuilder()
|
||||
.setAutorenewBillingEvent(autorenewBillingEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.build());
|
||||
|
||||
assertTransactionalFlow(true);
|
||||
@@ -214,8 +213,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow, Domain
|
||||
"TheRegistrar",
|
||||
autorenewBillingEvent.createVKey())))
|
||||
.setAutorenewBillingEvent(autorenewBillingEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.build());
|
||||
assertTransactionalFlow(true);
|
||||
}
|
||||
|
||||
@@ -181,9 +181,7 @@ class DomainRenewFlowTest extends ResourceFlowTestCase<DomainRenewFlow, Domain>
|
||||
.setRegistrationExpirationTime(expirationTime)
|
||||
.setStatusValues(ImmutableSet.copyOf(statusValues))
|
||||
.setAutorenewBillingEvent(autorenewEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
autorenewPollMessage.createVKey(),
|
||||
autorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.build();
|
||||
persistResources(
|
||||
ImmutableSet.of(
|
||||
|
||||
@@ -162,7 +162,7 @@ class DomainTransferCancelFlowTest
|
||||
.setEventTime(originalExpirationTime)
|
||||
.setAutorenewEndTime(END_OF_TIME)
|
||||
.setMsg("Domain was auto-renewed.")
|
||||
.setHistoryEntry(getOnlyHistoryEntryOfType(domain, DOMAIN_CREATE))
|
||||
.setHistoryEntry(getOnlyHistoryEntryOfType(domain, DOMAIN_TRANSFER_CANCEL))
|
||||
.build(),
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setRegistrarId("TheRegistrar")
|
||||
|
||||
@@ -47,7 +47,7 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2011"));
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-2011"));
|
||||
clock.setTo(DateTime.parse("2011-01-02T01:01:01Z"));
|
||||
setRegistrarIdForFlow("NewRegistrar");
|
||||
createTld("example");
|
||||
@@ -87,7 +87,7 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
|
||||
|
||||
@Test
|
||||
void testSuccess_contactPollMessage() throws Exception {
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3-2011"));
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-2011"));
|
||||
persistResource(
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setId(MESSAGE_ID)
|
||||
@@ -102,7 +102,7 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
|
||||
|
||||
@Test
|
||||
void testFailure_contactPollMessage_withIncorrectYearField() throws Exception {
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3-1999"));
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-1999"));
|
||||
persistResource(
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setId(MESSAGE_ID)
|
||||
@@ -124,7 +124,7 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
|
||||
|
||||
@Test
|
||||
void testSuccess_recentActiveAutorenew() throws Exception {
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2010"));
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-2010"));
|
||||
persistAutorenewPollMessage(clock.nowUtc().minusMonths(6), END_OF_TIME);
|
||||
assertTransactionalFlow(true);
|
||||
runFlowAssertResponse(loadFile("poll_ack_response_empty.xml"));
|
||||
@@ -132,7 +132,7 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
|
||||
|
||||
@Test
|
||||
void testSuccess_oldActiveAutorenew() throws Exception {
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2009"));
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-2009"));
|
||||
persistAutorenewPollMessage(clock.nowUtc().minusYears(2), END_OF_TIME);
|
||||
// Create three other messages to be queued for retrieval to get our count right, since the poll
|
||||
// ack response wants there to be 4 messages in the queue when the ack comes back.
|
||||
@@ -141,14 +141,12 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
|
||||
}
|
||||
assertTransactionalFlow(true);
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"poll_ack_response.xml",
|
||||
ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2009", "COUNT", "4")));
|
||||
loadFile("poll_ack_response.xml", ImmutableMap.of("MSGID", "3-2009", "COUNT", "4")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_oldInactiveAutorenew() throws Exception {
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2010"));
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3-2010"));
|
||||
persistAutorenewPollMessage(clock.nowUtc().minusMonths(6), clock.nowUtc());
|
||||
assertTransactionalFlow(true);
|
||||
runFlowAssertResponse(loadFile("poll_ack_response_empty.xml"));
|
||||
@@ -162,35 +160,33 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
|
||||
}
|
||||
assertTransactionalFlow(true);
|
||||
runFlowAssertResponse(
|
||||
loadFile(
|
||||
"poll_ack_response.xml",
|
||||
ImmutableMap.of("MSGID", "1-3-EXAMPLE-4-3-2011", "COUNT", "4")));
|
||||
loadFile("poll_ack_response.xml", ImmutableMap.of("MSGID", "3-2011", "COUNT", "4")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_noSuchMessage() throws Exception {
|
||||
assertTransactionalFlow(true);
|
||||
Exception e = assertThrows(MessageDoesNotExistException.class, this::runFlow);
|
||||
assertThat(e).hasMessageThat().contains(String.format("(1-3-EXAMPLE-4-%d-2011)", MESSAGE_ID));
|
||||
assertThat(e).hasMessageThat().contains(String.format("(%d-2011)", MESSAGE_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_invalidId_tooFewComponents() throws Exception {
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1-2-3"));
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "1"));
|
||||
assertTransactionalFlow(true);
|
||||
assertThrows(InvalidMessageIdException.class, this::runFlow);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_invalidId_tooManyComponents() throws Exception {
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3-1999-2007"));
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-1999-2007"));
|
||||
assertTransactionalFlow(true);
|
||||
assertThrows(InvalidMessageIdException.class, this::runFlow);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_contactPollMessage_withMissingYearField() throws Exception {
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "2-2-ROID-4-3"));
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "3"));
|
||||
persistResource(
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setId(MESSAGE_ID)
|
||||
@@ -210,13 +206,6 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
|
||||
assertThrows(InvalidMessageIdException.class, this::runFlow);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_invalidEppResourceClassId() throws Exception {
|
||||
setEppInput("poll_ack.xml", ImmutableMap.of("MSGID", "999-1-1-1"));
|
||||
assertTransactionalFlow(true);
|
||||
assertThrows(InvalidMessageIdException.class, this::runFlow);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_missingId() throws Exception {
|
||||
setEppInput("poll_ack_missing_id.xml");
|
||||
@@ -250,6 +239,6 @@ class PollAckFlowTest extends FlowTestCase<PollAckFlow> {
|
||||
.build());
|
||||
assertTransactionalFlow(true);
|
||||
Exception e = assertThrows(MessageDoesNotExistException.class, this::runFlow);
|
||||
assertThat(e).hasMessageThat().contains(String.format("(1-3-EXAMPLE-4-%d-2011)", MESSAGE_ID));
|
||||
assertThat(e).hasMessageThat().contains(String.format("(%d-2011)", MESSAGE_ID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import google.registry.model.index.EppResourceIndexBucket;
|
||||
import google.registry.model.index.ForeignKeyIndex.ForeignKeyContactIndex;
|
||||
import google.registry.model.index.ForeignKeyIndex.ForeignKeyDomainIndex;
|
||||
import google.registry.model.index.ForeignKeyIndex.ForeignKeyHostIndex;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.rde.RdeRevision;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
@@ -63,7 +62,6 @@ public class ClassPathManagerTest {
|
||||
assertThat(ClassPathManager.getClass("Lock")).isEqualTo(Lock.class);
|
||||
assertThat(ClassPathManager.getClass("Domain")).isEqualTo(Domain.class);
|
||||
assertThat(ClassPathManager.getClass("HistoryEntry")).isEqualTo(HistoryEntry.class);
|
||||
assertThat(ClassPathManager.getClass("PollMessage")).isEqualTo(PollMessage.class);
|
||||
assertThat(ClassPathManager.getClass("ForeignKeyHostIndex"))
|
||||
.isEqualTo(ForeignKeyHostIndex.class);
|
||||
assertThat(ClassPathManager.getClass("ServerSecret")).isEqualTo(ServerSecret.class);
|
||||
@@ -117,7 +115,6 @@ public class ClassPathManagerTest {
|
||||
assertThat(ClassPathManager.getClassName(Lock.class)).isEqualTo("Lock");
|
||||
assertThat(ClassPathManager.getClassName(Domain.class)).isEqualTo("Domain");
|
||||
assertThat(ClassPathManager.getClassName(HistoryEntry.class)).isEqualTo("HistoryEntry");
|
||||
assertThat(ClassPathManager.getClassName(PollMessage.class)).isEqualTo("PollMessage");
|
||||
assertThat(ClassPathManager.getClassName(ForeignKeyHostIndex.class))
|
||||
.isEqualTo("ForeignKeyHostIndex");
|
||||
assertThat(ClassPathManager.getClassName(ServerSecret.class)).isEqualTo("ServerSecret");
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package google.registry.model.domain;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.flows.domain.DomainTransferUtils.createPendingTransferData;
|
||||
import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenStatus.NOT_STARTED;
|
||||
import static google.registry.model.domain.token.AllocationToken.TokenType.UNLIMITED_USE;
|
||||
@@ -40,11 +39,8 @@ import com.googlecode.objectify.Key;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Flag;
|
||||
import google.registry.model.billing.BillingEvent.Reason;
|
||||
import google.registry.model.billing.BillingEvent.Recurring;
|
||||
import google.registry.model.common.EntityGroupRoot;
|
||||
import google.registry.model.contact.ContactResource;
|
||||
import google.registry.model.domain.DesignatedContact.Type;
|
||||
import google.registry.model.domain.Period.Unit;
|
||||
import google.registry.model.domain.launch.LaunchNotice;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
import google.registry.model.domain.secdns.DelegationSignerData;
|
||||
@@ -52,7 +48,6 @@ import google.registry.model.domain.token.AllocationToken;
|
||||
import google.registry.model.domain.token.AllocationToken.TokenStatus;
|
||||
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
|
||||
import google.registry.model.eppcommon.StatusValue;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.host.Host;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
@@ -503,8 +498,7 @@ public class DomainSqlTest {
|
||||
domain
|
||||
.asBuilder()
|
||||
.setAutorenewBillingEvent(billEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.setDeletePollMessage(deletePollMessage.createVKey())
|
||||
.setTransferData(transferData)
|
||||
.setGracePeriods(gracePeriods)
|
||||
@@ -549,147 +543,10 @@ public class DomainSqlTest {
|
||||
assertThat(persisted.getGracePeriods()).isEqualTo(gracePeriods);
|
||||
}
|
||||
|
||||
@Test
|
||||
void persistDomainWithLegacyVKeys() {
|
||||
createTld("com");
|
||||
historyEntry =
|
||||
new DomainHistory.Builder()
|
||||
.setId(100L)
|
||||
.setType(HistoryEntry.Type.DOMAIN_CREATE)
|
||||
.setPeriod(Period.create(1, Period.Unit.YEARS))
|
||||
.setModificationTime(DateTime.now(UTC))
|
||||
.setDomainRepoId("4-COM")
|
||||
.setRegistrarId("registrar1")
|
||||
// These are non-null, but I don't think some tests set them.
|
||||
.setReason("felt like it")
|
||||
.setRequestedByRegistrar(false)
|
||||
.setXmlBytes(new byte[0])
|
||||
.build();
|
||||
BillingEvent.Recurring billEvent =
|
||||
new BillingEvent.Recurring.Builder()
|
||||
.setId(200L)
|
||||
.setReason(Reason.RENEW)
|
||||
.setFlags(ImmutableSet.of(Flag.AUTO_RENEW))
|
||||
.setTargetId("example.com")
|
||||
.setRegistrarId("registrar1")
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setRecurrenceEndTime(END_OF_TIME)
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
PollMessage.Autorenew autorenewPollMessage =
|
||||
new PollMessage.Autorenew.Builder()
|
||||
.setId(300L)
|
||||
.setRegistrarId("registrar1")
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setHistoryEntry(historyEntry)
|
||||
.build();
|
||||
PollMessage.OneTime deletePollMessage =
|
||||
new PollMessage.OneTime.Builder()
|
||||
.setId(400L)
|
||||
.setRegistrarId("registrar1")
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setHistoryEntry(historyEntry)
|
||||
.build();
|
||||
BillingEvent.OneTime oneTimeBillingEvent =
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setId(500L)
|
||||
// Use SERVER_STATUS so we don't have to add a period.
|
||||
.setReason(Reason.SERVER_STATUS)
|
||||
.setTargetId("example.com")
|
||||
.setRegistrarId("registrar1")
|
||||
.setBillingTime(DateTime.now(UTC))
|
||||
.setCost(Money.of(USD, 100))
|
||||
.setEventTime(DateTime.now(UTC).plusYears(1))
|
||||
.setDomainHistory(historyEntry)
|
||||
.build();
|
||||
DomainTransferData transferData =
|
||||
createPendingTransferData(
|
||||
domain.getRepoId(),
|
||||
historyEntry.getId(),
|
||||
new DomainTransferData.Builder()
|
||||
.setTransferRequestTrid(Trid.create("foo", "bar"))
|
||||
.setTransferRequestTime(fakeClock.nowUtc())
|
||||
.setGainingRegistrarId("registrar2")
|
||||
.setLosingRegistrarId("registrar1")
|
||||
.setPendingTransferExpirationTime(fakeClock.nowUtc().plusDays(1)),
|
||||
ImmutableSet.of(oneTimeBillingEvent, billEvent, autorenewPollMessage),
|
||||
Period.create(0, Unit.YEARS));
|
||||
gracePeriods =
|
||||
ImmutableSet.of(
|
||||
GracePeriod.create(
|
||||
GracePeriodStatus.ADD,
|
||||
"4-COM",
|
||||
END_OF_TIME,
|
||||
"registrar1",
|
||||
oneTimeBillingEvent.createVKey()),
|
||||
GracePeriod.createForRecurring(
|
||||
GracePeriodStatus.AUTO_RENEW,
|
||||
"4-COM",
|
||||
END_OF_TIME,
|
||||
"registrar1",
|
||||
billEvent.createVKey()));
|
||||
|
||||
domain =
|
||||
domain
|
||||
.asBuilder()
|
||||
.setAutorenewBillingEvent(Recurring.createVKey(billEvent.getId()))
|
||||
.setAutorenewPollMessage(
|
||||
createLegacyVKey(PollMessage.Autorenew.class, autorenewPollMessage.getId()),
|
||||
autorenewPollMessage.getHistoryRevisionId())
|
||||
.setDeletePollMessage(
|
||||
createLegacyVKey(PollMessage.OneTime.class, deletePollMessage.getId()))
|
||||
.setTransferData(transferData)
|
||||
.setGracePeriods(gracePeriods)
|
||||
.build();
|
||||
historyEntry = historyEntry.asBuilder().setDomain(domain).build();
|
||||
insertInDb(
|
||||
contact,
|
||||
contact2,
|
||||
host,
|
||||
historyEntry,
|
||||
autorenewPollMessage,
|
||||
billEvent,
|
||||
deletePollMessage,
|
||||
oneTimeBillingEvent,
|
||||
domain);
|
||||
|
||||
// Store the existing BillingRecurrence VKey. This happens after the event has been persisted.
|
||||
Domain persisted = loadByKey(domain.createVKey());
|
||||
|
||||
// Verify that the domain data has been persisted.
|
||||
// dsData still isn't persisted. gracePeriods appears to have the same values but for some
|
||||
// reason is showing up as different.
|
||||
assertEqualDomainExcept(persisted, "creationTime", "dsData", "gracePeriods");
|
||||
|
||||
// Verify that the DomainBase object from the history record sets the fields correctly.
|
||||
DomainHistory persistedHistoryEntry = loadByKey(historyEntry.createVKey());
|
||||
assertThat(persistedHistoryEntry.getDomainBase().get().getAutorenewPollMessage())
|
||||
.isEqualTo(domain.getAutorenewPollMessage());
|
||||
assertThat(persistedHistoryEntry.getDomainBase().get().getAutorenewBillingEvent())
|
||||
.isEqualTo(domain.getAutorenewBillingEvent());
|
||||
assertThat(persistedHistoryEntry.getDomainBase().get().getDeletePollMessage())
|
||||
.isEqualTo(domain.getDeletePollMessage());
|
||||
DomainTransferData persistedTransferData =
|
||||
persistedHistoryEntry.getDomainBase().get().getTransferData();
|
||||
DomainTransferData originalTransferData = domain.getTransferData();
|
||||
assertThat(persistedTransferData.getServerApproveBillingEvent())
|
||||
.isEqualTo(originalTransferData.getServerApproveBillingEvent());
|
||||
assertThat(persistedTransferData.getServerApproveAutorenewEvent())
|
||||
.isEqualTo(originalTransferData.getServerApproveAutorenewEvent());
|
||||
assertThat(persistedTransferData.getServerApproveAutorenewPollMessage())
|
||||
.isEqualTo(originalTransferData.getServerApproveAutorenewPollMessage());
|
||||
assertThat(domain.getGracePeriods()).isEqualTo(gracePeriods);
|
||||
}
|
||||
|
||||
private <T> VKey<T> createKey(Class<T> clazz, String name) {
|
||||
return VKey.create(clazz, name, Key.create(clazz, name));
|
||||
}
|
||||
|
||||
private <T> VKey<T> createLegacyVKey(Class<T> clazz, long id) {
|
||||
return VKey.create(
|
||||
clazz, id, Key.create(Key.create(EntityGroupRoot.class, "per-tld"), clazz, id));
|
||||
}
|
||||
|
||||
private void assertEqualDomainExcept(Domain thatDomain, String... excepts) {
|
||||
ImmutableList<String> moreExcepts =
|
||||
new ImmutableList.Builder<String>()
|
||||
|
||||
@@ -41,7 +41,6 @@ import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.ImmutableObjectSubject;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
@@ -114,7 +113,7 @@ public class DomainTest {
|
||||
oneTimeBillKey =
|
||||
persistResource(
|
||||
new BillingEvent.OneTime.Builder()
|
||||
// Use SERVER_STATUS so we don't have to add a period.
|
||||
// Use SERVER_STATUS, so we don't have to add a period.
|
||||
.setReason(Reason.SERVER_STATUS)
|
||||
.setTargetId(domain.getDomainName())
|
||||
.setRegistrarId(domain.getCurrentSponsorRegistrarId())
|
||||
@@ -140,7 +139,7 @@ public class DomainTest {
|
||||
BillingEvent.OneTime oneTimeBill =
|
||||
new BillingEvent.OneTime.Builder()
|
||||
.setId(500L)
|
||||
// Use SERVER_STATUS so we don't have to add a period.
|
||||
// Use SERVER_STATUS, so we don't have to add a period.
|
||||
.setReason(Reason.SERVER_STATUS)
|
||||
.setTargetId("example.com")
|
||||
.setRegistrarId("registrar1")
|
||||
@@ -163,10 +162,8 @@ public class DomainTest {
|
||||
.build();
|
||||
insertInDb(historyEntry, oneTimeBill, recurringBill);
|
||||
recurringBillKey = recurringBill.createVKey();
|
||||
VKey<PollMessage.Autorenew> autorenewPollKey =
|
||||
VKey.from(Key.create(Key.create(domainHistory), PollMessage.Autorenew.class, 3));
|
||||
VKey<PollMessage.OneTime> onetimePollKey =
|
||||
VKey.from(Key.create(Key.create(domainHistory), PollMessage.OneTime.class, 1));
|
||||
VKey<PollMessage.Autorenew> autorenewPollKey = VKey.createSql(PollMessage.Autorenew.class, 3L);
|
||||
VKey<PollMessage.OneTime> onetimePollKey = VKey.createSql(PollMessage.OneTime.class, 1L);
|
||||
// Set up a new persisted domain entity.
|
||||
domain =
|
||||
persistResource(
|
||||
@@ -215,7 +212,7 @@ public class DomainTest {
|
||||
.build())
|
||||
.setDeletePollMessage(onetimePollKey)
|
||||
.setAutorenewBillingEvent(recurringBillKey)
|
||||
.setAutorenewPollMessage(autorenewPollKey, historyEntry.getId())
|
||||
.setAutorenewPollMessage(autorenewPollKey)
|
||||
.setSmdId("smdid")
|
||||
.addGracePeriod(
|
||||
GracePeriod.create(
|
||||
@@ -849,7 +846,7 @@ public class DomainTest {
|
||||
|
||||
@Test
|
||||
void testClone_transferDuringAutorenew() {
|
||||
// When the domain is an an autorenew grace period, we should not extend the registration
|
||||
// When the domain is an autorenew grace period, we should not extend the registration
|
||||
// expiration by a further year--it should just be whatever the autorenew was
|
||||
DateTime now = DateTime.now(UTC);
|
||||
DateTime transferExpirationTime = now.minusDays(1);
|
||||
|
||||
+10
-31
@@ -46,7 +46,7 @@ public class PollMessageExternalKeyConverterTest {
|
||||
public final AppEngineExtension appEngine = AppEngineExtension.builder().withCloudSql().build();
|
||||
|
||||
private HistoryEntry historyEntry;
|
||||
private FakeClock clock = new FakeClock(DateTime.parse("2007-07-07T01:01:01Z"));
|
||||
private final FakeClock clock = new FakeClock(DateTime.parse("2007-07-07T01:01:01Z"));
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
@@ -77,8 +77,8 @@ public class PollMessageExternalKeyConverterTest {
|
||||
.setMsg("Test poll message")
|
||||
.setHistoryEntry(historyEntry)
|
||||
.build());
|
||||
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("1-2-FOOBAR-4-5-2007");
|
||||
assertVKeysEqual(parsePollMessageExternalId("1-2-FOOBAR-4-5-2007"), pollMessage.createVKey());
|
||||
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("5-2007");
|
||||
assertVKeysEqual(parsePollMessageExternalId("5-2007"), pollMessage.createVKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -94,8 +94,8 @@ public class PollMessageExternalKeyConverterTest {
|
||||
.setMsg("Test poll message")
|
||||
.setHistoryEntry(historyEntry)
|
||||
.build());
|
||||
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("2-5-ROID-6-7-2007");
|
||||
assertVKeysEqual(parsePollMessageExternalId("2-5-ROID-6-7-2007"), pollMessage.createVKey());
|
||||
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("7-2007");
|
||||
assertVKeysEqual(parsePollMessageExternalId("7-2007"), pollMessage.createVKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -111,46 +111,25 @@ public class PollMessageExternalKeyConverterTest {
|
||||
.setMsg("Test poll message")
|
||||
.setHistoryEntry(historyEntry)
|
||||
.build());
|
||||
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("3-5-ROID-6-7-2007");
|
||||
assertVKeysEqual(parsePollMessageExternalId("3-5-ROID-6-7-2007"), pollMessage.createVKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_missingYearField() {
|
||||
assertThrows(
|
||||
PollMessageExternalKeyParseException.class,
|
||||
() -> parsePollMessageExternalId("1-2-FOOBAR-4-5"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_invalidEppResourceTypeId() {
|
||||
// Populate the testdata correctly as for 1-2-FOOBAR-4-5 so we know that the only thing that
|
||||
// is wrong here is the EppResourceTypeId.
|
||||
testSuccess_domain();
|
||||
assertThrows(
|
||||
PollMessageExternalKeyParseException.class,
|
||||
() -> parsePollMessageExternalId("4-2-FOOBAR-4-5-2007"));
|
||||
assertThat(makePollMessageExternalId(pollMessage)).isEqualTo("7-2007");
|
||||
assertVKeysEqual(parsePollMessageExternalId("7-2007"), pollMessage.createVKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_tooFewComponentParts() {
|
||||
assertThrows(
|
||||
PollMessageExternalKeyParseException.class,
|
||||
() -> parsePollMessageExternalId("1-3-EXAMPLE"));
|
||||
assertThrows(PollMessageExternalKeyParseException.class, () -> parsePollMessageExternalId("1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_tooManyComponentParts() {
|
||||
assertThrows(
|
||||
PollMessageExternalKeyParseException.class,
|
||||
() -> parsePollMessageExternalId("1-3-EXAMPLE-4-5-2007-2009"));
|
||||
PollMessageExternalKeyParseException.class, () -> parsePollMessageExternalId("1-3-2009"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_nonNumericIds() {
|
||||
assertThrows(
|
||||
PollMessageExternalKeyParseException.class,
|
||||
() -> parsePollMessageExternalId("A-B-FOOBAR-D-E-F"));
|
||||
PollMessageExternalKeyParseException.class, () -> parsePollMessageExternalId("A-2007"));
|
||||
}
|
||||
|
||||
// We may have VKeys of slightly varying types, e.g. VKey<PollMessage> (superclass) and
|
||||
|
||||
@@ -18,16 +18,13 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.joda.time.DateTimeZone.UTC;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Cancellation;
|
||||
import google.registry.model.billing.BillingEvent.OneTime;
|
||||
import google.registry.model.billing.BillingEvent.Recurring;
|
||||
import google.registry.model.domain.Domain;
|
||||
import google.registry.model.domain.Period;
|
||||
import google.registry.model.eppcommon.Trid;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.reporting.HistoryEntry;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -51,21 +48,11 @@ public class TransferDataTest {
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
Key<HistoryEntry> historyEntryKey =
|
||||
Key.create(Key.create(Domain.class, "4-TLD"), HistoryEntry.class, 1356L);
|
||||
transferBillingEventKey = OneTime.createVKey(12345L);
|
||||
otherServerApproveBillingEventKey = Cancellation.createVKey(2468L);
|
||||
recurringBillingEventKey = Recurring.createVKey(13579L);
|
||||
autorenewPollMessageKey =
|
||||
VKey.create(
|
||||
PollMessage.Autorenew.class,
|
||||
67890L,
|
||||
Key.create(historyEntryKey, PollMessage.Autorenew.class, 67890L));
|
||||
otherServerApprovePollMessageKey =
|
||||
VKey.create(
|
||||
PollMessage.OneTime.class,
|
||||
314159L,
|
||||
Key.create(historyEntryKey, PollMessage.OneTime.class, 314159L));
|
||||
autorenewPollMessageKey = VKey.createSql(PollMessage.Autorenew.class, 67890L);
|
||||
otherServerApprovePollMessageKey = VKey.createSql(PollMessage.OneTime.class, 314159L);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -334,8 +334,7 @@ public class DomainToXjcConverterTest {
|
||||
.setMsg("Domain was auto-renewed.")
|
||||
.setHistoryEntry(domainHistory)
|
||||
.build())
|
||||
.createVKey(),
|
||||
domainHistory.getId())
|
||||
.createVKey())
|
||||
.setTransferData(
|
||||
new DomainTransferData.Builder()
|
||||
.setGainingRegistrarId("NewRegistrar")
|
||||
|
||||
@@ -175,8 +175,7 @@ final class RdeFixtures {
|
||||
.setMsg("Domain was auto-renewed.")
|
||||
.setHistoryEntry(historyEntry)
|
||||
.build())
|
||||
.createVKey(),
|
||||
historyEntry.getId())
|
||||
.createVKey())
|
||||
.setTransferData(
|
||||
new DomainTransferData.Builder()
|
||||
.setGainingRegistrarId("gaining")
|
||||
|
||||
@@ -667,8 +667,7 @@ public class DatabaseHelper {
|
||||
domain
|
||||
.asBuilder()
|
||||
.setAutorenewBillingEvent(autorenewEvent.createVKey())
|
||||
.setAutorenewPollMessage(
|
||||
autorenewPollMessage.createVKey(), autorenewPollMessage.getHistoryRevisionId())
|
||||
.setAutorenewPollMessage(autorenewPollMessage.createVKey())
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,10 @@ import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.BouncyCastleProviderExtension;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.FakeUrlConnectionService;
|
||||
import google.registry.testing.TestCacheExtension;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -43,6 +45,10 @@ abstract class TmchActionTestCase {
|
||||
@RegisterExtension
|
||||
public final BouncyCastleProviderExtension bouncy = new BouncyCastleProviderExtension();
|
||||
|
||||
@RegisterExtension
|
||||
public final TestCacheExtension testCacheExtension =
|
||||
new TestCacheExtension.Builder().withClaimsListCache(Duration.ofHours(6)).build();
|
||||
|
||||
final FakeClock clock = new FakeClock();
|
||||
final Marksdb marksdb = new Marksdb();
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import google.registry.util.ResourceUtils;
|
||||
import google.registry.util.SystemClock;
|
||||
import java.nio.file.Path;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
|
||||
@@ -38,6 +39,7 @@ class TmchTestDataExpirationTest {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
@Disabled("TODO(b/243130376): update the data files when ICANN provides them")
|
||||
@Test
|
||||
void testActiveSignedMarkFiles_areValidAndNotExpired() throws Exception {
|
||||
DomainFlowTmchUtils tmchUtils =
|
||||
|
||||
@@ -77,10 +77,10 @@ public class AckPollMessagesCommandTest extends CommandTestCase<AckPollMessagesC
|
||||
assertThat(loadByKeysIfPresent(ImmutableList.of(pm1, pm2, pm3, pm4)).values())
|
||||
.containsExactly(futurePollMessage);
|
||||
assertInStdout(
|
||||
"1-FSDGS-TLD-2406-624-2013,2013-05-01T22:33:44.000Z,ninelives",
|
||||
"1-FSDGS-TLD-2406-316-2014,2014-01-01T22:33:44.000Z,foobar",
|
||||
"1-FSDGS-TLD-2406-791-2015,2015-01-08T22:33:44.000Z,ginger");
|
||||
assertNotInStdout("1-FSDGS-TLD-2406-123-2015,2015-09-01T22:33:44.000Z,notme");
|
||||
"624-2013,2013-05-01T22:33:44.000Z,ninelives",
|
||||
"316-2014,2014-01-01T22:33:44.000Z,foobar",
|
||||
"791-2015,2015-01-08T22:33:44.000Z,ginger");
|
||||
assertNotInStdout("123-2015,2015-09-01T22:33:44.000Z,notme");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -105,9 +105,9 @@ public class AckPollMessagesCommandTest extends CommandTestCase<AckPollMessagesC
|
||||
assertThat(loadByKeysIfPresent(ImmutableList.of(pm1, pm2, pm3)).values())
|
||||
.containsExactly(resaved);
|
||||
assertInStdout(
|
||||
"1-FSDGS-TLD-2406-625-2011,2011-04-15T22:33:44.000Z,autorenew",
|
||||
"1-FSDGS-TLD-2406-624-2013,2013-05-01T22:33:44.000Z,ninelives",
|
||||
"1-FSDGS-TLD-2406-316-2014,2014-01-01T22:33:44.000Z,foobar");
|
||||
"625-2011,2011-04-15T22:33:44.000Z,autorenew",
|
||||
"624-2013,2013-05-01T22:33:44.000Z,ninelives",
|
||||
"316-2014,2014-01-01T22:33:44.000Z,foobar");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -130,9 +130,9 @@ public class AckPollMessagesCommandTest extends CommandTestCase<AckPollMessagesC
|
||||
runCommand("-c", "TheRegistrar");
|
||||
assertThat(loadByKeysIfPresent(ImmutableList.of(pm1, pm2, pm3))).isEmpty();
|
||||
assertInStdout(
|
||||
"1-FSDGS-TLD-2406-625-2011,2011-04-15T22:33:44.000Z,autorenew",
|
||||
"1-FSDGS-TLD-2406-624-2013,2013-05-01T22:33:44.000Z,ninelives",
|
||||
"1-FSDGS-TLD-2406-316-2014,2014-01-01T22:33:44.000Z,foobar");
|
||||
"625-2011,2011-04-15T22:33:44.000Z,autorenew",
|
||||
"624-2013,2013-05-01T22:33:44.000Z,ninelives",
|
||||
"316-2014,2014-01-01T22:33:44.000Z,foobar");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -115,7 +115,7 @@ class EppLifecycleToolsTest extends EppTestCase {
|
||||
.atTime("2001-06-08T00:00:00Z")
|
||||
.hasResponse("poll_response_unrenew.xml");
|
||||
|
||||
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-7-TLD-20-21-2001"))
|
||||
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "21-2001"))
|
||||
.atTime("2001-06-08T00:00:01Z")
|
||||
.hasResponse("poll_ack_response_empty.xml");
|
||||
|
||||
@@ -136,7 +136,7 @@ class EppLifecycleToolsTest extends EppTestCase {
|
||||
.hasResponse(
|
||||
"poll_response_autorenew.xml",
|
||||
ImmutableMap.of(
|
||||
"ID", "1-7-TLD-20-23-2003",
|
||||
"ID", "23-2003",
|
||||
"QDATE", "2003-06-01T00:02:00Z",
|
||||
"DOMAIN", "example.tld",
|
||||
"EXDATE", "2004-06-01T00:02:00Z"));
|
||||
|
||||
@@ -155,7 +155,6 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
|
||||
.build()));
|
||||
|
||||
// Check that fields on domain were updated correctly.
|
||||
assertThat(domain.getAutorenewPollMessageHistoryId()).isEqualTo(synthetic.getId());
|
||||
assertThat(domain.getRegistrationExpirationTime()).isEqualTo(newExpirationTime);
|
||||
assertThat(domain.getLastEppUpdateTime()).isEqualTo(unrenewTime);
|
||||
assertThat(domain.getLastEppUpdateRegistrarId()).isEqualTo("TheRegistrar");
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
|
||||
<msgQ count="1" id="6-2011">
|
||||
<qDate>2011-01-02T01:01:01Z</qDate>
|
||||
<msg>Domain test.example was deleted by registry administrator with final deletion effective: 2011-01-02T00:56:01.008Z</msg>
|
||||
</msgQ>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
|
||||
<msgQ count="1" id="6-2011">
|
||||
<qDate>2011-01-01T01:01:01Z</qDate>
|
||||
<msg>Domain was auto-renewed.</msg>
|
||||
</msgQ>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="2-2-ROID-5-6-2011">
|
||||
<msgQ count="1" id="6-2011">
|
||||
<qDate>2011-01-01T01:01:01Z</qDate>
|
||||
<msg>Deleted contact jd1234</msg>
|
||||
</msgQ>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="2-2-ROID-5-3-2010">
|
||||
<msgQ count="1" id="3-2010">
|
||||
<qDate>2010-12-28T01:01:01Z</qDate>
|
||||
<msg>Transfer requested.</msg>
|
||||
</msgQ>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
|
||||
<msgQ count="1" id="6-2011">
|
||||
<qDate>2011-01-01T01:01:01Z</qDate>
|
||||
<msg>Domain deleted.</msg>
|
||||
</msgQ>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
|
||||
<msgQ count="1" id="6-2011">
|
||||
<qDate>2011-01-01T01:01:01Z</qDate>
|
||||
<msg>Transfer approved.</msg>
|
||||
</msgQ>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="1-3-EXAMPLE-5-6-2011">
|
||||
<msgQ count="1" id="6-2011">
|
||||
<qDate>2011-01-01T01:01:01Z</qDate>
|
||||
<msg>Transfer approved.</msg>
|
||||
</msgQ>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="3-4-ROID-5-6-2011">
|
||||
<msgQ count="1" id="6-2011">
|
||||
<qDate>2011-01-01T01:01:01Z</qDate>
|
||||
<msg>Deleted host ns1.test.example</msg>
|
||||
</msgQ>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="2-1-ROID-3-6-2000">
|
||||
<msgQ count="1" id="6-2000">
|
||||
<qDate>2000-06-08T22:00:00Z</qDate>
|
||||
<msg>Transfer requested.</msg>
|
||||
</msgQ>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="1-7-TLD-14-16-2000">
|
||||
<msgQ count="1" id="16-2000">
|
||||
<qDate>2000-06-02T13:00:00Z</qDate>
|
||||
<msg>The registry administrator has added the status(es) [serverHold].
|
||||
</msg>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<result code="1301">
|
||||
<msg>Command completed successfully; ack to dequeue</msg>
|
||||
</result>
|
||||
<msgQ count="1" id="1-7-TLD-20-21-2001">
|
||||
<msgQ count="1" id="21-2001">
|
||||
<qDate>2001-06-07T00:00:00Z</qDate>
|
||||
<msg>Domain example.tld was unrenewed by 3 years; now expires at 2003-06-01T00:02:00.000Z.</msg>
|
||||
</msgQ>
|
||||
|
||||
@@ -359,26 +359,6 @@ class google.registry.model.index.ForeignKeyIndex$ForeignKeyHostIndex {
|
||||
google.registry.persistence.VKey<E> topReference;
|
||||
org.joda.time.DateTime deletionTime;
|
||||
}
|
||||
class google.registry.model.poll.PollMessage {
|
||||
@Id java.lang.Long id;
|
||||
java.lang.String clientId;
|
||||
java.lang.String msg;
|
||||
org.joda.time.DateTime eventTime;
|
||||
}
|
||||
class google.registry.model.poll.PollMessage$Autorenew {
|
||||
@Id java.lang.Long id;
|
||||
java.lang.String clientId;
|
||||
java.lang.String msg;
|
||||
java.lang.String targetId;
|
||||
org.joda.time.DateTime autorenewEndTime;
|
||||
org.joda.time.DateTime eventTime;
|
||||
}
|
||||
class google.registry.model.poll.PollMessage$OneTime {
|
||||
@Id java.lang.Long id;
|
||||
java.lang.String clientId;
|
||||
java.lang.String msg;
|
||||
org.joda.time.DateTime eventTime;
|
||||
}
|
||||
class google.registry.model.rde.RdeRevision {
|
||||
@Id java.lang.String id;
|
||||
int revision;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -122,3 +122,4 @@ V121__drop_sql_checkpoint_and_txn.sql
|
||||
V122__add_current_package_token_to_domain.sql
|
||||
V123__drop_unused_columns_in_billing_cancellation_table.sql
|
||||
V124__add_console_user.sql
|
||||
V125__create_package_promotion.sql
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
-- Copyright 2022 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.
|
||||
|
||||
create table "PackagePromotion" (
|
||||
package_promotion_id int8 not null,
|
||||
last_notification_sent timestamptz,
|
||||
max_creates int4 not null,
|
||||
max_domains int4 not null,
|
||||
next_billing_date timestamptz not null,
|
||||
package_price_amount numeric(19, 2) not null,
|
||||
package_price_currency text not null,
|
||||
token text not null,
|
||||
primary key (package_promotion_id)
|
||||
);
|
||||
|
||||
create index IDXlg6a5tp70nch9cp0gc11brc5o on "PackagePromotion" (token);
|
||||
|
||||
@@ -270,7 +270,6 @@
|
||||
billing_recurrence_id int8,
|
||||
autorenew_end_time timestamptz,
|
||||
autorenew_poll_message_id int8,
|
||||
autorenew_poll_message_history_id int8,
|
||||
billing_contact text,
|
||||
current_package_token text,
|
||||
deletion_poll_message_id int8,
|
||||
@@ -340,7 +339,6 @@
|
||||
billing_recurrence_id int8,
|
||||
autorenew_end_time timestamptz,
|
||||
autorenew_poll_message_id int8,
|
||||
autorenew_poll_message_history_id int8,
|
||||
billing_contact text,
|
||||
current_package_token text,
|
||||
deletion_poll_message_id int8,
|
||||
|
||||
@@ -646,6 +646,22 @@ CREATE TABLE public."Lock" (
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PackagePromotion; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public."PackagePromotion" (
|
||||
package_promotion_id bigint NOT NULL,
|
||||
last_notification_sent timestamp with time zone,
|
||||
max_creates integer NOT NULL,
|
||||
max_domains integer NOT NULL,
|
||||
next_billing_date timestamp with time zone NOT NULL,
|
||||
package_price_amount numeric(19,2) NOT NULL,
|
||||
package_price_currency text NOT NULL,
|
||||
token text NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PollMessage; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1264,6 +1280,14 @@ ALTER TABLE ONLY public."Lock"
|
||||
ADD CONSTRAINT "Lock_pkey" PRIMARY KEY (resource_name, scope);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PackagePromotion PackagePromotion_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public."PackagePromotion"
|
||||
ADD CONSTRAINT "PackagePromotion_pkey" PRIMARY KEY (package_promotion_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: PollMessage PollMessage_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@@ -1766,6 +1790,13 @@ CREATE INDEX idxl49vydnq0h5j1piefwjy4i8er ON public."Host" USING btree (current_
|
||||
CREATE INDEX idxl8vobbecsd32k4ksavdfx8st6 ON public."BillingCancellation" USING btree (domain_repo_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idxlg6a5tp70nch9cp0gc11brc5o; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idxlg6a5tp70nch9cp0gc11brc5o ON public."PackagePromotion" USING btree (token);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idxlrq7v63pc21uoh3auq6eybyhl; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
Reference in New Issue
Block a user