mirror of
https://github.com/google/nomulus
synced 2026-09-06 08:07:03 +00:00
Add SQL schema for GracePeriodHistory (#746)
* Add schema for GracePeriodHistory Rebase on HEAD Rebase on HEAD Rebase on HEAD and rename column Use OfyService to generate id Refactor GracePeriodsSubject Rebase on HEAD Remove GracePeriodSubject and GracePeriodsSubject Rebase on HEAD Rebase on HEAD Rebase on HEAD Add gracePeriodHistoryRevisionId and remove some foreign key * Rebase on HEAD
This commit is contained in:
@@ -24,6 +24,7 @@ import com.googlecode.objectify.annotation.EntitySubclass;
|
||||
import com.googlecode.objectify.annotation.Ignore;
|
||||
import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.domain.DomainHistory.DomainHistoryId;
|
||||
import google.registry.model.domain.GracePeriod.GracePeriodHistory;
|
||||
import google.registry.model.domain.secdns.DomainDsDataHistory;
|
||||
import google.registry.model.host.HostResource;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
@@ -118,6 +119,24 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
|
||||
})
|
||||
Set<DomainDsDataHistory> dsDataHistories;
|
||||
|
||||
@OneToMany(
|
||||
cascade = {CascadeType.ALL},
|
||||
fetch = FetchType.EAGER,
|
||||
orphanRemoval = true)
|
||||
@JoinColumns({
|
||||
@JoinColumn(
|
||||
name = "domainHistoryRevisionId",
|
||||
referencedColumnName = "historyRevisionId",
|
||||
insertable = false,
|
||||
updatable = false),
|
||||
@JoinColumn(
|
||||
name = "domainRepoId",
|
||||
referencedColumnName = "domainRepoId",
|
||||
insertable = false,
|
||||
updatable = false)
|
||||
})
|
||||
Set<GracePeriodHistory> gracePeriodHistories;
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@Access(AccessType.PROPERTY)
|
||||
@@ -205,6 +224,10 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
|
||||
return VKey.create(DomainBase.class, getDomainRepoId());
|
||||
}
|
||||
|
||||
public Set<GracePeriodHistory> getGracePeriodHistories() {
|
||||
return nullToEmptyImmutableCopy(gracePeriodHistories);
|
||||
}
|
||||
|
||||
/** Creates a {@link VKey} instance for this entity. */
|
||||
public VKey<DomainHistory> createVKey() {
|
||||
return VKey.create(
|
||||
@@ -327,6 +350,10 @@ public class DomainHistory extends HistoryEntry implements SqlEntity {
|
||||
nullToEmptyImmutableCopy(instance.domainContent.getDsData()).stream()
|
||||
.map(dsData -> DomainDsDataHistory.createFrom(instance.id, dsData))
|
||||
.collect(toImmutableSet());
|
||||
instance.gracePeriodHistories =
|
||||
nullToEmptyImmutableCopy(instance.domainContent.getGracePeriods()).stream()
|
||||
.map(gracePeriod -> GracePeriodHistory.createFrom(instance.id, gracePeriod))
|
||||
.collect(toImmutableSet());
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@ package google.registry.model.domain;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.googlecode.objectify.annotation.Embed;
|
||||
import com.googlecode.objectify.annotation.OnLoad;
|
||||
import google.registry.model.billing.BillingEvent;
|
||||
import google.registry.model.billing.BillingEvent.Recurring;
|
||||
import google.registry.model.domain.rgp.GracePeriodStatus;
|
||||
@@ -25,7 +27,10 @@ import google.registry.model.ofy.ObjectifyService;
|
||||
import google.registry.persistence.VKey;
|
||||
import google.registry.schema.replay.DatastoreAndSqlEntity;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
import org.joda.time.DateTime;
|
||||
@@ -41,20 +46,36 @@ import org.joda.time.DateTime;
|
||||
@Table(indexes = @Index(columnList = "domainRepoId"))
|
||||
public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntity {
|
||||
|
||||
@Id
|
||||
@Access(AccessType.PROPERTY)
|
||||
@Override
|
||||
public long getGracePeriodId() {
|
||||
return super.getGracePeriodId();
|
||||
}
|
||||
|
||||
// TODO(b/169873747): Remove this method after explicitly re-saving all domain entities.
|
||||
@OnLoad
|
||||
void onLoad() {
|
||||
if (gracePeriodId == null) {
|
||||
gracePeriodId = ObjectifyService.allocateId();
|
||||
}
|
||||
}
|
||||
|
||||
private static GracePeriod createInternal(
|
||||
GracePeriodStatus type,
|
||||
String domainRepoId,
|
||||
DateTime expirationTime,
|
||||
String clientId,
|
||||
@Nullable VKey<BillingEvent.OneTime> billingEventOneTime,
|
||||
@Nullable VKey<BillingEvent.Recurring> billingEventRecurring) {
|
||||
@Nullable VKey<BillingEvent.Recurring> billingEventRecurring,
|
||||
@Nullable Long gracePeriodId) {
|
||||
checkArgument((billingEventOneTime == null) || (billingEventRecurring == null),
|
||||
"A grace period can have at most one billing event");
|
||||
checkArgument(
|
||||
(billingEventRecurring != null) == GracePeriodStatus.AUTO_RENEW.equals(type),
|
||||
"Recurring billing events must be present on (and only on) autorenew grace periods");
|
||||
GracePeriod instance = new GracePeriod();
|
||||
instance.id = ObjectifyService.allocateId();
|
||||
instance.gracePeriodId = gracePeriodId == null ? ObjectifyService.allocateId() : gracePeriodId;
|
||||
instance.type = checkArgumentNotNull(type);
|
||||
instance.domainRepoId = checkArgumentNotNull(domainRepoId);
|
||||
instance.expirationTime = checkArgumentNotNull(expirationTime);
|
||||
@@ -79,7 +100,28 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
|
||||
DateTime expirationTime,
|
||||
String clientId,
|
||||
@Nullable VKey<BillingEvent.OneTime> billingEventOneTime) {
|
||||
return createInternal(type, domainRepoId, expirationTime, clientId, billingEventOneTime, null);
|
||||
return createInternal(
|
||||
type, domainRepoId, expirationTime, clientId, billingEventOneTime, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a GracePeriod for an (optional) OneTime billing event and a given {@link
|
||||
* #gracePeriodId}.
|
||||
*
|
||||
* <p>Normal callers should always use {@link #forBillingEvent} instead, assuming they do not need
|
||||
* to avoid loading the BillingEvent from Datastore. This method should typically be called only
|
||||
* from test code to explicitly construct GracePeriods.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static GracePeriod create(
|
||||
GracePeriodStatus type,
|
||||
String domainRepoId,
|
||||
DateTime expirationTime,
|
||||
String clientId,
|
||||
@Nullable VKey<BillingEvent.OneTime> billingEventOneTime,
|
||||
@Nullable Long gracePeriodId) {
|
||||
return createInternal(
|
||||
type, domainRepoId, expirationTime, clientId, billingEventOneTime, null, gracePeriodId);
|
||||
}
|
||||
|
||||
/** Creates a GracePeriod for a Recurring billing event. */
|
||||
@@ -91,13 +133,27 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
|
||||
VKey<Recurring> billingEventRecurring) {
|
||||
checkArgumentNotNull(billingEventRecurring, "billingEventRecurring cannot be null");
|
||||
return createInternal(
|
||||
type, domainRepoId, expirationTime, clientId, null, billingEventRecurring);
|
||||
type, domainRepoId, expirationTime, clientId, null, billingEventRecurring, null);
|
||||
}
|
||||
|
||||
/** Creates a GracePeriod for a Recurring billing event and a given {@link #gracePeriodId}. */
|
||||
@VisibleForTesting
|
||||
public static GracePeriod createForRecurring(
|
||||
GracePeriodStatus type,
|
||||
String domainRepoId,
|
||||
DateTime expirationTime,
|
||||
String clientId,
|
||||
VKey<Recurring> billingEventRecurring,
|
||||
@Nullable Long gracePeriodId) {
|
||||
checkArgumentNotNull(billingEventRecurring, "billingEventRecurring cannot be null");
|
||||
return createInternal(
|
||||
type, domainRepoId, expirationTime, clientId, null, billingEventRecurring, gracePeriodId);
|
||||
}
|
||||
|
||||
/** Creates a GracePeriod with no billing event. */
|
||||
public static GracePeriod createWithoutBillingEvent(
|
||||
GracePeriodStatus type, String domainRepoId, DateTime expirationTime, String clientId) {
|
||||
return createInternal(type, domainRepoId, expirationTime, clientId, null, null);
|
||||
return createInternal(type, domainRepoId, expirationTime, clientId, null, null, null);
|
||||
}
|
||||
|
||||
/** Constructs a GracePeriod of the given type from the provided one-time BillingEvent. */
|
||||
@@ -119,7 +175,6 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
|
||||
*/
|
||||
public GracePeriod cloneAfterOfyLoad(String domainRepoId) {
|
||||
GracePeriod clone = clone(this);
|
||||
clone.id = ObjectifyService.allocateId();
|
||||
clone.domainRepoId = checkArgumentNotNull(domainRepoId);
|
||||
clone.restoreHistoryIds();
|
||||
return clone;
|
||||
@@ -136,4 +191,49 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit
|
||||
clone.billingEventRecurring = recurring;
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@link GracePeriod} with prepopulated {@link #gracePeriodId} generated
|
||||
* by {@link ObjectifyService#allocateId()}.
|
||||
*
|
||||
* <p>TODO(shicong): Figure out how to generate the id only when the entity is used for Cloud SQL.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public GracePeriod cloneWithPrepopulatedId() {
|
||||
GracePeriod clone = clone(this);
|
||||
clone.gracePeriodId = ObjectifyService.allocateId();
|
||||
return clone;
|
||||
}
|
||||
|
||||
/** Entity class to represent a historic {@link GracePeriod}. */
|
||||
@Entity(name = "GracePeriodHistory")
|
||||
@Table(indexes = @Index(columnList = "domainRepoId"))
|
||||
static class GracePeriodHistory extends GracePeriodBase {
|
||||
@Id Long gracePeriodHistoryRevisionId;
|
||||
|
||||
/** ID for the associated {@link DomainHistory} entity. */
|
||||
Long domainHistoryRevisionId;
|
||||
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
public long getGracePeriodId() {
|
||||
return super.getGracePeriodId();
|
||||
}
|
||||
|
||||
static GracePeriodHistory createFrom(long historyRevisionId, GracePeriod gracePeriod) {
|
||||
GracePeriodHistory instance = new GracePeriodHistory();
|
||||
instance.gracePeriodHistoryRevisionId = ObjectifyService.allocateId();
|
||||
instance.domainHistoryRevisionId = historyRevisionId;
|
||||
instance.gracePeriodId = gracePeriod.gracePeriodId;
|
||||
instance.type = gracePeriod.type;
|
||||
instance.domainRepoId = gracePeriod.domainRepoId;
|
||||
instance.expirationTime = gracePeriod.expirationTime;
|
||||
instance.clientId = gracePeriod.clientId;
|
||||
instance.billingEventOneTime = gracePeriod.billingEventOneTime;
|
||||
instance.billingEventOneTimeHistoryId = gracePeriod.billingEventOneTimeHistoryId;
|
||||
instance.billingEventRecurring = gracePeriod.billingEventRecurring;
|
||||
instance.billingEventRecurringHistoryId = gracePeriod.billingEventRecurringHistoryId;
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,21 +26,23 @@ import google.registry.persistence.VKey;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.Transient;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/** Base class containing common fields and methods for {@link GracePeriod}. */
|
||||
@Embed
|
||||
@MappedSuperclass
|
||||
@Access(AccessType.FIELD)
|
||||
public class GracePeriodBase extends ImmutableObject {
|
||||
|
||||
/** Unique id required for hibernate representation. */
|
||||
@javax.persistence.Id
|
||||
@Ignore
|
||||
Long id;
|
||||
@Transient Long gracePeriodId;
|
||||
|
||||
/** Repository id for the domain which this grace period belongs to. */
|
||||
@Ignore
|
||||
@@ -85,8 +87,8 @@ public class GracePeriodBase extends ImmutableObject {
|
||||
@Column(name = "billing_recurrence_history_id")
|
||||
Long billingEventRecurringHistoryId;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
public long getGracePeriodId() {
|
||||
return gracePeriodId;
|
||||
}
|
||||
|
||||
public GracePeriodStatus getType() {
|
||||
@@ -105,6 +107,12 @@ public class GracePeriodBase extends ImmutableObject {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/** This method is private because it is only used by Hibernate. */
|
||||
@SuppressWarnings("unused")
|
||||
private void setGracePeriodId(long gracePeriodId) {
|
||||
this.gracePeriodId = gracePeriodId;
|
||||
}
|
||||
|
||||
/** Returns true if this GracePeriod has an associated BillingEvent; i.e. if it's refundable. */
|
||||
public boolean hasBillingEvent() {
|
||||
return billingEventOneTime != null || billingEventRecurring != null;
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
<class>google.registry.model.domain.DomainBase</class>
|
||||
<class>google.registry.model.domain.DomainHistory</class>
|
||||
<class>google.registry.model.domain.GracePeriod</class>
|
||||
<class>google.registry.model.domain.GracePeriod$GracePeriodHistory</class>
|
||||
<class>google.registry.model.domain.secdns.DelegationSignerData</class>
|
||||
<class>google.registry.model.domain.secdns.DomainDsDataHistory</class>
|
||||
<class>google.registry.model.domain.token.AllocationToken</class>
|
||||
|
||||
Reference in New Issue
Block a user