/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.osgi.test;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Calendar;
import java.util.Locale;
import java.util.Properties;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceProvider;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.osgi.test.client.AuditedDataPoint;
import org.hibernate.osgi.test.client.DataPoint;
import org.hibernate.osgi.test.client.SomeService;
import org.hibernate.osgi.test.client.TestIntegrator;
import org.hibernate.osgi.test.client.TestStrategyRegistrationProvider;
import org.hibernate.osgi.test.client.TestTypeContributor;
import org.hibernate.type.BasicType;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.apache.karaf.features.BootFinished;
import org.apache.karaf.features.FeaturesService;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.ProbeBuilder;
import org.ops4j.pax.exam.TestProbeBuilder;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.karaf.options.LogLevelOption;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.ops4j.pax.exam.CoreOptions.options;
import static org.ops4j.pax.exam.CoreOptions.when;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.debugConfiguration;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFileExtend;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
/**
* Tests for hibernate-osgi running within a Karaf container via PaxExam.
*
* @author Steve Ebersole
* @author Brett Meyer
*/
@RunWith( PaxExam.class )
@ExamReactorStrategy( PerClass.class )
public class OsgiIntegrationTest {
private static final boolean DEBUG = false;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Prepare the Karaf container
@Configuration
public Option[] config() throws Exception {
final Properties paxExamEnvironment = loadPaxExamEnvironmentProperties();
final boolean debug = ConfigurationHelper.getBoolean(
"org.hibernate.testing.osgi.paxExam.debug",
Environment.getProperties(),
DEBUG
);
return options(
when( debug ).useOptions( debugConfiguration( "5005", true ) ),
karafDistributionConfiguration()
.frameworkUrl( paxExamEnvironment.getProperty( "org.ops4j.pax.exam.container.karaf.distroUrl" ) )
.karafVersion( paxExamEnvironment.getProperty( "org.ops4j.pax.exam.container.karaf.version" ) )
.name( "Apache Karaf" )
.unpackDirectory(
new File(
paxExamEnvironment.getProperty(
"org.ops4j.pax.exam.container.karaf.unpackDir"
)
)
)
.useDeployFolder( false ),
editConfigurationFileExtend(
"etc/org.ops4j.pax.url.mvn.cfg",
"org.ops4j.pax.url.mvn.repositories",
"https://repository.jboss.org/nexus/content/groups/public/"
),
configureConsole().ignoreLocalConsole().ignoreRemoteShell(),
when( debug ).useOptions( keepRuntimeFolder() ),
logLevel( LogLevelOption.LogLevel.INFO ),
features( featureXmlUrl( paxExamEnvironment ), "hibernate-orm" ),
features( featureXmlUrl( paxExamEnvironment ), "hibernate-envers" ),
features( testingFeatureXmlUrl(), "hibernate-osgi-testing" )
);
}
private static Properties loadPaxExamEnvironmentProperties() throws IOException {
Properties props = new Properties();
props.load( OsgiIntegrationTest.class.getResourceAsStream( "/pax-exam-environment.properties" ) );
return props;
}
private static String featureXmlUrl(Properties paxExamEnvironment) throws MalformedURLException {
return new File( paxExamEnvironment.getProperty( "org.hibernate.osgi.test.karafFeatureFile" ) ).toURI().toURL().toExternalForm();
}
private String testingFeatureXmlUrl() {
return OsgiIntegrationTest.class.getClassLoader().getResource( "org/hibernate/osgi/test/testing-bundles.xml" )
.toExternalForm();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Prepare the PaxExam probe (the bundle to deploy)
@ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
System.out.println( "Configuring probe..." );
// Note : I found locally that this part is not needed. But I am leaving this here as I might
// someday have a need for tweaking the probe and I want to remember how it is done...
// // attempt to override PaxExam's default of dynamically importing everything
// probe.setHeader( Constants.DYNAMICIMPORT_PACKAGE, "" );
// // and use defined imports instead
// probe.setHeader(
// Constants.IMPORT_PACKAGE,
// "javassist.util.proxy"
// + ",javax.persistence"
// + ",javax.persistence.spi"
// + ",org.h2"
// + ",org.osgi.framework"
// + ",org.hibernate"
// + ",org.hibernate.envers"
//// + ",org.hibernate.boot.model"
//// + ",org.hibernate.boot.registry.selector"
//// + ",org.hibernate.boot.registry.selector.spi"
//// + ",org.hibernate.cfg"
//// + ",org.hibernate.engine.spi"
//// + ",org.hibernate.integrator.spi"
//// + ",org.hibernate.proxy"
//// + ",org.hibernate.service"
//// + ",org.hibernate.service.spi"
//// + ",org.ops4j.pax.exam.options"
//// + ",org.ops4j.pax.exam"
// );
probe.setHeader( Constants.BUNDLE_ACTIVATOR, "org.hibernate.osgi.test.client.OsgiTestActivator" );
return probe;
}
@BeforeClass
public static void setLocaleToEnglish() {
Locale.setDefault( Locale.ENGLISH );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// The tests
@Inject
protected FeaturesService featuresService;
@Inject
BootFinished bootFinished;
@Inject
@SuppressWarnings("UnusedDeclaration")
private BundleContext bundleContext;
@Test
public void testActivation() throws Exception {
assertTrue( featuresService.isInstalled( featuresService.getFeature( "hibernate-orm" ) ) );
assertTrue( featuresService.isInstalled( featuresService.getFeature( "hibernate-envers" ) ) );
assertActiveBundle( "org.hibernate.core" );
assertActiveBundle( "org.hibernate.envers" );
}
@Test
public void testJpa() throws Exception {
final ServiceReference serviceReference = bundleContext.getServiceReference( PersistenceProvider.class.getName() );
final PersistenceProvider persistenceProvider = (PersistenceProvider) bundleContext.getService( serviceReference );
final EntityManagerFactory emf = persistenceProvider.createEntityManagerFactory( "hibernate-osgi-test", null );
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist( new DataPoint( "Brett" ) );
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
em.getTransaction().begin();
DataPoint dp = em.find( DataPoint.class, 1 );
assertNotNull( dp );
assertEquals( "Brett", dp.getName() );
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
em.getTransaction().begin();
dp = em.find( DataPoint.class, 1 );
dp.setName( "Brett2" );
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
em.getTransaction().begin();
em.createQuery( "delete from DataPoint" ).executeUpdate();
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
em.getTransaction().begin();
dp = em.find( DataPoint.class, 1 );
assertNull( dp );
em.getTransaction().commit();
em.close();
}
@Test
public void testNative() throws Exception {
final ServiceReference sr = bundleContext.getServiceReference( SessionFactory.class.getName() );
final SessionFactory sf = (SessionFactory) bundleContext.getService( sr );
Session s = sf.openSession();
s.getTransaction().begin();
s.persist( new DataPoint( "Brett" ) );
s.getTransaction().commit();
s.close();
s = sf.openSession();
s.getTransaction().begin();
DataPoint dp = (DataPoint) s.get( DataPoint.class, 1 );
assertNotNull( dp );
assertEquals( "Brett", dp.getName() );
s.getTransaction().commit();
s.close();
dp.setName( "Brett2" );
s = sf.openSession();
s.getTransaction().begin();
s.update( dp );
s.getTransaction().commit();
s.close();
s = sf.openSession();
s.getTransaction().begin();
dp = (DataPoint) s.get( DataPoint.class, 1 );
assertNotNull( dp );
assertEquals( "Brett2", dp.getName() );
s.getTransaction().commit();
s.close();
s = sf.openSession();
s.getTransaction().begin();
s.createQuery( "delete from DataPoint" ).executeUpdate();
s.getTransaction().commit();
s.close();
s = sf.openSession();
s.getTransaction().begin();
dp = (DataPoint) s.get( DataPoint.class, 1 );
assertNull( dp );
s.getTransaction().commit();
s.close();
}
@Test
public void testNativeEnvers() throws Exception {
final ServiceReference sr = bundleContext.getServiceReference( SessionFactory.class.getName() );
final SessionFactory sf = ( SessionFactory )bundleContext.getService( sr );
final Integer adpId;
Session s = sf.openSession();
s.getTransaction().begin();
AuditedDataPoint adp = new AuditedDataPoint( "Chris" );
s.persist( adp );
s.getTransaction().commit();
adpId = adp.getId();
s.close();
s = sf.openSession();
s.getTransaction().begin();
adp = s.get( AuditedDataPoint.class, adpId );
adp.setName( "Chris2" );
s.getTransaction().commit();
s.close();
s = sf.openSession();
AuditReader ar = AuditReaderFactory.get( s );
assertEquals( 2, ar.getRevisions( AuditedDataPoint.class, adpId ).size() );
AuditedDataPoint rev1 = ar.find( AuditedDataPoint.class, adpId, 1 );
AuditedDataPoint rev2 = ar.find( AuditedDataPoint.class, adpId, 2 );
assertEquals( new AuditedDataPoint( adpId, "Chris" ), rev1 );
assertEquals( new AuditedDataPoint( adpId, "Chris2" ), rev2 );
s.close();
}
@Test
public void testJpaEnvers() throws Exception {
final ServiceReference serviceReference = bundleContext.getServiceReference( PersistenceProvider.class.getName() );
final PersistenceProvider persistenceProvider = (PersistenceProvider) bundleContext.getService( serviceReference );
final EntityManagerFactory emf = persistenceProvider.createEntityManagerFactory( "hibernate-osgi-test", null );
final Integer adpId;
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
AuditedDataPoint adp = new AuditedDataPoint( "Chris" );
em.persist( adp );
em.getTransaction().commit();
adpId = adp.getId();
em.close();
em = emf.createEntityManager();
em.getTransaction().begin();
adp = em.find( AuditedDataPoint.class, adpId );
adp.setName( "Chris2" );
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
AuditReader ar = AuditReaderFactory.get( em );
assertEquals( 2, ar.getRevisions( AuditedDataPoint.class, adpId ).size() );
AuditedDataPoint rev1 = ar.find( AuditedDataPoint.class, adpId, 1 );
AuditedDataPoint rev2 = ar.find( AuditedDataPoint.class, adpId, 2 );
assertEquals( new AuditedDataPoint( adpId, "Chris" ), rev1 );
assertEquals( new AuditedDataPoint( adpId, "Chris2" ), rev2 );
em.close();
}
@Test
public void testExtensionPoints() throws Exception {
final ServiceReference sr = bundleContext.getServiceReference( SessionFactory.class.getName() );
final SessionFactoryImplementor sfi = (SessionFactoryImplementor) bundleContext.getService( sr );
assertTrue( TestIntegrator.passed() );
Class impl = sfi.getServiceRegistry().getService( StrategySelector.class ).selectStrategyImplementor( Calendar.class, TestStrategyRegistrationProvider.GREGORIAN );
assertNotNull( impl );
BasicType basicType = sfi.getTypeResolver().basic( TestTypeContributor.NAME );
assertNotNull( basicType );
}
@Test
public void testServiceContributorDiscovery() throws Exception {
final ServiceReference sr = bundleContext.getServiceReference( SessionFactory.class.getName() );
final SessionFactoryImplementor sfi = (SessionFactoryImplementor) bundleContext.getService( sr );
assertNotNull( sfi.getServiceRegistry().getService( SomeService.class ) );
}
private void assertActiveBundle(String symbolicName) {
for (Bundle bundle : bundleContext.getBundles()) {
if (bundle.getSymbolicName().equals( symbolicName )) {
Assert.assertEquals(
symbolicName + " was found, but not in an ACTIVE state.", Bundle.ACTIVE, bundle.getState());
return;
}
}
Assert.fail("Could not find bundle: " + symbolicName);
}
}