Remove ClaimsList from Datastore Schema (#1298)

* Remove ClaimsList from Datastore schema

* Remove some Datastore references

* Remove unnecessary annotations
This commit is contained in:
sarahcaseybot 2021-08-25 11:58:44 -04:00 committed by GitHub
parent bc62e13e41
commit d235347c12
11 changed files with 20 additions and 132 deletions

View file

@ -43,9 +43,6 @@ import google.registry.model.reporting.HistoryEntry;
import google.registry.model.server.Lock; import google.registry.model.server.Lock;
import google.registry.model.server.ServerSecret; import google.registry.model.server.ServerSecret;
import google.registry.model.tld.Registry; import google.registry.model.tld.Registry;
import google.registry.model.tmch.ClaimsList;
import google.registry.model.tmch.ClaimsList.ClaimsListRevision;
import google.registry.model.tmch.ClaimsList.ClaimsListSingleton;
import google.registry.model.tmch.TmchCrl; import google.registry.model.tmch.TmchCrl;
/** Sets of classes of the Objectify-registered entities in use throughout the model. */ /** Sets of classes of the Objectify-registered entities in use throughout the model. */
@ -59,9 +56,6 @@ public final class EntityClasses {
BillingEvent.Modification.class, BillingEvent.Modification.class,
BillingEvent.OneTime.class, BillingEvent.OneTime.class,
BillingEvent.Recurring.class, BillingEvent.Recurring.class,
ClaimsList.class,
ClaimsListRevision.class,
ClaimsListSingleton.class,
CommitLogBucket.class, CommitLogBucket.class,
CommitLogCheckpoint.class, CommitLogCheckpoint.class,
CommitLogCheckpointRoot.class, CommitLogCheckpointRoot.class,

View file

@ -17,34 +17,21 @@ package google.registry.model.tmch;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableMap.toImmutableMap; import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static google.registry.model.IdService.allocateId;
import static google.registry.model.ofy.ObjectifyService.auditedOfy;
import static google.registry.persistence.transaction.QueryComposer.Comparator.EQ; import static google.registry.persistence.transaction.QueryComposer.Comparator.EQ;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.Parent;
import google.registry.model.CreateAutoTimestamp; import google.registry.model.CreateAutoTimestamp;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.model.annotations.InCrossTld; import google.registry.model.replay.SqlOnlyEntity;
import google.registry.model.annotations.NotBackedUp;
import google.registry.model.annotations.NotBackedUp.Reason;
import google.registry.model.annotations.VirtualEntity;
import google.registry.model.common.CrossTldSingleton;
import google.registry.model.replay.DatastoreOnlyEntity;
import google.registry.model.replay.NonReplicatedEntity;
import google.registry.model.tld.label.ReservedList.ReservedListEntry; import google.registry.model.tld.label.ReservedList.ReservedListEntry;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nullable;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PostPersist; import javax.persistence.PostPersist;
import javax.persistence.PostUpdate; import javax.persistence.PostUpdate;
import javax.persistence.PreRemove; import javax.persistence.PreRemove;
@ -60,26 +47,15 @@ import org.joda.time.DateTime;
* succeeds, we will end up with having two exact same claims list with only different {@link * succeeds, we will end up with having two exact same claims list with only different {@link
* #revisionId}. However, this is not an actual problem because we only use the claims list with * #revisionId}. However, this is not an actual problem because we only use the claims list with
* highest {@link #revisionId}. * highest {@link #revisionId}.
*
* <p>TODO(b/162007765): Remove Datastore related fields and methods.
*/ */
@Entity @Entity(name = "ClaimsList")
@NotBackedUp(reason = Reason.EXTERNALLY_SOURCED)
@javax.persistence.Entity(name = "ClaimsList")
@Table @Table
@InCrossTld public class ClaimsList extends ImmutableObject implements SqlOnlyEntity {
public class ClaimsList extends ImmutableObject implements NonReplicatedEntity {
@Transient @Id long id; @Id
@Transient @Parent Key<ClaimsListRevision> parent;
@Ignore
@javax.persistence.Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
Long revisionId; Long revisionId;
@Ignore
@Column(nullable = false) @Column(nullable = false)
CreateAutoTimestamp creationTimestamp = CreateAutoTimestamp.create(null); CreateAutoTimestamp creationTimestamp = CreateAutoTimestamp.create(null);
@ -217,65 +193,8 @@ public class ClaimsList extends ImmutableObject implements NonReplicatedEntity {
public static ClaimsList create( public static ClaimsList create(
DateTime tmdbGenerationTime, ImmutableMap<String, String> labelsToKeys) { DateTime tmdbGenerationTime, ImmutableMap<String, String> labelsToKeys) {
ClaimsList instance = new ClaimsList(); ClaimsList instance = new ClaimsList();
instance.id = allocateId();
instance.creationTime = checkNotNull(tmdbGenerationTime); instance.creationTime = checkNotNull(tmdbGenerationTime);
instance.labelsToKeys = checkNotNull(labelsToKeys); instance.labelsToKeys = checkNotNull(labelsToKeys);
return instance; return instance;
} }
/** Virtual parent entity for claims list shards of a specific revision. */
@Entity
@VirtualEntity
public static class ClaimsListRevision extends ImmutableObject implements DatastoreOnlyEntity {
@Parent Key<ClaimsListSingleton> parent;
@Id long versionId;
@VisibleForTesting
public static Key<ClaimsListRevision> createKey(ClaimsListSingleton singleton) {
ClaimsListRevision revision = new ClaimsListRevision();
revision.versionId = allocateId();
revision.parent = Key.create(singleton);
return Key.create(revision);
}
@VisibleForTesting
public static Key<ClaimsListRevision> createKey() {
return createKey(new ClaimsListSingleton());
}
}
/**
* Serves as the coordinating claims list singleton linking to the {@link ClaimsListRevision} that
* is live.
*/
@Entity
@NotBackedUp(reason = Reason.EXTERNALLY_SOURCED)
public static class ClaimsListSingleton extends CrossTldSingleton implements DatastoreOnlyEntity {
Key<ClaimsListRevision> activeRevision;
static ClaimsListSingleton create(Key<ClaimsListRevision> revision) {
ClaimsListSingleton instance = new ClaimsListSingleton();
instance.activeRevision = revision;
return instance;
}
@VisibleForTesting
public void setActiveRevision(Key<ClaimsListRevision> revision) {
activeRevision = revision;
}
}
/**
* Returns the current ClaimsListRevision if there is one, or null if no claims list revisions
* have ever been persisted yet.
*/
@Nullable
public static Key<ClaimsListRevision> getCurrentRevision() {
ClaimsListSingleton singleton = auditedOfy().load().entity(new ClaimsListSingleton()).now();
return singleton == null ? null : singleton.activeRevision;
}
/** Exception when trying to directly save a {@link ClaimsList} without sharding. */
public static class UnshardedSaveException extends RuntimeException {}
} }

View file

@ -40,7 +40,6 @@ import google.registry.model.index.ForeignKeyIndex.ForeignKeyHostIndex;
import google.registry.model.ofy.DatastoreTransactionManager; import google.registry.model.ofy.DatastoreTransactionManager;
import google.registry.model.replay.NonReplicatedEntity; import google.registry.model.replay.NonReplicatedEntity;
import google.registry.model.replay.SqlOnlyEntity; import google.registry.model.replay.SqlOnlyEntity;
import google.registry.model.tmch.ClaimsList.ClaimsListSingleton;
import google.registry.persistence.JpaRetries; import google.registry.persistence.JpaRetries;
import google.registry.persistence.VKey; import google.registry.persistence.VKey;
import google.registry.util.Clock; import google.registry.util.Clock;
@ -90,7 +89,6 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
// TODO(b/176108270): Remove this property after database migration. // TODO(b/176108270): Remove this property after database migration.
private static final ImmutableSet<Class<? extends ImmutableObject>> IGNORED_ENTITY_CLASSES = private static final ImmutableSet<Class<? extends ImmutableObject>> IGNORED_ENTITY_CLASSES =
ImmutableSet.of( ImmutableSet.of(
ClaimsListSingleton.class,
EppResourceIndex.class, EppResourceIndex.class,
ForeignKeyContactIndex.class, ForeignKeyContactIndex.class,
ForeignKeyDomainIndex.class, ForeignKeyDomainIndex.class,

View file

@ -46,7 +46,7 @@ public final class TmchDnlAction implements Runnable {
@Inject @Key("marksdbDnlLoginAndPassword") Optional<String> marksdbDnlLoginAndPassword; @Inject @Key("marksdbDnlLoginAndPassword") Optional<String> marksdbDnlLoginAndPassword;
@Inject TmchDnlAction() {} @Inject TmchDnlAction() {}
/** Synchronously fetches latest domain name list and saves it to Datastore. */ /** Synchronously fetches latest domain name list and saves it to Cloud SQL. */
@Override @Override
public void run() { public void run() {
List<String> lines; List<String> lines;

View file

@ -62,7 +62,7 @@ import google.registry.model.replay.SqlReplayCheckpoint;
import google.registry.model.server.Lock; import google.registry.model.server.Lock;
import google.registry.model.tld.label.PremiumList; import google.registry.model.tld.label.PremiumList;
import google.registry.model.tld.label.PremiumList.PremiumEntry; import google.registry.model.tld.label.PremiumList.PremiumEntry;
import google.registry.model.tmch.ClaimsList; import google.registry.model.tmch.TmchCrl;
import google.registry.model.translators.VKeyTranslatorFactory; import google.registry.model.translators.VKeyTranslatorFactory;
import google.registry.persistence.VKey; import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTransactionManager; import google.registry.persistence.transaction.JpaTransactionManager;
@ -455,7 +455,7 @@ public class ReplayCommitLogsToSqlActionTest {
jpaTm().transact(() -> SqlReplayCheckpoint.set(now.minusMinutes(1).minusMillis(1))); jpaTm().transact(() -> SqlReplayCheckpoint.set(now.minusMinutes(1).minusMillis(1)));
// Save a couple deletes that aren't propagated to SQL (the objects deleted are irrelevant) // Save a couple deletes that aren't propagated to SQL (the objects deleted are irrelevant)
Key<ClaimsList> claimsListKey = Key.create(ClaimsList.class, 1L); Key<TmchCrl> tmchCrlKey = Key.create(TmchCrl.class, 1L);
saveDiffFile( saveDiffFile(
gcsUtils, gcsUtils,
createCheckpoint(now.minusMinutes(1)), createCheckpoint(now.minusMinutes(1)),
@ -463,7 +463,7 @@ public class ReplayCommitLogsToSqlActionTest {
getBucketKey(1), getBucketKey(1),
now.minusMinutes(1), now.minusMinutes(1),
// one object only exists in Datastore, one is dually-written (so isn't replicated) // one object only exists in Datastore, one is dually-written (so isn't replicated)
ImmutableSet.of(getCrossTldKey(), claimsListKey))); ImmutableSet.of(getCrossTldKey(), tmchCrlKey)));
runAndAssertSuccess(now.minusMinutes(1), 1, 1); runAndAssertSuccess(now.minusMinutes(1), 1, 1);
verify(spy, times(0)).delete(any(VKey.class)); verify(spy, times(0)).delete(any(VKey.class));

View file

@ -758,11 +758,11 @@ class EppLifecycleDomainTest extends EppTestCase {
.hasResponse( .hasResponse(
"poll_response_autorenew.xml", "poll_response_autorenew.xml",
ImmutableMap.of( ImmutableMap.of(
"ID", "1-C-EXAMPLE-13-16-2002", "ID", "1-B-EXAMPLE-12-15-2002",
"QDATE", "2002-06-01T00:04:00Z", "QDATE", "2002-06-01T00:04:00Z",
"DOMAIN", "fakesite.example", "DOMAIN", "fakesite.example",
"EXDATE", "2003-06-01T00:04:00Z")); "EXDATE", "2003-06-01T00:04:00Z"));
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-C-EXAMPLE-13-16-2002")) assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-B-EXAMPLE-12-15-2002"))
.atTime("2002-07-01T00:02:00Z") .atTime("2002-07-01T00:02:00Z")
.hasResponse("poll_ack_response_empty.xml"); .hasResponse("poll_ack_response_empty.xml");
@ -776,13 +776,13 @@ class EppLifecycleDomainTest extends EppTestCase {
.hasResponse( .hasResponse(
"poll_response_autorenew.xml", "poll_response_autorenew.xml",
ImmutableMap.of( ImmutableMap.of(
"ID", "1-C-EXAMPLE-13-16-2003", // Note -- Year is different from previous ID. "ID", "1-B-EXAMPLE-12-15-2003", // Note -- Year is different from previous ID.
"QDATE", "2003-06-01T00:04:00Z", "QDATE", "2003-06-01T00:04:00Z",
"DOMAIN", "fakesite.example", "DOMAIN", "fakesite.example",
"EXDATE", "2004-06-01T00:04:00Z")); "EXDATE", "2004-06-01T00:04:00Z"));
// Ack the second poll message and verify that none remain. // Ack the second poll message and verify that none remain.
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-C-EXAMPLE-13-16-2003")) assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-B-EXAMPLE-12-15-2003"))
.atTime("2003-07-01T00:05:05Z") .atTime("2003-07-01T00:05:05Z")
.hasResponse("poll_ack_response_empty.xml"); .hasResponse("poll_ack_response_empty.xml");
assertThatCommand("poll.xml") assertThatCommand("poll.xml")
@ -812,7 +812,7 @@ class EppLifecycleDomainTest extends EppTestCase {
// As the losing registrar, read the request poll message, and then ack it. // As the losing registrar, read the request poll message, and then ack it.
assertThatLoginSucceeds("NewRegistrar", "foo-BAR2"); assertThatLoginSucceeds("NewRegistrar", "foo-BAR2");
String messageId = "1-C-EXAMPLE-19-25-2001"; String messageId = "1-B-EXAMPLE-18-24-2001";
assertThatCommand("poll.xml") assertThatCommand("poll.xml")
.atTime("2001-01-01T00:01:00Z") .atTime("2001-01-01T00:01:00Z")
.hasResponse("poll_response_domain_transfer_request.xml", ImmutableMap.of("ID", messageId)); .hasResponse("poll_response_domain_transfer_request.xml", ImmutableMap.of("ID", messageId));
@ -821,7 +821,7 @@ class EppLifecycleDomainTest extends EppTestCase {
.hasResponse("poll_ack_response_empty.xml"); .hasResponse("poll_ack_response_empty.xml");
// Five days in the future, expect a server approval poll message to the loser, and ack it. // Five days in the future, expect a server approval poll message to the loser, and ack it.
messageId = "1-C-EXAMPLE-19-24-2001"; messageId = "1-B-EXAMPLE-18-23-2001";
assertThatCommand("poll.xml") assertThatCommand("poll.xml")
.atTime("2001-01-06T00:01:00Z") .atTime("2001-01-06T00:01:00Z")
.hasResponse( .hasResponse(
@ -833,7 +833,7 @@ class EppLifecycleDomainTest extends EppTestCase {
assertThatLogoutSucceeds(); assertThatLogoutSucceeds();
// Also expect a server approval poll message to the winner, with the transfer request trid. // Also expect a server approval poll message to the winner, with the transfer request trid.
messageId = "1-C-EXAMPLE-19-23-2001"; messageId = "1-B-EXAMPLE-18-22-2001";
assertThatLoginSucceeds("TheRegistrar", "password2"); assertThatLoginSucceeds("TheRegistrar", "password2");
assertThatCommand("poll.xml") assertThatCommand("poll.xml")
.atTime("2001-01-06T00:02:00Z") .atTime("2001-01-06T00:02:00Z")

View file

@ -20,10 +20,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension; import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.testing.DatastoreEntityExtension;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
@ -36,10 +34,6 @@ public class ClaimsListDaoTest {
final JpaIntegrationWithCoverageExtension jpa = final JpaIntegrationWithCoverageExtension jpa =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension(); new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
@RegisterExtension
@Order(value = 1)
final DatastoreEntityExtension datastoreEntityExtension = new DatastoreEntityExtension();
@Test @Test
void save_insertsClaimsListSuccessfully() { void save_insertsClaimsListSuccessfully() {
ClaimsList claimsList = ClaimsList claimsList =

View file

@ -109,7 +109,7 @@ class EppLifecycleToolsTest extends EppTestCase {
.atTime("2001-06-08T00:00:00Z") .atTime("2001-06-08T00:00:00Z")
.hasResponse("poll_response_unrenew.xml"); .hasResponse("poll_response_unrenew.xml");
assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-8-TLD-21-22-2001")) assertThatCommand("poll_ack.xml", ImmutableMap.of("ID", "1-7-TLD-20-21-2001"))
.atTime("2001-06-08T00:00:01Z") .atTime("2001-06-08T00:00:01Z")
.hasResponse("poll_ack_response_empty.xml"); .hasResponse("poll_ack_response_empty.xml");
@ -130,7 +130,7 @@ class EppLifecycleToolsTest extends EppTestCase {
.hasResponse( .hasResponse(
"poll_response_autorenew.xml", "poll_response_autorenew.xml",
ImmutableMap.of( ImmutableMap.of(
"ID", "1-8-TLD-21-24-2003", "ID", "1-7-TLD-20-23-2003",
"QDATE", "2003-06-01T00:02:00Z", "QDATE", "2003-06-01T00:02:00Z",
"DOMAIN", "example.tld", "DOMAIN", "example.tld",
"EXDATE", "2004-06-01T00:02:00Z")); "EXDATE", "2004-06-01T00:02:00Z"));

View file

@ -1,5 +1,3 @@
ClaimsList
ClaimsListSingleton
Cursor Cursor
Registrar Registrar
RegistrarContact RegistrarContact

View file

@ -3,7 +3,7 @@
<result code="1301"> <result code="1301">
<msg>Command completed successfully; ack to dequeue</msg> <msg>Command completed successfully; ack to dequeue</msg>
</result> </result>
<msgQ count="1" id="1-8-TLD-21-22-2001"> <msgQ count="1" id="1-7-TLD-20-21-2001">
<qDate>2001-06-07T00:00:00Z</qDate> <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> <msg>Domain example.tld was unrenewed by 3 years; now expires at 2003-06-01T00:02:00.000Z.</msg>
</msgQ> </msgQ>

View file

@ -789,21 +789,6 @@ enum google.registry.model.tld.Registry$TldType {
REAL; REAL;
TEST; TEST;
} }
class google.registry.model.tmch.ClaimsList {
@Id long id;
@Parent com.googlecode.objectify.Key<google.registry.model.tmch.ClaimsList$ClaimsListRevision> parent;
com.google.common.collect.ImmutableMap<java.lang.String, java.lang.String> labelsToKeys;
org.joda.time.DateTime creationTime;
}
class google.registry.model.tmch.ClaimsList$ClaimsListRevision {
@Id long versionId;
@Parent com.googlecode.objectify.Key<google.registry.model.tmch.ClaimsList$ClaimsListSingleton> parent;
}
class google.registry.model.tmch.ClaimsList$ClaimsListSingleton {
@Id long id;
@Parent com.googlecode.objectify.Key<google.registry.model.common.EntityGroupRoot> parent;
com.googlecode.objectify.Key<google.registry.model.tmch.ClaimsList$ClaimsListRevision> activeRevision;
}
class google.registry.model.tmch.TmchCrl { class google.registry.model.tmch.TmchCrl {
@Id long id; @Id long id;
@Parent com.googlecode.objectify.Key<google.registry.model.common.EntityGroupRoot> parent; @Parent com.googlecode.objectify.Key<google.registry.model.common.EntityGroupRoot> parent;