diff --git a/core/src/main/java/google/registry/model/domain/Domain.java b/core/src/main/java/google/registry/model/domain/Domain.java index 868539b44..bd655acab 100644 --- a/core/src/main/java/google/registry/model/domain/Domain.java +++ b/core/src/main/java/google/registry/model/domain/Domain.java @@ -210,7 +210,8 @@ public class Domain extends DomainBase implements ForeignKeyedEppResource { .setSubordinateHosts(domainBase.getSubordinateHosts()) .setStatusValues(domainBase.getStatusValues()) .setTransferData(domainBase.getTransferData()) - .setDnsRefreshRequestTime(domainBase.getDnsRefreshRequestTime()); + .setDnsRefreshRequestTime(domainBase.getDnsRefreshRequestTime()) + .setCurrentPackageToken(domainBase.getCurrentPackageToken().orElse(null)); } } } diff --git a/core/src/main/java/google/registry/model/domain/DomainBase.java b/core/src/main/java/google/registry/model/domain/DomainBase.java index c2ca61793..75624daf4 100644 --- a/core/src/main/java/google/registry/model/domain/DomainBase.java +++ b/core/src/main/java/google/registry/model/domain/DomainBase.java @@ -56,6 +56,7 @@ import google.registry.model.contact.ContactResource; import google.registry.model.domain.launch.LaunchNotice; import google.registry.model.domain.rgp.GracePeriodStatus; import google.registry.model.domain.secdns.DelegationSignerData; +import google.registry.model.domain.token.AllocationToken; import google.registry.model.eppcommon.StatusValue; import google.registry.model.host.Host; import google.registry.model.poll.PollMessage; @@ -282,6 +283,9 @@ public class DomainBase extends EppResource // TODO(mcilwain): Start using this field once we are further along in the DB migration. @Ignore DateTime dnsRefreshRequestTime; + /** The {@link AllocationToken} for the package this domain is currently a part of. */ + @Nullable VKey currentPackageToken; + /** * Returns the DNS refresh request time iff this domain's DNS needs refreshing, otherwise absent. */ @@ -330,6 +334,10 @@ public class DomainBase extends EppResource return smdId; } + public Optional> getCurrentPackageToken() { + return Optional.ofNullable(currentPackageToken); + } + /** * Returns the autorenew end time if there is one, otherwise empty. * @@ -938,5 +946,10 @@ public class DomainBase extends EppResource getInstance().lastTransferTime = lastTransferTime; return thisCastToDerived(); } + + public B setCurrentPackageToken(@Nullable VKey currentPackageToken) { + getInstance().currentPackageToken = currentPackageToken; + return thisCastToDerived(); + } } } diff --git a/core/src/test/java/google/registry/model/domain/DomainSqlTest.java b/core/src/test/java/google/registry/model/domain/DomainSqlTest.java index 3da803ea4..47085763a 100644 --- a/core/src/test/java/google/registry/model/domain/DomainSqlTest.java +++ b/core/src/test/java/google/registry/model/domain/DomainSqlTest.java @@ -17,11 +17,14 @@ 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; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.insertInDb; import static google.registry.testing.DatabaseHelper.loadByEntity; import static google.registry.testing.DatabaseHelper.loadByKey; +import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.DatabaseHelper.updateInDb; import static google.registry.testing.SqlHelper.assertThrowForeignKeyViolation; import static google.registry.testing.SqlHelper.saveRegistrar; @@ -31,6 +34,7 @@ import static org.joda.money.CurrencyUnit.USD; import static org.joda.time.DateTimeZone.UTC; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Sets; import com.googlecode.objectify.Key; import google.registry.model.billing.BillingEvent; @@ -44,6 +48,8 @@ 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; +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; @@ -86,6 +92,7 @@ public class DomainSqlTest { private ContactResource contact; private ContactResource contact2; private ImmutableSet gracePeriods; + private AllocationToken allocationToken; @BeforeEach void setUp() { @@ -138,6 +145,24 @@ public class DomainSqlTest { .build(); contact = makeContact("contact_id1"); contact2 = makeContact("contact_id2"); + + allocationToken = + new AllocationToken.Builder() + .setToken("abc123Unlimited") + .setTokenType(UNLIMITED_USE) + .setCreationTimeForTest(DateTime.parse("2010-11-12T05:00:00Z")) + .setAllowedTlds(ImmutableSet.of("dev", "app")) + .setAllowedRegistrarIds(ImmutableSet.of("TheRegistrar, NewRegistrar")) + .setDiscountFraction(0.5) + .setDiscountPremiums(true) + .setDiscountYears(3) + .setTokenStatusTransitions( + ImmutableSortedMap.naturalOrder() + .put(START_OF_TIME, NOT_STARTED) + .put(DateTime.now(UTC), TokenStatus.VALID) + .put(DateTime.now(UTC).plusWeeks(8), TokenStatus.ENDED) + .build()) + .build(); } @Test @@ -146,12 +171,27 @@ public class DomainSqlTest { assertEqualDomainExcept(loadByKey(domain.createVKey())); } + @Test + void testDomainBasePersistenceWithCurrentPackageToken() { + domain = domain.asBuilder().setCurrentPackageToken(allocationToken.createVKey()).build(); + persistResource(allocationToken); + persistDomain(); + assertEqualDomainExcept(loadByKey(domain.createVKey())); + } + @Test void testHostForeignKeyConstraints() { // Persist the domain without the associated host object. assertThrowForeignKeyViolation(() -> insertInDb(contact, contact2, domain)); } + @Test + void testCurrentPackageTokenForeignKeyConstraints() { + // Persist the domain without the associated allocation token object. + domain = domain.asBuilder().setCurrentPackageToken(allocationToken.createVKey()).build(); + assertThrowForeignKeyViolation(() -> persistDomain()); + } + @Test void testContactForeignKeyConstraints() { // Persist the domain without the associated contact objects. diff --git a/core/src/test/resources/google/registry/model/schema.txt b/core/src/test/resources/google/registry/model/schema.txt index 6081c3c49..b7465bae5 100644 --- a/core/src/test/resources/google/registry/model/schema.txt +++ b/core/src/test/resources/google/registry/model/schema.txt @@ -106,6 +106,7 @@ class google.registry.model.domain.Domain { google.registry.persistence.VKey billingContact; google.registry.persistence.VKey registrantContact; google.registry.persistence.VKey techContact; + google.registry.persistence.VKey currentPackageToken; google.registry.persistence.VKey autorenewPollMessage; google.registry.persistence.VKey deletePollMessage; java.lang.String creationClientId; @@ -138,6 +139,7 @@ class google.registry.model.domain.DomainBase { google.registry.persistence.VKey billingContact; google.registry.persistence.VKey registrantContact; google.registry.persistence.VKey techContact; + google.registry.persistence.VKey currentPackageToken; google.registry.persistence.VKey autorenewPollMessage; google.registry.persistence.VKey deletePollMessage; java.lang.String creationClientId; 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 0abb25f29..5cf240d73 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,7 +261,7 @@ td.section { generated on - 2022-08-03 03:39:41.842844 + 2022-08-08 20:39:49.590205 last flyway file @@ -284,7 +284,7 @@ td.section { generated on - 2022-08-03 03:39:41.842844 + 2022-08-08 20:39:49.590205 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 bc1c71788..ef4265441 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,7 +261,7 @@ td.section { generated on - 2022-08-03 03:39:39.509159 + 2022-08-08 20:39:47.815781 last flyway file @@ -284,7 +284,7 @@ td.section { generated on - 2022-08-03 03:39:39.509159 + 2022-08-08 20:39:47.815781 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 86515b994..2371d1809 100644 --- a/db/src/main/resources/sql/schema/db-schema.sql.generated +++ b/db/src/main/resources/sql/schema/db-schema.sql.generated @@ -272,6 +272,7 @@ autorenew_poll_message_id int8, autorenew_poll_message_history_id int8, billing_contact text, + current_package_token text, deletion_poll_message_id int8, dns_refresh_request_time timestamptz, domain_name text, @@ -341,6 +342,7 @@ autorenew_poll_message_id int8, autorenew_poll_message_history_id int8, billing_contact text, + current_package_token text, deletion_poll_message_id int8, dns_refresh_request_time timestamptz, domain_name text,