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
This commit is contained in:
gbrodman 2019-10-09 15:15:04 -04:00 committed by GitHub
parent a694e247cd
commit 906b054f4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 54 additions and 74 deletions

View file

@ -19,34 +19,23 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters; import com.beust.jcommander.Parameters;
import com.google.common.annotations.VisibleForTesting; 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.NomulusNamingStrategy;
import google.registry.persistence.NomulusPostgreSQLDialect; import google.registry.persistence.NomulusPostgreSQLDialect;
import google.registry.persistence.UpdateAutoTimestampConverter; import google.registry.persistence.PersistenceModule;
import google.registry.persistence.ZonedDateTimeConverter;
import google.registry.schema.domain.RegistryLock;
import google.registry.schema.tld.PremiumList;
import google.registry.schema.tmch.ClaimsList;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.hibernate.boot.MetadataSources; import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Environment; 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.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType; import org.hibernate.tool.schema.TargetType;
import org.joda.time.Period;
import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.PostgreSQLContainer;
/** /**
@ -59,25 +48,6 @@ import org.testcontainers.containers.PostgreSQLContainer;
@Parameters(separators = " =", commandDescription = "Generate PostgreSQL schema.") @Parameters(separators = " =", commandDescription = "Generate PostgreSQL schema.")
public class GenerateSqlSchemaCommand implements Command { 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<Class> 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 @VisibleForTesting
public static final String DB_OPTIONS_CLASH = public static final String DB_OPTIONS_CLASH =
"Database host and port may not be specified along with the option to start a " "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 = MetadataSources metadata =
new MetadataSources(new StandardServiceRegistryBuilder().applySettings(settings).build()); new MetadataSources(new StandardServiceRegistryBuilder().applySettings(settings).build());
SQL_TABLE_CLASSES.forEach(metadata::addAnnotatedClass);
addAnnotatedClasses(metadata, settings);
SchemaExport schemaExport = new SchemaExport(); SchemaExport schemaExport = new SchemaExport();
schemaExport.setHaltOnError(true); schemaExport.setHaltOnError(true);
schemaExport.setFormat(true); schemaExport.setFormat(true);
@ -203,4 +175,30 @@ public class GenerateSqlSchemaCommand implements Command {
} }
} }
} }
private void addAnnotatedClasses(MetadataSources metadata, Map<String, String> 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<String> 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);
}
}
}
} }

View file

@ -19,7 +19,6 @@ import static google.registry.model.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.testing.JUnitBackports.assertThrows; import static google.registry.testing.JUnitBackports.assertThrows;
import google.registry.model.transaction.JpaTransactionManagerRule; import google.registry.model.transaction.JpaTransactionManagerRule;
import google.registry.persistence.CreateAutoTimestampConverter;
import google.registry.schema.domain.RegistryLock; import google.registry.schema.domain.RegistryLock;
import google.registry.schema.domain.RegistryLock.Action; import google.registry.schema.domain.RegistryLock.Action;
import google.registry.testing.AppEngineRule; import google.registry.testing.AppEngineRule;
@ -38,9 +37,7 @@ public final class RegistryLockDaoTest {
@Rule @Rule
public final JpaTransactionManagerRule jpaTmRule = public final JpaTransactionManagerRule jpaTmRule =
new JpaTransactionManagerRule.Builder() new JpaTransactionManagerRule.Builder().build();
.withEntityClass(RegistryLock.class, CreateAutoTimestampConverter.class)
.build();
@Test @Test
public void testSaveAndLoad_success() { public void testSaveAndLoad_success() {

View file

@ -27,9 +27,10 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Environment; 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.joda.time.DateTime;
import org.junit.rules.ExternalResource; import org.junit.rules.ExternalResource;
import org.junit.rules.RuleChain; import org.junit.rules.RuleChain;
@ -120,10 +121,19 @@ public class JpaTransactionManagerRule extends ExternalResource {
properties.put(Environment.USER, username); properties.put(Environment.USER, username);
properties.put(Environment.PASS, password); properties.put(Environment.PASS, password);
MetadataSources metadataSources = ParsedPersistenceXmlDescriptor descriptor =
new MetadataSources(new StandardServiceRegistryBuilder().applySettings(properties).build()); PersistenceXmlParser.locatePersistenceUnits(properties).stream()
extraEntityClasses.forEach(metadataSources::addAnnotatedClass); .filter(unit -> PersistenceModule.PERSISTENCE_UNIT_NAME.equals(unit.getName()))
return metadataSources.buildMetadata().getSessionFactoryBuilder().build(); .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}. */ /** Returns the {@link FakeClock} used by the underlying {@link JpaTransactionManagerImpl}. */

View file

@ -23,32 +23,21 @@ import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.junit.ClassRule;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.JUnit4; import org.junit.runners.JUnit4;
import org.testcontainers.containers.PostgreSQLContainer;
@RunWith(JUnit4.class) @RunWith(JUnit4.class)
public class CreateAutoTimestampConverterTest { public class CreateAutoTimestampConverterTest {
@ClassRule
public static PostgreSQLContainer postgres =
new PostgreSQLContainer()
.withDatabaseName("postgres")
.withUsername("postgres")
.withPassword("domain-registry");
@Rule @Rule
public final JpaTransactionManagerRule jpaTmRule = public final JpaTransactionManagerRule jpaTmRule =
new JpaTransactionManagerRule.Builder() new JpaTransactionManagerRule.Builder()
.withEntityClass(TestEntity.class, CreateAutoTimestampConverter.class) .withEntityClass(TestEntity.class)
.withProperty(Environment.HBM2DDL_AUTO, "update") .withProperty(Environment.HBM2DDL_AUTO, "update")
.build(); .build();
public CreateAutoTimestampConverterTest() {}
@Test @Test
public void testTypeConversion() { public void testTypeConversion() {
CreateAutoTimestamp ts = CreateAutoTimestamp.create(DateTime.parse("2019-09-9T11:39:00Z")); CreateAutoTimestamp ts = CreateAutoTimestamp.create(DateTime.parse("2019-09-9T11:39:00Z"));

View file

@ -22,32 +22,21 @@ import google.registry.model.transaction.JpaTransactionManagerRule;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import org.hibernate.cfg.Environment; import org.hibernate.cfg.Environment;
import org.junit.ClassRule;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.JUnit4; import org.junit.runners.JUnit4;
import org.testcontainers.containers.PostgreSQLContainer;
@RunWith(JUnit4.class) @RunWith(JUnit4.class)
public class UpdateAutoTimestampConverterTest { public class UpdateAutoTimestampConverterTest {
@ClassRule
public static PostgreSQLContainer postgres =
new PostgreSQLContainer()
.withDatabaseName("postgres")
.withUsername("postgres")
.withPassword("domain-registry");
@Rule @Rule
public final JpaTransactionManagerRule jpaTmRule = public final JpaTransactionManagerRule jpaTmRule =
new JpaTransactionManagerRule.Builder() new JpaTransactionManagerRule.Builder()
.withEntityClass(TestEntity.class, UpdateAutoTimestampConverter.class) .withEntityClass(TestEntity.class)
.withProperty(Environment.HBM2DDL_AUTO, "update") .withProperty(Environment.HBM2DDL_AUTO, "update")
.build(); .build();
public UpdateAutoTimestampConverterTest() {}
@Test @Test
public void testTypeConversion() { public void testTypeConversion() {
TestEntity ent = new TestEntity("myinst", null); TestEntity ent = new TestEntity("myinst", null);

View file

@ -37,7 +37,7 @@ public class ZonedDateTimeConverterTest {
@Rule @Rule
public final JpaTransactionManagerRule jpaTmRule = public final JpaTransactionManagerRule jpaTmRule =
new JpaTransactionManagerRule.Builder() new JpaTransactionManagerRule.Builder()
.withEntityClass(TestEntity.class, ZonedDateTimeConverter.class) .withEntityClass(TestEntity.class)
.withProperty(Environment.HBM2DDL_AUTO, "update") .withProperty(Environment.HBM2DDL_AUTO, "update")
.build(); .build();

View file

@ -20,7 +20,6 @@ import static google.registry.testing.JUnitBackports.assertThrows;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import google.registry.model.transaction.JpaTransactionManagerRule; import google.registry.model.transaction.JpaTransactionManagerRule;
import google.registry.persistence.CreateAutoTimestampConverter;
import java.math.BigDecimal; import java.math.BigDecimal;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
import org.joda.money.CurrencyUnit; import org.joda.money.CurrencyUnit;
@ -35,9 +34,7 @@ public class PremiumListDaoTest {
@Rule @Rule
public final JpaTransactionManagerRule jpaTmRule = public final JpaTransactionManagerRule jpaTmRule =
new JpaTransactionManagerRule.Builder() new JpaTransactionManagerRule.Builder().build();
.withEntityClass(PremiumList.class, CreateAutoTimestampConverter.class)
.build();
private static final ImmutableMap<String, BigDecimal> TEST_PRICES = private static final ImmutableMap<String, BigDecimal> TEST_PRICES =
ImmutableMap.of( ImmutableMap.of(