简体   繁体   中英

Using JPA/Hibernate within PaxExam / OSGI Container

I have been successful in getting JPA/Hibernate to work, by following Christian Schneider's tutorial: http://liquid-reality.de/display/liquid/2012/01/13/Apache+Karaf+Tutorial+Part+6+-+Database+Access

But this involves creating a "file named etc/org.ops4j.datasource-tasklist.cfg with the following content:"

osgi.jdbc.driver.name=H2-pool-xa
url=jdbc:h2:mem:person
dataSourceName=person

This clearly will not work when running PaxExam using an OSGI Container.

In addition, I'd rather not add environment-specific data source parameters in either the blueprint.xml or persistence.xml files, as that would subsequently require these files to be modified as code is run in different environments.

As such, there must be a way to spin up a data source from within the test class invoked by JUnit/PaxExam, either within the config() method or somewhere else?

So the question is:

  • Using the parameters defined in the above excerpt from Christian's tutorial (eg dataSourceName=person), how would we spin up a new data source to be defined within the OSGI container instantiated by PaxExam?
  • Does this involve enhancements to the test class
  • Or is it better to create data source definitions in standalone files which are then added to the OSGI container?

Some project details, my test class is given as follows:

package info.xyz.playground.test.osgi;

import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import info.xyz.playground.core.service.Calculator;

import javax.inject.Inject;

import org.junit.Test;
import org.junit.runner.RunWith;
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.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerMethod;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;

@RunWith(PaxExam.class)
@ExamReactorStrategy(PerMethod.class)
public class PlaygroundOsgiTestClient
{
    @Inject
    private BundleContext _bundleContext;

    @Inject
    protected Calculator _calculator;


    @ProbeBuilder
    public TestProbeBuilder probeConfiguration(TestProbeBuilder probe)
    {
        System.out.println("TestProbeBuilder gets called");
        probe.setHeader(Constants.DYNAMICIMPORT_PACKAGE, "*");
        probe.setHeader(Constants.IMPORT_PACKAGE, "info.xyz.playground.core.service");
        probe.setHeader(Constants.IMPORT_PACKAGE, "info.xyz.playground.core.service.impl");
        return probe;
    }


    @Configuration
    public Option[] config()
    {
        return new Option[] {
                junitBundles(),

                // Aries
                mavenBundle().groupId("org.apache.aries").artifactId("org.apache.aries.util").versionAsInProject(),
                mavenBundle().groupId("org.apache.aries.proxy").artifactId("org.apache.aries.proxy.api").versionAsInProject(),
                mavenBundle().groupId("org.apache.aries.proxy").artifactId("org.apache.aries.proxy.impl").versionAsInProject(),
                mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.api").versionAsInProject(),
                mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.cm").versionAsInProject(),
                mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.core").versionAsInProject(),
                mavenBundle().groupId("org.apache.aries.blueprint").artifactId("org.apache.aries.blueprint.core.compatibility").versionAsInProject().noStart(),

                // Hibernate and its dependencies
                mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.antlr").versionAsInProject().noStart(),
                mavenBundle().groupId("org.jboss.logging").artifactId("jboss-logging").versionAsInProject().noStart(),
                mavenBundle().groupId("org.hibernate.javax.persistence").artifactId("hibernate-jpa-2.1-api").versionAsInProject().noStart(),
                mavenBundle().groupId("org.javassist").artifactId("javassist").versionAsInProject().noStart(),
                mavenBundle().groupId("org.jboss").artifactId("jandex").versionAsInProject().noStart(),
                mavenBundle().groupId("org.apache.servicemix.bundles").artifactId("org.apache.servicemix.bundles.dom4j").versionAsInProject().noStart(),
                mavenBundle().groupId("org.hibernate.common").artifactId("hibernate-commons-annotations").versionAsInProject().noStart(),
                mavenBundle().groupId("org.hibernate").artifactId("hibernate-core").versionAsInProject().noStart(),
                mavenBundle().groupId("org.hibernate").artifactId("hibernate-entitymanager").versionAsInProject().noStart(),
                mavenBundle().groupId("org.apache.geronimo.specs").artifactId("geronimo-jta_1.1_spec").versionAsInProject().noStart(),
                mavenBundle().groupId("org.hibernate").artifactId("hibernate-osgi").versionAsInProject().noStart(),

                // platform
                mavenBundle().groupId("info.xyz.playground").artifactId("xyz-playground-core").versionAsInProject(),
        };
    }


    @Test
    public void testOne()
    {
        // TODO invoke service to perform database operation
    }

}

The blueprint.xml file is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint default-activation="eager"
    xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0" xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0"

    xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0 
            http://www.w3.org/2001/XMLSchema-instance http://www.w3.org/2001/XMLSchema-instance 
            http://aries.apache.org/xmlns/jpa/v1.0.0 http://aries.apache.org/xmlns/jpa/v1.0.0 
            http://aries.apache.org/xmlns/transactions/v1.0.0 http://aries.apache.org/xmlns/transactions/v1.0.0">

    <bean id="calculatorService" class="info.xyz.playground.core.service.impl.CalculatorImpl" />
    <service ref="calculatorService" interface="info.xyz.playground.core.service.Calculator" />

</blueprint>

The persistence.xml file is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">

    <persistence-unit name="Playground" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>osgi:service/Playground</jta-data-source>
        <class>info.xyz.playground.core.data.Thing</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
        </properties>
    </persistence-unit>

</persistence>

The pom.xml file from my test project is as follows:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>info.xyz.playground</groupId>
    <artifactId>xyz-playground-test-osgi</artifactId>
    <version>0.0.1</version>

    <parent>
        <groupId>info.xyz.playground</groupId>
        <artifactId>xyz-playground</artifactId>
        <version>0.0.1</version>
        <relativePath>../xyz-playground</relativePath>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-container-native</artifactId>
            <version>${pax.exam.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-junit4</artifactId>
            <version>${pax.exam.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-link-mvn</artifactId>
            <version>${pax.exam.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.url</groupId>
            <artifactId>pax-url-aether</artifactId>
            <version>${pax.url.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam</artifactId>
            <version>${pax.exam.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-inject</artifactId>
            <version>${pax.exam.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.aries</groupId>
            <artifactId>org.apache.aries.util</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.aries.proxy</groupId>
            <artifactId>org.apache.aries.proxy.api</artifactId>
            <version>1.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.aries.proxy</groupId>
            <artifactId>org.apache.aries.proxy.impl</artifactId>
            <version>1.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.aries.blueprint</groupId>
            <artifactId>org.apache.aries.blueprint.api</artifactId>
            <version>1.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.aries.blueprint</groupId>
            <artifactId>org.apache.aries.blueprint.core</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.aries.blueprint</groupId>
            <artifactId>org.apache.aries.blueprint.core.compatibility</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.aries.blueprint</groupId>
            <artifactId>org.apache.aries.blueprint.cm</artifactId>
            <version>1.0.5</version>
        </dependency>

        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.apache.felix.framework</artifactId>
            <version>5.4.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${ch.qos.logback.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${ch.qos.logback.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>${javax.inject.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- Testing target -->
        <dependency>
            <groupId>info.xyz.playground</groupId>
            <artifactId>xyz-playground-core</artifactId>
            <version>0.0.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- Needed if you use versionAsInProject() -->
            <plugin>
                <groupId>org.apache.servicemix.tooling</groupId>
                <artifactId>depends-maven-plugin</artifactId>
                <version>1.3.1</version>
                <executions>
                    <execution>
                        <id>generate-depends-file</id>
                        <goals>
                            <goal>generate-depends-file</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

You can use the same approach as the aries itests . Inject the ConfigurationAdmin and create a config in the @Before method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM