From 1c90a6648e31abec2deddb92e7fa03bf58ef3a19 Mon Sep 17 00:00:00 2001 From: Lai Jiang Date: Fri, 28 Oct 2022 12:25:57 -0400 Subject: [PATCH] Remove bulk query entities (#1834) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These alternative ORMs are introduced as a way to make querying large number of domains and domain histories more efficient through bulk loading from several to-be-joined tables separately, then in-memory re-assembly of the final entity, bypassing the need to query multiple tables each time an entity is queried. Their primary use case is loading these entities for comparison between datastore and SQL during the migration, which has been completed. The code remain unused as of now and their existence makes refactoring and general maintenance more complicated than necessary due to the need to keep them up to date. Therefore we remove the related code. - - - This change is [Reviewable](https://reviewable.io/reviews/google/nomulus/1834) --- .../common/RegistryPipelineComponent.java | 10 - .../RegistryPipelineWorkerInitializer.java | 3 - .../model/bulkquery/BulkQueryEntities.java | 112 --------- .../model/bulkquery/DomainHistoryHost.java | 69 ------ .../model/bulkquery/DomainHistoryLite.java | 125 ---------- .../registry/model/bulkquery/DomainHost.java | 64 ----- .../registry/model/bulkquery/DomainLite.java | 48 ---- .../registry/model/domain/DomainHistory.java | 14 -- .../persistence/BulkQueryJpaFactory.java | 65 ------ .../persistence/PersistenceModule.java | 22 -- .../common/RegistryPipelineOptionsTest.java | 12 - .../model/bulkquery/BulkQueryHelper.java | 89 ------- .../bulkquery/DomainHistoryLiteTest.java | 125 ---------- .../model/bulkquery/DomainLiteTest.java | 111 --------- .../model/bulkquery/TestSetupHelper.java | 219 ------------------ 15 files changed, 1088 deletions(-) delete mode 100644 core/src/main/java/google/registry/model/bulkquery/BulkQueryEntities.java delete mode 100644 core/src/main/java/google/registry/model/bulkquery/DomainHistoryHost.java delete mode 100644 core/src/main/java/google/registry/model/bulkquery/DomainHistoryLite.java delete mode 100644 core/src/main/java/google/registry/model/bulkquery/DomainHost.java delete mode 100644 core/src/main/java/google/registry/model/bulkquery/DomainLite.java delete mode 100644 core/src/main/java/google/registry/persistence/BulkQueryJpaFactory.java delete mode 100644 core/src/test/java/google/registry/model/bulkquery/BulkQueryHelper.java delete mode 100644 core/src/test/java/google/registry/model/bulkquery/DomainHistoryLiteTest.java delete mode 100644 core/src/test/java/google/registry/model/bulkquery/DomainLiteTest.java delete mode 100644 core/src/test/java/google/registry/model/bulkquery/TestSetupHelper.java diff --git a/core/src/main/java/google/registry/beam/common/RegistryPipelineComponent.java b/core/src/main/java/google/registry/beam/common/RegistryPipelineComponent.java index f89d11eaa..461461b6a 100644 --- a/core/src/main/java/google/registry/beam/common/RegistryPipelineComponent.java +++ b/core/src/main/java/google/registry/beam/common/RegistryPipelineComponent.java @@ -20,9 +20,7 @@ import dagger.Lazy; import google.registry.config.CredentialModule; import google.registry.config.RegistryConfig.Config; import google.registry.config.RegistryConfig.ConfigModule; -import google.registry.model.domain.Domain; import google.registry.persistence.PersistenceModule; -import google.registry.persistence.PersistenceModule.BeamBulkQueryJpaTm; import google.registry.persistence.PersistenceModule.BeamJpaTm; import google.registry.persistence.PersistenceModule.BeamReadOnlyReplicaJpaTm; import google.registry.persistence.PersistenceModule.TransactionIsolationLevel; @@ -52,14 +50,6 @@ public interface RegistryPipelineComponent { @BeamJpaTm Lazy getJpaTransactionManager(); - /** - * Returns a {@link JpaTransactionManager} optimized for bulk loading multi-level JPA entities - * ({@link Domain} and {@link google.registry.model.domain.DomainHistory}). Please refer to {@link - * google.registry.model.bulkquery.BulkQueryEntities} for more information. - */ - @BeamBulkQueryJpaTm - Lazy getBulkQueryJpaTransactionManager(); - /** * A {@link JpaTransactionManager} that uses the Postgres read-only replica if configured (uses * the standard DB otherwise). diff --git a/core/src/main/java/google/registry/beam/common/RegistryPipelineWorkerInitializer.java b/core/src/main/java/google/registry/beam/common/RegistryPipelineWorkerInitializer.java index ea6899b68..9a4dea183 100644 --- a/core/src/main/java/google/registry/beam/common/RegistryPipelineWorkerInitializer.java +++ b/core/src/main/java/google/registry/beam/common/RegistryPipelineWorkerInitializer.java @@ -55,9 +55,6 @@ public class RegistryPipelineWorkerInitializer implements JvmInitializer { toRegistryPipelineComponent(registryOptions); Lazy transactionManagerLazy; switch (registryOptions.getJpaTransactionManagerType()) { - case BULK_QUERY: - transactionManagerLazy = registryPipelineComponent.getBulkQueryJpaTransactionManager(); - break; case READ_ONLY_REPLICA: transactionManagerLazy = registryPipelineComponent.getReadOnlyReplicaJpaTransactionManager(); diff --git a/core/src/main/java/google/registry/model/bulkquery/BulkQueryEntities.java b/core/src/main/java/google/registry/model/bulkquery/BulkQueryEntities.java deleted file mode 100644 index 4aaba85a3..000000000 --- a/core/src/main/java/google/registry/model/bulkquery/BulkQueryEntities.java +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2021 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.model.bulkquery; - -import static com.google.common.collect.ImmutableSet.toImmutableSet; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import google.registry.model.domain.Domain; -import google.registry.model.domain.DomainBase; -import google.registry.model.domain.DomainHistory; -import google.registry.model.domain.GracePeriod; -import google.registry.model.domain.GracePeriod.GracePeriodHistory; -import google.registry.model.domain.secdns.DomainDsData; -import google.registry.model.domain.secdns.DomainDsDataHistory; -import google.registry.model.host.Host; -import google.registry.model.reporting.DomainTransactionRecord; -import google.registry.persistence.VKey; -import google.registry.persistence.transaction.JpaTransactionManager; - -/** - * Utilities for managing an alternative JPA entity model optimized for bulk loading multi-level - * entities such as {@link Domain} and {@link DomainHistory}. - * - *

In a bulk query for a multi-level JPA entity type, the JPA framework only generates a bulk - * query (SELECT * FROM table) for the base table. Then, for each row in the base table, additional - * queries are issued to load associated rows in child tables. This can be very slow when an entity - * type has multiple child tables. - * - *

We have defined an alternative entity model for {@link Domain} and {@link DomainHistory}, - * where the base table as well as the child tables are mapped to single-level entity types. The - * idea is to load each of these types using a bulk query, and assemble them into the target type in - * memory in a pipeline. The main use case is Datastore-Cloud SQL validation during the Registry - * database migration, where we will need the full database snapshots frequently. - */ -public class BulkQueryEntities { - /** - * The JPA entity classes in persistence.xml to replace when creating the {@link - * JpaTransactionManager} for bulk query. - */ - public static final ImmutableMap JPA_ENTITIES_REPLACEMENTS = - ImmutableMap.of( - Domain.class.getCanonicalName(), - DomainLite.class.getCanonicalName(), - DomainHistory.class.getCanonicalName(), - DomainHistoryLite.class.getCanonicalName()); - - /* The JPA entity classes that are not included in persistence.xml and need to be added to - * the {@link JpaTransactionManager} for bulk query.*/ - public static final ImmutableList JPA_ENTITIES_NEW = - ImmutableList.of( - DomainHost.class.getCanonicalName(), DomainHistoryHost.class.getCanonicalName()); - - public static Domain assembleDomain( - DomainLite domainLite, - ImmutableSet gracePeriods, - ImmutableSet domainDsData, - ImmutableSet> nsHosts) { - Domain.Builder builder = new Domain.Builder(); - builder.copyFrom(domainLite); - builder.setGracePeriods(gracePeriods); - builder.setDsData(domainDsData); - builder.setNameservers(nsHosts); - // Restore the original update timestamp (this gets cleared when we set nameservers or DS data). - builder.setUpdateTimestamp(domainLite.getUpdateTimestamp()); - return builder.build(); - } - - public static DomainHistory assembleDomainHistory( - DomainHistoryLite domainHistoryLite, - ImmutableSet dsDataHistories, - ImmutableSet> domainHistoryHosts, - ImmutableSet gracePeriodHistories, - ImmutableSet transactionRecords) { - DomainHistory.Builder builder = new DomainHistory.Builder(); - builder.copyFrom(domainHistoryLite); - DomainBase rawDomainBase = domainHistoryLite.domainBase; - if (rawDomainBase != null) { - DomainBase newDomainBase = - domainHistoryLite - .domainBase - .asBuilder() - .setNameservers(domainHistoryHosts) - .setGracePeriods( - gracePeriodHistories.stream() - .map(GracePeriod::createFromHistory) - .collect(toImmutableSet())) - .setDsData( - dsDataHistories.stream().map(DomainDsData::create).collect(toImmutableSet())) - // Restore the original update timestamp (this gets cleared when we set nameservers or - // DS data). - .setUpdateTimestamp(domainHistoryLite.domainBase.getUpdateTimestamp()) - .build(); - builder.setDomain(newDomainBase); - } - return builder.buildAndAssemble( - dsDataHistories, domainHistoryHosts, gracePeriodHistories, transactionRecords); - } -} diff --git a/core/src/main/java/google/registry/model/bulkquery/DomainHistoryHost.java b/core/src/main/java/google/registry/model/bulkquery/DomainHistoryHost.java deleted file mode 100644 index 8b328a26d..000000000 --- a/core/src/main/java/google/registry/model/bulkquery/DomainHistoryHost.java +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2021 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.model.bulkquery; - -import com.google.common.base.Objects; -import google.registry.model.domain.DomainHistory.DomainHistoryId; -import google.registry.model.host.Host; -import google.registry.persistence.VKey; -import java.io.Serializable; -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.IdClass; - -/** - * A name server host referenced by a {@link google.registry.model.domain.DomainHistory} record. - * Please refer to {@link BulkQueryEntities} for usage. - */ -@Entity -@Access(AccessType.FIELD) -@IdClass(DomainHistoryHost.class) -public class DomainHistoryHost implements Serializable { - - @Id private Long domainHistoryHistoryRevisionId; - @Id private String domainHistoryDomainRepoId; - @Id private String hostRepoId; - - private DomainHistoryHost() {} - - public DomainHistoryId getDomainHistoryId() { - return new DomainHistoryId(domainHistoryDomainRepoId, domainHistoryHistoryRevisionId); - } - - public VKey getHostVKey() { - return VKey.create(Host.class, hostRepoId); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof DomainHistoryHost)) { - return false; - } - DomainHistoryHost that = (DomainHistoryHost) o; - return Objects.equal(domainHistoryHistoryRevisionId, that.domainHistoryHistoryRevisionId) - && Objects.equal(domainHistoryDomainRepoId, that.domainHistoryDomainRepoId) - && Objects.equal(hostRepoId, that.hostRepoId); - } - - @Override - public int hashCode() { - return Objects.hashCode(domainHistoryHistoryRevisionId, domainHistoryDomainRepoId, hostRepoId); - } -} diff --git a/core/src/main/java/google/registry/model/bulkquery/DomainHistoryLite.java b/core/src/main/java/google/registry/model/bulkquery/DomainHistoryLite.java deleted file mode 100644 index 65243e8bd..000000000 --- a/core/src/main/java/google/registry/model/bulkquery/DomainHistoryLite.java +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2021 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.model.bulkquery; - -import com.googlecode.objectify.Key; -import google.registry.model.domain.Domain; -import google.registry.model.domain.DomainBase; -import google.registry.model.domain.DomainHistory; -import google.registry.model.domain.DomainHistory.DomainHistoryId; -import google.registry.model.domain.Period; -import google.registry.model.reporting.HistoryEntry; -import google.registry.persistence.VKey; -import javax.annotation.Nullable; -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.AttributeOverride; -import javax.persistence.AttributeOverrides; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.IdClass; -import javax.persistence.PostLoad; - -/** - * A 'light' version of {@link DomainHistory} with only base table ("DomainHistory") attributes, - * which allows fast bulk loading. They are used in in-memory assembly of {@code DomainHistory} - * instances along with bulk-loaded child entities ({@code GracePeriodHistory} etc). The in-memory - * assembly achieves much higher performance than loading {@code DomainHistory} directly. - * - *

Please refer to {@link BulkQueryEntities} for more information. - * - *

This class is adapted from {@link DomainHistory} by removing the {@code dsDataHistories}, - * {@code gracePeriodHistories}, and {@code nsHosts} fields and associated methods. - */ -@Entity(name = "DomainHistory") -@Access(AccessType.FIELD) -@IdClass(DomainHistoryId.class) -public class DomainHistoryLite extends HistoryEntry { - - // Store DomainBase instead of Domain so we don't pick up its @Id - // Nullable for the sake of pre-Registry-3.0 history objects - @Nullable DomainBase domainBase; - - @Id - @Access(AccessType.PROPERTY) - public String getDomainRepoId() { - // We need to handle null case here because Hibernate sometimes accesses this method before - // parent gets initialized - return parent == null ? null : parent.getName(); - } - - /** This method is private because it is only used by Hibernate. */ - @SuppressWarnings("unused") - private void setDomainRepoId(String domainRepoId) { - parent = Key.create(Domain.class, domainRepoId); - } - - @Override - @Nullable - @Access(AccessType.PROPERTY) - @AttributeOverrides({ - @AttributeOverride(name = "unit", column = @Column(name = "historyPeriodUnit")), - @AttributeOverride(name = "value", column = @Column(name = "historyPeriodValue")) - }) - public Period getPeriod() { - return super.getPeriod(); - } - - /** - * For transfers, the id of the other registrar. - * - *

For requests and cancels, the other registrar is the losing party (because the registrar - * sending the EPP transfer command is the gaining party). For approves and rejects, the other - * registrar is the gaining party. - */ - @Nullable - @Access(AccessType.PROPERTY) - @Column(name = "historyOtherRegistrarId") - @Override - public String getOtherRegistrarId() { - return super.getOtherRegistrarId(); - } - - @Id - @Column(name = "historyRevisionId") - @Access(AccessType.PROPERTY) - @Override - public long getId() { - return super.getId(); - } - - /** The key to the {@link Domain} this is based off of. */ - public VKey getParentVKey() { - return VKey.create(Domain.class, getDomainRepoId()); - } - - public DomainHistoryId getDomainHistoryId() { - return new DomainHistoryId(getDomainRepoId(), getId()); - } - - @PostLoad - void postLoad() { - if (domainBase == null) { - return; - } - // See inline comments in DomainHistory.postLoad for reasons for the following lines. - if (domainBase.getDomainName() == null) { - domainBase = null; - } else if (domainBase.getRepoId() == null) { - domainBase.setRepoId(parent.getName()); - } - } -} diff --git a/core/src/main/java/google/registry/model/bulkquery/DomainHost.java b/core/src/main/java/google/registry/model/bulkquery/DomainHost.java deleted file mode 100644 index a543cfb47..000000000 --- a/core/src/main/java/google/registry/model/bulkquery/DomainHost.java +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2021 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.model.bulkquery; - -import com.google.common.base.Objects; -import google.registry.model.host.Host; -import google.registry.persistence.VKey; -import java.io.Serializable; -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.IdClass; - -/** A name server host of a domain. Please refer to {@link BulkQueryEntities} for usage. */ -@Entity -@Access(AccessType.FIELD) -@IdClass(DomainHost.class) -public class DomainHost implements Serializable { - - @Id private String domainRepoId; - - @Id private String hostRepoId; - - DomainHost() {} - - public String getDomainRepoId() { - return domainRepoId; - } - - public VKey getHostVKey() { - return VKey.create(Host.class, hostRepoId); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof DomainHost)) { - return false; - } - DomainHost that = (DomainHost) o; - return Objects.equal(domainRepoId, that.domainRepoId) - && Objects.equal(hostRepoId, that.hostRepoId); - } - - @Override - public int hashCode() { - return Objects.hashCode(domainRepoId, hostRepoId); - } -} diff --git a/core/src/main/java/google/registry/model/bulkquery/DomainLite.java b/core/src/main/java/google/registry/model/bulkquery/DomainLite.java deleted file mode 100644 index a9f436c0d..000000000 --- a/core/src/main/java/google/registry/model/bulkquery/DomainLite.java +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2021 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.model.bulkquery; - -import google.registry.model.domain.Domain; -import google.registry.model.domain.DomainBase; -import google.registry.persistence.VKey; -import google.registry.persistence.WithVKey; -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.Entity; - -/** - * A 'light' version of {@link Domain} with only base table ("Domain") attributes, which allows fast - * bulk loading. They are used in in-memory assembly of {@code Domain} instances along with - * bulk-loaded child entities ({@code GracePeriod} etc). The in-memory assembly achieves much higher - * performance than loading {@code Domain} directly. - * - *

Please refer to {@link BulkQueryEntities} for more information. - */ -@Entity(name = "Domain") -@WithVKey(String.class) -@Access(AccessType.FIELD) -public class DomainLite extends DomainBase { - - @Override - @javax.persistence.Id - @Access(AccessType.PROPERTY) - public String getRepoId() { - return super.getRepoId(); - } - - public static VKey createVKey(String repoId) { - return VKey.createSql(DomainLite.class, repoId); - } -} 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 aa9117ebf..10f1c030c 100644 --- a/core/src/main/java/google/registry/model/domain/DomainHistory.java +++ b/core/src/main/java/google/registry/model/domain/DomainHistory.java @@ -403,19 +403,5 @@ public class DomainHistory extends HistoryEntry { fillAuxiliaryFieldsFromDomain(instance); return instance; } - - public DomainHistory buildAndAssemble( - ImmutableSet dsDataHistories, - ImmutableSet> domainHistoryHosts, - ImmutableSet gracePeriodHistories, - ImmutableSet transactionRecords) { - DomainHistory instance = super.build(); - instance.dsDataHistories = dsDataHistories; - instance.nsHosts = domainHistoryHosts; - instance.gracePeriodHistories = gracePeriodHistories; - instance.domainTransactionRecords = transactionRecords; - instance.hashCode = null; - return instance; - } } } diff --git a/core/src/main/java/google/registry/persistence/BulkQueryJpaFactory.java b/core/src/main/java/google/registry/persistence/BulkQueryJpaFactory.java deleted file mode 100644 index b846cf08c..000000000 --- a/core/src/main/java/google/registry/persistence/BulkQueryJpaFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2021 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.persistence; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Streams; -import google.registry.model.bulkquery.BulkQueryEntities; -import google.registry.persistence.transaction.JpaTransactionManager; -import google.registry.persistence.transaction.JpaTransactionManagerImpl; -import google.registry.util.Clock; -import java.util.List; -import javax.persistence.EntityManagerFactory; -import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; -import org.hibernate.jpa.boot.spi.Bootstrap; - -/** - * Defines factory method for instantiating the bulk-query optimized {@link JpaTransactionManager}. - */ -public final class BulkQueryJpaFactory { - - private BulkQueryJpaFactory() {} - - static EntityManagerFactory createBulkQueryEntityManagerFactory( - ImmutableMap cloudSqlConfigs) { - ParsedPersistenceXmlDescriptor descriptor = - PersistenceXmlUtility.getParsedPersistenceXmlDescriptor(); - - List updatedManagedClasses = - Streams.concat( - descriptor.getManagedClassNames().stream(), - BulkQueryEntities.JPA_ENTITIES_NEW.stream()) - .map( - name -> { - if (BulkQueryEntities.JPA_ENTITIES_REPLACEMENTS.containsKey(name)) { - return BulkQueryEntities.JPA_ENTITIES_REPLACEMENTS.get(name); - } - return name; - }) - .collect(ImmutableList.toImmutableList()); - - descriptor.getManagedClassNames().clear(); - descriptor.getManagedClassNames().addAll(updatedManagedClasses); - - return Bootstrap.getEntityManagerFactoryBuilder(descriptor, cloudSqlConfigs).build(); - } - - public static JpaTransactionManager createBulkQueryJpaTransactionManager( - ImmutableMap cloudSqlConfigs, Clock clock) { - return new JpaTransactionManagerImpl( - createBulkQueryEntityManagerFactory(cloudSqlConfigs), clock); - } -} diff --git a/core/src/main/java/google/registry/persistence/PersistenceModule.java b/core/src/main/java/google/registry/persistence/PersistenceModule.java index bee057e11..62ff1334c 100644 --- a/core/src/main/java/google/registry/persistence/PersistenceModule.java +++ b/core/src/main/java/google/registry/persistence/PersistenceModule.java @@ -241,15 +241,6 @@ public abstract class PersistenceModule { return new JpaTransactionManagerImpl(create(beamCloudSqlConfigs), clock); } - @Provides - @Singleton - @BeamBulkQueryJpaTm - static JpaTransactionManager provideBeamBulkQueryJpaTm( - @BeamPipelineCloudSqlConfigs ImmutableMap beamCloudSqlConfigs, Clock clock) { - return new JpaTransactionManagerImpl( - BulkQueryJpaFactory.createBulkQueryEntityManagerFactory(beamCloudSqlConfigs), clock); - } - @Provides @Singleton @NomulusToolJpaTm @@ -371,11 +362,6 @@ public abstract class PersistenceModule { public enum JpaTransactionManagerType { /** The regular {@link JpaTransactionManager} for general use. */ REGULAR, - /** - * The {@link JpaTransactionManager} optimized for bulk loading multi-level JPA entities. Please - * see {@link google.registry.model.bulkquery.BulkQueryEntities} for more information. - */ - BULK_QUERY, /** * The {@link JpaTransactionManager} that uses the read-only Postgres replica if configured, or * the standard DB if not. @@ -398,14 +384,6 @@ public abstract class PersistenceModule { @Documented public @interface BeamJpaTm {} - /** - * Dagger qualifier for {@link JpaTransactionManager} that uses an alternative entity model for - * faster bulk queries. - */ - @Qualifier - @Documented - public @interface BeamBulkQueryJpaTm {} - /** * Dagger qualifier for {@link JpaTransactionManager} used inside BEAM pipelines that uses the * read-only Postgres replica if one is configured (otherwise it uses the standard DB). diff --git a/core/src/test/java/google/registry/beam/common/RegistryPipelineOptionsTest.java b/core/src/test/java/google/registry/beam/common/RegistryPipelineOptionsTest.java index fc8d981e6..e5c61ef4d 100644 --- a/core/src/test/java/google/registry/beam/common/RegistryPipelineOptionsTest.java +++ b/core/src/test/java/google/registry/beam/common/RegistryPipelineOptionsTest.java @@ -145,16 +145,4 @@ class RegistryPipelineOptionsTest { .as(RegistryPipelineOptions.class); assertThat(options.getJpaTransactionManagerType()).isEqualTo(JpaTransactionManagerType.REGULAR); } - - @Test - void jpaTransactionManagerType_bulkQueryJpa() { - RegistryPipelineOptions options = - PipelineOptionsFactory.fromArgs( - "--registryEnvironment=" + RegistryEnvironment.UNITTEST.name(), - "--jpaTransactionManagerType=BULK_QUERY") - .withValidation() - .as(RegistryPipelineOptions.class); - assertThat(options.getJpaTransactionManagerType()) - .isEqualTo(JpaTransactionManagerType.BULK_QUERY); - } } diff --git a/core/src/test/java/google/registry/model/bulkquery/BulkQueryHelper.java b/core/src/test/java/google/registry/model/bulkquery/BulkQueryHelper.java deleted file mode 100644 index ad9ff4a4b..000000000 --- a/core/src/test/java/google/registry/model/bulkquery/BulkQueryHelper.java +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2021 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.model.bulkquery; - -import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static google.registry.model.bulkquery.BulkQueryEntities.assembleDomain; -import static google.registry.model.bulkquery.BulkQueryEntities.assembleDomainHistory; -import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; - -import google.registry.model.domain.Domain; -import google.registry.model.domain.DomainHistory; -import google.registry.model.domain.DomainHistory.DomainHistoryId; -import google.registry.model.domain.GracePeriod; -import google.registry.model.domain.GracePeriod.GracePeriodHistory; -import google.registry.model.domain.secdns.DomainDsData; -import google.registry.model.domain.secdns.DomainDsDataHistory; -import google.registry.model.reporting.DomainTransactionRecord; -import google.registry.persistence.VKey; - -/** - * Helpers for bulk-loading {@link Domain} and {@link google.registry.model.domain.DomainHistory} - * entities in tests. - */ -public class BulkQueryHelper { - - static Domain loadAndAssembleDomain(String domainRepoId) { - return jpaTm() - .transact( - () -> - assembleDomain( - jpaTm().loadByKey(DomainLite.createVKey(domainRepoId)), - jpaTm() - .loadAllOfStream(GracePeriod.class) - .filter(gracePeriod -> gracePeriod.getDomainRepoId().equals(domainRepoId)) - .collect(toImmutableSet()), - jpaTm() - .loadAllOfStream(DomainDsData.class) - .filter(dsData -> dsData.getDomainRepoId().equals(domainRepoId)) - .collect(toImmutableSet()), - jpaTm() - .loadAllOfStream(DomainHost.class) - .filter(domainHost -> domainHost.getDomainRepoId().equals(domainRepoId)) - .map(DomainHost::getHostVKey) - .collect(toImmutableSet()))); - } - - static DomainHistory loadAndAssembleDomainHistory(DomainHistoryId domainHistoryId) { - return jpaTm() - .transact( - () -> - assembleDomainHistory( - jpaTm().loadByKey(VKey.createSql(DomainHistoryLite.class, domainHistoryId)), - jpaTm() - .loadAllOfStream(DomainDsDataHistory.class) - .filter( - domainDsDataHistory -> - domainDsDataHistory.getDomainHistoryId().equals(domainHistoryId)) - .collect(toImmutableSet()), - jpaTm() - .loadAllOfStream(DomainHistoryHost.class) - .filter( - domainHistoryHost -> - domainHistoryHost.getDomainHistoryId().equals(domainHistoryId)) - .map(DomainHistoryHost::getHostVKey) - .collect(toImmutableSet()), - jpaTm() - .loadAllOfStream(GracePeriodHistory.class) - .filter( - gracePeriodHistory -> - gracePeriodHistory.getDomainHistoryId().equals(domainHistoryId)) - .collect(toImmutableSet()), - jpaTm() - .loadAllOfStream(DomainTransactionRecord.class) - .filter(x -> true) - .collect(toImmutableSet()))); - } -} diff --git a/core/src/test/java/google/registry/model/bulkquery/DomainHistoryLiteTest.java b/core/src/test/java/google/registry/model/bulkquery/DomainHistoryLiteTest.java deleted file mode 100644 index db9ed65d9..000000000 --- a/core/src/test/java/google/registry/model/bulkquery/DomainHistoryLiteTest.java +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2021 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.model.bulkquery; - -import static com.google.common.truth.Truth.assertThat; -import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; -import static org.joda.time.DateTimeZone.UTC; - -import com.google.common.collect.Sets; -import com.google.common.collect.Sets.SetView; -import com.google.common.truth.Truth8; -import google.registry.model.domain.DomainHistory; -import google.registry.testing.AppEngineExtension; -import google.registry.testing.FakeClock; -import java.util.Set; -import java.util.stream.Collectors; -import javax.persistence.metamodel.Attribute; -import org.joda.time.DateTime; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -/** Unit tests for {@link DomainHistoryLite}. */ -public class DomainHistoryLiteTest { - - protected FakeClock fakeClock = new FakeClock(DateTime.now(UTC)); - - @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withCloudSql().withClock(fakeClock).build(); - - private final TestSetupHelper setupHelper = new TestSetupHelper(fakeClock); - - @BeforeEach - void setUp() { - setupHelper.initializeAllEntities(); - } - - @AfterEach - void afterEach() { - setupHelper.tearDownBulkQueryJpaTm(); - } - - @Test - void readDomainHistoryHost() { - setupHelper.applyChangeToDomainAndHistory(); - setupHelper.setupBulkQueryJpaTm(appEngine); - Truth8.assertThat( - jpaTm().transact(() -> jpaTm().loadAllOf(DomainHistoryHost.class)).stream() - .map(DomainHistoryHost::getHostVKey)) - .containsExactly(setupHelper.host.createVKey()); - } - - @Test - void domainHistoryLiteAttributes_versusDomainHistory() { - Set domainHistoryAttributes = - jpaTm() - .transact( - () -> - jpaTm() - .getEntityManager() - .getMetamodel() - .entity(DomainHistory.class) - .getAttributes()) - .stream() - .map(Attribute::getName) - .collect(Collectors.toSet()); - setupHelper.setupBulkQueryJpaTm(appEngine); - Set domainHistoryLiteAttributes = - jpaTm() - .transact( - () -> - jpaTm() - .getEntityManager() - .getMetamodel() - .entity(DomainHistoryLite.class) - .getAttributes()) - .stream() - .map(Attribute::getName) - .collect(Collectors.toSet()); - - assertThat(domainHistoryAttributes).containsAtLeastElementsIn(domainHistoryLiteAttributes); - - SetView excludedFromDomainHistory = - Sets.difference(domainHistoryAttributes, domainHistoryLiteAttributes); - assertThat(excludedFromDomainHistory) - .containsExactly( - "dsDataHistories", - "gracePeriodHistories", - "internalDomainTransactionRecords", - "nsHosts"); - } - - @Test - void readDomainHistory_noContent() { - setupHelper.setupBulkQueryJpaTm(appEngine); - assertThat( - BulkQueryHelper.loadAndAssembleDomainHistory( - setupHelper.domainHistory.getDomainHistoryId())) - .isEqualTo(setupHelper.domainHistory); - } - - @Test - void readDomainHistory_full() { - setupHelper.applyChangeToDomainAndHistory(); - setupHelper.setupBulkQueryJpaTm(appEngine); - assertThat( - BulkQueryHelper.loadAndAssembleDomainHistory( - setupHelper.domainHistory.getDomainHistoryId())) - .isEqualTo(setupHelper.domainHistory); - } -} diff --git a/core/src/test/java/google/registry/model/bulkquery/DomainLiteTest.java b/core/src/test/java/google/registry/model/bulkquery/DomainLiteTest.java deleted file mode 100644 index a8a5c5569..000000000 --- a/core/src/test/java/google/registry/model/bulkquery/DomainLiteTest.java +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2021 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.model.bulkquery; - -import static com.google.common.truth.Truth.assertThat; -import static google.registry.model.bulkquery.BulkQueryHelper.loadAndAssembleDomain; -import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; -import static org.joda.time.DateTimeZone.UTC; - -import com.google.common.collect.Sets; -import com.google.common.collect.Sets.SetView; -import com.google.common.truth.Truth8; -import google.registry.model.domain.Domain; -import google.registry.testing.AppEngineExtension; -import google.registry.testing.FakeClock; -import java.util.Set; -import java.util.stream.Collectors; -import javax.persistence.metamodel.Attribute; -import org.joda.time.DateTime; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -/** Unit tests for reading {@link DomainLite}. */ -class DomainLiteTest { - - protected FakeClock fakeClock = new FakeClock(DateTime.now(UTC)); - - @RegisterExtension - public final AppEngineExtension appEngine = - AppEngineExtension.builder().withCloudSql().withClock(fakeClock).build(); - - private final TestSetupHelper setupHelper = new TestSetupHelper(fakeClock); - - @BeforeEach - void setUp() { - setupHelper.initializeAllEntities(); - } - - @AfterEach - void afterEach() { - setupHelper.tearDownBulkQueryJpaTm(); - } - - @Test - void readDomainHost() { - setupHelper.applyChangeToDomainAndHistory(); - setupHelper.setupBulkQueryJpaTm(appEngine); - Truth8.assertThat( - jpaTm().transact(() -> jpaTm().loadAllOf(DomainHost.class)).stream() - .map(DomainHost::getHostVKey)) - .containsExactly(setupHelper.host.createVKey()); - } - - @Test - void domainLiteAttributes_versusDomain() { - Set domainAttributes = - jpaTm() - .transact( - () -> - jpaTm().getEntityManager().getMetamodel().entity(Domain.class).getAttributes()) - .stream() - .map(Attribute::getName) - .collect(Collectors.toSet()); - setupHelper.setupBulkQueryJpaTm(appEngine); - Set domainLiteAttributes = - jpaTm() - .transact( - () -> - jpaTm() - .getEntityManager() - .getMetamodel() - .entity(DomainLite.class) - .getAttributes()) - .stream() - .map(Attribute::getName) - .collect(Collectors.toSet()); - - assertThat(domainAttributes).containsAtLeastElementsIn(domainLiteAttributes); - - SetView excludedFromDomain = Sets.difference(domainAttributes, domainLiteAttributes); - assertThat(excludedFromDomain) - .containsExactly("internalDelegationSignerData", "internalGracePeriods", "nsHosts"); - } - - @Test - void readDomainLite_simple() { - setupHelper.setupBulkQueryJpaTm(appEngine); - assertThat(loadAndAssembleDomain(TestSetupHelper.DOMAIN_REPO_ID)).isEqualTo(setupHelper.domain); - } - - @Test - void readDomainLite_full() { - setupHelper.applyChangeToDomainAndHistory(); - setupHelper.setupBulkQueryJpaTm(appEngine); - assertThat(loadAndAssembleDomain(TestSetupHelper.DOMAIN_REPO_ID)).isEqualTo(setupHelper.domain); - } -} diff --git a/core/src/test/java/google/registry/model/bulkquery/TestSetupHelper.java b/core/src/test/java/google/registry/model/bulkquery/TestSetupHelper.java deleted file mode 100644 index e5ad5062a..000000000 --- a/core/src/test/java/google/registry/model/bulkquery/TestSetupHelper.java +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2021 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.model.bulkquery; - -import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm; -import static google.registry.testing.SqlHelper.saveRegistrar; -import static google.registry.util.DateTimeUtils.END_OF_TIME; -import static google.registry.util.DateTimeUtils.START_OF_TIME; -import static java.nio.charset.StandardCharsets.UTF_8; - -import com.google.common.base.Ascii; -import com.google.common.collect.ImmutableSet; -import google.registry.model.contact.Contact; -import google.registry.model.domain.DesignatedContact; -import google.registry.model.domain.Domain; -import google.registry.model.domain.DomainAuthInfo; -import google.registry.model.domain.DomainHistory; -import google.registry.model.domain.GracePeriod; -import google.registry.model.domain.Period; -import google.registry.model.domain.launch.LaunchNotice; -import google.registry.model.domain.rgp.GracePeriodStatus; -import google.registry.model.domain.secdns.DomainDsData; -import google.registry.model.eppcommon.AuthInfo.PasswordAuth; -import google.registry.model.eppcommon.StatusValue; -import google.registry.model.eppcommon.Trid; -import google.registry.model.host.Host; -import google.registry.model.registrar.Registrar; -import google.registry.model.reporting.DomainTransactionRecord; -import google.registry.model.reporting.DomainTransactionRecord.TransactionReportField; -import google.registry.model.reporting.HistoryEntry; -import google.registry.model.tld.Registry; -import google.registry.model.transfer.ContactTransferData; -import google.registry.persistence.BulkQueryJpaFactory; -import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension; -import google.registry.persistence.transaction.JpaTransactionManager; -import google.registry.persistence.transaction.TransactionManagerFactory; -import google.registry.testing.AppEngineExtension; -import google.registry.testing.DatabaseHelper; -import google.registry.testing.FakeClock; - -/** - * Utilities for managing domain-related SQL test scenarios. - * - *

The {@link #initializeAllEntities} method initializes the database, and the {@link - * #applyChangeToDomainAndHistory} makes one change to the domain, generating an additional history - * event. The most up-to-date values of the relevant entities are saved in public instance - * variables, {@link #domain} etc. - * - *

This class makes use of {@link DatabaseHelper}, which requires Datastore. Tests that use this - * class should use {@link AppEngineExtension}. - */ -public final class TestSetupHelper { - - public static final String TLD = "tld"; - public static final String DOMAIN_REPO_ID = "4-TLD"; - public static final String DOMAIN_NAME = "example.tld"; - public static final String REGISTRAR_ID = "AnRegistrar"; - - private final FakeClock fakeClock; - - public Registry registry; - public Registrar registrar; - public Contact contact; - public Domain domain; - public DomainHistory domainHistory; - public Host host; - - private JpaTransactionManager originalJpaTm; - private JpaTransactionManager bulkQueryJpaTm; - - public TestSetupHelper(FakeClock fakeClock) { - this.fakeClock = fakeClock; - } - - public void initializeAllEntities() { - registry = putInDb(DatabaseHelper.newRegistry(TLD, Ascii.toUpperCase(TLD))); - registrar = saveRegistrar(REGISTRAR_ID); - contact = putInDb(createContact(DOMAIN_REPO_ID, REGISTRAR_ID)); - domain = putInDb(createSimpleDomain(contact)); - domainHistory = putInDb(createHistoryWithoutContent(domain, fakeClock)); - host = putInDb(createHost()); - } - - public void applyChangeToDomainAndHistory() { - domain = putInDb(createFullDomain(contact, host, fakeClock)); - domainHistory = putInDb(createFullHistory(domain, fakeClock)); - } - - public void setupBulkQueryJpaTm(AppEngineExtension appEngineExtension) { - bulkQueryJpaTm = - BulkQueryJpaFactory.createBulkQueryJpaTransactionManager( - appEngineExtension - .getJpaIntegrationTestExtension() - .map(JpaIntegrationTestExtension::getJpaProperties) - .orElseThrow( - () -> new IllegalStateException("Expecting JpaIntegrationTestExtension.")), - fakeClock); - originalJpaTm = TransactionManagerFactory.jpaTm(); - TransactionManagerFactory.setJpaTm(() -> bulkQueryJpaTm); - } - - public void tearDownBulkQueryJpaTm() { - if (bulkQueryJpaTm != null) { - bulkQueryJpaTm.teardown(); - TransactionManagerFactory.setJpaTm(() -> originalJpaTm); - } - } - - static Contact createContact(String repoId, String registrarId) { - return new Contact.Builder() - .setRepoId(repoId) - .setCreationRegistrarId(registrarId) - .setTransferData(new ContactTransferData.Builder().build()) - .setPersistedCurrentSponsorRegistrarId(registrarId) - .build(); - } - - static Domain createSimpleDomain(Contact contact) { - return DatabaseHelper.newDomain(DOMAIN_NAME, DOMAIN_REPO_ID, contact) - .asBuilder() - .setCreationRegistrarId(REGISTRAR_ID) - .setPersistedCurrentSponsorRegistrarId(REGISTRAR_ID) - .build(); - } - - static Domain createFullDomain(Contact contact, Host host, FakeClock fakeClock) { - return createSimpleDomain(contact) - .asBuilder() - .setDomainName(DOMAIN_NAME) - .setRepoId(DOMAIN_REPO_ID) - .setCreationRegistrarId(REGISTRAR_ID) - .setLastEppUpdateTime(fakeClock.nowUtc()) - .setLastEppUpdateRegistrarId(REGISTRAR_ID) - .setLastTransferTime(fakeClock.nowUtc()) - .setNameservers(host.createVKey()) - .setStatusValues( - ImmutableSet.of( - StatusValue.CLIENT_DELETE_PROHIBITED, - StatusValue.SERVER_DELETE_PROHIBITED, - StatusValue.SERVER_TRANSFER_PROHIBITED, - StatusValue.SERVER_UPDATE_PROHIBITED, - StatusValue.SERVER_RENEW_PROHIBITED, - StatusValue.SERVER_HOLD)) - .setContacts( - ImmutableSet.of( - DesignatedContact.create(DesignatedContact.Type.ADMIN, contact.createVKey()))) - .setSubordinateHosts(ImmutableSet.of("ns1.example.com")) - .setPersistedCurrentSponsorRegistrarId(REGISTRAR_ID) - .setRegistrationExpirationTime(fakeClock.nowUtc().plusYears(1)) - .setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("password"))) - .setDsData(ImmutableSet.of(DomainDsData.create(1, 2, 3, new byte[] {0, 1, 2}))) - .setLaunchNotice(LaunchNotice.create("tcnid", "validatorId", START_OF_TIME, START_OF_TIME)) - .setSmdId("smdid") - .addGracePeriod( - GracePeriod.create( - GracePeriodStatus.ADD, DOMAIN_REPO_ID, END_OF_TIME, REGISTRAR_ID, null, 100L)) - .build(); - } - - static Host createHost() { - return new Host.Builder() - .setRepoId("host1") - .setHostName("ns1.example.com") - .setCreationRegistrarId(REGISTRAR_ID) - .setPersistedCurrentSponsorRegistrarId(REGISTRAR_ID) - .build(); - } - - static DomainTransactionRecord createDomainTransactionRecord(FakeClock fakeClock) { - return new DomainTransactionRecord.Builder() - .setTld(TLD) - .setReportingTime(fakeClock.nowUtc()) - .setReportField(TransactionReportField.NET_ADDS_1_YR) - .setReportAmount(1) - .build(); - } - - static DomainHistory createHistoryWithoutContent(Domain domain, FakeClock fakeClock) { - return new DomainHistory.Builder() - .setType(HistoryEntry.Type.DOMAIN_CREATE) - .setXmlBytes("".getBytes(UTF_8)) - .setModificationTime(fakeClock.nowUtc()) - .setRegistrarId(REGISTRAR_ID) - .setTrid(Trid.create("ABC-123", "server-trid")) - .setBySuperuser(false) - .setReason("reason") - .setRequestedByRegistrar(true) - .setDomainRepoId(domain.getRepoId()) - .setOtherRegistrarId("otherClient") - .setPeriod(Period.create(1, Period.Unit.YEARS)) - .build(); - } - - static DomainHistory createFullHistory(Domain domain, FakeClock fakeClock) { - return createHistoryWithoutContent(domain, fakeClock) - .asBuilder() - .setType(HistoryEntry.Type.DOMAIN_TRANSFER_APPROVE) - .setDomain(domain) - .setDomainTransactionRecords(ImmutableSet.of(createDomainTransactionRecord(fakeClock))) - .build(); - } - - static T putInDb(T entity) { - jpaTm().transact(() -> jpaTm().put(entity)); - return jpaTm().transact(() -> jpaTm().loadByEntity(entity)); - } -}