Implement DatastoreEntity and SqlEntity on more classes (#570)

* Implement DatastoreEntity and SqlEntity on more classes

For classes that aren't going to transition to SQL, they should just
return an empty list of SqlEntities. When reading these in from the
commit log manifests, we just won't persist anything to SQL.

By having all Datastore entity classes implement DatastoreEntity, we can
avoid potential bugs where we forget to transition some entity to SQL,
or we forget to have the capability to read back from the commit logs.

Note: the EntityTest is still @Ignore'd because there are many SQL and
Datastore classes left -- ones that we are still in the process of
converting or adding, or ones that require more complicated transitions.

Note: Locks and Cursors aren't converted (even though we could) because
they're ephemeral

* Responses to CR

Add a @EntityForTest annotation
fix null that snuck in

* Keep the test ignored for now
This commit is contained in:
gbrodman 2020-05-01 17:04:13 -04:00 committed by GitHub
parent 0e225a71c4
commit b6be22f447
31 changed files with 217 additions and 34 deletions

View file

@ -21,6 +21,7 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id; 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.ImmutableObject;
import google.registry.model.UpdateAutoTimestamp; import google.registry.model.UpdateAutoTimestamp;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import java.util.List; import java.util.List;
import org.joda.time.DateTime; import org.joda.time.DateTime;
@ -37,7 +40,7 @@ import org.joda.time.DateTime;
* as scoped on {@link EntityGroupRoot}. * as scoped on {@link EntityGroupRoot}.
*/ */
@Entity @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. */ /** The types of cursors, used as the string id field for each cursor in Datastore. */
public enum CursorType { public enum CursorType {
@ -134,6 +137,11 @@ public class Cursor extends ImmutableObject {
return CursorType.valueOf(String.join("_", id.subList(1, id.size()))); return CursorType.valueOf(String.join("_", id.subList(1, id.size())));
} }
@Override
public ImmutableList<SqlEntity> 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 * 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). * cursor (or null, if the cursor is a global cursor).

View file

@ -14,10 +14,13 @@
package google.registry.model.common; package google.registry.model.common;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Id;
import google.registry.model.BackupGroupRoot; 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 * 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. * the entity group for the single namespace where global data applicable for all TLDs lived.
*/ */
@Entity @Entity
public class EntityGroupRoot extends BackupGroupRoot { public class EntityGroupRoot extends BackupGroupRoot implements DatastoreEntity {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Id @Id
@ -44,4 +47,9 @@ public class EntityGroupRoot extends BackupGroupRoot {
public static Key<EntityGroupRoot> getCrossTldKey() { public static Key<EntityGroupRoot> getCrossTldKey() {
return Key.create(EntityGroupRoot.class, "cross-tld"); return Key.create(EntityGroupRoot.class, "cross-tld");
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // not persisted in SQL
}
} }

View file

@ -30,6 +30,7 @@ import google.registry.model.annotations.ExternalMessagingName;
import google.registry.model.annotations.ReportedOn; import google.registry.model.annotations.ReportedOn;
import google.registry.model.contact.PostalInfo.Type; import google.registry.model.contact.PostalInfo.Type;
import google.registry.model.transfer.TransferData; import google.registry.model.transfer.TransferData;
import google.registry.schema.replay.DatastoreAndSqlEntity;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -60,7 +61,7 @@ import org.joda.time.DateTime;
}) })
@ExternalMessagingName("contact") @ExternalMessagingName("contact")
public class ContactResource extends EppResource public class ContactResource extends EppResource
implements ForeignKeyedEppResource, ResourceWithTransferData { implements DatastoreAndSqlEntity, ForeignKeyedEppResource, ResourceWithTransferData {
/** /**
* Unique identifier for this contact. * Unique identifier for this contact.

View file

@ -107,7 +107,7 @@ import org.joda.time.Interval;
}) })
@ExternalMessagingName("domain") @ExternalMessagingName("domain")
public class DomainBase extends EppResource 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. */ /** 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; public static final int MAX_REGISTRATION_YEARS = 10;

View file

@ -35,6 +35,7 @@ import google.registry.model.domain.DomainBase;
import google.registry.model.transfer.TransferData; import google.registry.model.transfer.TransferData;
import google.registry.persistence.VKey; import google.registry.persistence.VKey;
import google.registry.persistence.WithStringVKey; import google.registry.persistence.WithStringVKey;
import google.registry.schema.replay.DatastoreAndSqlEntity;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@ -55,7 +56,8 @@ import org.joda.time.DateTime;
@javax.persistence.Entity @javax.persistence.Entity
@ExternalMessagingName("host") @ExternalMessagingName("host")
@WithStringVKey @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. * Fully qualified hostname, which is a unique identifier for this host.

View file

@ -22,6 +22,7 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.collect.ContiguousSet; import com.google.common.collect.ContiguousSet;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Range; import com.google.common.collect.Range;
@ -33,6 +34,8 @@ import google.registry.model.Buildable;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp;
import google.registry.model.annotations.NotBackedUp.Reason; 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 google.registry.util.NonFinalForTesting;
import java.util.Random; import java.util.Random;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -51,7 +54,7 @@ import org.joda.time.DateTime;
*/ */
@Entity @Entity
@NotBackedUp(reason = Reason.COMMIT_LOGS) @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 * 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; return lastWrittenTime;
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // not persisted in SQL
}
/** /**
* Returns the key for the specified bucket ID. * Returns the key for the specified bucket ID.
* *

View file

@ -27,6 +27,8 @@ import com.googlecode.objectify.annotation.Parent;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp;
import google.registry.model.annotations.NotBackedUp.Reason; 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.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -44,7 +46,7 @@ import org.joda.time.DateTime;
*/ */
@Entity @Entity
@NotBackedUp(reason = Reason.COMMIT_LOGS) @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. */ /** Shared singleton parent entity for commit log checkpoints. */
@Parent @Parent
@ -71,6 +73,11 @@ public class CommitLogCheckpoint extends ImmutableObject {
return builder.build(); return builder.build();
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // not persisted in SQL
}
/** /**
* Creates a CommitLogCheckpoint for the given wall time and bucket checkpoint times, specified as * Creates a CommitLogCheckpoint for the given wall time and bucket checkpoint times, specified as
* a map from bucket ID to bucket commit timestamp. * a map from bucket ID to bucket commit timestamp.

View file

@ -17,12 +17,15 @@ package google.registry.model.ofy;
import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Id;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp;
import google.registry.model.annotations.NotBackedUp.Reason; import google.registry.model.annotations.NotBackedUp.Reason;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import org.joda.time.DateTime; import org.joda.time.DateTime;
/** /**
@ -30,7 +33,7 @@ import org.joda.time.DateTime;
*/ */
@Entity @Entity
@NotBackedUp(reason = Reason.COMMIT_LOGS) @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. 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; return lastWrittenTime;
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // not persisted in SQL
}
public static CommitLogCheckpointRoot loadRoot() { public static CommitLogCheckpointRoot loadRoot() {
CommitLogCheckpointRoot root = ofy().load().key(getKey()).now(); CommitLogCheckpointRoot root = ofy().load().key(getKey()).now();
return root == null ? new CommitLogCheckpointRoot() : root; return root == null ? new CommitLogCheckpointRoot() : root;

View file

@ -17,6 +17,7 @@ package google.registry.model.ofy;
import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static org.joda.time.DateTimeZone.UTC; import static org.joda.time.DateTimeZone.UTC;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity; 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.ImmutableObject;
import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp;
import google.registry.model.annotations.NotBackedUp.Reason; 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.LinkedHashSet;
import java.util.Set; import java.util.Set;
import org.joda.time.DateTime; import org.joda.time.DateTime;
@ -38,7 +41,7 @@ import org.joda.time.DateTime;
*/ */
@Entity @Entity
@NotBackedUp(reason = Reason.COMMIT_LOGS) @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. */ /** Commit log manifests are parented on a random bucket. */
@Parent @Parent
@ -67,6 +70,11 @@ public class CommitLogManifest extends ImmutableObject {
return nullToEmptyImmutableCopy(deletions); return nullToEmptyImmutableCopy(deletions);
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // not persisted in SQL
}
public static CommitLogManifest create( public static CommitLogManifest create(
Key<CommitLogBucket> parent, DateTime commitTime, Set<Key<?>> deletions) { Key<CommitLogBucket> parent, DateTime commitTime, Set<Key<?>> deletions) {
CommitLogManifest instance = new CommitLogManifest(); CommitLogManifest instance = new CommitLogManifest();

View file

@ -21,6 +21,7 @@ import static google.registry.model.ofy.ObjectifyService.ofy;
import com.google.appengine.api.datastore.KeyFactory; import com.google.appengine.api.datastore.KeyFactory;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id; 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.ImmutableObject;
import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp;
import google.registry.model.annotations.NotBackedUp.Reason; 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). */ /** Representation of a saved entity in a {@link CommitLogManifest} (not deletes). */
@Entity @Entity
@NotBackedUp(reason = Reason.COMMIT_LOGS) @NotBackedUp(reason = Reason.COMMIT_LOGS)
public class CommitLogMutation extends ImmutableObject { public class CommitLogMutation extends ImmutableObject implements DatastoreEntity {
/** The manifest this belongs to. */ /** The manifest this belongs to. */
@Parent @Parent
@ -58,6 +61,11 @@ public class CommitLogMutation extends ImmutableObject {
return createFromPbBytes(entityProtoBytes); return createFromPbBytes(entityProtoBytes);
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // not persisted in SQL
}
/** /**
* Returns a new mutation entity created from an @Entity ImmutableObject instance. * Returns a new mutation entity created from an @Entity ImmutableObject instance.
* *

View file

@ -109,7 +109,7 @@ import org.joda.time.DateTime;
name = "registrar_iana_identifier_idx"), name = "registrar_iana_identifier_idx"),
}) })
public class Registrar extends ImmutableObject public class Registrar extends ImmutableObject
implements Buildable, Jsonifiable, DatastoreAndSqlEntity { implements Buildable, DatastoreAndSqlEntity, Jsonifiable {
/** Represents the type of a registrar entity. */ /** Represents the type of a registrar entity. */
public enum Type { public enum Type {

View file

@ -42,6 +42,7 @@ import google.registry.model.ImmutableObject;
import google.registry.model.JsonMapBuilder; import google.registry.model.JsonMapBuilder;
import google.registry.model.Jsonifiable; import google.registry.model.Jsonifiable;
import google.registry.model.annotations.ReportedOn; import google.registry.model.annotations.ReportedOn;
import google.registry.schema.replay.DatastoreAndSqlEntity;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -68,7 +69,8 @@ import javax.persistence.Transient;
@javax.persistence.Index(columnList = "gaeUserId", name = "registrarpoc_gae_user_id_idx") @javax.persistence.Index(columnList = "gaeUserId", name = "registrarpoc_gae_user_id_idx")
}) })
// TODO(shicong): Rename the class name to RegistrarPoc after database migration // 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<Registrar> parent; @Parent @Transient Key<Registrar> parent;

View file

@ -31,6 +31,7 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.CacheLoader.InvalidCacheLoadException; import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.hash.BloomFilter; import com.google.common.hash.BloomFilter;
import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.common.util.concurrent.UncheckedExecutionException;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
@ -41,6 +42,8 @@ import google.registry.model.Buildable;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.model.annotations.ReportedOn; import google.registry.model.annotations.ReportedOn;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import google.registry.util.NonFinalForTesting; import google.registry.util.NonFinalForTesting;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -53,26 +56,28 @@ import javax.annotation.Nullable;
import org.joda.money.Money; import org.joda.money.Money;
import org.joda.time.Duration; 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 @ReportedOn
@Entity @Entity
public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.PremiumListEntry> { public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.PremiumListEntry>
implements DatastoreEntity {
/** Stores the revision key for the set of currently used premium list entry entities. */ /** Stores the revision key for the set of currently used premium list entry entities. */
Key<PremiumListRevision> revisionKey; Key<PremiumListRevision> revisionKey;
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // PremiumList is dual-written
}
/** Virtual parent entity for premium list entry entities associated with a single revision. */ /** Virtual parent entity for premium list entry entities associated with a single revision. */
@ReportedOn @ReportedOn
@Entity @Entity
public static class PremiumListRevision extends ImmutableObject { public static class PremiumListRevision extends ImmutableObject {
@Parent @Parent Key<PremiumList> parent;
Key<PremiumList> parent;
@Id @Id long revisionId;
long revisionId;
/** /**
* A Bloom filter that is used to determine efficiently and quickly whether a label might be * 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<Money, PremiumList.Pr
@ReportedOn @ReportedOn
@Entity @Entity
public static class PremiumListEntry extends DomainLabelEntry<Money, PremiumListEntry> public static class PremiumListEntry extends DomainLabelEntry<Money, PremiumListEntry>
implements Buildable { implements Buildable, DatastoreEntity {
@Parent @Parent
Key<PremiumListRevision> parent; Key<PremiumListRevision> parent;
@ -266,6 +271,11 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
return new Builder(clone(this)); return new Builder(clone(this));
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return null;
}
/** A builder for constructing {@link PremiumListEntry} objects, since they are immutable. */ /** A builder for constructing {@link PremiumListEntry} objects, since they are immutable. */
public static class Builder extends DomainLabelEntry.Builder<PremiumListEntry, Builder> { public static class Builder extends DomainLabelEntry.Builder<PremiumListEntry, Builder> {

View file

@ -30,6 +30,7 @@ import com.google.common.base.Splitter;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.MapDifference; 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.Buildable;
import google.registry.model.registry.Registry; import google.registry.model.registry.Registry;
import google.registry.model.registry.label.DomainLabelMetrics.MetricsReservedListMatch; 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.ReservedList.ReservedEntry;
import google.registry.schema.tld.ReservedListDao; import google.registry.schema.tld.ReservedListDao;
import java.util.List; import java.util.List;
@ -59,7 +62,8 @@ import org.joda.time.DateTime;
*/ */
@Entity @Entity
public final class ReservedList public final class ReservedList
extends BaseDomainLabelList<ReservationType, ReservedList.ReservedListEntry> { extends BaseDomainLabelList<ReservationType, ReservedList.ReservedListEntry> implements
DatastoreEntity {
private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@ -68,6 +72,11 @@ public final class ReservedList
boolean shouldPublish = true; boolean shouldPublish = true;
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // ReservedList is dual-written
}
/** /**
* A reserved list entry entity, persisted to Datastore, that represents a single label and its * A reserved list entry entity, persisted to Datastore, that represents a single label and its
* reservation type. * reservation type.

View file

@ -22,12 +22,15 @@ import static google.registry.util.DateTimeUtils.isAtOrAfter;
import com.google.auto.value.AutoValue; import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger; import com.google.common.flogger.FluentLogger;
import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Id;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp;
import google.registry.model.annotations.NotBackedUp.Reason; 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.RequestStatusChecker;
import google.registry.util.RequestStatusCheckerImpl; import google.registry.util.RequestStatusCheckerImpl;
import java.io.Serializable; import java.io.Serializable;
@ -47,7 +50,7 @@ import org.joda.time.Duration;
*/ */
@Entity @Entity
@NotBackedUp(reason = Reason.TRANSIENT) @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 long serialVersionUID = 756397280691684645L;
private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@ -256,4 +259,9 @@ public class Lock extends ImmutableObject implements Serializable {
} }
}); });
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // Locks are not converted since they are ephemeral
}
} }

View file

@ -26,6 +26,7 @@ import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.MapDifference; import com.google.common.collect.MapDifference;
import com.google.common.collect.MapDifference.ValueDifference; 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.NotBackedUp.Reason;
import google.registry.model.annotations.VirtualEntity; import google.registry.model.annotations.VirtualEntity;
import google.registry.model.common.CrossTldSingleton; 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.ClaimsList;
import google.registry.schema.tmch.ClaimsListDao; import google.registry.schema.tmch.ClaimsListDao;
import google.registry.util.CollectionUtils; import google.registry.util.CollectionUtils;
@ -75,7 +78,7 @@ import org.joda.time.DateTime;
*/ */
@Entity @Entity
@NotBackedUp(reason = Reason.EXTERNALLY_SOURCED) @NotBackedUp(reason = Reason.EXTERNALLY_SOURCED)
public class ClaimsListShard extends ImmutableObject { public class ClaimsListShard extends ImmutableObject implements DatastoreEntity {
private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@ -289,10 +292,15 @@ public class ClaimsListShard extends ImmutableObject {
} }
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // ClaimsLists are dually written
}
/** Virtual parent entity for claims list shards of a specific revision. */ /** Virtual parent entity for claims list shards of a specific revision. */
@Entity @Entity
@VirtualEntity @VirtualEntity
public static class ClaimsListRevision extends ImmutableObject { public static class ClaimsListRevision extends ImmutableObject implements DatastoreEntity {
@Parent @Parent
Key<ClaimsListSingleton> parent; Key<ClaimsListSingleton> parent;
@ -311,6 +319,11 @@ public class ClaimsListShard extends ImmutableObject {
public static Key<ClaimsListRevision> createKey() { public static Key<ClaimsListRevision> createKey() {
return createKey(new ClaimsListSingleton()); return createKey(new ClaimsListSingleton());
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // ClaimsLists are dually written
}
} }
/** /**
@ -319,7 +332,7 @@ public class ClaimsListShard extends ImmutableObject {
*/ */
@Entity @Entity
@NotBackedUp(reason = Reason.EXTERNALLY_SOURCED) @NotBackedUp(reason = Reason.EXTERNALLY_SOURCED)
public static class ClaimsListSingleton extends CrossTldSingleton { public static class ClaimsListSingleton extends CrossTldSingleton implements DatastoreEntity {
Key<ClaimsListRevision> activeRevision; Key<ClaimsListRevision> activeRevision;
static ClaimsListSingleton create(Key<ClaimsListRevision> revision) { static ClaimsListSingleton create(Key<ClaimsListRevision> revision) {
@ -332,6 +345,11 @@ public class ClaimsListShard extends ImmutableObject {
public void setActiveRevision(Key<ClaimsListRevision> revision) { public void setActiveRevision(Key<ClaimsListRevision> revision) {
activeRevision = revision; activeRevision = revision;
} }
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // ClaimsLists are dually written
}
} }
/** /**

View file

@ -16,10 +16,13 @@ package google.registry.schema.cursor;
import static com.google.appengine.api.search.checkers.Preconditions.checkNotNull; 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.ImmutableObject;
import google.registry.model.UpdateAutoTimestamp; import google.registry.model.UpdateAutoTimestamp;
import google.registry.model.common.Cursor.CursorType; import google.registry.model.common.Cursor.CursorType;
import google.registry.schema.cursor.Cursor.CursorId; 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 google.registry.util.DateTimeUtils;
import java.io.Serializable; import java.io.Serializable;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
@ -38,7 +41,7 @@ import org.joda.time.DateTime;
@Entity @Entity
@Table @Table
@IdClass(CursorId.class) @IdClass(CursorId.class)
public class Cursor { public class Cursor implements SqlEntity {
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Column(nullable = false) @Column(nullable = false)
@ -100,6 +103,11 @@ public class Cursor {
return lastUpdateTime.getTimestamp(); return lastUpdateTime.getTimestamp();
} }
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // Cursors are not converted since they are ephemeral
}
static class CursorId extends ImmutableObject implements Serializable { static class CursorId extends ImmutableObject implements Serializable {
public CursorType type; public CursorType type;

View file

@ -19,10 +19,13 @@ import static google.registry.util.DateTimeUtils.isBeforeOrAt;
import static google.registry.util.DateTimeUtils.toZonedDateTime; import static google.registry.util.DateTimeUtils.toZonedDateTime;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.collect.ImmutableList;
import google.registry.model.Buildable; import google.registry.model.Buildable;
import google.registry.model.CreateAutoTimestamp; import google.registry.model.CreateAutoTimestamp;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.model.UpdateAutoTimestamp; import google.registry.model.UpdateAutoTimestamp;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import google.registry.util.DateTimeUtils; import google.registry.util.DateTimeUtils;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Optional; 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_verification_code", columnList = "verificationCode"),
@Index(name = "idx_registry_lock_registrar_id", columnList = "registrarId") @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 @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@ -230,6 +233,11 @@ public final class RegistryLock extends ImmutableObject implements Buildable {
return new Builder(clone(this)); return new Builder(clone(this));
} }
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // not stored in Datastore
}
/** Builder for {@link google.registry.schema.domain.RegistryLock}. */ /** Builder for {@link google.registry.schema.domain.RegistryLock}. */
public static class Builder extends Buildable.Builder<RegistryLock> { public static class Builder extends Buildable.Builder<RegistryLock> {
public Builder() {} public Builder() {}

View file

@ -16,7 +16,10 @@ package google.registry.schema.server;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.collect.ImmutableList;
import google.registry.model.ImmutableObject; 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.schema.server.Lock.LockId;
import google.registry.util.DateTimeUtils; import google.registry.util.DateTimeUtils;
import java.io.Serializable; import java.io.Serializable;
@ -40,7 +43,7 @@ import org.joda.time.Duration;
@Entity @Entity
@Table @Table
@IdClass(LockId.class) @IdClass(LockId.class)
public class Lock { public class Lock implements SqlEntity {
/** The resource name used to create the lock. */ /** The resource name used to create the lock. */
@Column(nullable = false) @Column(nullable = false)
@ -116,6 +119,11 @@ public class Lock {
return new Lock(resourceName, GLOBAL, requestLogId, acquiredTime, leaseLength); return new Lock(resourceName, GLOBAL, requestLogId, acquiredTime, leaseLength);
} }
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // Locks are not converted since they are ephemeral
}
static class LockId extends ImmutableObject implements Serializable { static class LockId extends ImmutableObject implements Serializable {
String resourceName; String resourceName;

View file

@ -14,7 +14,10 @@
package google.registry.schema.tld; package google.registry.schema.tld;
import com.google.common.collect.ImmutableList;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import javax.persistence.Column; import javax.persistence.Column;
@ -27,7 +30,7 @@ import javax.persistence.Id;
* <p>These are not persisted directly, but rather, using {@link PremiumList#getLabelsToPrices()}. * <p>These are not persisted directly, but rather, using {@link PremiumList#getLabelsToPrices()}.
*/ */
@Entity @Entity
public class PremiumEntry extends ImmutableObject implements Serializable { public class PremiumEntry extends ImmutableObject implements Serializable, SqlEntity {
@Id @Id
@Column(nullable = false) @Column(nullable = false)
@ -41,4 +44,9 @@ public class PremiumEntry extends ImmutableObject implements Serializable {
String domainLabel; String domainLabel;
private PremiumEntry() {} private PremiumEntry() {}
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // PremiumList is dually-written
}
} }

View file

@ -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.base.Preconditions.checkState;
import static com.google.common.hash.Funnels.stringFunnel; import static com.google.common.hash.Funnels.stringFunnel;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.hash.BloomFilter; import com.google.common.hash.BloomFilter;
import google.registry.model.CreateAutoTimestamp; import google.registry.model.CreateAutoTimestamp;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -49,7 +52,7 @@ import org.joda.time.DateTime;
*/ */
@Entity @Entity
@Table(indexes = {@Index(columnList = "name", name = "premiumlist_name_idx")}) @Table(indexes = {@Index(columnList = "name", name = "premiumlist_name_idx")})
public class PremiumList { public class PremiumList implements SqlEntity {
@Column(nullable = false) @Column(nullable = false)
private String name; private String name;
@ -140,4 +143,9 @@ public class PremiumList {
public BloomFilter<String> getBloomFilter() { public BloomFilter<String> getBloomFilter() {
return bloomFilter; return bloomFilter;
} }
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // PremiumList is dual-written
}
} }

View file

@ -54,7 +54,7 @@ public class PremiumListUtils {
Map<String, BigDecimal> priceAmounts = Map<String, BigDecimal> priceAmounts =
Maps.transformValues(prices, ple -> ple.getValue().getAmount()); 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() {} private PremiumListUtils() {}

View file

@ -26,6 +26,8 @@ import com.google.common.collect.ImmutableMap;
import google.registry.model.CreateAutoTimestamp; import google.registry.model.CreateAutoTimestamp;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.model.registry.label.ReservationType; 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.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -53,7 +55,7 @@ import org.joda.time.DateTime;
*/ */
@Entity @Entity
@Table(indexes = {@Index(columnList = "name", name = "reservedlist_name_idx")}) @Table(indexes = {@Index(columnList = "name", name = "reservedlist_name_idx")})
public class ReservedList extends ImmutableObject { public class ReservedList extends ImmutableObject implements SqlEntity {
@Column(nullable = false) @Column(nullable = false)
private String name; private String name;
@ -76,6 +78,11 @@ public class ReservedList extends ImmutableObject {
@MapKeyColumn(name = "domainLabel") @MapKeyColumn(name = "domainLabel")
private Map<String, ReservedEntry> labelsToReservations; private Map<String, ReservedEntry> labelsToReservations;
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // ReservedList is dual-written\
}
@Embeddable @Embeddable
public static class ReservedEntry extends ImmutableObject { public static class ReservedEntry extends ImmutableObject {
@Column(nullable = false) @Column(nullable = false)

View file

@ -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.toJodaDateTime;
import static google.registry.util.DateTimeUtils.toZonedDateTime; import static google.registry.util.DateTimeUtils.toZonedDateTime;
import com.google.common.collect.ImmutableList;
import google.registry.model.CreateAutoTimestamp; import google.registry.model.CreateAutoTimestamp;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -46,7 +49,7 @@ import org.joda.time.DateTime;
*/ */
@Entity @Entity
@Table @Table
public class ClaimsList extends ImmutableObject { public class ClaimsList extends ImmutableObject implements SqlEntity {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column @Column
@ -105,4 +108,9 @@ public class ClaimsList extends ImmutableObject {
public Optional<String> getClaimKey(String label) { public Optional<String> getClaimKey(String label) {
return Optional.ofNullable(labelsToKeys.get(label)); return Optional.ofNullable(labelsToKeys.get(label));
} }
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // ClaimsList is dual-written
}
} }

View file

@ -23,6 +23,7 @@ import com.google.common.hash.BloomFilter;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import google.registry.schema.replay.EntityTest.EntityForTesting;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import org.junit.Rule; import org.junit.Rule;
@ -50,6 +51,7 @@ public class BloomFilterConverterTest {
} }
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
@EntityForTesting
public static class TestEntity extends ImmutableObject { public static class TestEntity extends ImmutableObject {
@Id String name = "id"; @Id String name = "id";

View file

@ -20,6 +20,7 @@ import google.registry.model.CreateAutoTimestamp;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import google.registry.schema.replay.EntityTest.EntityForTesting;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
@ -66,6 +67,7 @@ public class CreateAutoTimestampConverterTest {
} }
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
@EntityForTesting
public static class TestEntity extends ImmutableObject { public static class TestEntity extends ImmutableObject {
@Id String name; @Id String name;

View file

@ -21,6 +21,7 @@ import static org.junit.Assert.assertThrows;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import google.registry.schema.replay.EntityTest.EntityForTesting;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
@ -78,6 +79,7 @@ public class CurrencyUnitConverterTest {
} }
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
@EntityForTesting
public static class TestEntity extends ImmutableObject { public static class TestEntity extends ImmutableObject {
@Id String name = "id"; @Id String name = "id";

View file

@ -20,6 +20,7 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import google.registry.schema.replay.EntityTest.EntityForTesting;
import java.math.BigInteger; import java.math.BigInteger;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
@ -65,6 +66,7 @@ public class DurationConverterTest {
} }
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
@EntityForTesting
public static class TestEntity extends ImmutableObject { public static class TestEntity extends ImmutableObject {
@Id String name = "id"; @Id String name = "id";

View file

@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableMap;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import google.registry.schema.replay.EntityTest.EntityForTesting;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; 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 // 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. // inner class. The double quotes are added to conform to our schema generation convention.
@Entity(name = "\"TestEntity\"") @Entity(name = "\"TestEntity\"")
@EntityForTesting
public static class TestEntity extends ImmutableObject { public static class TestEntity extends ImmutableObject {
@Id String name = "id"; @Id String name = "id";
@ -164,6 +166,7 @@ public class JodaMoneyConverterTest {
// See comments on the annotation for TestEntity above for reason. // See comments on the annotation for TestEntity above for reason.
@Entity(name = "\"ComplexTestEntity\"") @Entity(name = "\"ComplexTestEntity\"")
@EntityForTesting
// This entity is used to test column override for embedded fields and collections. // This entity is used to test column override for embedded fields and collections.
public static class ComplexTestEntity extends ImmutableObject { public static class ComplexTestEntity extends ImmutableObject {

View file

@ -20,6 +20,7 @@ import google.registry.model.ImmutableObject;
import google.registry.model.UpdateAutoTimestamp; import google.registry.model.UpdateAutoTimestamp;
import google.registry.persistence.transaction.JpaTestRules; import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule; import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import google.registry.schema.replay.EntityTest.EntityForTesting;
import google.registry.testing.FakeClock; import google.registry.testing.FakeClock;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
@ -77,6 +78,7 @@ public class UpdateAutoTimestampConverterTest {
} }
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference. @Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
@EntityForTesting
public static class TestEntity extends ImmutableObject { public static class TestEntity extends ImmutableObject {
@Id String name; @Id String name;

View file

@ -22,6 +22,10 @@ import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfo; import io.github.classgraph.ClassInfo;
import io.github.classgraph.ClassInfoList; import io.github.classgraph.ClassInfoList;
import io.github.classgraph.ScanResult; 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.Ignore;
import org.junit.Test; import org.junit.Test;
@ -59,7 +63,13 @@ public class EntityTest {
return classInfoList.stream() return classInfoList.stream()
.filter(ClassInfo::isStandardClass) .filter(ClassInfo::isStandardClass)
.map(ClassInfo::loadClass) .map(ClassInfo::loadClass)
.filter(clazz -> !clazz.isAnnotationPresent(EntityForTesting.class))
.map(Class::getName) .map(Class::getName)
.collect(toImmutableSet()); .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 {}
} }