diff --git a/core/src/main/java/google/registry/model/common/Cursor.java b/core/src/main/java/google/registry/model/common/Cursor.java index 9e8a88c25..1339076af 100644 --- a/core/src/main/java/google/registry/model/common/Cursor.java +++ b/core/src/main/java/google/registry/model/common/Cursor.java @@ -21,6 +21,7 @@ import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.util.DateTimeUtils.START_OF_TIME; import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; @@ -28,6 +29,8 @@ import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; import google.registry.model.UpdateAutoTimestamp; import google.registry.model.registry.Registry; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import java.util.List; import org.joda.time.DateTime; @@ -37,7 +40,7 @@ import org.joda.time.DateTime; * as scoped on {@link EntityGroupRoot}. */ @Entity -public class Cursor extends ImmutableObject { +public class Cursor extends ImmutableObject implements DatastoreEntity { /** The types of cursors, used as the string id field for each cursor in Datastore. */ public enum CursorType { @@ -134,6 +137,11 @@ public class Cursor extends ImmutableObject { return CursorType.valueOf(String.join("_", id.subList(1, id.size()))); } + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // Cursors are not converted since they are ephemeral + } + /** * Checks that the type of the scoped object (or null) matches the required type for the specified * cursor (or null, if the cursor is a global cursor). diff --git a/core/src/main/java/google/registry/model/common/EntityGroupRoot.java b/core/src/main/java/google/registry/model/common/EntityGroupRoot.java index 29bc9db3f..11a9af336 100644 --- a/core/src/main/java/google/registry/model/common/EntityGroupRoot.java +++ b/core/src/main/java/google/registry/model/common/EntityGroupRoot.java @@ -14,10 +14,13 @@ package google.registry.model.common; +import com.google.common.collect.ImmutableList; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import google.registry.model.BackupGroupRoot; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; /** * The root key for the entity group which is known as the cross-tld entity group for historical @@ -34,7 +37,7 @@ import google.registry.model.BackupGroupRoot; * the entity group for the single namespace where global data applicable for all TLDs lived. */ @Entity -public class EntityGroupRoot extends BackupGroupRoot { +public class EntityGroupRoot extends BackupGroupRoot implements DatastoreEntity { @SuppressWarnings("unused") @Id @@ -44,4 +47,9 @@ public class EntityGroupRoot extends BackupGroupRoot { public static Key getCrossTldKey() { return Key.create(EntityGroupRoot.class, "cross-tld"); } + + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // not persisted in SQL + } } diff --git a/core/src/main/java/google/registry/model/contact/ContactResource.java b/core/src/main/java/google/registry/model/contact/ContactResource.java index f459677ae..ad526f9f7 100644 --- a/core/src/main/java/google/registry/model/contact/ContactResource.java +++ b/core/src/main/java/google/registry/model/contact/ContactResource.java @@ -30,6 +30,7 @@ import google.registry.model.annotations.ExternalMessagingName; import google.registry.model.annotations.ReportedOn; import google.registry.model.contact.PostalInfo.Type; import google.registry.model.transfer.TransferData; +import google.registry.schema.replay.DatastoreAndSqlEntity; import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; @@ -60,7 +61,7 @@ import org.joda.time.DateTime; }) @ExternalMessagingName("contact") public class ContactResource extends EppResource - implements ForeignKeyedEppResource, ResourceWithTransferData { + implements DatastoreAndSqlEntity, ForeignKeyedEppResource, ResourceWithTransferData { /** * Unique identifier for this contact. 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 3e6127a72..50fbc01f7 100644 --- a/core/src/main/java/google/registry/model/domain/DomainBase.java +++ b/core/src/main/java/google/registry/model/domain/DomainBase.java @@ -107,7 +107,7 @@ import org.joda.time.Interval; }) @ExternalMessagingName("domain") public class DomainBase extends EppResource - implements ForeignKeyedEppResource, ResourceWithTransferData, DatastoreAndSqlEntity { + implements DatastoreAndSqlEntity, ForeignKeyedEppResource, ResourceWithTransferData { /** The max number of years that a domain can be registered for, as set by ICANN policy. */ public static final int MAX_REGISTRATION_YEARS = 10; diff --git a/core/src/main/java/google/registry/model/host/HostResource.java b/core/src/main/java/google/registry/model/host/HostResource.java index 4e806d143..d51f1ffcb 100644 --- a/core/src/main/java/google/registry/model/host/HostResource.java +++ b/core/src/main/java/google/registry/model/host/HostResource.java @@ -35,6 +35,7 @@ import google.registry.model.domain.DomainBase; import google.registry.model.transfer.TransferData; import google.registry.persistence.VKey; import google.registry.persistence.WithStringVKey; +import google.registry.schema.replay.DatastoreAndSqlEntity; import java.net.InetAddress; import java.util.Optional; import java.util.Set; @@ -55,7 +56,8 @@ import org.joda.time.DateTime; @javax.persistence.Entity @ExternalMessagingName("host") @WithStringVKey -public class HostResource extends EppResource implements ForeignKeyedEppResource { +public class HostResource extends EppResource + implements DatastoreAndSqlEntity, ForeignKeyedEppResource { /** * Fully qualified hostname, which is a unique identifier for this host. diff --git a/core/src/main/java/google/registry/model/ofy/CommitLogBucket.java b/core/src/main/java/google/registry/model/ofy/CommitLogBucket.java index f1f5dbe28..bf9266e61 100644 --- a/core/src/main/java/google/registry/model/ofy/CommitLogBucket.java +++ b/core/src/main/java/google/registry/model/ofy/CommitLogBucket.java @@ -22,6 +22,7 @@ import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.util.DateTimeUtils.START_OF_TIME; import com.google.common.collect.ContiguousSet; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Range; @@ -33,6 +34,8 @@ import google.registry.model.Buildable; import google.registry.model.ImmutableObject; import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp.Reason; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import google.registry.util.NonFinalForTesting; import java.util.Random; import java.util.function.Supplier; @@ -51,7 +54,7 @@ import org.joda.time.DateTime; */ @Entity @NotBackedUp(reason = Reason.COMMIT_LOGS) -public class CommitLogBucket extends ImmutableObject implements Buildable { +public class CommitLogBucket extends ImmutableObject implements Buildable, DatastoreEntity { /** * Ranges from 1 to {@link RegistryConfig#getCommitLogBucketCount()}, inclusive; starts at 1 since @@ -70,6 +73,11 @@ public class CommitLogBucket extends ImmutableObject implements Buildable { return lastWrittenTime; } + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // not persisted in SQL + } + /** * Returns the key for the specified bucket ID. * diff --git a/core/src/main/java/google/registry/model/ofy/CommitLogCheckpoint.java b/core/src/main/java/google/registry/model/ofy/CommitLogCheckpoint.java index 771725723..6a9fb712b 100644 --- a/core/src/main/java/google/registry/model/ofy/CommitLogCheckpoint.java +++ b/core/src/main/java/google/registry/model/ofy/CommitLogCheckpoint.java @@ -27,6 +27,8 @@ import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp.Reason; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -44,7 +46,7 @@ import org.joda.time.DateTime; */ @Entity @NotBackedUp(reason = Reason.COMMIT_LOGS) -public class CommitLogCheckpoint extends ImmutableObject { +public class CommitLogCheckpoint extends ImmutableObject implements DatastoreEntity { /** Shared singleton parent entity for commit log checkpoints. */ @Parent @@ -71,6 +73,11 @@ public class CommitLogCheckpoint extends ImmutableObject { return builder.build(); } + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // not persisted in SQL + } + /** * Creates a CommitLogCheckpoint for the given wall time and bucket checkpoint times, specified as * a map from bucket ID to bucket commit timestamp. diff --git a/core/src/main/java/google/registry/model/ofy/CommitLogCheckpointRoot.java b/core/src/main/java/google/registry/model/ofy/CommitLogCheckpointRoot.java index 041b8e89d..79bc14b7c 100644 --- a/core/src/main/java/google/registry/model/ofy/CommitLogCheckpointRoot.java +++ b/core/src/main/java/google/registry/model/ofy/CommitLogCheckpointRoot.java @@ -17,12 +17,15 @@ package google.registry.model.ofy; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.util.DateTimeUtils.START_OF_TIME; +import com.google.common.collect.ImmutableList; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import google.registry.model.ImmutableObject; import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp.Reason; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import org.joda.time.DateTime; /** @@ -30,7 +33,7 @@ import org.joda.time.DateTime; */ @Entity @NotBackedUp(reason = Reason.COMMIT_LOGS) -public class CommitLogCheckpointRoot extends ImmutableObject { +public class CommitLogCheckpointRoot extends ImmutableObject implements DatastoreEntity { public static final long SINGLETON_ID = 1; // There is always exactly one of these. @@ -49,6 +52,11 @@ public class CommitLogCheckpointRoot extends ImmutableObject { return lastWrittenTime; } + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // not persisted in SQL + } + public static CommitLogCheckpointRoot loadRoot() { CommitLogCheckpointRoot root = ofy().load().key(getKey()).now(); return root == null ? new CommitLogCheckpointRoot() : root; diff --git a/core/src/main/java/google/registry/model/ofy/CommitLogManifest.java b/core/src/main/java/google/registry/model/ofy/CommitLogManifest.java index b75be844e..5bc07ed8f 100644 --- a/core/src/main/java/google/registry/model/ofy/CommitLogManifest.java +++ b/core/src/main/java/google/registry/model/ofy/CommitLogManifest.java @@ -17,6 +17,7 @@ package google.registry.model.ofy; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static org.joda.time.DateTimeZone.UTC; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; @@ -25,6 +26,8 @@ import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp.Reason; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import java.util.LinkedHashSet; import java.util.Set; import org.joda.time.DateTime; @@ -38,7 +41,7 @@ import org.joda.time.DateTime; */ @Entity @NotBackedUp(reason = Reason.COMMIT_LOGS) -public class CommitLogManifest extends ImmutableObject { +public class CommitLogManifest extends ImmutableObject implements DatastoreEntity { /** Commit log manifests are parented on a random bucket. */ @Parent @@ -67,6 +70,11 @@ public class CommitLogManifest extends ImmutableObject { return nullToEmptyImmutableCopy(deletions); } + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // not persisted in SQL + } + public static CommitLogManifest create( Key parent, DateTime commitTime, Set> deletions) { CommitLogManifest instance = new CommitLogManifest(); diff --git a/core/src/main/java/google/registry/model/ofy/CommitLogMutation.java b/core/src/main/java/google/registry/model/ofy/CommitLogMutation.java index ffeafe80e..61942b073 100644 --- a/core/src/main/java/google/registry/model/ofy/CommitLogMutation.java +++ b/core/src/main/java/google/registry/model/ofy/CommitLogMutation.java @@ -21,6 +21,7 @@ import static google.registry.model.ofy.ObjectifyService.ofy; import com.google.appengine.api.datastore.KeyFactory; import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; @@ -28,11 +29,13 @@ import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp.Reason; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; /** Representation of a saved entity in a {@link CommitLogManifest} (not deletes). */ @Entity @NotBackedUp(reason = Reason.COMMIT_LOGS) -public class CommitLogMutation extends ImmutableObject { +public class CommitLogMutation extends ImmutableObject implements DatastoreEntity { /** The manifest this belongs to. */ @Parent @@ -58,6 +61,11 @@ public class CommitLogMutation extends ImmutableObject { return createFromPbBytes(entityProtoBytes); } + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // not persisted in SQL + } + /** * Returns a new mutation entity created from an @Entity ImmutableObject instance. * 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 4758e1dda..4594e8eec 100644 --- a/core/src/main/java/google/registry/model/registrar/Registrar.java +++ b/core/src/main/java/google/registry/model/registrar/Registrar.java @@ -109,7 +109,7 @@ import org.joda.time.DateTime; name = "registrar_iana_identifier_idx"), }) public class Registrar extends ImmutableObject - implements Buildable, Jsonifiable, DatastoreAndSqlEntity { + implements Buildable, DatastoreAndSqlEntity, Jsonifiable { /** Represents the type of a registrar entity. */ public enum Type { diff --git a/core/src/main/java/google/registry/model/registrar/RegistrarContact.java b/core/src/main/java/google/registry/model/registrar/RegistrarContact.java index 2255522fe..dce8d9bd4 100644 --- a/core/src/main/java/google/registry/model/registrar/RegistrarContact.java +++ b/core/src/main/java/google/registry/model/registrar/RegistrarContact.java @@ -42,6 +42,7 @@ import google.registry.model.ImmutableObject; import google.registry.model.JsonMapBuilder; import google.registry.model.Jsonifiable; import google.registry.model.annotations.ReportedOn; +import google.registry.schema.replay.DatastoreAndSqlEntity; import java.util.Arrays; import java.util.Map; import java.util.Optional; @@ -68,7 +69,8 @@ import javax.persistence.Transient; @javax.persistence.Index(columnList = "gaeUserId", name = "registrarpoc_gae_user_id_idx") }) // TODO(shicong): Rename the class name to RegistrarPoc after database migration -public class RegistrarContact extends ImmutableObject implements Jsonifiable { +public class RegistrarContact extends ImmutableObject + implements DatastoreAndSqlEntity, Jsonifiable { @Parent @Transient Key parent; diff --git a/core/src/main/java/google/registry/model/registry/label/PremiumList.java b/core/src/main/java/google/registry/model/registry/label/PremiumList.java index a2fdf756e..e94ce784c 100644 --- a/core/src/main/java/google/registry/model/registry/label/PremiumList.java +++ b/core/src/main/java/google/registry/model/registry/label/PremiumList.java @@ -31,6 +31,7 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader.InvalidCacheLoadException; import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableList; import com.google.common.hash.BloomFilter; import com.google.common.util.concurrent.UncheckedExecutionException; import com.googlecode.objectify.Key; @@ -41,6 +42,8 @@ import google.registry.model.Buildable; import google.registry.model.ImmutableObject; import google.registry.model.annotations.ReportedOn; import google.registry.model.registry.Registry; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import google.registry.util.NonFinalForTesting; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -53,26 +56,28 @@ import javax.annotation.Nullable; import org.joda.money.Money; import org.joda.time.Duration; -/** - * A premium list entity, persisted to Datastore, that is used to check domain label prices. - */ +/** A premium list entity, persisted to Datastore, that is used to check domain label prices. */ @ReportedOn @Entity -public final class PremiumList extends BaseDomainLabelList { +public final class PremiumList extends BaseDomainLabelList + implements DatastoreEntity { /** Stores the revision key for the set of currently used premium list entry entities. */ Key revisionKey; + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // PremiumList is dual-written + } + /** Virtual parent entity for premium list entry entities associated with a single revision. */ @ReportedOn @Entity public static class PremiumListRevision extends ImmutableObject { - @Parent - Key parent; + @Parent Key parent; - @Id - long revisionId; + @Id long revisionId; /** * A Bloom filter that is used to determine efficiently and quickly whether a label might be @@ -249,7 +254,7 @@ public final class PremiumList extends BaseDomainLabelList - implements Buildable { + implements Buildable, DatastoreEntity { @Parent Key parent; @@ -266,6 +271,11 @@ public final class PremiumList extends BaseDomainLabelList toSqlEntities() { + return null; + } + /** A builder for constructing {@link PremiumListEntry} objects, since they are immutable. */ public static class Builder extends DomainLabelEntry.Builder { diff --git a/core/src/main/java/google/registry/model/registry/label/ReservedList.java b/core/src/main/java/google/registry/model/registry/label/ReservedList.java index b654c8f13..c9b725a2f 100644 --- a/core/src/main/java/google/registry/model/registry/label/ReservedList.java +++ b/core/src/main/java/google/registry/model/registry/label/ReservedList.java @@ -30,6 +30,7 @@ import com.google.common.base.Splitter; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.MapDifference; @@ -45,6 +46,8 @@ import com.googlecode.objectify.mapper.Mapper; import google.registry.model.Buildable; import google.registry.model.registry.Registry; import google.registry.model.registry.label.DomainLabelMetrics.MetricsReservedListMatch; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import google.registry.schema.tld.ReservedList.ReservedEntry; import google.registry.schema.tld.ReservedListDao; import java.util.List; @@ -59,7 +62,8 @@ import org.joda.time.DateTime; */ @Entity public final class ReservedList - extends BaseDomainLabelList { + extends BaseDomainLabelList implements + DatastoreEntity { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); @@ -68,6 +72,11 @@ public final class ReservedList boolean shouldPublish = true; + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // ReservedList is dual-written + } + /** * A reserved list entry entity, persisted to Datastore, that represents a single label and its * reservation type. diff --git a/core/src/main/java/google/registry/model/server/Lock.java b/core/src/main/java/google/registry/model/server/Lock.java index 1687e2e7e..962a93319 100644 --- a/core/src/main/java/google/registry/model/server/Lock.java +++ b/core/src/main/java/google/registry/model/server/Lock.java @@ -22,12 +22,15 @@ import static google.registry.util.DateTimeUtils.isAtOrAfter; import com.google.auto.value.AutoValue; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; import com.google.common.flogger.FluentLogger; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import google.registry.model.ImmutableObject; import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp.Reason; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import google.registry.util.RequestStatusChecker; import google.registry.util.RequestStatusCheckerImpl; import java.io.Serializable; @@ -47,7 +50,7 @@ import org.joda.time.Duration; */ @Entity @NotBackedUp(reason = Reason.TRANSIENT) -public class Lock extends ImmutableObject implements Serializable { +public class Lock extends ImmutableObject implements DatastoreEntity, Serializable { private static final long serialVersionUID = 756397280691684645L; private static final FluentLogger logger = FluentLogger.forEnclosingClass(); @@ -256,4 +259,9 @@ public class Lock extends ImmutableObject implements Serializable { } }); } + + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // Locks are not converted since they are ephemeral + } } diff --git a/core/src/main/java/google/registry/model/tmch/ClaimsListShard.java b/core/src/main/java/google/registry/model/tmch/ClaimsListShard.java index f33072f23..3e81b862b 100644 --- a/core/src/main/java/google/registry/model/tmch/ClaimsListShard.java +++ b/core/src/main/java/google/registry/model/tmch/ClaimsListShard.java @@ -26,6 +26,7 @@ import static google.registry.util.DateTimeUtils.START_OF_TIME; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.MapDifference; import com.google.common.collect.MapDifference.ValueDifference; @@ -44,6 +45,8 @@ 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.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import google.registry.schema.tmch.ClaimsList; import google.registry.schema.tmch.ClaimsListDao; import google.registry.util.CollectionUtils; @@ -75,7 +78,7 @@ import org.joda.time.DateTime; */ @Entity @NotBackedUp(reason = Reason.EXTERNALLY_SOURCED) -public class ClaimsListShard extends ImmutableObject { +public class ClaimsListShard extends ImmutableObject implements DatastoreEntity { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); @@ -289,10 +292,15 @@ public class ClaimsListShard extends ImmutableObject { } } + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // ClaimsLists are dually written + } + /** Virtual parent entity for claims list shards of a specific revision. */ @Entity @VirtualEntity - public static class ClaimsListRevision extends ImmutableObject { + public static class ClaimsListRevision extends ImmutableObject implements DatastoreEntity { @Parent Key parent; @@ -311,6 +319,11 @@ public class ClaimsListShard extends ImmutableObject { public static Key createKey() { return createKey(new ClaimsListSingleton()); } + + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // ClaimsLists are dually written + } } /** @@ -319,7 +332,7 @@ public class ClaimsListShard extends ImmutableObject { */ @Entity @NotBackedUp(reason = Reason.EXTERNALLY_SOURCED) - public static class ClaimsListSingleton extends CrossTldSingleton { + public static class ClaimsListSingleton extends CrossTldSingleton implements DatastoreEntity { Key activeRevision; static ClaimsListSingleton create(Key revision) { @@ -332,6 +345,11 @@ public class ClaimsListShard extends ImmutableObject { public void setActiveRevision(Key revision) { activeRevision = revision; } + + @Override + public ImmutableList toSqlEntities() { + return ImmutableList.of(); // ClaimsLists are dually written + } } /** diff --git a/core/src/main/java/google/registry/schema/cursor/Cursor.java b/core/src/main/java/google/registry/schema/cursor/Cursor.java index ad9f5e2c2..399ce29db 100644 --- a/core/src/main/java/google/registry/schema/cursor/Cursor.java +++ b/core/src/main/java/google/registry/schema/cursor/Cursor.java @@ -16,10 +16,13 @@ package google.registry.schema.cursor; import static com.google.appengine.api.search.checkers.Preconditions.checkNotNull; +import com.google.common.collect.ImmutableList; import google.registry.model.ImmutableObject; import google.registry.model.UpdateAutoTimestamp; import google.registry.model.common.Cursor.CursorType; import google.registry.schema.cursor.Cursor.CursorId; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import google.registry.util.DateTimeUtils; import java.io.Serializable; import java.time.ZonedDateTime; @@ -38,7 +41,7 @@ import org.joda.time.DateTime; @Entity @Table @IdClass(CursorId.class) -public class Cursor { +public class Cursor implements SqlEntity { @Enumerated(EnumType.STRING) @Column(nullable = false) @@ -100,6 +103,11 @@ public class Cursor { return lastUpdateTime.getTimestamp(); } + @Override + public ImmutableList toDatastoreEntities() { + return ImmutableList.of(); // Cursors are not converted since they are ephemeral + } + static class CursorId extends ImmutableObject implements Serializable { public CursorType type; diff --git a/core/src/main/java/google/registry/schema/domain/RegistryLock.java b/core/src/main/java/google/registry/schema/domain/RegistryLock.java index f6b2ca4e2..e20134fa3 100644 --- a/core/src/main/java/google/registry/schema/domain/RegistryLock.java +++ b/core/src/main/java/google/registry/schema/domain/RegistryLock.java @@ -19,10 +19,13 @@ import static google.registry.util.DateTimeUtils.isBeforeOrAt; import static google.registry.util.DateTimeUtils.toZonedDateTime; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; +import com.google.common.collect.ImmutableList; import google.registry.model.Buildable; import google.registry.model.CreateAutoTimestamp; import google.registry.model.ImmutableObject; import google.registry.model.UpdateAutoTimestamp; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import google.registry.util.DateTimeUtils; import java.time.ZonedDateTime; import java.util.Optional; @@ -73,7 +76,7 @@ import org.joda.time.Duration; @Index(name = "idx_registry_lock_verification_code", columnList = "verificationCode"), @Index(name = "idx_registry_lock_registrar_id", columnList = "registrarId") }) -public final class RegistryLock extends ImmutableObject implements Buildable { +public final class RegistryLock extends ImmutableObject implements Buildable, SqlEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -230,6 +233,11 @@ public final class RegistryLock extends ImmutableObject implements Buildable { return new Builder(clone(this)); } + @Override + public ImmutableList toDatastoreEntities() { + return ImmutableList.of(); // not stored in Datastore + } + /** Builder for {@link google.registry.schema.domain.RegistryLock}. */ public static class Builder extends Buildable.Builder { public Builder() {} diff --git a/core/src/main/java/google/registry/schema/server/Lock.java b/core/src/main/java/google/registry/schema/server/Lock.java index 6ddf8f818..1b3ea8f2f 100644 --- a/core/src/main/java/google/registry/schema/server/Lock.java +++ b/core/src/main/java/google/registry/schema/server/Lock.java @@ -16,7 +16,10 @@ package google.registry.schema.server; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; +import com.google.common.collect.ImmutableList; import google.registry.model.ImmutableObject; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import google.registry.schema.server.Lock.LockId; import google.registry.util.DateTimeUtils; import java.io.Serializable; @@ -40,7 +43,7 @@ import org.joda.time.Duration; @Entity @Table @IdClass(LockId.class) -public class Lock { +public class Lock implements SqlEntity { /** The resource name used to create the lock. */ @Column(nullable = false) @@ -116,6 +119,11 @@ public class Lock { return new Lock(resourceName, GLOBAL, requestLogId, acquiredTime, leaseLength); } + @Override + public ImmutableList toDatastoreEntities() { + return ImmutableList.of(); // Locks are not converted since they are ephemeral + } + static class LockId extends ImmutableObject implements Serializable { String resourceName; diff --git a/core/src/main/java/google/registry/schema/tld/PremiumEntry.java b/core/src/main/java/google/registry/schema/tld/PremiumEntry.java index 262409b21..cc5068ff4 100644 --- a/core/src/main/java/google/registry/schema/tld/PremiumEntry.java +++ b/core/src/main/java/google/registry/schema/tld/PremiumEntry.java @@ -14,7 +14,10 @@ package google.registry.schema.tld; +import com.google.common.collect.ImmutableList; import google.registry.model.ImmutableObject; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import java.io.Serializable; import java.math.BigDecimal; import javax.persistence.Column; @@ -27,7 +30,7 @@ import javax.persistence.Id; *

These are not persisted directly, but rather, using {@link PremiumList#getLabelsToPrices()}. */ @Entity -public class PremiumEntry extends ImmutableObject implements Serializable { +public class PremiumEntry extends ImmutableObject implements Serializable, SqlEntity { @Id @Column(nullable = false) @@ -41,4 +44,9 @@ public class PremiumEntry extends ImmutableObject implements Serializable { String domainLabel; private PremiumEntry() {} + + @Override + public ImmutableList toDatastoreEntities() { + return ImmutableList.of(); // PremiumList is dually-written + } } diff --git a/core/src/main/java/google/registry/schema/tld/PremiumList.java b/core/src/main/java/google/registry/schema/tld/PremiumList.java index 595da5e87..6b45c5358 100644 --- a/core/src/main/java/google/registry/schema/tld/PremiumList.java +++ b/core/src/main/java/google/registry/schema/tld/PremiumList.java @@ -18,9 +18,12 @@ import static com.google.common.base.Charsets.US_ASCII; import static com.google.common.base.Preconditions.checkState; import static com.google.common.hash.Funnels.stringFunnel; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.hash.BloomFilter; import google.registry.model.CreateAutoTimestamp; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import java.math.BigDecimal; import java.util.Map; import javax.annotation.Nullable; @@ -49,7 +52,7 @@ import org.joda.time.DateTime; */ @Entity @Table(indexes = {@Index(columnList = "name", name = "premiumlist_name_idx")}) -public class PremiumList { +public class PremiumList implements SqlEntity { @Column(nullable = false) private String name; @@ -140,4 +143,9 @@ public class PremiumList { public BloomFilter getBloomFilter() { return bloomFilter; } + + @Override + public ImmutableList toDatastoreEntities() { + return ImmutableList.of(); // PremiumList is dual-written + } } diff --git a/core/src/main/java/google/registry/schema/tld/PremiumListUtils.java b/core/src/main/java/google/registry/schema/tld/PremiumListUtils.java index 4fc3c8cdf..33fdbf226 100644 --- a/core/src/main/java/google/registry/schema/tld/PremiumListUtils.java +++ b/core/src/main/java/google/registry/schema/tld/PremiumListUtils.java @@ -54,7 +54,7 @@ public class PremiumListUtils { Map priceAmounts = Maps.transformValues(prices, ple -> ple.getValue().getAmount()); - return google.registry.schema.tld.PremiumList.create(name, currency, priceAmounts); + return PremiumList.create(name, currency, priceAmounts); } private PremiumListUtils() {} diff --git a/core/src/main/java/google/registry/schema/tld/ReservedList.java b/core/src/main/java/google/registry/schema/tld/ReservedList.java index 86a9a27ed..ce77660ae 100644 --- a/core/src/main/java/google/registry/schema/tld/ReservedList.java +++ b/core/src/main/java/google/registry/schema/tld/ReservedList.java @@ -26,6 +26,8 @@ import com.google.common.collect.ImmutableMap; import google.registry.model.CreateAutoTimestamp; import google.registry.model.ImmutableObject; import google.registry.model.registry.label.ReservationType; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import java.util.Map; import java.util.stream.Stream; import javax.annotation.Nullable; @@ -53,7 +55,7 @@ import org.joda.time.DateTime; */ @Entity @Table(indexes = {@Index(columnList = "name", name = "reservedlist_name_idx")}) -public class ReservedList extends ImmutableObject { +public class ReservedList extends ImmutableObject implements SqlEntity { @Column(nullable = false) private String name; @@ -76,6 +78,11 @@ public class ReservedList extends ImmutableObject { @MapKeyColumn(name = "domainLabel") private Map labelsToReservations; + @Override + public ImmutableList toDatastoreEntities() { + return ImmutableList.of(); // ReservedList is dual-written\ + } + @Embeddable public static class ReservedEntry extends ImmutableObject { @Column(nullable = false) diff --git a/core/src/main/java/google/registry/schema/tmch/ClaimsList.java b/core/src/main/java/google/registry/schema/tmch/ClaimsList.java index a09767dd4..2d023fa9b 100644 --- a/core/src/main/java/google/registry/schema/tmch/ClaimsList.java +++ b/core/src/main/java/google/registry/schema/tmch/ClaimsList.java @@ -18,8 +18,11 @@ import static com.google.common.base.Preconditions.checkState; import static google.registry.util.DateTimeUtils.toJodaDateTime; import static google.registry.util.DateTimeUtils.toZonedDateTime; +import com.google.common.collect.ImmutableList; import google.registry.model.CreateAutoTimestamp; import google.registry.model.ImmutableObject; +import google.registry.schema.replay.DatastoreEntity; +import google.registry.schema.replay.SqlEntity; import java.time.ZonedDateTime; import java.util.Map; import java.util.Optional; @@ -46,7 +49,7 @@ import org.joda.time.DateTime; */ @Entity @Table -public class ClaimsList extends ImmutableObject { +public class ClaimsList extends ImmutableObject implements SqlEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column @@ -105,4 +108,9 @@ public class ClaimsList extends ImmutableObject { public Optional getClaimKey(String label) { return Optional.ofNullable(labelsToKeys.get(label)); } + + @Override + public ImmutableList toDatastoreEntities() { + return ImmutableList.of(); // ClaimsList is dual-written + } } diff --git a/core/src/test/java/google/registry/persistence/converter/BloomFilterConverterTest.java b/core/src/test/java/google/registry/persistence/converter/BloomFilterConverterTest.java index e6d8fa44c..91eb2551a 100644 --- a/core/src/test/java/google/registry/persistence/converter/BloomFilterConverterTest.java +++ b/core/src/test/java/google/registry/persistence/converter/BloomFilterConverterTest.java @@ -23,6 +23,7 @@ import com.google.common.hash.BloomFilter; import google.registry.model.ImmutableObject; import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; +import google.registry.schema.replay.EntityTest.EntityForTesting; import javax.persistence.Entity; import javax.persistence.Id; import org.junit.Rule; @@ -50,6 +51,7 @@ public class BloomFilterConverterTest { } @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. + @EntityForTesting public static class TestEntity extends ImmutableObject { @Id String name = "id"; diff --git a/core/src/test/java/google/registry/persistence/converter/CreateAutoTimestampConverterTest.java b/core/src/test/java/google/registry/persistence/converter/CreateAutoTimestampConverterTest.java index 56f5d003c..b75753d88 100644 --- a/core/src/test/java/google/registry/persistence/converter/CreateAutoTimestampConverterTest.java +++ b/core/src/test/java/google/registry/persistence/converter/CreateAutoTimestampConverterTest.java @@ -20,6 +20,7 @@ import google.registry.model.CreateAutoTimestamp; import google.registry.model.ImmutableObject; import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; +import google.registry.schema.replay.EntityTest.EntityForTesting; import google.registry.testing.FakeClock; import javax.persistence.Entity; import javax.persistence.Id; @@ -66,6 +67,7 @@ public class CreateAutoTimestampConverterTest { } @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. + @EntityForTesting public static class TestEntity extends ImmutableObject { @Id String name; diff --git a/core/src/test/java/google/registry/persistence/converter/CurrencyUnitConverterTest.java b/core/src/test/java/google/registry/persistence/converter/CurrencyUnitConverterTest.java index 64de67727..790e25b74 100644 --- a/core/src/test/java/google/registry/persistence/converter/CurrencyUnitConverterTest.java +++ b/core/src/test/java/google/registry/persistence/converter/CurrencyUnitConverterTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertThrows; import google.registry.model.ImmutableObject; import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; +import google.registry.schema.replay.EntityTest.EntityForTesting; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.PersistenceException; @@ -78,6 +79,7 @@ public class CurrencyUnitConverterTest { } @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. + @EntityForTesting public static class TestEntity extends ImmutableObject { @Id String name = "id"; diff --git a/core/src/test/java/google/registry/persistence/converter/DurationConverterTest.java b/core/src/test/java/google/registry/persistence/converter/DurationConverterTest.java index c8e801bb2..c87b2e2c6 100644 --- a/core/src/test/java/google/registry/persistence/converter/DurationConverterTest.java +++ b/core/src/test/java/google/registry/persistence/converter/DurationConverterTest.java @@ -20,6 +20,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory. import google.registry.model.ImmutableObject; import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; +import google.registry.schema.replay.EntityTest.EntityForTesting; import java.math.BigInteger; import javax.persistence.Entity; import javax.persistence.Id; @@ -65,6 +66,7 @@ public class DurationConverterTest { } @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. + @EntityForTesting public static class TestEntity extends ImmutableObject { @Id String name = "id"; diff --git a/core/src/test/java/google/registry/persistence/converter/JodaMoneyConverterTest.java b/core/src/test/java/google/registry/persistence/converter/JodaMoneyConverterTest.java index a892b870c..67eff7ffd 100644 --- a/core/src/test/java/google/registry/persistence/converter/JodaMoneyConverterTest.java +++ b/core/src/test/java/google/registry/persistence/converter/JodaMoneyConverterTest.java @@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableMap; import google.registry.model.ImmutableObject; import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; +import google.registry.schema.replay.EntityTest.EntityForTesting; import java.math.BigDecimal; import java.util.Arrays; import java.util.List; @@ -149,6 +150,7 @@ public class JodaMoneyConverterTest { // Override entity name to exclude outer-class name in table name. Not necessary if class is not // inner class. The double quotes are added to conform to our schema generation convention. @Entity(name = "\"TestEntity\"") + @EntityForTesting public static class TestEntity extends ImmutableObject { @Id String name = "id"; @@ -164,6 +166,7 @@ public class JodaMoneyConverterTest { // See comments on the annotation for TestEntity above for reason. @Entity(name = "\"ComplexTestEntity\"") + @EntityForTesting // This entity is used to test column override for embedded fields and collections. public static class ComplexTestEntity extends ImmutableObject { diff --git a/core/src/test/java/google/registry/persistence/converter/UpdateAutoTimestampConverterTest.java b/core/src/test/java/google/registry/persistence/converter/UpdateAutoTimestampConverterTest.java index 4878a46ef..a6aa107a4 100644 --- a/core/src/test/java/google/registry/persistence/converter/UpdateAutoTimestampConverterTest.java +++ b/core/src/test/java/google/registry/persistence/converter/UpdateAutoTimestampConverterTest.java @@ -20,6 +20,7 @@ import google.registry.model.ImmutableObject; import google.registry.model.UpdateAutoTimestamp; import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; +import google.registry.schema.replay.EntityTest.EntityForTesting; import google.registry.testing.FakeClock; import javax.persistence.Entity; import javax.persistence.Id; @@ -77,6 +78,7 @@ public class UpdateAutoTimestampConverterTest { } @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. + @EntityForTesting public static class TestEntity extends ImmutableObject { @Id String name; diff --git a/core/src/test/java/google/registry/schema/replay/EntityTest.java b/core/src/test/java/google/registry/schema/replay/EntityTest.java index 7f430b5bf..86d5f5166 100644 --- a/core/src/test/java/google/registry/schema/replay/EntityTest.java +++ b/core/src/test/java/google/registry/schema/replay/EntityTest.java @@ -22,6 +22,10 @@ import io.github.classgraph.ClassGraph; import io.github.classgraph.ClassInfo; import io.github.classgraph.ClassInfoList; import io.github.classgraph.ScanResult; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import org.junit.Ignore; import org.junit.Test; @@ -59,7 +63,13 @@ public class EntityTest { return classInfoList.stream() .filter(ClassInfo::isStandardClass) .map(ClassInfo::loadClass) + .filter(clazz -> !clazz.isAnnotationPresent(EntityForTesting.class)) .map(Class::getName) .collect(toImmutableSet()); } + + /** Entities that are solely used for testing, to avoid scanning them in {@link EntityTest}. */ + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.RUNTIME) + public @interface EntityForTesting {} }