diff --git a/.gitignore b/.gitignore index 334886a995..d56282dee7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ target velocity.log derby.log *.iml +dependency-reduced-pom.xml diff --git a/openjpa-integration/karaf/pom.xml b/openjpa-integration/karaf/pom.xml new file mode 100644 index 0000000000..f7b2499771 --- /dev/null +++ b/openjpa-integration/karaf/pom.xml @@ -0,0 +1,134 @@ + + + + 4.0.0 + + org.apache.openjpa + openjpa-integration + 3.0.0-SNAPSHOT + + openjpa-integration-karaf + + + 4.8.0 + ${project.basedir}${file.separator}..${file.separator}..${file.separator}openjpa-project${file.separator}checkstyle.xml + + + + + org.apache.openjpa + openjpa-features + ${project.version} + xml + features + test + + + org.apache.openjpa + openjpa-integration-tasklist-model + ${project.version} + + + org.slf4j + slf4j-api + + + org.apache.openjpa + openjpa-persistence + ${project.version} + + + + org.slf4j + slf4j-jdk14 + 1.7.21 + + + + + org.osgi + osgi.core + 6.0.0 + provided + + + org.osgi + org.osgi.service.jdbc + 1.0.0 + provided + + + + org.ops4j.pax.exam + pax-exam-container-karaf + ${pax.exam.version} + test + + + org.ops4j.pax.exam + pax-exam-junit4 + ${pax.exam.version} + test + + + org.ops4j.pax.exam + pax-exam + ${pax.exam.version} + test + + + org.ops4j.pax.url + pax-url-aether + 1.6.0 + test + + + javax.inject + javax.inject + 1 + test + + + + junit + junit + test + + + + + + + + org.apache.servicemix.tooling + depends-maven-plugin + 1.3.1 + + + generate-depends-file + + generate-depends-file + + + + + + + \ No newline at end of file diff --git a/openjpa-integration/karaf/src/test/java/org/apache/openjpa/itest/karaf/KarafTest.java b/openjpa-integration/karaf/src/test/java/org/apache/openjpa/itest/karaf/KarafTest.java new file mode 100644 index 0000000000..e7bac92336 --- /dev/null +++ b/openjpa-integration/karaf/src/test/java/org/apache/openjpa/itest/karaf/KarafTest.java @@ -0,0 +1,97 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.openjpa.itest.karaf; + +import static org.ops4j.pax.exam.CoreOptions.maven; +import static org.ops4j.pax.exam.CoreOptions.mavenBundle; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut; +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 java.io.File; +import java.util.Collection; + +import javax.inject.Inject; + +import org.apache.openjpa.integration.tasklist.model.Task; +import org.apache.openjpa.integration.tasklist.model.TaskService; +import org.junit.Assert; +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.junit.PaxExam; +import org.ops4j.pax.exam.options.MavenArtifactUrlReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Integration test to prove the openjpa feature works in apache karaf. + * The test does not use Aries JPA to keep it as bare as possible. Keep in mind that + * this is not the best practice to use JPA in OSGi. + * + * The DataSource is created using a config and pax-jdbc-config. Openjpa accesses the + * DataSource using jndi and aries jndi. + */ +@RunWith(PaxExam.class) +public class KarafTest { + private static final String DATASOURCE_H2_CFG = "etc/org.ops4j.datasource-h2.cfg"; + + Logger LOG = LoggerFactory.getLogger(KarafTest.class); + + @Inject + TaskService taskService; + + @Configuration + public Option[] config() { + MavenArtifactUrlReference karafUrl = maven() + .groupId("org.apache.karaf") + .artifactId("apache-karaf") + .version("4.0.7").type("tar.gz"); + MavenArtifactUrlReference openjpa = maven() + .groupId("org.apache.openjpa") + .artifactId("openjpa-features") + .versionAsInProject() + .type("xml") + .classifier("features"); + return new Option[] { + karafDistributionConfiguration().frameworkUrl(karafUrl).name("Apache Karaf") + .unpackDirectory(new File("target/exam")), + keepRuntimeFolder(), + features(openjpa, "openjpa", "pax-jdbc-h2", "pax-jdbc-config" , "scr" , "jndi"), + mavenBundle("org.apache.openjpa", "openjpa-integration-tasklist-model").versionAsInProject(), + editConfigurationFilePut(DATASOURCE_H2_CFG, "osgi.jdbc.driver.name", "H2"), + editConfigurationFilePut(DATASOURCE_H2_CFG, "url", "jdbc:h2:test"), + editConfigurationFilePut(DATASOURCE_H2_CFG, "dataSourceName", "tasklist"), + //KarafDistributionOption.debugConfiguration("5005", true), + }; + } + + @Test + public void test1() throws Exception { + Task task = new Task(); + task.setId(1); + task.setTitle("Task1"); + taskService.addTask(task); + + Collection tasks = taskService.getTasks(); + Assert.assertEquals(1, tasks.size()); + Assert.assertEquals("Task1", tasks.iterator().next().getTitle()); + } + +} diff --git a/openjpa-integration/pom.xml b/openjpa-integration/pom.xml index cb5ba27865..abdd16ecba 100644 --- a/openjpa-integration/pom.xml +++ b/openjpa-integration/pom.xml @@ -43,6 +43,8 @@ tck validation jmx + karaf + tasklist-model diff --git a/openjpa-integration/tasklist-model/bnd.bnd b/openjpa-integration/tasklist-model/bnd.bnd new file mode 100644 index 0000000000..e898aef31e --- /dev/null +++ b/openjpa-integration/tasklist-model/bnd.bnd @@ -0,0 +1,2 @@ +Meta-Persistence: \ + META-INF/persistence.xml diff --git a/openjpa-integration/tasklist-model/pom.xml b/openjpa-integration/tasklist-model/pom.xml new file mode 100644 index 0000000000..ee6870d0a1 --- /dev/null +++ b/openjpa-integration/tasklist-model/pom.xml @@ -0,0 +1,109 @@ + + + + 4.0.0 + + org.apache.openjpa + openjpa-integration + 3.0.0-SNAPSHOT + + openjpa-integration-tasklist-model + + bundle + + + ${project.basedir}${file.separator}..${file.separator}..${file.separator}openjpa-project${file.separator}checkstyle.xml + + + + + org.osgi + osgi.core + 6.0.0 + provided + + + org.osgi + osgi.cmpn + 6.0.0 + provided + + + org.eclipse.persistence + javax.persistence + 2.1.0 + + + org.slf4j + slf4j-api + + + + + + + + org.apache.felix + maven-bundle-plugin + 3.0.0 + true + + NONE + + <_include>-bnd.bnd + + + + + org.apache.openjpa + openjpa-maven-plugin + + **/*.class + true + true + + + + enhancer + process-classes + + enhance + + + + + + org.apache.openjpa + openjpa + ${project.version} + + + + + + + + diff --git a/openjpa-integration/tasklist-model/src/main/java/org/apache/openjpa/integration/tasklist/impl/TaskServiceImpl.java b/openjpa-integration/tasklist-model/src/main/java/org/apache/openjpa/integration/tasklist/impl/TaskServiceImpl.java new file mode 100644 index 0000000000..8f84fa561f --- /dev/null +++ b/openjpa-integration/tasklist-model/src/main/java/org/apache/openjpa/integration/tasklist/impl/TaskServiceImpl.java @@ -0,0 +1,111 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.openjpa.integration.tasklist.impl; + +import java.sql.SQLException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.spi.PersistenceProvider; +import javax.sql.DataSource; + +import org.apache.openjpa.integration.tasklist.model.Task; +import org.apache.openjpa.integration.tasklist.model.TaskService; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component +public class TaskServiceImpl implements TaskService { + Logger LOG = LoggerFactory.getLogger(TaskServiceImpl.class); + + // Wait for DataSource to avoid race condition at startup + @Reference + DataSource ds; + + @Reference + PersistenceProvider provider; + + private EntityManagerFactory emf; + + @Activate + public void activate() throws SQLException { + this. emf = createEMF(); + } + + private EntityManagerFactory createEMF() { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(Task.class.getClassLoader()); + Map map = new HashMap(); + return provider.createEntityManagerFactory("tasklist", map); + } finally { + Thread.currentThread().setContextClassLoader(cl); + } + + } + + @Deactivate + public void deActivate() throws SQLException { + emf.close(); + } + + @Override + public Task getTask(Integer id) { + return null; + } + + @Override + public void addTask(Task task) { + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + em.persist(task); + em.flush(); + em.getTransaction().commit(); + em.close(); + } + + @Override + public void updateTask(Task task) { + } + + @Override + public void deleteTask(Integer id) { + } + + @Override + public Collection getTasks() { + EntityManager em = null; + try { + em = emf.createEntityManager(); + CriteriaQuery query = em.getCriteriaBuilder().createQuery(Task.class); + return em.createQuery(query.select(query.from(Task.class))).getResultList(); + } finally { + if (em != null) { + em.close(); + } + } + } + +} diff --git a/openjpa-integration/tasklist-model/src/main/java/org/apache/openjpa/integration/tasklist/model/Task.java b/openjpa-integration/tasklist-model/src/main/java/org/apache/openjpa/integration/tasklist/model/Task.java new file mode 100644 index 0000000000..29583e500b --- /dev/null +++ b/openjpa-integration/tasklist-model/src/main/java/org/apache/openjpa/integration/tasklist/model/Task.java @@ -0,0 +1,87 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.openjpa.integration.tasklist.model; + +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.xml.bind.annotation.XmlRootElement; + +@Entity +@XmlRootElement +public class Task { + @Id + Integer id; + String title; + String description; + Date dueDate; + boolean finished; + + + public Task() { + } + + + public Task(Integer id, String title, String description) { + super(); + this.id = id; + this.title = title; + this.description = description; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = new Integer(id); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Date getDueDate() { + return dueDate; + } + + public void setDueDate(Date dueDate) { + this.dueDate = dueDate; + } + + public boolean isFinished() { + return finished; + } + + public void setFinished(boolean finished) { + this.finished = finished; + } + +} diff --git a/openjpa-integration/tasklist-model/src/main/java/org/apache/openjpa/integration/tasklist/model/TaskService.java b/openjpa-integration/tasklist-model/src/main/java/org/apache/openjpa/integration/tasklist/model/TaskService.java new file mode 100644 index 0000000000..bdd335c3a0 --- /dev/null +++ b/openjpa-integration/tasklist-model/src/main/java/org/apache/openjpa/integration/tasklist/model/TaskService.java @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.openjpa.integration.tasklist.model; + +import java.util.Collection; + +public interface TaskService { + Task getTask(Integer id); + + void addTask(Task task); + + void updateTask(Task task); + + void deleteTask(Integer id); + + Collection getTasks(); +} diff --git a/openjpa-integration/tasklist-model/src/main/resources/META-INF/persistence.xml b/openjpa-integration/tasklist-model/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..892d87dfc5 --- /dev/null +++ b/openjpa-integration/tasklist-model/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,34 @@ + + + + + + osgi:service/javax.sql.DataSource + org.apache.openjpa.integration.tasklist.model.Task + + + + + + + + + +