diff --git a/core/src/main/java/google/registry/model/registrar/Registrar.java b/core/src/main/java/google/registry/model/registrar/Registrar.java index 203ed0a24..8084c0de4 100644 --- a/core/src/main/java/google/registry/model/registrar/Registrar.java +++ b/core/src/main/java/google/registry/model/registrar/Registrar.java @@ -37,6 +37,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory. import static google.registry.persistence.transaction.TransactionManagerUtil.transactIfJpaTm; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy; +import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.PasswordUtils.SALT_SUPPLIER; import static google.registry.util.PasswordUtils.hashPassword; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; @@ -458,6 +459,14 @@ public class Registrar extends ImmutableObject /** The time that the certificate was last updated. */ DateTime lastCertificateUpdateTime; + /** The time that an expiring certificate notification email was sent to the registrar. */ + DateTime lastExpiringCertNotificationSentDate = START_OF_TIME; + + /** + * The time that an expiring failover certificate notification email was sent to the registrar. + */ + DateTime lastExpiringFailoverCertNotificationSentDate = START_OF_TIME; + /** Telephone support passcode (5-digit numeric) */ String phonePasscode; @@ -508,6 +517,14 @@ public class Registrar extends ImmutableObject return lastCertificateUpdateTime; } + public DateTime getLastExpiringCertNotificationSentDate() { + return lastExpiringCertNotificationSentDate; + } + + public DateTime getLastExpiringFailoverCertNotificationSentDate() { + return lastExpiringFailoverCertNotificationSentDate; + } + public String getRegistrarName() { return registrarName; } @@ -671,6 +688,10 @@ public class Registrar extends ImmutableObject .putString("creationTime", creationTime.getTimestamp()) .putString("lastUpdateTime", lastUpdateTime.getTimestamp()) .putString("lastCertificateUpdateTime", lastCertificateUpdateTime) + .putString("lastExpiringCertNotificationSentDate", lastExpiringCertNotificationSentDate) + .putString( + "lastExpiringFailoverCertNotificationSentDate", + lastExpiringFailoverCertNotificationSentDate) .put("registrarName", registrarName) .put("type", type) .put("state", state) @@ -839,6 +860,19 @@ public class Registrar extends ImmutableObject return this; } + public Builder setLastExpiringCertNotificationSentDate(DateTime now) { + checkArgumentNotNull(now, "Registrar lastExpiringCertNotificationSentDate cannot be null"); + getInstance().lastExpiringCertNotificationSentDate = now; + return this; + } + + public Builder setLastExpiringFailoverCertNotificationSentDate(DateTime now) { + checkArgumentNotNull( + now, "Registrar lastExpiringFailoverCertNotificationSentDate cannot be null"); + getInstance().lastExpiringFailoverCertNotificationSentDate = now; + return this; + } + public Builder setFailoverClientCertificate(String clientCertificate, DateTime now) { clientCertificate = emptyToNull(clientCertificate); String clientCertificateHash = calculateHash(clientCertificate); diff --git a/core/src/test/java/google/registry/model/registrar/RegistrarTest.java b/core/src/test/java/google/registry/model/registrar/RegistrarTest.java index 6f609c4d9..5cf2c05b7 100644 --- a/core/src/test/java/google/registry/model/registrar/RegistrarTest.java +++ b/core/src/test/java/google/registry/model/registrar/RegistrarTest.java @@ -29,6 +29,7 @@ import static google.registry.testing.DatabaseHelper.newRegistry; import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.DatabaseHelper.persistSimpleResource; import static google.registry.testing.DatabaseHelper.persistSimpleResources; +import static google.registry.util.DateTimeUtils.START_OF_TIME; import static org.junit.jupiter.api.Assertions.assertThrows; import com.google.common.collect.ImmutableList; @@ -414,6 +415,64 @@ class RegistrarTest extends EntityTestCase { IllegalArgumentException.class, () -> new Registrar.Builder().setPhonePasscode("code1")); } + @TestOfyAndSql + void testSuccess_getLastExpiringCertNotificationSentDate_returnsInitialValue() { + assertThat(registrar.getLastExpiringCertNotificationSentDate()).isEqualTo(START_OF_TIME); + } + + @TestOfyAndSql + void testSuccess_getLastExpiringFailoverCertNotificationSentDate_returnsInitialValue() { + assertThat(registrar.getLastExpiringFailoverCertNotificationSentDate()) + .isEqualTo(START_OF_TIME); + } + + @TestOfyAndSql + void testSuccess_setLastExpiringCertNotificationSentDate() { + assertThat( + registrar + .asBuilder() + .setLastExpiringCertNotificationSentDate(fakeClock.nowUtc()) + .build() + .getLastExpiringCertNotificationSentDate()) + .isEqualTo(fakeClock.nowUtc()); + } + + @TestOfyAndSql + void testFailure_setLastExpiringCertNotificationSentDate_nullDate() { + IllegalArgumentException thrown = + assertThrows( + IllegalArgumentException.class, + () -> new Registrar.Builder().setLastExpiringCertNotificationSentDate(null).build()); + assertThat(thrown) + .hasMessageThat() + .isEqualTo("Registrar lastExpiringCertNotificationSentDate cannot be null"); + } + + @TestOfyAndSql + void testSuccess_setLastExpiringFailoverCertNotificationSentDate() { + assertThat( + registrar + .asBuilder() + .setLastExpiringFailoverCertNotificationSentDate(fakeClock.nowUtc()) + .build() + .getLastExpiringFailoverCertNotificationSentDate()) + .isEqualTo(fakeClock.nowUtc()); + } + + @TestOfyAndSql + void testFailure_setLastExpiringFailoverCertNotificationSentDate_nullDate() { + IllegalArgumentException thrown = + assertThrows( + IllegalArgumentException.class, + () -> + new Registrar.Builder() + .setLastExpiringFailoverCertNotificationSentDate(null) + .build()); + assertThat(thrown) + .hasMessageThat() + .isEqualTo("Registrar lastExpiringFailoverCertNotificationSentDate cannot be null"); + } + @TestOfyAndSql void testSuccess_setAllowedTlds() { assertThat( diff --git a/core/src/test/resources/google/registry/model/schema.txt b/core/src/test/resources/google/registry/model/schema.txt index e45717468..c3a8555c0 100644 --- a/core/src/test/resources/google/registry/model/schema.txt +++ b/core/src/test/resources/google/registry/model/schema.txt @@ -600,6 +600,8 @@ class google.registry.model.registrar.Registrar { java.util.Set allowedTlds; java.util.Set rdapBaseUrls; org.joda.time.DateTime lastCertificateUpdateTime; + org.joda.time.DateTime lastExpiringCertNotificationSentDate; + org.joda.time.DateTime lastExpiringFailoverCertNotificationSentDate; } class google.registry.model.registrar.Registrar$BillingAccountEntry { java.lang.String accountId; 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 f21f543cb..e0ea31f8c 100644 --- a/db/src/main/resources/sql/schema/db-schema.sql.generated +++ b/db/src/main/resources/sql/schema/db-schema.sql.generated @@ -581,6 +581,8 @@ i18n_address_zip text, ip_address_allow_list text[], last_certificate_update_time timestamptz, + last_expiring_cert_notification_sent_date timestamptz, + last_expiring_failover_cert_notification_sent_date timestamptz, last_update_time timestamptz not null, localized_address_city text, localized_address_country_code text,