Add DuallyWrittenEntity convenience interface (#866)

* Add DuallyWrittenEntity convenience interface

For classes that are dually written we don't need to worry about replay
conversion, so this just allows us to remove unnecessary unimportant
methods

* Rename DWE to NonReplicatedEntity and enable test
This commit is contained in:
gbrodman 2020-11-09 15:13:40 -05:00 committed by GitHub
parent 0c6363c04f
commit acce1a7d3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 50 additions and 49 deletions

View file

@ -19,7 +19,6 @@ import static google.registry.model.rde.RdeNamingUtils.makePartialName;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
@ -29,8 +28,7 @@ import google.registry.model.ImmutableObject;
import google.registry.model.rde.RdeRevision.RdeRevisionId;
import google.registry.persistence.VKey;
import google.registry.persistence.converter.LocalDateConverter;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import google.registry.schema.replay.NonReplicatedEntity;
import java.io.Serializable;
import java.util.Optional;
import javax.persistence.Column;
@ -52,7 +50,7 @@ import org.joda.time.LocalDate;
@Entity
@javax.persistence.Entity
@IdClass(RdeRevisionId.class)
public final class RdeRevision extends BackupGroupRoot implements DatastoreEntity, SqlEntity {
public final class RdeRevision extends BackupGroupRoot implements NonReplicatedEntity {
/** String triplet of tld, date, and mode, e.g. {@code soy_2015-09-01_full}. */
@Id @Transient String id;
@ -89,16 +87,6 @@ public final class RdeRevision extends BackupGroupRoot implements DatastoreEntit
return revision;
}
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // we don't care about RdeRevision history
}
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // we don't care about RdeRevision history
}
/**
* Returns next revision ID to use when staging a new deposit file for the given triplet.
*

View file

@ -46,8 +46,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.DatastoreAndSqlEntity;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.NonReplicatedEntity;
import google.registry.schema.replay.SqlEntity;
import google.registry.schema.tld.PremiumListDao;
import google.registry.util.NonFinalForTesting;
@ -90,7 +90,7 @@ import org.joda.time.Duration;
@javax.persistence.Entity
@Table(indexes = {@Index(columnList = "name", name = "premiumlist_name_idx")})
public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.PremiumListEntry>
implements DatastoreAndSqlEntity {
implements NonReplicatedEntity {
/** Stores the revision key for the set of currently used premium list entry entities. */
@Transient Key<PremiumListRevision> revisionKey;

View file

@ -38,7 +38,7 @@ 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.DatastoreAndSqlEntity;
import google.registry.schema.replay.NonReplicatedEntity;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -67,7 +67,7 @@ import org.joda.time.DateTime;
@Table(indexes = {@Index(columnList = "name", name = "reservedlist_name_idx")})
public final class ReservedList
extends BaseDomainLabelList<ReservationType, ReservedList.ReservedListEntry>
implements DatastoreAndSqlEntity {
implements NonReplicatedEntity {
@Mapify(ReservedListEntry.LabelMapper.class)
@ElementCollection

View file

@ -17,7 +17,6 @@ package google.registry.model.server;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
import com.google.common.collect.ImmutableList;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
@ -28,8 +27,7 @@ import google.registry.model.Buildable;
import google.registry.model.CreateAutoTimestamp;
import google.registry.model.ImmutableObject;
import google.registry.model.annotations.ReportedOn;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import google.registry.schema.replay.NonReplicatedEntity;
import javax.persistence.Column;
import javax.persistence.Index;
import javax.persistence.PostLoad;
@ -60,7 +58,7 @@ import javax.persistence.Transient;
@ReportedOn
@javax.persistence.Entity(name = "KmsSecret")
@Table(indexes = {@Index(columnList = "secretName")})
public class KmsSecretRevision extends ImmutableObject implements DatastoreEntity, SqlEntity {
public class KmsSecretRevision extends ImmutableObject implements NonReplicatedEntity {
/**
* The maximum allowable secret size. Although Datastore allows entities up to 1 MB in size,
@ -129,16 +127,6 @@ public class KmsSecretRevision extends ImmutableObject implements DatastoreEntit
secretName = parent.getName();
}
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // This is dually-written, as we do not care about history
}
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // This is dually-written, as we do not care about history
}
/** A builder for constructing {@link KmsSecretRevision} entities, since they are immutable. */
public static class Builder extends Buildable.Builder<KmsSecretRevision> {

View file

@ -28,7 +28,6 @@ import static google.registry.util.DateTimeUtils.isBeforeOrAt;
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.Iterables;
import com.google.common.collect.MapDifference;
@ -45,8 +44,7 @@ import google.registry.model.ImmutableObject;
import google.registry.model.annotations.NotBackedUp;
import google.registry.model.annotations.NotBackedUp.Reason;
import google.registry.model.common.EntityGroupRoot;
import google.registry.schema.replay.DatastoreEntity;
import google.registry.schema.replay.SqlEntity;
import google.registry.schema.replay.NonReplicatedEntity;
import google.registry.util.CollectionUtils;
import java.util.Map;
import java.util.Optional;
@ -82,8 +80,7 @@ import org.joda.time.DateTime;
@Entity
@javax.persistence.Entity
@NotBackedUp(reason = Reason.EXTERNALLY_SOURCED)
public class SignedMarkRevocationList extends ImmutableObject
implements DatastoreEntity, SqlEntity {
public class SignedMarkRevocationList extends ImmutableObject implements NonReplicatedEntity {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@ -262,16 +259,6 @@ public class SignedMarkRevocationList extends ImmutableObject
}
}
@Override
public ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of(); // Dually-written every day
}
@Override
public ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of(); // Dually-written every day
}
/** Exception when trying to directly save a {@link SignedMarkRevocationList} without sharding. */
public static class UnshardedSaveException extends RuntimeException {}
}

View file

@ -0,0 +1,35 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.schema.replay;
import com.google.common.collect.ImmutableList;
/**
* Represents an entity that should not participate in asynchronous replication.
*
* <p>We expect that this is a result of the entity being dually-written.
*/
public interface NonReplicatedEntity extends DatastoreEntity, SqlEntity {
@Override
default ImmutableList<DatastoreEntity> toDatastoreEntities() {
return ImmutableList.of();
}
@Override
default ImmutableList<SqlEntity> toSqlEntities() {
return ImmutableList.of();
}
}

View file

@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.annotation.Embed;
import google.registry.model.common.GaeUserIdConverter;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfo;
import io.github.classgraph.ClassInfoList;
@ -27,7 +28,6 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
/**
@ -35,8 +35,10 @@ import org.junit.jupiter.api.Test;
*/
public class EntityTest {
private static final ImmutableSet<Class<?>> NON_CONVERTED_CLASSES =
ImmutableSet.of(GaeUserIdConverter.class);
@Test
@Disabled("This won't be done until b/152410794 is done, since it requires many entity changes")
void testSqlEntityPersistence() {
try (ScanResult scanResult =
new ClassGraph().enableAnnotationInfo().whitelistPackages("google.registry").scan()) {
@ -74,6 +76,7 @@ public class EntityTest {
.map(ClassInfo::loadClass)
.filter(clazz -> !clazz.isAnnotationPresent(EntityForTesting.class))
.filter(clazz -> !clazz.isAnnotationPresent(Embed.class))
.filter(clazz -> !NON_CONVERTED_CLASSES.contains(clazz))
.map(Class::getName)
.collect(toImmutableSet());
}