From 4c6e160244254a55b4e7d607f0900853acbd533b Mon Sep 17 00:00:00 2001 From: gbrodman Date: Wed, 9 Oct 2019 15:15:04 -0400 Subject: [PATCH] Load persistence.xml classes before adding test entities (#307) * Load persistence.xml classes before adding test entities * Also use persistence.xml in GenerateSqlSchemaCommand * Add exception message * remove duplicate line --- .../tools/GenerateSqlSchemaCommand.java | 68 +++++++++---------- .../model/registry/RegistryLockDaoTest.java | 5 +- .../JpaTransactionManagerRule.java | 22 ++++-- .../CreateAutoTimestampConverterTest.java | 13 +--- .../UpdateAutoTimestampConverterTest.java | 13 +--- .../ZonedDateTimeConverterTest.java | 2 +- .../schema/tld/PremiumListDaoTest.java | 5 +- 7 files changed, 54 insertions(+), 74 deletions(-) diff --git a/core/src/main/java/google/registry/tools/GenerateSqlSchemaCommand.java b/core/src/main/java/google/registry/tools/GenerateSqlSchemaCommand.java index 4f2e1bef2..6e39fd5e5 100644 --- a/core/src/main/java/google/registry/tools/GenerateSqlSchemaCommand.java +++ b/core/src/main/java/google/registry/tools/GenerateSqlSchemaCommand.java @@ -19,34 +19,23 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableSet; -import google.registry.model.domain.DesignatedContact; -import google.registry.model.domain.DomainBase; -import google.registry.model.domain.GracePeriod; -import google.registry.model.domain.secdns.DelegationSignerData; -import google.registry.model.eppcommon.Trid; -import google.registry.model.transfer.BaseTransferObject; -import google.registry.model.transfer.TransferData; -import google.registry.persistence.CreateAutoTimestampConverter; import google.registry.persistence.NomulusNamingStrategy; import google.registry.persistence.NomulusPostgreSQLDialect; -import google.registry.persistence.UpdateAutoTimestampConverter; -import google.registry.persistence.ZonedDateTimeConverter; -import google.registry.schema.domain.RegistryLock; -import google.registry.schema.tld.PremiumList; -import google.registry.schema.tmch.ClaimsList; +import google.registry.persistence.PersistenceModule; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.EnumSet; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Environment; +import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; +import org.hibernate.jpa.boot.internal.PersistenceXmlParser; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.hibernate.tool.schema.TargetType; -import org.joda.time.Period; import org.testcontainers.containers.PostgreSQLContainer; /** @@ -59,25 +48,6 @@ import org.testcontainers.containers.PostgreSQLContainer; @Parameters(separators = " =", commandDescription = "Generate PostgreSQL schema.") public class GenerateSqlSchemaCommand implements Command { - // TODO(mmuller): These should be read from persistence.xml so we don't need to maintain two - // separate lists of all SQL table classes. - private static final ImmutableSet SQL_TABLE_CLASSES = - ImmutableSet.of( - BaseTransferObject.class, - ClaimsList.class, - CreateAutoTimestampConverter.class, - DelegationSignerData.class, - DesignatedContact.class, - DomainBase.class, - GracePeriod.class, - Period.class, - PremiumList.class, - RegistryLock.class, - TransferData.class, - Trid.class, - UpdateAutoTimestampConverter.class, - ZonedDateTimeConverter.class); - @VisibleForTesting public static final String DB_OPTIONS_CLASH = "Database host and port may not be specified along with the option to start a " @@ -164,7 +134,9 @@ public class GenerateSqlSchemaCommand implements Command { MetadataSources metadata = new MetadataSources(new StandardServiceRegistryBuilder().applySettings(settings).build()); - SQL_TABLE_CLASSES.forEach(metadata::addAnnotatedClass); + + addAnnotatedClasses(metadata, settings); + SchemaExport schemaExport = new SchemaExport(); schemaExport.setHaltOnError(true); schemaExport.setFormat(true); @@ -203,4 +175,30 @@ public class GenerateSqlSchemaCommand implements Command { } } } + + private void addAnnotatedClasses(MetadataSources metadata, Map settings) { + ParsedPersistenceXmlDescriptor descriptor = + PersistenceXmlParser.locatePersistenceUnits(settings).stream() + .filter(unit -> PersistenceModule.PERSISTENCE_UNIT_NAME.equals(unit.getName())) + .findFirst() + .orElseThrow( + () -> + new IllegalArgumentException( + String.format( + "Could not find persistence unit with name %s", + PersistenceModule.PERSISTENCE_UNIT_NAME))); + + List classNames = descriptor.getManagedClassNames(); + for (String className : classNames) { + try { + Class clazz = Class.forName(className); + metadata.addAnnotatedClass(clazz); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException( + String.format( + "Could not load class with name %s present in persistence.xml", className), + e); + } + } + } } diff --git a/core/src/test/java/google/registry/model/registry/RegistryLockDaoTest.java b/core/src/test/java/google/registry/model/registry/RegistryLockDaoTest.java index 862ef26f6..42809f71f 100644 --- a/core/src/test/java/google/registry/model/registry/RegistryLockDaoTest.java +++ b/core/src/test/java/google/registry/model/registry/RegistryLockDaoTest.java @@ -19,7 +19,6 @@ import static google.registry.model.transaction.TransactionManagerFactory.jpaTm; import static google.registry.testing.JUnitBackports.assertThrows; import google.registry.model.transaction.JpaTransactionManagerRule; -import google.registry.persistence.CreateAutoTimestampConverter; import google.registry.schema.domain.RegistryLock; import google.registry.schema.domain.RegistryLock.Action; import google.registry.testing.AppEngineRule; @@ -38,9 +37,7 @@ public final class RegistryLockDaoTest { @Rule public final JpaTransactionManagerRule jpaTmRule = - new JpaTransactionManagerRule.Builder() - .withEntityClass(RegistryLock.class, CreateAutoTimestampConverter.class) - .build(); + new JpaTransactionManagerRule.Builder().build(); @Test public void testSaveAndLoad_success() { diff --git a/core/src/test/java/google/registry/model/transaction/JpaTransactionManagerRule.java b/core/src/test/java/google/registry/model/transaction/JpaTransactionManagerRule.java index 655ce76d5..b61f1ec2e 100644 --- a/core/src/test/java/google/registry/model/transaction/JpaTransactionManagerRule.java +++ b/core/src/test/java/google/registry/model/transaction/JpaTransactionManagerRule.java @@ -27,9 +27,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import javax.persistence.EntityManagerFactory; -import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Environment; +import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; +import org.hibernate.jpa.boot.internal.PersistenceXmlParser; +import org.hibernate.jpa.boot.spi.Bootstrap; import org.joda.time.DateTime; import org.junit.rules.ExternalResource; import org.junit.rules.RuleChain; @@ -120,10 +121,19 @@ public class JpaTransactionManagerRule extends ExternalResource { properties.put(Environment.USER, username); properties.put(Environment.PASS, password); - MetadataSources metadataSources = - new MetadataSources(new StandardServiceRegistryBuilder().applySettings(properties).build()); - extraEntityClasses.forEach(metadataSources::addAnnotatedClass); - return metadataSources.buildMetadata().getSessionFactoryBuilder().build(); + ParsedPersistenceXmlDescriptor descriptor = + PersistenceXmlParser.locatePersistenceUnits(properties).stream() + .filter(unit -> PersistenceModule.PERSISTENCE_UNIT_NAME.equals(unit.getName())) + .findFirst() + .orElseThrow( + () -> + new IllegalArgumentException( + String.format( + "Could not find persistence unit with name %s", + PersistenceModule.PERSISTENCE_UNIT_NAME))); + + extraEntityClasses.stream().map(Class::getName).forEach(descriptor::addClasses); + return Bootstrap.getEntityManagerFactoryBuilder(descriptor, properties).build(); } /** Returns the {@link FakeClock} used by the underlying {@link JpaTransactionManagerImpl}. */ diff --git a/core/src/test/java/google/registry/persistence/CreateAutoTimestampConverterTest.java b/core/src/test/java/google/registry/persistence/CreateAutoTimestampConverterTest.java index 9c8b06f90..6851bdbd9 100644 --- a/core/src/test/java/google/registry/persistence/CreateAutoTimestampConverterTest.java +++ b/core/src/test/java/google/registry/persistence/CreateAutoTimestampConverterTest.java @@ -23,32 +23,21 @@ import javax.persistence.Entity; import javax.persistence.Id; import org.hibernate.cfg.Environment; import org.joda.time.DateTime; -import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import org.testcontainers.containers.PostgreSQLContainer; @RunWith(JUnit4.class) public class CreateAutoTimestampConverterTest { - @ClassRule - public static PostgreSQLContainer postgres = - new PostgreSQLContainer() - .withDatabaseName("postgres") - .withUsername("postgres") - .withPassword("domain-registry"); - @Rule public final JpaTransactionManagerRule jpaTmRule = new JpaTransactionManagerRule.Builder() - .withEntityClass(TestEntity.class, CreateAutoTimestampConverter.class) + .withEntityClass(TestEntity.class) .withProperty(Environment.HBM2DDL_AUTO, "update") .build(); - public CreateAutoTimestampConverterTest() {} - @Test public void testTypeConversion() { CreateAutoTimestamp ts = CreateAutoTimestamp.create(DateTime.parse("2019-09-9T11:39:00Z")); diff --git a/core/src/test/java/google/registry/persistence/UpdateAutoTimestampConverterTest.java b/core/src/test/java/google/registry/persistence/UpdateAutoTimestampConverterTest.java index b0a8fe03a..05c5b4885 100644 --- a/core/src/test/java/google/registry/persistence/UpdateAutoTimestampConverterTest.java +++ b/core/src/test/java/google/registry/persistence/UpdateAutoTimestampConverterTest.java @@ -22,32 +22,21 @@ import google.registry.model.transaction.JpaTransactionManagerRule; import javax.persistence.Entity; import javax.persistence.Id; import org.hibernate.cfg.Environment; -import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import org.testcontainers.containers.PostgreSQLContainer; @RunWith(JUnit4.class) public class UpdateAutoTimestampConverterTest { - @ClassRule - public static PostgreSQLContainer postgres = - new PostgreSQLContainer() - .withDatabaseName("postgres") - .withUsername("postgres") - .withPassword("domain-registry"); - @Rule public final JpaTransactionManagerRule jpaTmRule = new JpaTransactionManagerRule.Builder() - .withEntityClass(TestEntity.class, UpdateAutoTimestampConverter.class) + .withEntityClass(TestEntity.class) .withProperty(Environment.HBM2DDL_AUTO, "update") .build(); - public UpdateAutoTimestampConverterTest() {} - @Test public void testTypeConversion() { TestEntity ent = new TestEntity("myinst", null); diff --git a/core/src/test/java/google/registry/persistence/ZonedDateTimeConverterTest.java b/core/src/test/java/google/registry/persistence/ZonedDateTimeConverterTest.java index a6697fc77..ece7df1a2 100644 --- a/core/src/test/java/google/registry/persistence/ZonedDateTimeConverterTest.java +++ b/core/src/test/java/google/registry/persistence/ZonedDateTimeConverterTest.java @@ -37,7 +37,7 @@ public class ZonedDateTimeConverterTest { @Rule public final JpaTransactionManagerRule jpaTmRule = new JpaTransactionManagerRule.Builder() - .withEntityClass(TestEntity.class, ZonedDateTimeConverter.class) + .withEntityClass(TestEntity.class) .withProperty(Environment.HBM2DDL_AUTO, "update") .build(); diff --git a/core/src/test/java/google/registry/schema/tld/PremiumListDaoTest.java b/core/src/test/java/google/registry/schema/tld/PremiumListDaoTest.java index c36af0748..21e3d366e 100644 --- a/core/src/test/java/google/registry/schema/tld/PremiumListDaoTest.java +++ b/core/src/test/java/google/registry/schema/tld/PremiumListDaoTest.java @@ -20,7 +20,6 @@ import static google.registry.testing.JUnitBackports.assertThrows; import com.google.common.collect.ImmutableMap; import google.registry.model.transaction.JpaTransactionManagerRule; -import google.registry.persistence.CreateAutoTimestampConverter; import java.math.BigDecimal; import javax.persistence.PersistenceException; import org.joda.money.CurrencyUnit; @@ -35,9 +34,7 @@ public class PremiumListDaoTest { @Rule public final JpaTransactionManagerRule jpaTmRule = - new JpaTransactionManagerRule.Builder() - .withEntityClass(PremiumList.class, CreateAutoTimestampConverter.class) - .build(); + new JpaTransactionManagerRule.Builder().build(); private static final ImmutableMap TEST_PRICES = ImmutableMap.of(