package me.moodcat.database.bootstrapper; import com.google.inject.Inject; import com.google.inject.Singleton; import lombok.extern.slf4j.Slf4j; import me.moodcat.database.entities.Artist; import me.moodcat.database.entities.Room; import me.moodcat.database.entities.Song; import org.hibernate.Session; import org.hibernate.cfg.Configuration; import org.hibernate.jpa.internal.EntityManagerImpl; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.rules.MethodRule; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.metamodel.EntityType; import java.io.IOException; import java.util.Properties; import java.util.concurrent.ExecutionException; /** * A JUnit {@link MethodRule} that ensures a certain database environment is loaded * for the test. * * @author Jan-Willem Gmelig Meyling */ @Slf4j @Singleton public class BootstrapRule implements TestRule { private final Bootstrapper bootstrapper; private final EntityManager entityManager; private final EntityManagerFactory entityManagerFactory; @Inject public BootstrapRule(Bootstrapper bootstrapper, EntityManagerFactory entityManagerFactory, EntityManager entityManager) { this.bootstrapper = bootstrapper; this.entityManager = entityManager; this.entityManagerFactory = entityManagerFactory; } @Override public Statement apply(Statement statement, Description description) { final TestBootstrap testBootstrapAnnotation = description.getAnnotation(TestBootstrap.class); if (testBootstrapAnnotation == null) { return statement; } return new Statement() { @Override public void evaluate() throws Throwable { try { dropSchema(); for(String configuration : testBootstrapAnnotation.value()) { bootstrapper.parseFromResource(configuration); } statement.evaluate(); } finally { bootstrapper.cleanup(); } } }; } protected void dropSchema() throws ExecutionException, InterruptedException, IOException { log.info("Dropping schema!"); Configuration config = new Configuration(); Properties properties = new Properties(); properties.putAll(entityManagerFactory.getProperties()); config.setProperties(properties); entityManagerFactory.getMetamodel().getEntities() .stream() .map(EntityType::getJavaType) .forEach(config::addAnnotatedClass); EntityManagerImpl em = (EntityManagerImpl) entityManager; Session session = em.getSession(); session.doWork(connection -> new SchemaExport(config, connection).create(false, true)); entityManager.clear(); log.info("Dropped schema successfully!"); } public Artist getArtist(Integer id) { return bootstrapper.getArtist(id); } public Room getRoom(Integer id) { return bootstrapper.getRoom(id); } public Song getSong(Integer id) { return bootstrapper.getSong(id); } }