From 02eb7cfcc37c57a73925dae40d5f47e6bc0fc214 Mon Sep 17 00:00:00 2001 From: Lai Jiang Date: Thu, 20 May 2021 11:58:41 -0400 Subject: [PATCH] Switch from using raw HistoryEntries to typed subclasses thereof (#1150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HistoryEntry is used to record all histories (contact, domain, host) in Datastore. In SQL it is now split into three subclasses (and thus tables): ContactHistory, DomainHistory and HostHistory. Its builder is genericized as a result which led to a lot of compiler warnings for the use of a raw HistoryEntry in the existing code base. This PR cleans things up by replacing all the explicit use of raw HistoryEntry with the corresponding subclass and also adds some guardrails to prevent the use of raw HistoryEntry accidentally. Note that because DomainHistory includes nsHosts and gracePeriodHistory, both of which are assigned a roid from ofy when built, the assigned roids for resources after history entries are built are incremented compared to when only HistoryEntrys are built (before this PR) in RdapDomainSearchActionTest. Also added a convenient tm().updateAll() varargs method. --- This change is [Reviewable](https://reviewable.io/reviews/google/nomulus/1150) --- .../batch/DeleteContactsAndHostsAction.java | 7 +- .../batch/DeleteProberDataAction.java | 16 ++- .../ExpandRecurringBillingEventsAction.java | 9 +- .../google/registry/flows/FlowModule.java | 80 ++++++++---- .../model/contact/ContactHistory.java | 5 + .../registry/model/domain/DomainHistory.java | 9 +- .../registry/model/host/HostHistory.java | 5 + .../ofy/DatastoreTransactionManager.java | 5 + .../model/reporting/HistoryEntry.java | 110 +++++++++++++---- .../JpaTransactionManagerImpl.java | 5 + .../transaction/TransactionManager.java | 3 + .../registry/tools/DomainLockUtils.java | 3 +- .../registry/tools/UnrenewDomainCommand.java | 2 +- .../CreateSyntheticHistoryEntriesAction.java | 3 +- .../batch/DeleteExpiredDomainsActionTest.java | 5 +- .../batch/DeleteProberDataActionTest.java | 5 +- ...xpandRecurringBillingEventsActionTest.java | 9 +- .../beam/initsql/DomainBaseUtilTest.java | 5 +- .../beam/initsql/InitSqlPipelineTest.java | 5 +- .../flows/domain/DomainDeleteFlowTest.java | 11 +- .../flows/domain/DomainInfoFlowTest.java | 5 +- .../flows/domain/DomainRenewFlowTest.java | 2 +- .../domain/DomainRestoreRequestFlowTest.java | 5 +- .../domain/DomainTransferApproveFlowTest.java | 5 +- .../domain/DomainTransferRejectFlowTest.java | 5 +- .../flows/domain/DomainUpdateFlowTest.java | 9 +- .../flows/poll/PollRequestFlowTest.java | 10 +- .../model/domain/DomainBaseSqlTest.java | 2 - .../registry/model/domain/DomainBaseTest.java | 8 +- .../history/LegacyHistoryObjectTest.java | 5 +- .../google/registry/model/ofy/OfyTest.java | 35 +++--- .../registry/model/poll/PollMessageTest.java | 5 +- .../model/reporting/HistoryEntryTest.java | 9 +- .../rdap/RdapDomainSearchActionTest.java | 114 +++++++++--------- .../java/google/registry/rde/RdeFixtures.java | 5 +- .../registry/testing/DatabaseHelper.java | 11 +- .../testing/FullFieldsTestEntityHelper.java | 24 ++-- ...dupeOneTimeBillingEventIdsCommandTest.java | 3 +- .../BackfillRegistryLocksCommandTest.java | 5 +- .../server/KillAllEppResourcesActionTest.java | 3 +- .../ResaveAllHistoryEntriesActionTest.java | 16 ++- .../google/registry/model/schema.txt | 21 ++++ 42 files changed, 380 insertions(+), 229 deletions(-) diff --git a/core/src/main/java/google/registry/batch/DeleteContactsAndHostsAction.java b/core/src/main/java/google/registry/batch/DeleteContactsAndHostsAction.java index 08163eefb..75db980c9 100644 --- a/core/src/main/java/google/registry/batch/DeleteContactsAndHostsAction.java +++ b/core/src/main/java/google/registry/batch/DeleteContactsAndHostsAction.java @@ -370,11 +370,10 @@ public class DeleteContactsAndHostsAction implements Runnable { : "it was transferred prior to deletion"); HistoryEntry historyEntry = - new HistoryEntry.Builder() + HistoryEntry.createBuilderForResource(resource) .setClientId(deletionRequest.requestingClientId()) .setModificationTime(now) .setType(getHistoryEntryType(resource, deleteAllowed)) - .setParent(deletionRequest.key()) .build(); PollMessage.OneTime pollMessage = @@ -409,7 +408,9 @@ public class DeleteContactsAndHostsAction implements Runnable { } else { resourceToSave = resource.asBuilder().removeStatusValue(PENDING_DELETE).build(); } - auditedOfy().save().entities(resourceToSave, historyEntry, pollMessage); + auditedOfy() + .save() + .entities(resourceToSave, historyEntry.asHistoryEntry(), pollMessage); return DeletionResult.create( deleteAllowed ? Type.DELETED : Type.NOT_DELETED, pollMessageText); } diff --git a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java index 3eb9aba5b..79a859cc2 100644 --- a/core/src/main/java/google/registry/batch/DeleteProberDataAction.java +++ b/core/src/main/java/google/registry/batch/DeleteProberDataAction.java @@ -44,11 +44,11 @@ import google.registry.mapreduce.MapreduceRunner; import google.registry.mapreduce.inputs.EppResourceInputs; import google.registry.model.EppResourceUtils; import google.registry.model.domain.DomainBase; +import google.registry.model.domain.DomainHistory; import google.registry.model.index.EppResourceIndex; import google.registry.model.index.ForeignKeyIndex; import google.registry.model.registry.Registry; import google.registry.model.registry.Registry.TldType; -import google.registry.model.reporting.HistoryEntry; import google.registry.request.Action; import google.registry.request.Parameter; import google.registry.request.Response; @@ -253,9 +253,9 @@ public class DeleteProberDataAction implements Runnable { .setDeletionTime(tm().getTransactionTime()) .setStatusValues(null) .build(); - HistoryEntry historyEntry = - new HistoryEntry.Builder() - .setParent(domain) + DomainHistory historyEntry = + new DomainHistory.Builder() + .setDomain(domain) .setType(DOMAIN_DELETE) .setModificationTime(tm().getTransactionTime()) .setBySuperuser(true) @@ -263,11 +263,9 @@ public class DeleteProberDataAction implements Runnable { .setClientId(registryAdminClientId) .build(); // Note that we don't bother handling grace periods, billing events, pending - // transfers, - // poll messages, or auto-renews because these will all be hard-deleted the next - // time the - // mapreduce runs anyway. - auditedOfy().save().entities(deletedDomain, historyEntry); + // transfers, poll messages, or auto-renews because these will all be hard-deleted + // the next time the mapreduce runs anyway. + tm().putAll(deletedDomain, historyEntry); updateForeignKeyIndexDeletionTime(deletedDomain); dnsQueue.addDomainRefreshTask(deletedDomain.getDomainName()); }); diff --git a/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java b/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java index 33b942349..f1d2d632b 100644 --- a/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java +++ b/core/src/main/java/google/registry/batch/ExpandRecurringBillingEventsAction.java @@ -49,6 +49,7 @@ import google.registry.model.billing.BillingEvent.OneTime; import google.registry.model.billing.BillingEvent.Recurring; import google.registry.model.common.Cursor; import google.registry.model.domain.DomainBase; +import google.registry.model.domain.DomainHistory; import google.registry.model.domain.Period; import google.registry.model.registry.Registry; import google.registry.model.reporting.DomainTransactionRecord; @@ -188,12 +189,14 @@ public class ExpandRecurringBillingEventsAction implements Runnable { // an event persisted. for (DateTime billingTime : difference(billingTimes, existingBillingTimes)) { // Construct a new HistoryEntry that parents over the OneTime - HistoryEntry historyEntry = - new HistoryEntry.Builder() + DomainHistory historyEntry = + new DomainHistory.Builder() .setBySuperuser(false) .setClientId(recurring.getClientId()) .setModificationTime(tm().getTransactionTime()) - .setParent(domainKey) + // TODO (jianglai): modify this to use setDomain instead when + // converting this action to be SQL-aware. + .setDomainRepoId(domainKey.getName()) .setPeriod(Period.create(1, YEARS)) .setReason( "Domain autorenewal by ExpandRecurringBillingEventsAction") diff --git a/core/src/main/java/google/registry/flows/FlowModule.java b/core/src/main/java/google/registry/flows/FlowModule.java index 2905d26a5..bbabbfb80 100644 --- a/core/src/main/java/google/registry/flows/FlowModule.java +++ b/core/src/main/java/google/registry/flows/FlowModule.java @@ -213,50 +213,78 @@ public class FlowModule { return Strings.nullToEmpty(((Poll) eppInput.getCommandWrapper().getCommand()).getMessageId()); } + private static > + B makeHistoryEntryBuilder( + B builder, + Trid trid, + byte[] inputXmlBytes, + boolean isSuperuser, + String clientId, + EppInput eppInput) { + builder + .setTrid(trid) + .setXmlBytes(inputXmlBytes) + .setBySuperuser(isSuperuser) + .setClientId(clientId); + Optional metadataExtension = + eppInput.getSingleExtension(MetadataExtension.class); + metadataExtension.ifPresent( + extension -> + builder + .setReason(extension.getReason()) + .setRequestedByRegistrar(extension.getRequestedByRegistrar())); + return builder; + } + /** - * Provides a partially filled in {@link HistoryEntry} builder. + * Provides a partially filled in {@link ContactHistory.Builder} * *

This is not marked with {@link FlowScope} so that each retry gets a fresh one. Otherwise, * the fact that the builder is one-use would cause NPEs. */ @Provides - static HistoryEntry.Builder provideHistoryEntryBuilder( + static ContactHistory.Builder provideContactHistoryBuilder( Trid trid, @InputXml byte[] inputXmlBytes, @Superuser boolean isSuperuser, @ClientId String clientId, EppInput eppInput) { - HistoryEntry.Builder historyBuilder = - new HistoryEntry.Builder() - .setTrid(trid) - .setXmlBytes(inputXmlBytes) - .setBySuperuser(isSuperuser) - .setClientId(clientId); - Optional metadataExtension = - eppInput.getSingleExtension(MetadataExtension.class); - metadataExtension.ifPresent( - extension -> - historyBuilder - .setReason(extension.getReason()) - .setRequestedByRegistrar(extension.getRequestedByRegistrar())); - return historyBuilder; + return makeHistoryEntryBuilder( + new ContactHistory.Builder(), trid, inputXmlBytes, isSuperuser, clientId, eppInput); } + /** + * Provides a partially filled in {@link HostHistory.Builder} + * + *

This is not marked with {@link FlowScope} so that each retry gets a fresh one. Otherwise, + * the fact that the builder is one-use would cause NPEs. + */ @Provides - static ContactHistory.Builder provideContactHistoryBuilder( - HistoryEntry.Builder historyEntryBuilder) { - return new ContactHistory.Builder().copyFrom(historyEntryBuilder); + static HostHistory.Builder provideHostHistoryBuilder( + Trid trid, + @InputXml byte[] inputXmlBytes, + @Superuser boolean isSuperuser, + @ClientId String clientId, + EppInput eppInput) { + return makeHistoryEntryBuilder( + new HostHistory.Builder(), trid, inputXmlBytes, isSuperuser, clientId, eppInput); } + /** + * Provides a partially filled in {@link DomainHistory.Builder} + * + *

This is not marked with {@link FlowScope} so that each retry gets a fresh one. Otherwise, + * the fact that the builder is one-use would cause NPEs. + */ @Provides static DomainHistory.Builder provideDomainHistoryBuilder( - HistoryEntry.Builder historyEntryBuilder) { - return new DomainHistory.Builder().copyFrom(historyEntryBuilder); - } - - @Provides - static HostHistory.Builder provideHostHistoryBuilder(HistoryEntry.Builder historyEntryBuilder) { - return new HostHistory.Builder().copyFrom(historyEntryBuilder); + Trid trid, + @InputXml byte[] inputXmlBytes, + @Superuser boolean isSuperuser, + @ClientId String clientId, + EppInput eppInput) { + return makeHistoryEntryBuilder( + new DomainHistory.Builder(), trid, inputXmlBytes, isSuperuser, clientId, eppInput); } /** diff --git a/core/src/main/java/google/registry/model/contact/ContactHistory.java b/core/src/main/java/google/registry/model/contact/ContactHistory.java index 564681759..033a51329 100644 --- a/core/src/main/java/google/registry/model/contact/ContactHistory.java +++ b/core/src/main/java/google/registry/model/contact/ContactHistory.java @@ -41,6 +41,11 @@ import javax.persistence.PostLoad; *

In addition to the general history fields (e.g. action time, registrar ID) we also persist a * copy of the contact entity at this point in time. We persist a raw {@link ContactBase} so that * the foreign-keyed fields in that class can refer to this object. + * + *

This class is only marked as a Datastore entity subclass and registered with Objectify so that + * when building it its ID can be auto-populated by Objectify. It is converted to its superclass + * {@link HistoryEntry} when persisted to Datastore using {@link + * google.registry.persistence.transaction.TransactionManager}. */ @Entity @javax.persistence.Table( diff --git a/core/src/main/java/google/registry/model/domain/DomainHistory.java b/core/src/main/java/google/registry/model/domain/DomainHistory.java index 9bd3780a0..052a86669 100644 --- a/core/src/main/java/google/registry/model/domain/DomainHistory.java +++ b/core/src/main/java/google/registry/model/domain/DomainHistory.java @@ -21,7 +21,6 @@ import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.EntitySubclass; -import com.googlecode.objectify.annotation.Ignore; import google.registry.model.ImmutableObject; import google.registry.model.domain.DomainHistory.DomainHistoryId; import google.registry.model.domain.GracePeriod.GracePeriodHistory; @@ -62,6 +61,11 @@ import javax.persistence.Table; *

In addition to the general history fields (e.g. action time, registrar ID) we also persist a * copy of the domain entity at this point in time. We persist a raw {@link DomainContent} so that * the foreign-keyed fields in that class can refer to this object. + * + *

This class is only marked as a Datastore entity subclass and registered with Objectify so that + * when building it its ID can be auto-populated by Objectify. It is converted to its superclass + * {@link HistoryEntry} when persisted to Datastore using {@link + * google.registry.persistence.transaction.TransactionManager}. */ @Entity @Table( @@ -97,7 +101,6 @@ public class DomainHistory extends HistoryEntry implements SqlEntity { // We could have reused domainContent.nsHosts here, but Hibernate throws a weird exception after // we change to use a composite primary key. // TODO(b/166776754): Investigate if we can reuse domainContent.nsHosts for storing host keys. - @Ignore @ElementCollection @JoinTable( name = "DomainHistoryHost", @@ -111,7 +114,6 @@ public class DomainHistory extends HistoryEntry implements SqlEntity { @Column(name = "host_repo_id") Set> nsHosts; - @Ignore @OneToMany( cascade = {CascadeType.ALL}, fetch = FetchType.EAGER, @@ -131,7 +133,6 @@ public class DomainHistory extends HistoryEntry implements SqlEntity { // HashSet rather than ImmutableSet so that Hibernate can fill them out lazily on request Set dsDataHistories = new HashSet<>(); - @Ignore @OneToMany( cascade = {CascadeType.ALL}, fetch = FetchType.EAGER, diff --git a/core/src/main/java/google/registry/model/host/HostHistory.java b/core/src/main/java/google/registry/model/host/HostHistory.java index fa71064b8..2526073b8 100644 --- a/core/src/main/java/google/registry/model/host/HostHistory.java +++ b/core/src/main/java/google/registry/model/host/HostHistory.java @@ -41,6 +41,11 @@ import javax.persistence.PostLoad; *

In addition to the general history fields (e.g. action time, registrar ID) we also persist a * copy of the host entity at this point in time. We persist a raw {@link HostBase} so that the * foreign-keyed fields in that class can refer to this object. + * + *

This class is only marked as a Datastore entity subclass and registered with Objectify so that + * when building it its ID can be auto-populated by Objectify. It is converted to its superclass + * {@link HistoryEntry} when persisted to Datastore using {@link + * google.registry.persistence.transaction.TransactionManager}. */ @Entity @javax.persistence.Table( diff --git a/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java b/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java index 861ffe3dd..11b935158 100644 --- a/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java +++ b/core/src/main/java/google/registry/model/ofy/DatastoreTransactionManager.java @@ -173,6 +173,11 @@ public class DatastoreTransactionManager implements TransactionManager { putAll(entities); } + @Override + public void updateAll(Object... entities) { + updateAll(ImmutableList.of(entities)); + } + @Override public void updateWithoutBackup(Object entity) { putWithoutBackup(entity); diff --git a/core/src/main/java/google/registry/model/reporting/HistoryEntry.java b/core/src/main/java/google/registry/model/reporting/HistoryEntry.java index 080e5c90f..8d088912b 100644 --- a/core/src/main/java/google/registry/model/reporting/HistoryEntry.java +++ b/core/src/main/java/google/registry/model/reporting/HistoryEntry.java @@ -32,14 +32,17 @@ import google.registry.model.Buildable; import google.registry.model.EppResource; import google.registry.model.ImmutableObject; import google.registry.model.annotations.ReportedOn; +import google.registry.model.contact.ContactBase; import google.registry.model.contact.ContactHistory; import google.registry.model.contact.ContactHistory.ContactHistoryId; import google.registry.model.contact.ContactResource; import google.registry.model.domain.DomainBase; +import google.registry.model.domain.DomainContent; import google.registry.model.domain.DomainHistory; import google.registry.model.domain.DomainHistory.DomainHistoryId; import google.registry.model.domain.Period; import google.registry.model.eppcommon.Trid; +import google.registry.model.host.HostBase; import google.registry.model.host.HostHistory; import google.registry.model.host.HostHistory.HostHistoryId; import google.registry.model.host.HostResource; @@ -60,7 +63,21 @@ import javax.persistence.MappedSuperclass; import javax.persistence.Transient; import org.joda.time.DateTime; -/** A record of an EPP command that mutated a resource. */ +/** + * A record of an EPP command that mutated a resource. + * + *

Due to historical reasons this class is persisted only to Datastore. It has three subclasses + * that include the parent resource itself which are persisted to Cloud SQL. During migration this + * class cannot be made abstract in order for the class to be persisted and loaded to and from + * Datastore. However it should never be used directly in the Java code itself. When it is loaded + * from Datastore it should be converted to a subclass for handling and when a new history entry is + * built it should always be a subclass, which is automatically converted to HistoryEntry when + * persisting to Datastore. + * + *

Some care has been taken to make it close to impossible to use this class directly, but the + * user should still exercise caution. After the migration is complete this class will be made + * abstract. + */ @ReportedOn @Entity @MappedSuperclass @@ -203,6 +220,12 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor @ImmutableObject.EmptySetToNull protected Set domainTransactionRecords; + // Make it impossible to instantiate a HistoryEntry explicitly. One should only instantiate a + // subtype of HistoryEntry. + protected HistoryEntry() { + super(); + } + public long getId() { // For some reason, Hibernate throws NPE during some initialization phase if we don't deal with // the null case. Setting the id to 0L when it is null should be fine because 0L for primitive @@ -285,13 +308,50 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor domainTransactionRecords == null ? null : ImmutableSet.copyOf(domainTransactionRecords); } + /** + * Throws an error when trying to get a builder from a bare {@link HistoryEntry}. + * + *

This method only exists to satisfy the requirement that the {@link HistoryEntry} is NOT + * abstract, it should never be called directly and all three of the subclass of {@link + * HistoryEntry} implements it. + */ @Override - public Builder asBuilder() { - return new Builder(clone(this)); + public Builder asBuilder() { + throw new UnsupportedOperationException( + "You should never attempt to build a HistoryEntry from a raw HistoryEntry. A raw " + + "HistoryEntry should only exist internally when persisting to datastore. If you need " + + "to build from a raw HistoryEntry, use " + + "{Contact,Host,Domain}History.Builder.copyFrom(HistoryEntry) instead."); } + /** + * Clones and returns a {@code HistoryEntry} objec + * + *

This is useful when converting a subclass to the base class to persist to Datastore. + */ public HistoryEntry asHistoryEntry() { - return new Builder().copyFrom(this).build(); + HistoryEntry historyEntry = new HistoryEntry(); + copy(this, historyEntry); + return historyEntry; + } + + protected static void copy(HistoryEntry src, HistoryEntry dst) { + dst.id = src.id; + dst.parent = src.parent; + dst.type = src.type; + dst.period = src.period; + dst.xmlBytes = src.xmlBytes; + dst.modificationTime = src.modificationTime; + dst.clientId = src.clientId; + dst.otherClientId = src.otherClientId; + dst.trid = src.trid; + dst.bySuperuser = src.bySuperuser; + dst.reason = src.reason; + dst.requestedByRegistrar = src.requestedByRegistrar; + dst.domainTransactionRecords = + src.domainTransactionRecords == null + ? null + : ImmutableSet.copyOf(src.domainTransactionRecords); } @SuppressWarnings("unchecked") @@ -349,33 +409,18 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor } /** A builder for {@link HistoryEntry} since it is immutable */ - public static class Builder> + public abstract static class Builder> extends GenericBuilder { - public Builder() {} + protected Builder() {} - public Builder(T instance) { + protected Builder(T instance) { super(instance); } // Used to fill out the fields in this object from an object which may not be exactly the same // as the class T, where both classes still subclass HistoryEntry public B copyFrom(HistoryEntry historyEntry) { - setId(historyEntry.id); - setParent(historyEntry.parent); - setType(historyEntry.type); - setPeriod(historyEntry.period); - setXmlBytes(historyEntry.xmlBytes); - setModificationTime(historyEntry.modificationTime); - setClientId(historyEntry.clientId); - setOtherClientId(historyEntry.otherClientId); - setTrid(historyEntry.trid); - setBySuperuser(historyEntry.bySuperuser); - setReason(historyEntry.reason); - setRequestedByRegistrar(historyEntry.requestedByRegistrar); - setDomainTransactionRecords( - historyEntry.domainTransactionRecords == null - ? null - : ImmutableSet.copyOf(historyEntry.domainTransactionRecords)); + copy(historyEntry, getInstance()); return thisCastToDerived(); } @@ -400,13 +445,13 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor return thisCastToDerived(); } - public B setParent(EppResource parent) { + protected B setParent(EppResource parent) { getInstance().parent = Key.create(parent); return thisCastToDerived(); } // Until we move completely to SQL, override this in subclasses (e.g. HostHistory) to set VKeys - public B setParent(Key parent) { + protected B setParent(Key parent) { getInstance().parent = parent; return thisCastToDerived(); } @@ -467,4 +512,19 @@ public class HistoryEntry extends ImmutableObject implements Buildable, Datastor return thisCastToDerived(); } } + + public static + HistoryEntry.Builder createBuilderForResource(E parent) { + if (parent instanceof DomainContent) { + return new DomainHistory.Builder().setDomain((DomainContent) parent); + } else if (parent instanceof ContactBase) { + return new ContactHistory.Builder().setContact((ContactBase) parent); + } else if (parent instanceof HostBase) { + return new HostHistory.Builder().setHost((HostBase) parent); + } else { + throw new IllegalStateException( + String.format( + "Class %s does not have an associated HistoryEntry", parent.getClass().getName())); + } + } } diff --git a/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java b/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java index 822c8b358..30b96fce0 100644 --- a/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java +++ b/core/src/main/java/google/registry/persistence/transaction/JpaTransactionManagerImpl.java @@ -350,6 +350,11 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager { entities.forEach(this::update); } + @Override + public void updateAll(Object... entities) { + updateAll(ImmutableList.of(entities)); + } + @Override public void updateWithoutBackup(Object entity) { update(entity); diff --git a/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java b/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java index 8eb97f73f..8a6f76cee 100644 --- a/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java +++ b/core/src/main/java/google/registry/persistence/transaction/TransactionManager.java @@ -159,6 +159,9 @@ public interface TransactionManager { /** Updates all entities in the database, throws exception if any entity does not exist. */ void updateAll(ImmutableCollection entities); + /** Updates all entities in the database, throws exception if any entity does not exist. */ + void updateAll(Object... entities); + /** * Updates an entity in the database without writing commit logs if the underlying database is * Datastore. diff --git a/core/src/main/java/google/registry/tools/DomainLockUtils.java b/core/src/main/java/google/registry/tools/DomainLockUtils.java index 81d289f84..5037b7396 100644 --- a/core/src/main/java/google/registry/tools/DomainLockUtils.java +++ b/core/src/main/java/google/registry/tools/DomainLockUtils.java @@ -22,7 +22,6 @@ import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STAT import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; -import com.googlecode.objectify.Key; import google.registry.batch.AsyncTaskEnqueuer; import google.registry.config.RegistryConfig.Config; import google.registry.model.billing.BillingEvent; @@ -370,7 +369,7 @@ public final class DomainLockUtils { .setRequestedByRegistrar(!lock.isSuperuser()) .setType(HistoryEntry.Type.DOMAIN_UPDATE) .setModificationTime(now) - .setParent(Key.create(domain)) + .setDomain(domain) .setReason(reason) .build(); tm().update(domain); diff --git a/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java b/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java index 43497aaa5..207f32e98 100644 --- a/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java +++ b/core/src/main/java/google/registry/tools/UnrenewDomainCommand.java @@ -185,7 +185,7 @@ class UnrenewDomainCommand extends ConfirmingCommand implements CommandWithRemot leapSafeSubtractYears(domain.getRegistrationExpirationTime(), period); DomainHistory domainHistory = new DomainHistory.Builder() - .setParent(domain) + .setDomain(domain) .setModificationTime(now) .setBySuperuser(true) .setType(Type.SYNTHETIC) diff --git a/core/src/main/java/google/registry/tools/javascrap/CreateSyntheticHistoryEntriesAction.java b/core/src/main/java/google/registry/tools/javascrap/CreateSyntheticHistoryEntriesAction.java index be764669b..18a75225a 100644 --- a/core/src/main/java/google/registry/tools/javascrap/CreateSyntheticHistoryEntriesAction.java +++ b/core/src/main/java/google/registry/tools/javascrap/CreateSyntheticHistoryEntriesAction.java @@ -113,12 +113,11 @@ public class CreateSyntheticHistoryEntriesAction implements Runnable { () -> { EppResource eppResource = ofy().load().key(resourceKey).now(); tm().put( - new HistoryEntry.Builder<>() + HistoryEntry.createBuilderForResource(eppResource) .setClientId(registryAdminRegistrarId) .setBySuperuser(true) .setRequestedByRegistrar(false) .setModificationTime(tm().getTransactionTime()) - .setParent(eppResource) .setReason( "Backfill EppResource history objects during Cloud SQL migration") .setType(HistoryEntry.Type.SYNTHETIC) diff --git a/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java b/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java index e5e135561..8fdf6fcb3 100644 --- a/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java +++ b/core/src/test/java/google/registry/batch/DeleteExpiredDomainsActionTest.java @@ -33,6 +33,7 @@ import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Flag; import google.registry.model.billing.BillingEvent.Reason; import google.registry.model.domain.DomainBase; +import google.registry.model.domain.DomainHistory; import google.registry.model.ofy.Ofy; import google.registry.model.poll.PollMessage; import google.registry.model.reporting.HistoryEntry; @@ -166,9 +167,9 @@ class DeleteExpiredDomainsActionTest { DomainBase pendingExpirationDomain = persistActiveDomain(domainName); HistoryEntry createHistoryEntry = persistResource( - new HistoryEntry.Builder() + new DomainHistory.Builder() .setType(DOMAIN_CREATE) - .setParent(pendingExpirationDomain) + .setDomain(pendingExpirationDomain) .setModificationTime(clock.nowUtc().minusMonths(9)) .setClientId(pendingExpirationDomain.getCreationClientId()) .build()); diff --git a/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java b/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java index 8c8207a88..0656f8116 100644 --- a/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java +++ b/core/src/test/java/google/registry/batch/DeleteProberDataActionTest.java @@ -39,6 +39,7 @@ import google.registry.model.ImmutableObject; import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent.Reason; import google.registry.model.domain.DomainBase; +import google.registry.model.domain.DomainHistory; import google.registry.model.index.EppResourceIndex; import google.registry.model.index.ForeignKeyIndex; import google.registry.model.poll.PollMessage; @@ -281,8 +282,8 @@ class DeleteProberDataActionTest extends MapreduceTestCase historyEntryKey = Key.create( persistResource( - new HistoryEntry.Builder() - .setParent(domainKey) + new DomainHistory.Builder() + .setDomainRepoId(domainKey.getName()) .setType(HistoryEntry.Type.DOMAIN_CREATE) .setClientId("TheRegistrar") .setModificationTime(fakeClock.nowUtc().minusYears(1)) diff --git a/core/src/test/java/google/registry/beam/initsql/InitSqlPipelineTest.java b/core/src/test/java/google/registry/beam/initsql/InitSqlPipelineTest.java index 294638b20..7d578376f 100644 --- a/core/src/test/java/google/registry/beam/initsql/InitSqlPipelineTest.java +++ b/core/src/test/java/google/registry/beam/initsql/InitSqlPipelineTest.java @@ -38,6 +38,7 @@ import google.registry.model.contact.ContactResource; import google.registry.model.domain.DesignatedContact; import google.registry.model.domain.DomainAuthInfo; import google.registry.model.domain.DomainBase; +import google.registry.model.domain.DomainHistory; import google.registry.model.domain.GracePeriod; import google.registry.model.domain.launch.LaunchNotice; import google.registry.model.domain.rgp.GracePeriodStatus; @@ -178,8 +179,8 @@ class InitSqlPipelineTest { .build()); historyEntry = persistResource( - new HistoryEntry.Builder() - .setParent(domainKey) + new DomainHistory.Builder() + .setDomainRepoId(domainKey.getName()) .setModificationTime(fakeClock.nowUtc()) .setClientId(registrar1.getClientId()) .setType(HistoryEntry.Type.DOMAIN_CREATE) diff --git a/core/src/test/java/google/registry/flows/domain/DomainDeleteFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainDeleteFlowTest.java index a86ccda8d..e631b75ca 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainDeleteFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainDeleteFlowTest.java @@ -84,6 +84,7 @@ import google.registry.model.billing.BillingEvent.Flag; import google.registry.model.billing.BillingEvent.Reason; import google.registry.model.contact.ContactResource; import google.registry.model.domain.DomainBase; +import google.registry.model.domain.DomainHistory; import google.registry.model.domain.GracePeriod; import google.registry.model.domain.rgp.GracePeriodStatus; import google.registry.model.eppcommon.ProtocolDefinition.ServiceExtension; @@ -121,7 +122,7 @@ class DomainDeleteFlowTest extends ResourceFlowTestCase { // response data block is produced in the poll message. HistoryEntry historyEntry = persistResource( - new HistoryEntry.Builder() + new ContactHistory.Builder() .setClientId("NewRegistrar") .setModificationTime(clock.nowUtc().minusDays(1)) .setType(HistoryEntry.Type.CONTACT_DELETE) - .setParent(contact) + .setContact(contact) .build()); persistResource( new PollMessage.OneTime.Builder() @@ -233,11 +235,11 @@ class PollRequestFlowTest extends FlowTestCase { // response data block is produced in the poll message. HistoryEntry historyEntry = persistResource( - new HistoryEntry.Builder() + new HostHistory.Builder() .setClientId("NewRegistrar") .setModificationTime(clock.nowUtc().minusDays(1)) .setType(HistoryEntry.Type.HOST_DELETE) - .setParent(host) + .setHost(host) .build()); persistResource( new PollMessage.OneTime.Builder() diff --git a/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java b/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java index 3c3dc160c..0e1957818 100644 --- a/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java +++ b/core/src/test/java/google/registry/model/domain/DomainBaseSqlTest.java @@ -441,7 +441,6 @@ public class DomainBaseSqlTest { .setType(HistoryEntry.Type.DOMAIN_CREATE) .setPeriod(Period.create(1, Period.Unit.YEARS)) .setModificationTime(DateTime.now(UTC)) - .setParent(Key.create(DomainBase.class, "4-COM")) .setDomainRepoId("4-COM") .setClientId("registrar1") // These are non-null, but I don't think some tests set them. @@ -572,7 +571,6 @@ public class DomainBaseSqlTest { .setType(HistoryEntry.Type.DOMAIN_CREATE) .setPeriod(Period.create(1, Period.Unit.YEARS)) .setModificationTime(DateTime.now(UTC)) - .setParent(Key.create(DomainBase.class, "4-COM")) .setDomainRepoId("4-COM") .setClientId("registrar1") // These are non-null, but I don't think some tests set them. diff --git a/core/src/test/java/google/registry/model/domain/DomainBaseTest.java b/core/src/test/java/google/registry/model/domain/DomainBaseTest.java index 0c8d934c2..681ca7152 100644 --- a/core/src/test/java/google/registry/model/domain/DomainBaseTest.java +++ b/core/src/test/java/google/registry/model/domain/DomainBaseTest.java @@ -100,8 +100,8 @@ public class DomainBaseTest extends EntityTestCase { historyEntryKey = Key.create( persistResource( - new HistoryEntry.Builder() - .setParent(domainKey.getOfyKey()) + new DomainHistory.Builder() + .setDomainRepoId(domainKey.getOfyKey().getName()) .setModificationTime(fakeClock.nowUtc()) .setType(HistoryEntry.Type.DOMAIN_CREATE) .setClientId("aregistrar") @@ -364,8 +364,8 @@ public class DomainBaseTest extends EntityTestCase { private void doExpiredTransferTest(DateTime oldExpirationTime) { HistoryEntry historyEntry = - new HistoryEntry.Builder() - .setParent(domain) + new DomainHistory.Builder() + .setDomain(domain) .setModificationTime(fakeClock.nowUtc()) .setClientId(domain.getCurrentSponsorClientId()) .setType(HistoryEntry.Type.DOMAIN_TRANSFER_REQUEST) diff --git a/core/src/test/java/google/registry/model/history/LegacyHistoryObjectTest.java b/core/src/test/java/google/registry/model/history/LegacyHistoryObjectTest.java index 599856c67..3bc35b5d9 100644 --- a/core/src/test/java/google/registry/model/history/LegacyHistoryObjectTest.java +++ b/core/src/test/java/google/registry/model/history/LegacyHistoryObjectTest.java @@ -207,9 +207,8 @@ public class LegacyHistoryObjectTest extends EntityTestCase { .build(); } - private HistoryEntry.Builder historyEntryBuilderFor(EppResource parent) { - return new HistoryEntry.Builder() - .setParent(parent) + private HistoryEntry.Builder historyEntryBuilderFor(EppResource parent) { + return HistoryEntry.createBuilderForResource(parent) .setType(HistoryEntry.Type.DOMAIN_CREATE) .setXmlBytes("".getBytes(UTF_8)) .setModificationTime(fakeClock.nowUtc()) diff --git a/core/src/test/java/google/registry/model/ofy/OfyTest.java b/core/src/test/java/google/registry/model/ofy/OfyTest.java index d5d8e29a8..96fa1167f 100644 --- a/core/src/test/java/google/registry/model/ofy/OfyTest.java +++ b/core/src/test/java/google/registry/model/ofy/OfyTest.java @@ -17,6 +17,7 @@ package google.registry.model.ofy; import static com.google.appengine.api.datastore.DatastoreServiceFactory.getDatastoreService; import static com.google.common.truth.Truth.assertThat; import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterruptibly; +import static google.registry.model.ImmutableObjectSubject.assertAboutImmutableObjects; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.auditedOfy; import static google.registry.model.ofy.Ofy.getBaseEntityClassFromEntityOrKey; @@ -40,6 +41,7 @@ import com.googlecode.objectify.annotation.OnLoad; import com.googlecode.objectify.annotation.OnSave; import com.googlecode.objectify.annotation.Parent; import google.registry.model.ImmutableObject; +import google.registry.model.contact.ContactHistory; import google.registry.model.contact.ContactResource; import google.registry.model.domain.DomainBase; import google.registry.model.eppcommon.Trid; @@ -70,11 +72,11 @@ public class OfyTest { void beforeEach() { createTld("tld"); someObject = - new HistoryEntry.Builder() + new ContactHistory.Builder() .setClientId("clientid") .setModificationTime(START_OF_TIME) .setType(HistoryEntry.Type.CONTACT_CREATE) - .setParent(persistActiveContact("parentContact")) + .setContact(persistActiveContact("parentContact")) .setTrid(Trid.create("client", "server")) .setXmlBytes("".getBytes(UTF_8)) .build(); @@ -99,7 +101,8 @@ public class OfyTest { @Test void testBackupGroupRootTimestampsMustIncreaseOnSave() { - doBackupGroupRootTimestampInversionTest(() -> auditedOfy().save().entity(someObject)); + doBackupGroupRootTimestampInversionTest( + () -> auditedOfy().save().entity(someObject.asHistoryEntry())); } @Test @@ -115,8 +118,8 @@ public class OfyTest { () -> tm().transact( () -> { - auditedOfy().save().entity(someObject); - auditedOfy().save().entity(someObject); + auditedOfy().save().entity(someObject.asHistoryEntry()); + auditedOfy().save().entity(someObject.asHistoryEntry()); })); assertThat(thrown).hasMessageThat().contains("Multiple entries with same key"); } @@ -143,7 +146,7 @@ public class OfyTest { () -> tm().transact( () -> { - auditedOfy().save().entity(someObject); + auditedOfy().save().entity(someObject.asHistoryEntry()); auditedOfy().delete().entity(someObject); })); assertThat(thrown).hasMessageThat().contains("Multiple entries with same key"); @@ -158,7 +161,7 @@ public class OfyTest { tm().transact( () -> { auditedOfy().delete().entity(someObject); - auditedOfy().save().entity(someObject); + auditedOfy().save().entity(someObject.asHistoryEntry()); })); assertThat(thrown).hasMessageThat().contains("Multiple entries with same key"); } @@ -288,7 +291,7 @@ public class OfyTest { public Integer get() { // There will be something in the manifest now, but it won't be committed if // we throw. - auditedOfy().save().entity(someObject); + auditedOfy().save().entity(someObject.asHistoryEntry()); count++; if (count == 3) { return count; @@ -310,7 +313,7 @@ public class OfyTest { public Void get() { if (firstCallToVrun) { firstCallToVrun = false; - auditedOfy().save().entity(someObject); + auditedOfy().save().entity(someObject.asHistoryEntry()); return null; } fail("Shouldn't have retried."); @@ -409,24 +412,26 @@ public class OfyTest { @Test void test_doWithFreshSessionCache() { - auditedOfy().saveWithoutBackup().entity(someObject).now(); + auditedOfy().saveWithoutBackup().entity(someObject.asHistoryEntry()).now(); final HistoryEntry modifiedObject = someObject.asBuilder().setModificationTime(END_OF_TIME).build(); // Mutate the saved objected, bypassing the Objectify session cache. - getDatastoreService().put(auditedOfy().saveWithoutBackup().toEntity(modifiedObject)); + getDatastoreService() + .put(auditedOfy().saveWithoutBackup().toEntity(modifiedObject.asHistoryEntry())); // Normal loading should come from the session cache and shouldn't reflect the mutation. - assertThat(auditedOfy().load().entity(someObject).now()).isEqualTo(someObject); + assertThat(auditedOfy().load().entity(someObject).now()).isEqualTo(someObject.asHistoryEntry()); // Loading inside doWithFreshSessionCache() should reflect the mutation. boolean ran = auditedOfy() .doWithFreshSessionCache( () -> { - assertThat(auditedOfy().load().entity(someObject).now()) - .isEqualTo(modifiedObject); + assertAboutImmutableObjects() + .that(auditedOfy().load().entity(someObject).now()) + .isEqualExceptFields(modifiedObject, "contactBase"); return true; }); assertThat(ran).isTrue(); // Test the normal loading again to verify that we've restored the original session unchanged. - assertThat(auditedOfy().load().entity(someObject).now()).isEqualTo(someObject); + assertThat(auditedOfy().load().entity(someObject).now()).isEqualTo(someObject.asHistoryEntry()); } } diff --git a/core/src/test/java/google/registry/model/poll/PollMessageTest.java b/core/src/test/java/google/registry/model/poll/PollMessageTest.java index c86281bff..58662948c 100644 --- a/core/src/test/java/google/registry/model/poll/PollMessageTest.java +++ b/core/src/test/java/google/registry/model/poll/PollMessageTest.java @@ -26,6 +26,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import google.registry.model.EntityTestCase; import google.registry.model.contact.ContactResource; import google.registry.model.domain.DomainBase; +import google.registry.model.domain.DomainHistory; import google.registry.model.domain.Period; import google.registry.model.eppcommon.Trid; import google.registry.model.reporting.HistoryEntry; @@ -56,8 +57,8 @@ public class PollMessageTest extends EntityTestCase { domain = persistResource(newDomainBase("foo.foobar", contact)); historyEntry = persistResource( - new HistoryEntry.Builder() - .setParent(domain) + new DomainHistory.Builder() + .setDomain(domain) .setType(HistoryEntry.Type.DOMAIN_CREATE) .setPeriod(Period.create(1, Period.Unit.YEARS)) .setXmlBytes("".getBytes(UTF_8)) diff --git a/core/src/test/java/google/registry/model/reporting/HistoryEntryTest.java b/core/src/test/java/google/registry/model/reporting/HistoryEntryTest.java index 39d1df8a7..b93e74d39 100644 --- a/core/src/test/java/google/registry/model/reporting/HistoryEntryTest.java +++ b/core/src/test/java/google/registry/model/reporting/HistoryEntryTest.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertThrows; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import google.registry.model.EntityTestCase; +import google.registry.model.contact.ContactHistory; import google.registry.model.domain.DomainBase; import google.registry.model.domain.DomainHistory; import google.registry.model.domain.Period; @@ -96,7 +97,7 @@ class HistoryEntryTest extends EntityTestCase { assertThrows( IllegalArgumentException.class, () -> - new HistoryEntry.Builder() + new ContactHistory.Builder() .setId(5L) .setModificationTime(DateTime.parse("1985-07-12T22:30:00Z")) .setClientId("TheRegistrar") @@ -111,7 +112,7 @@ class HistoryEntryTest extends EntityTestCase { assertThrows( IllegalArgumentException.class, () -> - new HistoryEntry.Builder() + new ContactHistory.Builder() .setId(5L) .setType(HistoryEntry.Type.CONTACT_CREATE) .setClientId("TheRegistrar") @@ -126,7 +127,7 @@ class HistoryEntryTest extends EntityTestCase { assertThrows( IllegalArgumentException.class, () -> - new HistoryEntry.Builder() + new ContactHistory.Builder() .setId(5L) .setType(HistoryEntry.Type.CONTACT_CREATE) .setModificationTime(DateTime.parse("1985-07-12T22:30:00Z")) @@ -141,7 +142,7 @@ class HistoryEntryTest extends EntityTestCase { assertThrows( IllegalArgumentException.class, () -> - new HistoryEntry.Builder() + new ContactHistory.Builder() .setId(5L) .setType(HistoryEntry.Type.SYNTHETIC) .setModificationTime(DateTime.parse("1985-07-12T22:30:00Z")) diff --git a/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java b/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java index b06f5ed87..1f5adc222 100644 --- a/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java +++ b/core/src/test/java/google/registry/rdap/RdapDomainSearchActionTest.java @@ -1147,9 +1147,9 @@ class RdapDomainSearchActionTest extends RdapSearchActionTestCase { tm().put(resource); tm().put( - new HistoryEntry.Builder() - .setParent(resource) + HistoryEntry.createBuilderForResource(resource) .setClientId(resource.getCreationClientId()) .setType(getHistoryEntryType(resource)) .setModificationTime(tm().getTransactionTime()) @@ -1158,10 +1158,9 @@ public class DatabaseHelper { public static HistoryEntry createHistoryEntryForEppResource( T parentResource) { return persistResource( - new HistoryEntry.Builder() + HistoryEntry.createBuilderForResource(parentResource) .setType(getHistoryEntryType(parentResource)) .setModificationTime(DateTime.now(DateTimeZone.UTC)) - .setParent(parentResource) .setClientId(parentResource.getPersistedCurrentSponsorClientId()) .build()); } diff --git a/core/src/test/java/google/registry/testing/FullFieldsTestEntityHelper.java b/core/src/test/java/google/registry/testing/FullFieldsTestEntityHelper.java index 0588cd6e8..13f7edc80 100644 --- a/core/src/test/java/google/registry/testing/FullFieldsTestEntityHelper.java +++ b/core/src/test/java/google/registry/testing/FullFieldsTestEntityHelper.java @@ -385,18 +385,16 @@ public final class FullFieldsTestEntityHelper { Period period, String reason, DateTime modificationTime) { - HistoryEntry.Builder builder = - new HistoryEntry.Builder() - .setParent(resource) - .setType(type) - .setPeriod(period) - .setXmlBytes("".getBytes(UTF_8)) - .setModificationTime(modificationTime) - .setClientId(resource.getPersistedCurrentSponsorClientId()) - .setTrid(Trid.create("ABC-123", "server-trid")) - .setBySuperuser(false) - .setReason(reason) - .setRequestedByRegistrar(false); - return builder.build(); + return HistoryEntry.createBuilderForResource(resource) + .setType(type) + .setPeriod(period) + .setXmlBytes("".getBytes(UTF_8)) + .setModificationTime(modificationTime) + .setClientId(resource.getPersistedCurrentSponsorClientId()) + .setTrid(Trid.create("ABC-123", "server-trid")) + .setBySuperuser(false) + .setReason(reason) + .setRequestedByRegistrar(false) + .build(); } } diff --git a/core/src/test/java/google/registry/tools/DedupeOneTimeBillingEventIdsCommandTest.java b/core/src/test/java/google/registry/tools/DedupeOneTimeBillingEventIdsCommandTest.java index 440936ccb..5e8ea92ca 100644 --- a/core/src/test/java/google/registry/tools/DedupeOneTimeBillingEventIdsCommandTest.java +++ b/core/src/test/java/google/registry/tools/DedupeOneTimeBillingEventIdsCommandTest.java @@ -128,8 +128,7 @@ class DedupeOneTimeBillingEventIdsCommandTest private HistoryEntry persistHistoryEntry(EppResource parent) { return persistResource( - new HistoryEntry.Builder() - .setParent(parent) + HistoryEntry.createBuilderForResource(parent) .setType(HistoryEntry.Type.DOMAIN_CREATE) .setPeriod(Period.create(1, Period.Unit.YEARS)) .setXmlBytes("".getBytes(UTF_8)) diff --git a/core/src/test/java/google/registry/tools/javascrap/BackfillRegistryLocksCommandTest.java b/core/src/test/java/google/registry/tools/javascrap/BackfillRegistryLocksCommandTest.java index a22db4747..816094f34 100644 --- a/core/src/test/java/google/registry/tools/javascrap/BackfillRegistryLocksCommandTest.java +++ b/core/src/test/java/google/registry/tools/javascrap/BackfillRegistryLocksCommandTest.java @@ -33,6 +33,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.truth.Truth8; import google.registry.model.domain.DomainBase; +import google.registry.model.domain.DomainHistory; import google.registry.model.registrar.Registrar; import google.registry.model.reporting.HistoryEntry; import google.registry.schema.domain.RegistryLock; @@ -127,11 +128,11 @@ class BackfillRegistryLocksCommandTest extends CommandTestCase gracePeriodHistories; + java.util.Set dsDataHistories; java.util.Set domainTransactionRecords; + java.util.Set> nsHosts; org.joda.time.DateTime modificationTime; } class google.registry.model.domain.GracePeriod { @@ -298,6 +301,16 @@ class google.registry.model.domain.GracePeriod { long gracePeriodId; org.joda.time.DateTime expirationTime; } +class google.registry.model.domain.GracePeriod$GracePeriodHistory { + google.registry.model.domain.rgp.GracePeriodStatus type; + google.registry.persistence.BillingVKey$BillingEventVKey billingEventOneTime; + google.registry.persistence.BillingVKey$BillingRecurrenceVKey billingEventRecurring; + java.lang.Long domainHistoryRevisionId; + java.lang.Long gracePeriodHistoryRevisionId; + java.lang.String clientId; + long gracePeriodId; + org.joda.time.DateTime expirationTime; +} class google.registry.model.domain.Period { google.registry.model.domain.Period$Unit unit; java.lang.Integer value; @@ -330,6 +343,14 @@ class google.registry.model.domain.secdns.DelegationSignerData { int digestType; int keyTag; } +class google.registry.model.domain.secdns.DomainDsDataHistory { + byte[] digest; + int algorithm; + int digestType; + int keyTag; + java.lang.Long domainHistoryRevisionId; + java.lang.Long dsDataHistoryRevisionId; +} class google.registry.model.domain.token.AllocationToken { @Id java.lang.String token; boolean discountPremiums;