diff --git a/core/src/main/java/google/registry/model/ImmutableObject.java b/core/src/main/java/google/registry/model/ImmutableObject.java index b17af27ea..31407dec7 100644 --- a/core/src/main/java/google/registry/model/ImmutableObject.java +++ b/core/src/main/java/google/registry/model/ImmutableObject.java @@ -61,7 +61,17 @@ public abstract class ImmutableObject implements Cloneable { private boolean equalsImmutableObject(ImmutableObject other) { return getClass().equals(other.getClass()) && hashCode() == other.hashCode() - && ModelUtils.getFieldValues(this).equals(ModelUtils.getFieldValues(other)); + && getSignificantFields().equals(other.getSignificantFields()); + } + + /** + * Returns the map of significant fields (fields that we care about for purposes of comparison and + * display). + * + *

Isolated into a method so that derived classes can override it. + */ + protected Map getSignificantFields() { + return ModelUtils.getFieldValues(this); } @Override @@ -72,7 +82,7 @@ public abstract class ImmutableObject implements Cloneable { @Override public int hashCode() { if (hashCode == null) { - hashCode = Arrays.hashCode(ModelUtils.getFieldValues(this).values().toArray()); + hashCode = Arrays.hashCode(getSignificantFields().values().toArray()); } return hashCode; } @@ -111,7 +121,7 @@ public abstract class ImmutableObject implements Cloneable { @Override public String toString() { NavigableMap sortedFields = new TreeMap<>(); - for (Entry entry : ModelUtils.getFieldValues(this).entrySet()) { + for (Entry entry : getSignificantFields().entrySet()) { sortedFields.put(entry.getKey().getName(), entry.getValue()); } return toStringHelper(sortedFields); @@ -121,7 +131,7 @@ public abstract class ImmutableObject implements Cloneable { public String toHydratedString() { // We can't use ImmutableSortedMap because we need to allow null values. NavigableMap sortedFields = new TreeMap<>(); - for (Entry entry : ModelUtils.getFieldValues(this).entrySet()) { + for (Entry entry : getSignificantFields().entrySet()) { Field field = entry.getKey(); Object value = entry.getValue(); sortedFields.put( @@ -161,7 +171,7 @@ public abstract class ImmutableObject implements Cloneable { // LinkedHashMap to preserve field ordering and because ImmutableMap forbids null // values. Map result = new LinkedHashMap<>(); - for (Entry entry : ModelUtils.getFieldValues(o).entrySet()) { + for (Entry entry : ((ImmutableObject) o).getSignificantFields().entrySet()) { Field field = entry.getKey(); if (!field.isAnnotationPresent(IgnoredInDiffableMap.class)) { result.put(field.getName(), toMapRecursive(entry.getValue())); diff --git a/core/src/main/java/google/registry/model/ModelUtils.java b/core/src/main/java/google/registry/model/ModelUtils.java index a69ceb577..14e62c0dc 100644 --- a/core/src/main/java/google/registry/model/ModelUtils.java +++ b/core/src/main/java/google/registry/model/ModelUtils.java @@ -194,7 +194,7 @@ public class ModelUtils { * returned map in its implementation of {@link ImmutableObject#toString} and {@link * ImmutableObject#equals}, which work by comparing and printing these maps. */ - static Map getFieldValues(Object instance) { + public static Map getFieldValues(Object instance) { // Don't make this ImmutableMap because field values can be null. Map values = new LinkedHashMap<>(); for (Field field : getAllFields(instance.getClass()).values()) { diff --git a/core/src/main/java/google/registry/model/domain/DomainContent.java b/core/src/main/java/google/registry/model/domain/DomainContent.java index db381600a..6fbb2d626 100644 --- a/core/src/main/java/google/registry/model/domain/DomainContent.java +++ b/core/src/main/java/google/registry/model/domain/DomainContent.java @@ -303,14 +303,13 @@ public class DomainContent extends EppResource allContacts.stream().map(DesignatedContact::reconstitute).collect(toImmutableSet()); setContactFields(allContacts, true); - // We have to return the cloned object here because the original object's - // hashcode is not correct due to the change to its domainRepoId. The cloned - // object will have a null hashcode so that it can get a recalculated hashcode - // when its hashCode() is invoked. + // We have to return the cloned object here because the original object's hashcode is not + // correct due to the change to its domainRepoId and history ids. The cloned object will have a + // null hashcode so that it can get a recalculated hashcode when its hashCode() is invoked. // TODO(b/162739503): Remove this after fully migrating to Cloud SQL. gracePeriods = nullToEmptyImmutableCopy(gracePeriods).stream() - .map(gracePeriod -> gracePeriod.cloneWithDomainRepoId(getRepoId())) + .map(gracePeriod -> gracePeriod.cloneAfterOfyLoad(getRepoId())) .collect(toImmutableSet()); // Restore history record ids. diff --git a/core/src/main/java/google/registry/model/domain/GracePeriod.java b/core/src/main/java/google/registry/model/domain/GracePeriod.java index 9070aa157..dcc52e641 100644 --- a/core/src/main/java/google/registry/model/domain/GracePeriod.java +++ b/core/src/main/java/google/registry/model/domain/GracePeriod.java @@ -21,6 +21,7 @@ import com.googlecode.objectify.annotation.Embed; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Recurring; import google.registry.model.domain.rgp.GracePeriodStatus; +import google.registry.model.ofy.ObjectifyService; import google.registry.persistence.VKey; import google.registry.schema.replay.DatastoreAndSqlEntity; import javax.annotation.Nullable; @@ -53,12 +54,15 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit (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.type = checkArgumentNotNull(type); instance.domainRepoId = checkArgumentNotNull(domainRepoId); instance.expirationTime = checkArgumentNotNull(expirationTime); instance.clientId = checkArgumentNotNull(clientId); instance.billingEventOneTime = billingEventOneTime; + instance.billingEventOneTimeHistoryId = DomainBase.getHistoryId(billingEventOneTime); instance.billingEventRecurring = billingEventRecurring; + instance.billingEventRecurringHistoryId = DomainBase.getHistoryId(billingEventRecurring); return instance; } @@ -108,14 +112,16 @@ public class GracePeriod extends GracePeriodBase implements DatastoreAndSqlEntit } /** - * Returns a clone of this {@link GracePeriod} with {@link #domainRepoId} set to the given value. + * Returns a clone of this {@link GracePeriod} with {@link #domainRepoId} set to the given value + * and reconstructed history ids. * *

TODO(b/162739503): Remove this function after fully migrating to Cloud SQL. */ - public GracePeriod cloneWithDomainRepoId(String domainRepoId) { + public GracePeriod cloneAfterOfyLoad(String domainRepoId) { GracePeriod clone = clone(this); + clone.id = ObjectifyService.allocateId(); clone.domainRepoId = checkArgumentNotNull(domainRepoId); + clone.restoreHistoryIds(); return clone; } - } diff --git a/core/src/main/java/google/registry/model/domain/GracePeriodBase.java b/core/src/main/java/google/registry/model/domain/GracePeriodBase.java index cca2db53b..64f1ede7f 100644 --- a/core/src/main/java/google/registry/model/domain/GracePeriodBase.java +++ b/core/src/main/java/google/registry/model/domain/GracePeriodBase.java @@ -14,18 +14,21 @@ package google.registry.model.domain; +import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Embed; import com.googlecode.objectify.annotation.Ignore; import google.registry.model.ImmutableObject; +import google.registry.model.ModelUtils; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.OneTime; import google.registry.model.domain.rgp.GracePeriodStatus; import google.registry.persistence.VKey; +import java.lang.reflect.Field; +import java.util.LinkedHashMap; +import java.util.Map; import javax.persistence.Column; import javax.persistence.EnumType; import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; import javax.persistence.MappedSuperclass; import org.joda.time.DateTime; @@ -36,7 +39,6 @@ public class GracePeriodBase extends ImmutableObject { /** Unique id required for hibernate representation. */ @javax.persistence.Id - @GeneratedValue(strategy = GenerationType.IDENTITY) @Ignore Long id; @@ -67,6 +69,10 @@ public class GracePeriodBase extends ImmutableObject { @Column(name = "billing_event_id") VKey billingEventOneTime = null; + @Ignore + @Column(name = "billing_event_history_id") + Long billingEventOneTimeHistoryId; + /** * The recurring billing event corresponding to the action that triggered this grace period, if * applicable - i.e. if the action was an autorenew - or null in all other cases. @@ -75,6 +81,14 @@ public class GracePeriodBase extends ImmutableObject { @Column(name = "billing_recurrence_id") VKey billingEventRecurring = null; + @Ignore + @Column(name = "billing_recurrence_history_id") + Long billingEventRecurringHistoryId; + + public long getId() { + return id; + } + public GracePeriodStatus getType() { return type; } @@ -101,6 +115,7 @@ public class GracePeriodBase extends ImmutableObject { * period is not AUTO_RENEW. */ public VKey getOneTimeBillingEvent() { + restoreOfyKeys(); return billingEventOneTime; } @@ -109,6 +124,63 @@ public class GracePeriodBase extends ImmutableObject { * period is AUTO_RENEW. */ public VKey getRecurringBillingEvent() { + restoreOfyKeys(); return billingEventRecurring; } + + /** + * Restores history ids for composite VKeys after a load from datastore. + * + *

For use by DomainContent.load() ONLY. + */ + protected void restoreHistoryIds() { + billingEventOneTimeHistoryId = DomainBase.getHistoryId(billingEventOneTime); + billingEventRecurringHistoryId = DomainBase.getHistoryId(billingEventRecurring); + } + + /** + * Override {@link ImmutableObject#getSignificantFields()} to exclude "id", which breaks equality + * testing in the unit tests. + */ + @Override + protected Map getSignificantFields() { + restoreOfyKeys(); + // Can't use streams or ImmutableMap because we can have null values. + Map result = new LinkedHashMap(); + for (Map.Entry entry : ModelUtils.getFieldValues(this).entrySet()) { + if (!entry.getKey().getName().equals("id")) { + result.put(entry.getKey(), entry.getValue()); + } + } + return result; + } + + /** + * Restores Ofy keys in the billing events. + * + *

This must be called by all methods that access the one time or recurring billing event keys. + * When the billing event keys are loaded from SQL, they are loaded as asymmetric keys because the + * database columns that we load them from do not contain all of the information necessary to + * reconsitute the Ofy side of the key. In other cases, we restore the Ofy key during the + * hibernate {@link javax.persistence.PostLoad} method from the other fields of the object, but we + * have been unable to make this work with hibernate's internal persistence model in this case + * because the {@link GracePeriod}'s hash code is evaluated prior to these calls, and would be + * invalidated by changing the fields. + */ + private final synchronized void restoreOfyKeys() { + if (billingEventOneTime != null && !billingEventOneTime.maybeGetOfyKey().isPresent()) { + billingEventOneTime = + DomainBase.restoreOfyFrom( + Key.create(DomainBase.class, domainRepoId), + billingEventOneTime, + billingEventOneTimeHistoryId); + } + if (billingEventRecurring != null && !billingEventRecurring.maybeGetOfyKey().isPresent()) { + billingEventRecurring = + DomainBase.restoreOfyFrom( + Key.create(DomainBase.class, domainRepoId), + billingEventRecurring, + billingEventRecurringHistoryId); + } + } } diff --git a/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java b/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java index 5641cdfdf..756833072 100644 --- a/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java +++ b/core/src/test/java/google/registry/flows/EppLifecycleDomainTest.java @@ -805,30 +805,35 @@ class EppLifecycleDomainTest extends EppTestCase { // As the losing registrar, read the request poll message, and then ack it. assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); + String messageId = "1-C-EXAMPLE-20-26-2001"; assertThatCommand("poll.xml") .atTime("2001-01-01T00:01:00Z") - .hasResponse("poll_response_domain_transfer_request.xml"); - assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-C-EXAMPLE-17-23-2001")) + .hasResponse("poll_response_domain_transfer_request.xml", ImmutableMap.of("ID", messageId)); + assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", messageId)) .atTime("2001-01-01T00:01:00Z") .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-C-EXAMPLE-20-25-2001"; assertThatCommand("poll.xml") .atTime("2001-01-06T00:01:00Z") - .hasResponse("poll_response_domain_transfer_server_approve_loser.xml"); - assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-C-EXAMPLE-17-22-2001")) + .hasResponse( + "poll_response_domain_transfer_server_approve_loser.xml", + ImmutableMap.of("ID", messageId)); + assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", messageId)) .atTime("2001-01-06T00:01:00Z") .hasResponse("poll_ack_response_empty.xml"); assertThatLogoutSucceeds(); // Also expect a server approval poll message to the winner, with the transfer request trid. + messageId = "1-C-EXAMPLE-20-24-2001"; assertThatLoginSucceeds("TheRegistrar", "password2"); assertThatCommand("poll.xml") .atTime("2001-01-06T00:02:00Z") .hasResponse( "poll_response_domain_transfer_server_approve_winner.xml", - ImmutableMap.of("SERVER_TRID", transferRequestTrid)); - assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-C-EXAMPLE-17-21-2001")) + ImmutableMap.of("SERVER_TRID", transferRequestTrid, "ID", messageId)); + assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", messageId)) .atTime("2001-01-06T00:02:00Z") .hasResponse("poll_ack_response_empty.xml"); assertThatLogoutSucceeds(); diff --git a/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java b/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java index 2eaa3248c..0ed048390 100644 --- a/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java +++ b/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java @@ -78,6 +78,7 @@ public class DomainBaseSqlTest { private HostResource host; private ContactResource contact; private ContactResource contact2; + private ImmutableSet gracePeriods; @BeforeEach void setUp() { @@ -506,6 +507,20 @@ public class DomainBaseSqlTest { .setServerApproveAutorenewEvent(billEvent.createVKey()) .setServerApproveAutorenewPollMessage(autorenewPollMessage.createVKey()) .build(); + 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())); jpaTm().insert(contact); jpaTm().insert(contact2); @@ -517,6 +532,7 @@ public class DomainBaseSqlTest { .setAutorenewPollMessage(autorenewPollMessage.createVKey()) .setDeletePollMessage(deletePollMessage.createVKey()) .setTransferData(transferData) + .setGracePeriods(gracePeriods) .build(); historyEntry = historyEntry.asBuilder().setDomainContent(domain).build(); jpaTm().insert(historyEntry); @@ -553,6 +569,7 @@ public class DomainBaseSqlTest { .isEqualTo(originalTransferData.getServerApproveAutorenewEvent()); assertThat(persistedTransferData.getServerApproveAutorenewPollMessage()) .isEqualTo(originalTransferData.getServerApproveAutorenewPollMessage()); + assertThat(persisted.getGracePeriods()).isEqualTo(gracePeriods); } @Test @@ -624,6 +641,21 @@ public class DomainBaseSqlTest { createLegacyVKey( PollMessage.Autorenew.class, autorenewPollMessage.getId())) .build(); + gracePeriods = + ImmutableSet.of( + GracePeriod.create( + GracePeriodStatus.ADD, + "4-COM", + END_OF_TIME, + "registrar1", + createLegacyVKey( + BillingEvent.OneTime.class, oneTimeBillingEvent.getId())), + GracePeriod.createForRecurring( + GracePeriodStatus.AUTO_RENEW, + "4-COM", + END_OF_TIME, + "registrar1", + createLegacyVKey(BillingEvent.Recurring.class, billEvent.getId()))); jpaTm().insert(contact); jpaTm().insert(contact2); @@ -639,6 +671,7 @@ public class DomainBaseSqlTest { .setDeletePollMessage( createLegacyVKey(PollMessage.OneTime.class, deletePollMessage.getId())) .setTransferData(transferData) + .setGracePeriods(gracePeriods) .build(); historyEntry = historyEntry.asBuilder().setDomainContent(domain).build(); jpaTm().insert(historyEntry); @@ -675,6 +708,7 @@ public class DomainBaseSqlTest { .isEqualTo(originalTransferData.getServerApproveAutorenewEvent()); assertThat(persistedTransferData.getServerApproveAutorenewPollMessage()) .isEqualTo(originalTransferData.getServerApproveAutorenewPollMessage()); + assertThat(domain.getGracePeriods()).isEqualTo(gracePeriods); } private VKey createLegacyVKey(Class clazz, long id) { diff --git a/core/src/test/java/google/registry/model/domain/DomainBaseTest.java b/core/src/test/java/google/registry/model/domain/DomainBaseTest.java index 03b473218..f93b720fc 100644 --- a/core/src/test/java/google/registry/model/domain/DomainBaseTest.java +++ b/core/src/test/java/google/registry/model/domain/DomainBaseTest.java @@ -38,6 +38,7 @@ import com.google.common.collect.Ordering; import com.google.common.collect.Streams; import com.googlecode.objectify.Key; import google.registry.model.EntityTestCase; +import google.registry.model.ImmutableObject; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Reason; import google.registry.model.contact.ContactResource; @@ -830,4 +831,63 @@ public class DomainBaseTest extends EntityTestCase { assertThat(getOnlyElement(clone.getGracePeriods()).getType()) .isEqualTo(GracePeriodStatus.TRANSFER); } + + @Test + void testHistoryIdRestoration() { + // Verify that history ids for billing events are restored during load from datastore. History + // ids are not used by business code or persisted in datastore, but only to reconstruct + // objectify keys when loading from SQL. + DateTime now = fakeClock.nowUtc(); + domain = + persistResource( + domain + .asBuilder() + .setRegistrationExpirationTime(now.plusYears(1)) + .setGracePeriods( + ImmutableSet.of( + GracePeriod.createForRecurring( + GracePeriodStatus.AUTO_RENEW, + domain.getRepoId(), + now.plusDays(1), + "NewRegistrar", + recurringBillKey), + GracePeriod.create( + GracePeriodStatus.RENEW, + domain.getRepoId(), + now.plusDays(1), + "NewRegistrar", + oneTimeBillKey))) + .build()); + ImmutableSet historyIds = + domain.getGracePeriods().stream() + .map( + gp -> + new BillEventInfo( + gp.getRecurringBillingEvent(), gp.billingEventRecurringHistoryId, + gp.getOneTimeBillingEvent(), gp.billingEventOneTimeHistoryId)) + .collect(toImmutableSet()); + assertThat(historyIds) + .isEqualTo( + ImmutableSet.of( + new BillEventInfo(null, null, oneTimeBillKey, historyEntryKey.getId()), + new BillEventInfo(recurringBillKey, historyEntryKey.getId(), null, null))); + } + + static class BillEventInfo extends ImmutableObject { + VKey billingEventRecurring; + Long billingEventRecurringHistoryId; + VKey billingEventOneTime; + Long billingEventOneTimeHistoryId; + + BillEventInfo( + VKey billingEventRecurring, + Long billingEventRecurringHistoryId, + VKey billingEventOneTime, + Long billingEventOneTimeHistoryId) { + this.billingEventRecurring = billingEventRecurring; + this.billingEventRecurringHistoryId = billingEventRecurringHistoryId; + this.billingEventOneTime = billingEventOneTime; + this.billingEventOneTimeHistoryId = billingEventOneTimeHistoryId; + } + } } diff --git a/core/src/test/java/google/registry/model/domain/GracePeriodTest.java b/core/src/test/java/google/registry/model/domain/GracePeriodTest.java index 3ae94f976..13dffc2be 100644 --- a/core/src/test/java/google/registry/model/domain/GracePeriodTest.java +++ b/core/src/test/java/google/registry/model/domain/GracePeriodTest.java @@ -44,6 +44,7 @@ public class GracePeriodTest { private final DateTime now = DateTime.now(UTC); private BillingEvent.OneTime onetime; + private VKey recurringKey; @BeforeEach void before() { @@ -59,6 +60,14 @@ public class GracePeriodTest { .setPeriodYears(1) .setTargetId("foo.google") .build(); + recurringKey = + VKey.create( + Recurring.class, + 12345, + Key.create( + Key.create(Key.create(DomainBase.class, "1-TEST"), HistoryEntry.class, 343L), + Recurring.class, + 12345)); } @Test @@ -71,6 +80,24 @@ public class GracePeriodTest { assertThat(gracePeriod.getClientId()).isEqualTo("TheRegistrar"); assertThat(gracePeriod.getExpirationTime()).isEqualTo(now.plusDays(1)); assertThat(gracePeriod.hasBillingEvent()).isTrue(); + assertThat(gracePeriod.billingEventOneTimeHistoryId).isEqualTo(12345L); + assertThat(gracePeriod.billingEventRecurringHistoryId).isNull(); + } + + @Test + void testSuccess_forRecurringEvent() { + GracePeriod gracePeriod = + GracePeriod.createForRecurring( + GracePeriodStatus.AUTO_RENEW, "1-TEST", now.plusDays(1), "TheRegistrar", recurringKey); + assertThat(gracePeriod.getType()).isEqualTo(GracePeriodStatus.AUTO_RENEW); + assertThat(gracePeriod.getDomainRepoId()).isEqualTo("1-TEST"); + assertThat(gracePeriod.getOneTimeBillingEvent()).isNull(); + assertThat(gracePeriod.getRecurringBillingEvent()).isEqualTo(recurringKey); + assertThat(gracePeriod.getClientId()).isEqualTo("TheRegistrar"); + assertThat(gracePeriod.getExpirationTime()).isEqualTo(now.plusDays(1)); + assertThat(gracePeriod.hasBillingEvent()).isTrue(); + assertThat(gracePeriod.billingEventOneTimeHistoryId).isNull(); + assertThat(gracePeriod.billingEventRecurringHistoryId).isEqualTo(343L); } @Test @@ -98,11 +125,6 @@ public class GracePeriodTest { @Test void testFailure_createForRecurring_notAutoRenew() { - Key recurringKey = - Key.create( - Key.create(Key.create(DomainBase.class, "1-TEST"), HistoryEntry.class, 343L), - Recurring.class, - 12345); IllegalArgumentException thrown = assertThrows( IllegalArgumentException.class, @@ -112,7 +134,7 @@ public class GracePeriodTest { "1-TEST", now.plusDays(1), "TheRegistrar", - VKey.create(Recurring.class, 12345, recurringKey))); + recurringKey)); assertThat(thrown).hasMessageThat().contains("autorenew"); } } diff --git a/core/src/test/java/google/registry/tools/EppLifecycleToolsTest.java b/core/src/test/java/google/registry/tools/EppLifecycleToolsTest.java index 3fa7b0cb4..ddfc50d2d 100644 --- a/core/src/test/java/google/registry/tools/EppLifecycleToolsTest.java +++ b/core/src/test/java/google/registry/tools/EppLifecycleToolsTest.java @@ -108,7 +108,7 @@ class EppLifecycleToolsTest extends EppTestCase { .atTime("2001-06-08T00:00:00Z") .hasResponse("poll_response_unrenew.xml"); - assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-8-TLD-17-18-2001")) + assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-8-TLD-23-24-2001")) .atTime("2001-06-08T00:00:01Z") .hasResponse("poll_ack_response_empty.xml"); @@ -129,7 +129,7 @@ class EppLifecycleToolsTest extends EppTestCase { .hasResponse( "poll_response_autorenew.xml", ImmutableMap.of( - "ID", "1-8-TLD-17-20-2003", + "ID", "1-8-TLD-23-26-2003", "QDATE", "2003-06-01T00:02:00Z", "DOMAIN", "example.tld", "EXDATE", "2004-06-01T00:02:00Z")); diff --git a/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_request.xml b/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_request.xml index 0f19e13b6..35ae1cf8c 100644 --- a/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_request.xml +++ b/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_request.xml @@ -3,7 +3,7 @@ Command completed successfully; ack to dequeue - + 2001-01-01T00:00:00Z Transfer requested. diff --git a/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_server_approve_loser.xml b/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_server_approve_loser.xml index a12a093f3..f85fbc526 100644 --- a/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_server_approve_loser.xml +++ b/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_server_approve_loser.xml @@ -3,7 +3,7 @@ Command completed successfully; ack to dequeue - + 2001-01-06T00:00:00Z Transfer approved. diff --git a/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_server_approve_winner.xml b/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_server_approve_winner.xml index bf4411bff..d9a089d88 100644 --- a/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_server_approve_winner.xml +++ b/core/src/test/resources/google/registry/flows/poll_response_domain_transfer_server_approve_winner.xml @@ -4,7 +4,7 @@ Command completed successfully; ack to dequeue - + 2001-01-06T00:00:00Z Transfer approved. diff --git a/core/src/test/resources/google/registry/flows/poll_response_unrenew.xml b/core/src/test/resources/google/registry/flows/poll_response_unrenew.xml index 704fcc389..112faf222 100644 --- a/core/src/test/resources/google/registry/flows/poll_response_unrenew.xml +++ b/core/src/test/resources/google/registry/flows/poll_response_unrenew.xml @@ -3,7 +3,7 @@ Command completed successfully; ack to dequeue - + 2001-06-07T00:00:00Z Domain example.tld was unrenewed by 3 years; now expires at 2003-06-01T00:02:00.000Z. diff --git a/db/src/main/resources/sql/er_diagram/brief_er_diagram.html b/db/src/main/resources/sql/er_diagram/brief_er_diagram.html index d26bf52e5..2e4b1fe7f 100644 --- a/db/src/main/resources/sql/er_diagram/brief_er_diagram.html +++ b/db/src/main/resources/sql/er_diagram/brief_er_diagram.html @@ -261,59 +261,59 @@ td.section { generated on - 2020-10-21 14:40:52.221127 + 2020-10-26 15:49:09.291097 last flyway file - V66__create_rde_revision.sql + V67__grace_period_history_ids.sql

 

 

- + SchemaCrawler_Diagram - - + + generated by - + SchemaCrawler 16.10.1 - + generated on - - 2020-10-21 14:40:52.221127 + + 2020-10-26 15:49:09.291097 - + allocationtoken_a08ccbef - - + + public.AllocationToken - - + + [table] - + token - + - + text not null - + domain_name - + - + text - + billingcancellation_6eedf614 @@ -1165,89 +1165,84 @@ td.section { graceperiod_cd3b2e8f - - + + public.GracePeriod - - + + [table] - + id - + - - bigserial not null + + int8 not null - - - - auto-incremented - - + billing_event_id - + - + int8 - + billing_recurrence_id - + - + int8 - + domain_repo_id - + - + text not null - + graceperiod_cd3b2e8f:w->domain_6c51cffa:e - - - - + + + + - - + + - fk2mys4hojm6ev2g9tmy5aq6m7g + fk_grace_period_domain_repo_id graceperiod_cd3b2e8f:w->billingevent_a57d1815:e - - - + + + - + fk_grace_period_billing_event_id graceperiod_cd3b2e8f:w->billingrecurrence_5fa2cb01:e - - - + + + - + fk_grace_period_billing_recurrence_id @@ -1266,67 +1261,67 @@ td.section { claimsentry_105da9f1 - - + + public.ClaimsEntry - - + + [table] - + revision_id - + - + int8 not null - + domain_label - + - + text not null - + claimslist_3d49bc2b - - + + public.ClaimsList - - + + [table] - + revision_id - - - - bigserial not null - + bigserial not null + + + + auto-incremented - + claimsentry_105da9f1:w->claimslist_3d49bc2b:e - - - - - - - - + + + + + + + + fk6sc6at5hedffc0nhdcab6ivuq @@ -1795,70 +1790,70 @@ td.section { cursor_6af40e8c - - + + public."Cursor" - - + + [table] - + "scope" - + - + text not null - + type - + - + text not null - + delegationsignerdata_e542a872 - - + + public.DelegationSignerData - - + + [table] - + domain_repo_id - + - + text not null - + key_tag - + - + int4 not null - + delegationsignerdata_e542a872:w->domain_6c51cffa:e - - - + + + - + fktr24j9v14ph2mfuw2gsmt12kq @@ -1890,50 +1885,50 @@ td.section { domainhost_1ea127c2 - - + + public.DomainHost - - + + [table] - + domain_repo_id - + - + text not null - + host_repo_id - + - + text - + domainhost_1ea127c2:w->domain_6c51cffa:e - - - - - - - - + + + + + + + + fkfmi7bdink53swivs390m2btxg domainhost_1ea127c2:w->host_f21b78de:e - - - + + + @@ -2104,415 +2099,415 @@ td.section { lock_f21d4861 - - + + public.Lock - - + + [table] - + resource_name - + - + text not null - + tld - + - + text not null - + premiumentry_b0060b91 - - + + public.PremiumEntry - - + + [table] - + revision_id - + - + int8 not null - + domain_label - + - + text not null - + premiumlist_7c3ea68b - - + + public.PremiumList - - + + [table] - + revision_id - - - - bigserial not null - - auto-incremented - - - name + bigserial not null + auto-incremented + + + name + + + + text not null - + premiumentry_b0060b91:w->premiumlist_7c3ea68b:e - - - - - - - - + + + + + + + + fko0gw90lpo1tuee56l0nb6y6g5 rderevision_83396864 - - + + public.RdeRevision - - + + [table] - + tld - + - + text not null - + mode - + - + text not null - + "date" - + - + date not null - + registrarpoc_ab47054d - - + + public.RegistrarPoc - - + + [table] - + email_address - + - + text not null - + gae_user_id - + - + text - + registrar_id - + - + text not null - + registrylock_ac88663e - - + + public.RegistryLock - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + registrar_id - + - + text not null - + repo_id - + - + text not null - + verification_code - + - + text not null - + relock_revision_id - + - + int8 - + registrylock_ac88663e:w->registrylock_ac88663e:e - - - - - - - - + + + + + + + + fk2lhcwpxlnqijr96irylrh1707 reservedentry_1a7b8520 - - + + public.ReservedEntry - - + + [table] - + revision_id - + - + int8 not null - + domain_label - + - + text not null - + reservedlist_b97c3f1c - - + + public.ReservedList - - + + [table] - + revision_id - - - - bigserial not null - - auto-incremented - - - name + bigserial not null + auto-incremented + + + name + + + + text not null - + reservedentry_1a7b8520:w->reservedlist_b97c3f1c:e - - - - - - - - + + + + + + + + fkgq03rk0bt1hb915dnyvd3vnfc spec11threatmatch_a61228a6 - - + + public.Spec11ThreatMatch - - + + [table] - + id - + - + bigserial not null - + - + auto-incremented - + check_date - + - + date not null - + registrar_id - + - + text not null - + tld - + - + text not null - + tld_f1fa57e2 - - + + public.Tld - - + + [table] - + tld_name - + - + text not null - + transaction_d50389d4 - - + + public.Transaction - - + + [table] - + id - + - + bigserial not null - + - + auto-incremented - + @@ -3713,7 +3708,7 @@ td.section { - fk2mys4hojm6ev2g9tmy5aq6m7g + fk_grace_period_domain_repo_id [foreign key, with no action] @@ -4135,12 +4130,7 @@ td.section { id - bigserial not null - - - - - auto-incremented + int8 not null @@ -4209,7 +4199,7 @@ td.section { - fk2mys4hojm6ev2g9tmy5aq6m7g + fk_grace_period_domain_repo_id [foreign key, with no action] diff --git a/db/src/main/resources/sql/er_diagram/full_er_diagram.html b/db/src/main/resources/sql/er_diagram/full_er_diagram.html index 29d12af1a..12a697db3 100644 --- a/db/src/main/resources/sql/er_diagram/full_er_diagram.html +++ b/db/src/main/resources/sql/er_diagram/full_er_diagram.html @@ -261,139 +261,139 @@ td.section { generated on - 2020-10-21 14:40:50.371645 + 2020-10-26 15:49:07.386754 last flyway file - V66__create_rde_revision.sql + V67__grace_period_history_ids.sql

 

 

- + SchemaCrawler_Diagram - - + + generated by - + SchemaCrawler 16.10.1 - + generated on - - 2020-10-21 14:40:50.371645 + + 2020-10-26 15:49:07.386754 - + allocationtoken_a08ccbef - - + + public.AllocationToken - - + + [table] - + token - + - + text not null - + update_timestamp - + - + timestamptz - + allowed_registrar_ids - + - + _text - + allowed_tlds - + - + _text - + creation_time - + - + timestamptz not null - + discount_fraction - + - + float8(17, 17) not null - + discount_premiums - + - + bool not null - + discount_years - + - + int4 not null - + domain_name - + - + text - + redemption_history_entry - + - + text - + token_status_transitions - + - + "hstore" - + token_type - + - + text - + billingcancellation_6eedf614 @@ -642,64 +642,72 @@ td.section { billingrecurrence_5fa2cb01 - - + + public.BillingRecurrence - - + + [table] - + billing_recurrence_id + + + + int8 not null + + + registrar_id + - int8 not null + text not null - registrar_id + domain_history_revision_id - text not null + int8 not null - domain_history_revision_id + domain_repo_id - int8 not null + text not null - domain_repo_id + event_time - text not null + timestamptz not null - event_time + flags - timestamptz not null + _text - flags + reason - _text + text not null - reason + domain_name @@ -707,96 +715,96 @@ td.section { text not null - domain_name + recurrence_end_time - text not null + timestamptz - recurrence_end_time + recurrence_time_of_year - timestamptz - - - recurrence_time_of_year - - - - text - + billingcancellation_6eedf614:w->billingrecurrence_5fa2cb01:e - + - - - - + + + + fk_billing_cancellation_billing_recurrence_id registrar_6e1503e3 - - + + public.Registrar - - + + [table] - + registrar_id + + + + text not null + + + allowed_tlds + - text not null + _text - allowed_tlds + billing_account_map - _text + "hstore" - billing_account_map + billing_identifier - "hstore" + int8 - billing_identifier + block_premium_names - int8 + bool not null - block_premium_names + client_certificate - bool not null + text - client_certificate + client_certificate_hash @@ -804,31 +812,31 @@ td.section { text - client_certificate_hash + contacts_require_syncing - text + bool not null - contacts_require_syncing + creation_time - bool not null + timestamptz - creation_time + drive_folder_id - timestamptz + text - drive_folder_id + email_address @@ -836,7 +844,7 @@ td.section { text - email_address + failover_client_certificate @@ -844,7 +852,7 @@ td.section { text - failover_client_certificate + failover_client_certificate_hash @@ -852,7 +860,7 @@ td.section { text - failover_client_certificate_hash + fax_number @@ -860,23 +868,23 @@ td.section { text - fax_number + iana_identifier - text + int8 - iana_identifier + icann_referral_email - int8 + text - icann_referral_email + i18n_address_city @@ -884,7 +892,7 @@ td.section { text - i18n_address_city + i18n_address_country_code @@ -892,7 +900,7 @@ td.section { text - i18n_address_country_code + i18n_address_state @@ -900,7 +908,7 @@ td.section { text - i18n_address_state + i18n_address_street_line1 @@ -908,7 +916,7 @@ td.section { text - i18n_address_street_line1 + i18n_address_street_line2 @@ -916,7 +924,7 @@ td.section { text - i18n_address_street_line2 + i18n_address_street_line3 @@ -924,7 +932,7 @@ td.section { text - i18n_address_street_line3 + i18n_address_zip @@ -932,23 +940,23 @@ td.section { text - i18n_address_zip + ip_address_allow_list - text + _text - ip_address_allow_list + last_certificate_update_time - _text + timestamptz - last_certificate_update_time + last_update_time @@ -956,15 +964,15 @@ td.section { timestamptz - last_update_time + localized_address_city - timestamptz + text - localized_address_city + localized_address_country_code @@ -972,7 +980,7 @@ td.section { text - localized_address_country_code + localized_address_state @@ -980,7 +988,7 @@ td.section { text - localized_address_state + localized_address_street_line1 @@ -988,7 +996,7 @@ td.section { text - localized_address_street_line1 + localized_address_street_line2 @@ -996,7 +1004,7 @@ td.section { text - localized_address_street_line2 + localized_address_street_line3 @@ -1004,7 +1012,7 @@ td.section { text - localized_address_street_line3 + localized_address_zip @@ -1012,7 +1020,7 @@ td.section { text - localized_address_zip + password_hash @@ -1020,7 +1028,7 @@ td.section { text - password_hash + phone_number @@ -1028,7 +1036,7 @@ td.section { text - phone_number + phone_passcode @@ -1036,7 +1044,7 @@ td.section { text - phone_passcode + po_number @@ -1044,39 +1052,39 @@ td.section { text - po_number + rdap_base_urls - text + _text - rdap_base_urls + registrar_name - _text + text not null - registrar_name + registry_lock_allowed - text not null + bool not null - registry_lock_allowed + password_salt - bool not null + text - password_salt + state @@ -1084,48 +1092,40 @@ td.section { text - state + type - text + text not null - type + url - text not null + text - url + whois_server text - - whois_server - - - - - text - - + billingcancellation_6eedf614:w->registrar_6e1503e3:e - + - - - - + + + + fk_billing_cancellation_registrar_id @@ -1586,106 +1586,114 @@ td.section { domain_6c51cffa:w->billingrecurrence_5fa2cb01:e - + - - - - - - + + + + + + fk_domain_billing_recurrence_id domain_6c51cffa:w->billingrecurrence_5fa2cb01:e - + - - - - + + + + fk_domain_transfer_billing_recurrence_id contact_8de8cb16 - - + + public.Contact - - + + [table] - + repo_id + + + + text not null + + + creation_registrar_id + text not null - creation_registrar_id + creation_time - text not null + timestamptz not null - creation_time + current_sponsor_registrar_id - timestamptz not null + text not null - current_sponsor_registrar_id + deletion_time - text not null + timestamptz - deletion_time + last_epp_update_registrar_id - timestamptz + text - last_epp_update_registrar_id + last_epp_update_time - text + timestamptz - last_epp_update_time + statuses - timestamptz + _text - statuses + auth_info_repo_id - _text + text - auth_info_repo_id + auth_info_value @@ -1693,7 +1701,7 @@ td.section { text - auth_info_value + contact_id @@ -1701,23 +1709,23 @@ td.section { text - contact_id + disclose_types_addr - text + _text - disclose_types_addr + disclose_show_email - _text + bool - disclose_show_email + disclose_show_fax @@ -1725,7 +1733,7 @@ td.section { bool - disclose_show_fax + disclose_mode_flag @@ -1733,15 +1741,15 @@ td.section { bool - disclose_mode_flag + disclose_types_name - bool + _text - disclose_types_name + disclose_types_org @@ -1749,23 +1757,23 @@ td.section { _text - disclose_types_org + disclose_show_voice - _text + bool - disclose_show_voice + email - bool + text - email + fax_phone_extension @@ -1773,7 +1781,7 @@ td.section { text - fax_phone_extension + fax_phone_number @@ -1781,7 +1789,7 @@ td.section { text - fax_phone_number + addr_i18n_city @@ -1789,7 +1797,7 @@ td.section { text - addr_i18n_city + addr_i18n_country_code @@ -1797,7 +1805,7 @@ td.section { text - addr_i18n_country_code + addr_i18n_state @@ -1805,7 +1813,7 @@ td.section { text - addr_i18n_state + addr_i18n_street_line1 @@ -1813,7 +1821,7 @@ td.section { text - addr_i18n_street_line1 + addr_i18n_street_line2 @@ -1821,7 +1829,7 @@ td.section { text - addr_i18n_street_line2 + addr_i18n_street_line3 @@ -1829,7 +1837,7 @@ td.section { text - addr_i18n_street_line3 + addr_i18n_zip @@ -1837,7 +1845,7 @@ td.section { text - addr_i18n_zip + addr_i18n_name @@ -1845,7 +1853,7 @@ td.section { text - addr_i18n_name + addr_i18n_org @@ -1853,7 +1861,7 @@ td.section { text - addr_i18n_org + addr_i18n_type @@ -1861,23 +1869,23 @@ td.section { text - addr_i18n_type + last_transfer_time - text + timestamptz - last_transfer_time + addr_local_city - timestamptz + text - addr_local_city + addr_local_country_code @@ -1885,7 +1893,7 @@ td.section { text - addr_local_country_code + addr_local_state @@ -1893,7 +1901,7 @@ td.section { text - addr_local_state + addr_local_street_line1 @@ -1901,7 +1909,7 @@ td.section { text - addr_local_street_line1 + addr_local_street_line2 @@ -1909,7 +1917,7 @@ td.section { text - addr_local_street_line2 + addr_local_street_line3 @@ -1917,7 +1925,7 @@ td.section { text - addr_local_street_line3 + addr_local_zip @@ -1925,7 +1933,7 @@ td.section { text - addr_local_zip + addr_local_name @@ -1933,7 +1941,7 @@ td.section { text - addr_local_name + addr_local_org @@ -1941,7 +1949,7 @@ td.section { text - addr_local_org + addr_local_type @@ -1949,7 +1957,7 @@ td.section { text - addr_local_type + search_name @@ -1957,7 +1965,7 @@ td.section { text - search_name + voice_phone_extension @@ -1965,7 +1973,7 @@ td.section { text - voice_phone_extension + voice_phone_number @@ -1973,15 +1981,15 @@ td.section { text - voice_phone_number + transfer_gaining_poll_message_id - text + int8 - transfer_gaining_poll_message_id + transfer_losing_poll_message_id @@ -1989,15 +1997,15 @@ td.section { int8 - transfer_losing_poll_message_id + transfer_client_txn_id - int8 + text - transfer_client_txn_id + transfer_server_txn_id @@ -2005,7 +2013,7 @@ td.section { text - transfer_server_txn_id + transfer_gaining_registrar_id @@ -2013,7 +2021,7 @@ td.section { text - transfer_gaining_registrar_id + transfer_losing_registrar_id @@ -2021,15 +2029,15 @@ td.section { text - transfer_losing_registrar_id + transfer_pending_expiration_time - text + timestamptz - transfer_pending_expiration_time + transfer_request_time @@ -2037,80 +2045,72 @@ td.section { timestamptz - transfer_request_time + transfer_status - timestamptz + text - transfer_status + update_timestamp - text - - - update_timestamp - - - - timestamptz - + domain_6c51cffa:w->contact_8de8cb16:e - - - - - - - - + + + + + + + + fk_domain_admin_contact domain_6c51cffa:w->contact_8de8cb16:e - - - - - - - - + + + + + + + + fk_domain_billing_contact domain_6c51cffa:w->contact_8de8cb16:e - - - - - - - - + + + + + + + + fk_domain_registrant_contact domain_6c51cffa:w->contact_8de8cb16:e - - - - - - - - + + + + + + + + fk_domain_tech_contact @@ -2362,372 +2362,383 @@ td.section { domain_6c51cffa:w->registrar_6e1503e3:e - - - - - - - - + + + + + + + + fk2jc69qyg2tv9hhnmif6oa1cx1 domain_6c51cffa:w->registrar_6e1503e3:e - - - - - - - - + + + + + + + + fk2u3srsfbei272093m3b3xwj23 domain_6c51cffa:w->registrar_6e1503e3:e - - - - - - - - + + + + + + + + fkjc0r9r5y1lfbt4gpbqw4wsuvq domain_6c51cffa:w->registrar_6e1503e3:e - + - - - - - + + + + + fk_domain_transfer_gaining_registrar_id domain_6c51cffa:w->registrar_6e1503e3:e - + - - - - + + + + fk_domain_transfer_losing_registrar_id billingevent_a57d1815:w->billingrecurrence_5fa2cb01:e - + - - - - + + + + fk_billing_event_cancellation_matching_billing_recurrence_id billingevent_a57d1815:w->registrar_6e1503e3:e - + - - - - - + + + + + fk_billing_event_registrar_id graceperiod_cd3b2e8f - - + + public.GracePeriod - - + + [table] - + id - + - - bigserial not null + + int8 not null - - - - auto-incremented - - + billing_event_id - + - + int8 - + billing_recurrence_id - + - + int8 - + registrar_id - + - + text not null - + domain_repo_id - + - + text not null - + expiration_time - + - + timestamptz not null - + type - + - + text not null - + + billing_event_history_id + + + + + int8 + + + billing_recurrence_history_id + + + + + int8 + + graceperiod_cd3b2e8f:w->domain_6c51cffa:e - - - - - - - - - fk2mys4hojm6ev2g9tmy5aq6m7g + + + + + + + + + fk_grace_period_domain_repo_id graceperiod_cd3b2e8f:w->billingevent_a57d1815:e - - - - - - - - + + + + + + + + fk_grace_period_billing_event_id graceperiod_cd3b2e8f:w->billingrecurrence_5fa2cb01:e - - - - - - - - + + + + + + + + fk_grace_period_billing_recurrence_id billingrecurrence_5fa2cb01:w->registrar_6e1503e3:e - - - - - - - - + + + + + + + + fk_billing_recurrence_registrar_id claimsentry_105da9f1 - - + + public.ClaimsEntry - - + + [table] - + revision_id - + - + int8 not null - + claim_key - + - + text not null - + domain_label - + - + text not null - + claimslist_3d49bc2b - - + + public.ClaimsList - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + creation_timestamp - + - + timestamptz not null - + tmdb_generation_time - + - + timestamptz not null - + claimsentry_105da9f1:w->claimslist_3d49bc2b:e - - - - - - - - + + + + + + + + fk6sc6at5hedffc0nhdcab6ivuq contact_8de8cb16:w->registrar_6e1503e3:e - - - - - - - - + + + + + + + + fk1sfyj7o7954prbn1exk7lpnoe contact_8de8cb16:w->registrar_6e1503e3:e - - - - - - - - + + + + + + + + fk93c185fx7chn68uv7nl6uv2s0 contact_8de8cb16:w->registrar_6e1503e3:e - - - - - - - - + + + + + + + + fkmb7tdiv85863134w1wogtxrb2 contact_8de8cb16:w->registrar_6e1503e3:e - - - - - - - - + + + + + + + + fk_contact_transfer_gaining_registrar_id contact_8de8cb16:w->registrar_6e1503e3:e - - - - - - - - + + + + + + + + fk_contact_transfer_losing_registrar_id @@ -3265,27 +3276,27 @@ td.section { contacthistory_d2964f8a:w->contact_8de8cb16:e - + - - - - + + + + fk_contact_history_contact_repo_id contacthistory_d2964f8a:w->registrar_6e1503e3:e - + - - - - - - + + + + + + fk_contact_history_registrar_id @@ -3304,14 +3315,14 @@ td.section { pollmessage_614a523e:w->contact_8de8cb16:e - - - - - - - - + + + + + + + + fk_poll_message_contact_repo_id @@ -4025,14 +4036,14 @@ td.section { pollmessage_614a523e:w->host_f21b78de:e - - - + + + - + fk_poll_message_host_repo_id @@ -4242,175 +4253,175 @@ td.section { pollmessage_614a523e:w->hosthistory_56210c2:e - - - - - - - - + + + + + + + + fk_poll_message_host_history pollmessage_614a523e:w->hosthistory_56210c2:e - - - - - - - - + + + + + + + + fk_poll_message_host_history pollmessage_614a523e:w->registrar_6e1503e3:e - + - - - - + + + + fk_poll_message_registrar_id pollmessage_614a523e:w->registrar_6e1503e3:e - - - - - - - + + + + + + + fk_poll_message_transfer_response_gaining_registrar_id pollmessage_614a523e:w->registrar_6e1503e3:e - - - - - - - + + + + + + + fk_poll_message_transfer_response_losing_registrar_id cursor_6af40e8c - - + + public."Cursor" - - + + [table] - + "scope" - + - + text not null - + type - + - + text not null - + cursor_time - + - + timestamptz not null - + last_update_time - + - + timestamptz not null - + delegationsignerdata_e542a872 - - + + public.DelegationSignerData - - + + [table] - + domain_repo_id - + - + text not null - + key_tag - + - + int4 not null - + algorithm - + - + int4 not null - + digest - + - + bytea not null - + digest_type - + - + int4 not null - + delegationsignerdata_e542a872:w->domain_6c51cffa:e - - - + + + - + fktr24j9v14ph2mfuw2gsmt12kq @@ -4429,63 +4440,63 @@ td.section { domainhistory_a54cc226:w->registrar_6e1503e3:e - - + + - - - - - + + + + + fk_domain_history_registrar_id domainhost_1ea127c2 - - + + public.DomainHost - - + + [table] - + domain_repo_id - + - + text not null - + host_repo_id - + - + text - + domainhost_1ea127c2:w->domain_6c51cffa:e - - - - + + + + - + - + fkfmi7bdink53swivs390m2btxg domainhost_1ea127c2:w->host_f21b78de:e - - - + + + @@ -4683,1020 +4694,1020 @@ td.section { hosthistory_56210c2:w->registrar_6e1503e3:e - + - - - - + + + + fk3d09knnmxrt6iniwnp8j2ykga lock_f21d4861 - - + + public.Lock - - + + [table] - + resource_name - + - + text not null - + tld - + - + text not null - + acquired_time - + - + timestamptz not null - + expiration_time - + - + timestamptz not null - + request_log_id - + - + text not null - + premiumentry_b0060b91 - - + + public.PremiumEntry - - + + [table] - + revision_id - + - + int8 not null - + price - + - + numeric(19, 2) not null - + domain_label - + - + text not null - + premiumlist_7c3ea68b - - + + public.PremiumList - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + creation_timestamp - + - + timestamptz not null - + name - + - + text not null - + bloom_filter - + - + bytea not null - + currency - + - + text not null - + premiumentry_b0060b91:w->premiumlist_7c3ea68b:e - - - - - - - - + + + + + + + + fko0gw90lpo1tuee56l0nb6y6g5 rderevision_83396864 - - + + public.RdeRevision - - + + [table] - + tld - + - + text not null - + mode - + - + text not null - + "date" - + - + date not null - + update_timestamp - + - + timestamptz - + revision - + - + int4 not null - + registrarpoc_ab47054d - - + + public.RegistrarPoc - - + + [table] - + email_address - + - + text not null - + allowed_to_set_registry_lock_password - + - + bool not null - + fax_number - + - + text - + gae_user_id - + - + text - + name - + - + text - + phone_number - + - + text - + registry_lock_password_hash - + - + text - + registry_lock_password_salt - + - + text - + types - + - + _text - + visible_in_domain_whois_as_abuse - + - + bool not null - + visible_in_whois_as_admin - + - + bool not null - + visible_in_whois_as_tech - + - + bool not null - + registry_lock_email_address - + - + text - + registrar_id - + - + text not null - + registrylock_ac88663e - - + + public.RegistryLock - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + lock_completion_timestamp - + - + timestamptz - + lock_request_timestamp - + - + timestamptz not null - + domain_name - + - + text not null - + is_superuser - + - + bool not null - + registrar_id - + - + text not null - + registrar_poc_id - + - + text - + repo_id - + - + text not null - + verification_code - + - + text not null - + unlock_request_timestamp - + - + timestamptz - + unlock_completion_timestamp - + - + timestamptz - + last_update_timestamp - + - + timestamptz - + relock_revision_id - + - + int8 - + relock_duration - + - + interval - + registrylock_ac88663e:w->registrylock_ac88663e:e - - - - - - - - + + + + + + + + fk2lhcwpxlnqijr96irylrh1707 reservedentry_1a7b8520 - - + + public.ReservedEntry - - + + [table] - + revision_id - + - + int8 not null - + comment - + - + text - + reservation_type - + - + int4 not null - + domain_label - + - + text not null - + reservedlist_b97c3f1c - - + + public.ReservedList - - + + [table] - + revision_id - + - + bigserial not null - + - + auto-incremented - + creation_timestamp - + - + timestamptz not null - + name - + - + text not null - + should_publish - + - + bool not null - + reservedentry_1a7b8520:w->reservedlist_b97c3f1c:e - - - - - - - - + + + + + + + + fkgq03rk0bt1hb915dnyvd3vnfc spec11threatmatch_a61228a6 - - + + public.Spec11ThreatMatch - - + + [table] - + id - + - + bigserial not null - + - + auto-incremented - + check_date - + - + date not null - + domain_name - + - + text not null - + domain_repo_id - + - + text not null - + registrar_id - + - + text not null - + threat_types - + - + _text not null - + tld - + - + text not null - + tld_f1fa57e2 - - + + public.Tld - - + + [table] - + tld_name - + - + text not null - + add_grace_period_length - + - + interval not null - + allowed_fully_qualified_host_names - + - + _text - + allowed_registrant_contact_ids - + - + _text - + anchor_tenant_add_grace_period_length - + - + interval not null - + auto_renew_grace_period_length - + - + interval not null - + automatic_transfer_length - + - + interval not null - + claims_period_end - + - + timestamptz not null - + create_billing_cost_amount - + - + numeric(19, 2) - + create_billing_cost_currency - + - + text - + creation_time - + - + timestamptz not null - + currency - + - + text not null - + dns_paused - + - + bool not null - + dns_writers - + - + _text not null - + drive_folder_id - + - + text - + eap_fee_schedule - + - + "hstore" not null - + escrow_enabled - + - + bool not null - + invoicing_enabled - + - + bool not null - + lordn_username - + - + text - + num_dns_publish_locks - + - + int4 not null - + pending_delete_length - + - + interval not null - + premium_list_name - + - + text - + pricing_engine_class_name - + - + text - + redemption_grace_period_length - + - + interval not null - + registry_lock_or_unlock_cost_amount - + - + numeric(19, 2) - + registry_lock_or_unlock_cost_currency - + - + text - + renew_billing_cost_transitions - + - + "hstore" not null - + renew_grace_period_length - + - + interval not null - + reserved_list_names - + - + _text not null - + restore_billing_cost_amount - + - + numeric(19, 2) - + restore_billing_cost_currency - + - + text - + roid_suffix - + - + text - + server_status_change_billing_cost_amount - + - + numeric(19, 2) - + server_status_change_billing_cost_currency - + - + text - + tld_state_transitions - + - + "hstore" not null - + tld_type - + - + text not null - + tld_unicode - + - + text not null - + transfer_grace_period_length - + - + interval not null - + transaction_d50389d4 - - + + public.Transaction - - + + [table] - + id - + - + bigserial not null - + - + auto-incremented - + contents - + - + bytea - + @@ -8228,7 +8239,7 @@ td.section { - fk2mys4hojm6ev2g9tmy5aq6m7g + fk_grace_period_domain_repo_id [foreign key, with no action] @@ -9149,12 +9160,7 @@ td.section { id - bigserial not null - - - - - auto-incremented + int8 not null @@ -9186,6 +9192,16 @@ td.section { type text not null + + + billing_event_history_id + int8 + + + + billing_recurrence_history_id + int8 + @@ -9238,7 +9254,7 @@ td.section { - fk2mys4hojm6ev2g9tmy5aq6m7g + fk_grace_period_domain_repo_id [foreign key, with no action] diff --git a/db/src/main/resources/sql/flyway.txt b/db/src/main/resources/sql/flyway.txt index db47392ef..290df0ff6 100644 --- a/db/src/main/resources/sql/flyway.txt +++ b/db/src/main/resources/sql/flyway.txt @@ -64,3 +64,4 @@ V63__add_schema_for_ds_data.sql V64__transfer_history_columns.sql V65__local_date_date_type.sql V66__create_rde_revision.sql +V67__grace_period_history_ids.sql diff --git a/db/src/main/resources/sql/flyway/V67__grace_period_history_ids.sql b/db/src/main/resources/sql/flyway/V67__grace_period_history_ids.sql new file mode 100644 index 000000000..4f0a583ca --- /dev/null +++ b/db/src/main/resources/sql/flyway/V67__grace_period_history_ids.sql @@ -0,0 +1,26 @@ +-- Copyright 2020 The Nomulus Authors. All Rights Reserved. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +ALTER TABLE "GracePeriod" ADD COLUMN billing_event_history_id int8; +ALTER TABLE "GracePeriod" ADD COLUMN billing_recurrence_history_id int8; + +ALTER TABLE ONLY public."GracePeriod" + DROP CONSTRAINT fk2mys4hojm6ev2g9tmy5aq6m7g; +ALTER TABLE ONLY public."GracePeriod" + ADD CONSTRAINT fk_grace_period_domain_repo_id + FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id) + DEFERRABLE INITIALLY DEFERRED; + +ALTER TABLE "GracePeriod" ALTER COLUMN id drop default; +DROP SEQUENCE "GracePeriod_id_seq"; diff --git a/db/src/main/resources/sql/schema/db-schema.sql.generated b/db/src/main/resources/sql/schema/db-schema.sql.generated index 6e7a72f18..d46cd81f5 100644 --- a/db/src/main/resources/sql/schema/db-schema.sql.generated +++ b/db/src/main/resources/sql/schema/db-schema.sql.generated @@ -383,9 +383,11 @@ ); create table "GracePeriod" ( - id bigserial not null, + id int8 not null, billing_event_id int8, + billing_event_history_id int8, billing_recurrence_id int8, + billing_recurrence_history_id int8, registrar_id text not null, domain_repo_id text not null, expiration_time timestamptz not null, diff --git a/db/src/main/resources/sql/schema/nomulus.golden.sql b/db/src/main/resources/sql/schema/nomulus.golden.sql index 0298bc968..aa4def939 100644 --- a/db/src/main/resources/sql/schema/nomulus.golden.sql +++ b/db/src/main/resources/sql/schema/nomulus.golden.sql @@ -515,29 +515,12 @@ CREATE TABLE public."GracePeriod" ( registrar_id text NOT NULL, domain_repo_id text NOT NULL, expiration_time timestamp with time zone NOT NULL, - type text NOT NULL + type text NOT NULL, + billing_event_history_id bigint, + billing_recurrence_history_id bigint ); --- --- Name: GracePeriod_id_seq; Type: SEQUENCE; Schema: public; Owner: - --- - -CREATE SEQUENCE public."GracePeriod_id_seq" - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - - --- --- Name: GracePeriod_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public."GracePeriod_id_seq" OWNED BY public."GracePeriod".id; - - -- -- Name: Host; Type: TABLE; Schema: public; Owner: - -- @@ -977,13 +960,6 @@ ALTER TABLE ONLY public."ClaimsList" ALTER COLUMN revision_id SET DEFAULT nextva ALTER TABLE ONLY public."DomainTransactionRecord" ALTER COLUMN id SET DEFAULT nextval('public."DomainTransactionRecord_id_seq"'::regclass); --- --- Name: GracePeriod id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."GracePeriod" ALTER COLUMN id SET DEFAULT nextval('public."GracePeriod_id_seq"'::regclass); - - -- -- Name: PremiumList revision_id; Type: DEFAULT; Schema: public; Owner: - -- @@ -1640,14 +1616,6 @@ ALTER TABLE ONLY public."RegistryLock" ADD CONSTRAINT fk2lhcwpxlnqijr96irylrh1707 FOREIGN KEY (relock_revision_id) REFERENCES public."RegistryLock"(revision_id); --- --- Name: GracePeriod fk2mys4hojm6ev2g9tmy5aq6m7g; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."GracePeriod" - ADD CONSTRAINT fk2mys4hojm6ev2g9tmy5aq6m7g FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id); - - -- -- Name: Domain fk2u3srsfbei272093m3b3xwj23; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -1896,6 +1864,14 @@ ALTER TABLE ONLY public."GracePeriod" ADD CONSTRAINT fk_grace_period_billing_recurrence_id FOREIGN KEY (billing_recurrence_id) REFERENCES public."BillingRecurrence"(billing_recurrence_id); +-- +-- Name: GracePeriod fk_grace_period_domain_repo_id; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."GracePeriod" + ADD CONSTRAINT fk_grace_period_domain_repo_id FOREIGN KEY (domain_repo_id) REFERENCES public."Domain"(repo_id) DEFERRABLE INITIALLY DEFERRED; + + -- -- Name: Host fk_host_superordinate_domain; Type: FK CONSTRAINT; Schema: public; Owner: - --