From 439ddee3d30fede3bc2bf7c64d226bc7e56ab739 Mon Sep 17 00:00:00 2001 From: Andrew Guibert Date: Thu, 3 Oct 2019 16:12:25 -0500 Subject: [PATCH 1/3] Initial copy of Derby extension --- .gitignore | 1 + bom/runtime/pom.xml | 26 +++ .../builditem/FeatureBuildItem.java | 3 +- .../common/src/main/filtered/extensions.json | 10 + .../orm/deployment/HibernateOrmProcessor.java | 4 + .../jdbc-derby/jdbc-derby-deployment/pom.xml | 42 +++++ .../derby/deployment/JDBCDerbyProcessor.java | 23 +++ .../jdbc-derby/jdbc-derby-runtime/pom.xml | 51 +++++ extensions/jdbc/jdbc-derby/pom.xml | 20 ++ integration-tests/jpa-derby/pom.xml | 126 +++++++++++++ .../derby/JPAFunctionalityTestEndpoint.java | 176 ++++++++++++++++++ .../java/io/quarkus/it/jpa/derby/Person.java | 65 +++++++ .../it/jpa/derby/SequencedAddress.java | 42 +++++ .../main/resources/META-INF/persistence.xml | 15 ++ .../src/main/resources/application.properties | 4 + .../derby/JPAFunctionalityInGraalITCase.java | 11 ++ .../it/jpa/derby/JPAFunctionalityTest.java | 21 +++ .../quarkus/it/jpa/derby/TestResources.java | 8 + test-framework/derby/pom.xml | 31 +++ .../test/derby/DerbyDatabaseTestResource.java | 55 ++++++ 20 files changed, 733 insertions(+), 1 deletion(-) create mode 100644 extensions/jdbc/jdbc-derby/jdbc-derby-deployment/pom.xml create mode 100644 extensions/jdbc/jdbc-derby/jdbc-derby-deployment/src/main/java/io/quarkus/jdbc/derby/deployment/JDBCDerbyProcessor.java create mode 100644 extensions/jdbc/jdbc-derby/jdbc-derby-runtime/pom.xml create mode 100644 extensions/jdbc/jdbc-derby/pom.xml create mode 100644 integration-tests/jpa-derby/pom.xml create mode 100644 integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/JPAFunctionalityTestEndpoint.java create mode 100644 integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/Person.java create mode 100644 integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/SequencedAddress.java create mode 100644 integration-tests/jpa-derby/src/main/resources/META-INF/persistence.xml create mode 100644 integration-tests/jpa-derby/src/main/resources/application.properties create mode 100644 integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/JPAFunctionalityInGraalITCase.java create mode 100644 integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/JPAFunctionalityTest.java create mode 100644 integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/TestResources.java create mode 100644 test-framework/derby/pom.xml create mode 100644 test-framework/derby/src/main/java/io/quarkus/test/derby/DerbyDatabaseTestResource.java diff --git a/.gitignore b/.gitignore index db596be74051a..02cbb04774f70 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ out lib bin dependency-reduced-pom.xml +derby.log hotspot.log .directory .java-version diff --git a/bom/runtime/pom.xml b/bom/runtime/pom.xml index 0f829bfd676a9..16ff387b61e74 100644 --- a/bom/runtime/pom.xml +++ b/bom/runtime/pom.xml @@ -106,6 +106,7 @@ 2.4.4 8.0.17 7.2.1.jre8 + 10.14.2.0 1.2.6 4.1.1 5.5.2 @@ -403,6 +404,11 @@ quarkus-jdbc-mysql ${project.version} + + io.quarkus + quarkus-jdbc-derby + ${project.version} + io.quarkus quarkus-kafka-client @@ -670,6 +676,11 @@ quarkus-test-h2 ${project.version} + + io.quarkus + quarkus-test-derby + ${project.version} + io.quarkus quarkus-test-kubernetes-client @@ -1792,6 +1803,21 @@ mysql-connector-java ${mysql-jdbc.version} + + org.apache.derby + derbyclient + ${derby-jdbc.version} + + + org.apache.derby + derbynet + ${derby-jdbc.version} + + + org.apache.derby + derbytools + ${derby-jdbc.version} + com.microsoft.sqlserver mssql-jdbc diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/FeatureBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/FeatureBuildItem.java index 51b40a2b75769..aa1fc5fb759c3 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/FeatureBuildItem.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/FeatureBuildItem.java @@ -21,9 +21,10 @@ public final class FeatureBuildItem extends MultiBuildItem { public static final String HIBERNATE_SEARCH_ELASTICSEARCH = "hibernate-search-elasticsearch"; public static final String INFINISPAN_CLIENT = "infinispan-client"; public static final String JAEGER = "jaeger"; + public static final String JDBC_DERBY = "jdbc-derby"; public static final String JDBC_H2 = "jdbc-h2"; - public static final String JDBC_MARIADB = "jdbc-mariadb"; public static final String JDBC_POSTGRESQL = "jdbc-postgresql"; + public static final String JDBC_MARIADB = "jdbc-mariadb"; public static final String JDBC_MSSQL = "jdbc-mssql"; public static final String JDBC_MYSQL = "jdbc-mysql"; public static final String JGIT = "jgit"; diff --git a/devtools/common/src/main/filtered/extensions.json b/devtools/common/src/main/filtered/extensions.json index d585d455e2fa7..0239d602ce2c5 100644 --- a/devtools/common/src/main/filtered/extensions.json +++ b/devtools/common/src/main/filtered/extensions.json @@ -157,6 +157,16 @@ "artifactId": "quarkus-infinispan-client", "guide": "https://quarkus.io/guides/infinispan-client-guide" }, + { + "name": "JDBC Driver - Derby", + "labels": [ + "jdbc-derby", + "jdbc", + "derby" + ], + "groupId": "io.quarkus", + "artifactId": "quarkus-jdbc-derby" + }, { "name": "JDBC Driver - H2", "labels": [ diff --git a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java index f99bf2b145d58..8c998ba8ce85b 100644 --- a/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java +++ b/extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java @@ -27,6 +27,7 @@ import org.hibernate.boot.archive.scan.spi.ClassDescriptor; import org.hibernate.cfg.AvailableSettings; +import org.hibernate.dialect.DerbyTenSevenDialect; import org.hibernate.dialect.MariaDB103Dialect; import org.hibernate.dialect.MySQL8Dialect; import org.hibernate.integrator.spi.Integrator; @@ -517,6 +518,9 @@ private Optional guessDialect(Optional driver) { if (resolvedDriver.contains("com.mysql.cj.jdbc.Driver")) { return Optional.of(MySQL8Dialect.class.getName()); } + if (resolvedDriver.contains("org.apache.derby.jdbc.ClientDriver")) { + return Optional.of((DerbyTenSevenDialect.class.getName())); + } String error = driver.isPresent() ? "Hibernate extension could not guess the dialect from the driver '" + resolvedDriver diff --git a/extensions/jdbc/jdbc-derby/jdbc-derby-deployment/pom.xml b/extensions/jdbc/jdbc-derby/jdbc-derby-deployment/pom.xml new file mode 100644 index 0000000000000..a61c08f105b2f --- /dev/null +++ b/extensions/jdbc/jdbc-derby/jdbc-derby-deployment/pom.xml @@ -0,0 +1,42 @@ + + + + quarkus-jdbc-derby-parent + io.quarkus + 999-SNAPSHOT + + 4.0.0 + + quarkus-jdbc-derby-deployment + Quarkus - JDBC - Derby - Deployment + + + + io.quarkus + quarkus-core-deployment + + + io.quarkus + quarkus-jdbc-derby + + + + + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${project.version} + + + + + + + diff --git a/extensions/jdbc/jdbc-derby/jdbc-derby-deployment/src/main/java/io/quarkus/jdbc/derby/deployment/JDBCDerbyProcessor.java b/extensions/jdbc/jdbc-derby/jdbc-derby-deployment/src/main/java/io/quarkus/jdbc/derby/deployment/JDBCDerbyProcessor.java new file mode 100644 index 0000000000000..bc21bd3aed538 --- /dev/null +++ b/extensions/jdbc/jdbc-derby/jdbc-derby-deployment/src/main/java/io/quarkus/jdbc/derby/deployment/JDBCDerbyProcessor.java @@ -0,0 +1,23 @@ +package io.quarkus.jdbc.derby.deployment; + +import io.quarkus.deployment.annotations.BuildProducer; +import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.builditem.FeatureBuildItem; +import io.quarkus.deployment.builditem.substrate.ReflectiveClassBuildItem; + +public class JDBCDerbyProcessor { + + @BuildStep + FeatureBuildItem feature() { + return new FeatureBuildItem(FeatureBuildItem.JDBC_DERBY); + } + + @BuildStep + void registerDriverForReflection(BuildProducer reflectiveClass) { + //Not strictly necessary when using Agroal, as it also registers + //any JDBC driver being configured explicitly through its configuration. + //We register it for the sake of people not using Agroal. + reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, org.apache.derby.jdbc.ClientDriver.class.getName())); + } + +} diff --git a/extensions/jdbc/jdbc-derby/jdbc-derby-runtime/pom.xml b/extensions/jdbc/jdbc-derby/jdbc-derby-runtime/pom.xml new file mode 100644 index 0000000000000..9e726aa9ac62d --- /dev/null +++ b/extensions/jdbc/jdbc-derby/jdbc-derby-runtime/pom.xml @@ -0,0 +1,51 @@ + + + + quarkus-jdbc-derby-parent + io.quarkus + 999-SNAPSHOT + + 4.0.0 + + quarkus-jdbc-derby + Quarkus - JDBC - Derby - Runtime + + + + io.quarkus + quarkus-core + + + org.apache.derby + derbyclient + + + com.oracle.substratevm + svm + + + + + + + io.quarkus + quarkus-bootstrap-maven-plugin + + + maven-compiler-plugin + + + + io.quarkus + quarkus-extension-processor + ${project.version} + + + + + + + + diff --git a/extensions/jdbc/jdbc-derby/pom.xml b/extensions/jdbc/jdbc-derby/pom.xml new file mode 100644 index 0000000000000..b6aa9d0a15e66 --- /dev/null +++ b/extensions/jdbc/jdbc-derby/pom.xml @@ -0,0 +1,20 @@ + + + + quarkus-jdbc-parent + io.quarkus + 999-SNAPSHOT + + 4.0.0 + + quarkus-jdbc-derby-parent + Quarkus - JDBC - Derby + pom + + jdbc-derby-deployment + jdbc-derby-runtime + + + diff --git a/integration-tests/jpa-derby/pom.xml b/integration-tests/jpa-derby/pom.xml new file mode 100644 index 0000000000000..4310c9ef59d9c --- /dev/null +++ b/integration-tests/jpa-derby/pom.xml @@ -0,0 +1,126 @@ + + + + quarkus-integration-tests-parent + io.quarkus + 999-SNAPSHOT + ../ + + 4.0.0 + + quarkus-integration-test-jpa-derby + Quarkus - Integration Tests - JPA - Derby + Module that contains JPA related tests running with the Derby database + + + + io.quarkus + quarkus-hibernate-orm + + + + io.quarkus + quarkus-jdbc-derby + + + + io.quarkus + quarkus-undertow + + + + + io.quarkus + quarkus-junit5 + test + + + io.quarkus + quarkus-test-derby + test + + + io.rest-assured + rest-assured + test + + + + + + + src/main/resources + true + + + + + io.quarkus + quarkus-maven-plugin + + + + build + + + + + + + + + + native-image + + + native + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + + + + + + + io.quarkus + quarkus-maven-plugin + + + native-image + + native-image + + + false + true + true + ${graalvmHome} + false + false + + + + + + + + + + + diff --git a/integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/JPAFunctionalityTestEndpoint.java b/integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/JPAFunctionalityTestEndpoint.java new file mode 100644 index 0000000000000..85467ad61daab --- /dev/null +++ b/integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/JPAFunctionalityTestEndpoint.java @@ -0,0 +1,176 @@ +package io.quarkus.it.jpa.derby; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.PersistenceUnit; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Basic test running JPA with the Derby database. + * The application can work in either standard JVM or SubstrateVM, while we run H2 as a separate JVM process. + */ +@WebServlet(name = "JPATestBootstrapEndpoint", urlPatterns = "/jpa-derby/testfunctionality") +public class JPAFunctionalityTestEndpoint extends HttpServlet { + + @PersistenceUnit(unitName = "templatePU") + EntityManagerFactory entityManagerFactory; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + try { + doStuffWithHibernate(entityManagerFactory); + } catch (Exception e) { + reportException("An error occurred while performing Hibernate operations", e, resp); + } + resp.getWriter().write("OK"); + } + + /** + * Lists the various operations we want to test for: + */ + private static void doStuffWithHibernate(EntityManagerFactory entityManagerFactory) { + + //Cleanup any existing data: + deleteAllPerson(entityManagerFactory); + + //Store some well known Person instances we can then test on: + storeTestPersons(entityManagerFactory); + + //Load all persons and run some checks on the query results: + verifyListOfExistingPersons(entityManagerFactory); + + //Try a JPA named query: + verifyJPANamedQuery(entityManagerFactory); + + verifyHqlFetch(entityManagerFactory); + + deleteAllPerson(entityManagerFactory); + + } + + private static void verifyHqlFetch(EntityManagerFactory emf) { + EntityManager em = emf.createEntityManager(); + try { + EntityTransaction transaction = em.getTransaction(); + try { + transaction.begin(); + + em.createQuery("from Person p left join fetch p.address a").getResultList(); + + transaction.commit(); + } catch (Exception e) { + if (transaction.isActive()) { + transaction.rollback(); + } + throw e; + } + } finally { + em.close(); + } + } + + private static void verifyJPANamedQuery(final EntityManagerFactory emf) { + EntityManager em = emf.createEntityManager(); + EntityTransaction transaction = em.getTransaction(); + transaction.begin(); + TypedQuery typedQuery = em.createNamedQuery( + "get_person_by_name", Person.class); + typedQuery.setParameter("name", "Quarkus"); + final Person singleResult = typedQuery.getSingleResult(); + + if (!singleResult.getName().equals("Quarkus")) { + throw new RuntimeException("Wrong result from named JPA query"); + } + + transaction.commit(); + em.close(); + } + + private static void verifyListOfExistingPersons(final EntityManagerFactory emf) { + EntityManager em = emf.createEntityManager(); + EntityTransaction transaction = em.getTransaction(); + transaction.begin(); + listExistingPersons(em); + transaction.commit(); + em.close(); + } + + private static void storeTestPersons(final EntityManagerFactory emf) { + EntityManager em = emf.createEntityManager(); + EntityTransaction transaction = em.getTransaction(); + transaction.begin(); + persistNewPerson(em, "Gizmo"); + persistNewPerson(em, "Quarkus"); + persistNewPerson(em, "Hibernate ORM"); + transaction.commit(); + em.close(); + } + + private static void deleteAllPerson(final EntityManagerFactory emf) { + EntityManager em = emf.createEntityManager(); + EntityTransaction transaction = em.getTransaction(); + transaction.begin(); + em.createNativeQuery("Delete from Person").executeUpdate(); + transaction.commit(); + em.close(); + } + + private static void listExistingPersons(EntityManager em) { + CriteriaBuilder cb = em.getCriteriaBuilder(); + + CriteriaQuery cq = cb.createQuery(Person.class); + Root from = cq.from(Person.class); + cq.select(from).orderBy(cb.asc(from.get("name"))); + TypedQuery q = em.createQuery(cq); + List allpersons = q.getResultList(); + if (allpersons.size() != 3) { + throw new RuntimeException("Incorrect number of results"); + } + if (!allpersons.get(0).getName().equals("Gizmo")) { + throw new RuntimeException("Incorrect order of results"); + } + StringBuilder sb = new StringBuilder("list of stored Person names:\n\t"); + for (Person p : allpersons) { + p.describeFully(sb); + } + sb.append("\nList complete.\n"); + System.out.print(sb); + } + + private static void persistNewPerson(EntityManager entityManager, String name) { + Person person = new Person(); + person.setName(name); + person.setAddress(new SequencedAddress("Street " + randomName())); + entityManager.persist(person); + } + + private static String randomName() { + return UUID.randomUUID().toString(); + } + + private void reportException(String errorMessage, final Exception e, final HttpServletResponse resp) throws IOException { + final PrintWriter writer = resp.getWriter(); + if (errorMessage != null) { + writer.write(errorMessage); + writer.write(" "); + } + writer.write(e.toString()); + writer.append("\n\t"); + e.printStackTrace(writer); + writer.append("\n\t"); + } + +} diff --git a/integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/Person.java b/integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/Person.java new file mode 100644 index 0000000000000..282cb6c3826dd --- /dev/null +++ b/integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/Person.java @@ -0,0 +1,65 @@ +package io.quarkus.it.jpa.derby; + +import java.util.UUID; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQuery; + +import org.hibernate.annotations.GenericGenerator; + +@Entity +@NamedQuery(name = "get_person_by_name", query = "select p from Person p where name = :name") +public class Person { + + private UUID id; + private String name; + private SequencedAddress address; + + public Person() { + } + + public Person(UUID id, String name, SequencedAddress address) { + this.id = id; + this.name = name; + this.address = address; + } + + @Id + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + public SequencedAddress getAddress() { + return address; + } + + public void setAddress(SequencedAddress address) { + this.address = address; + } + + public void describeFully(StringBuilder sb) { + sb.append("Person with id=").append(id).append(", name='").append(name).append("', address { "); + getAddress().describeFully(sb); + sb.append(" }"); + } +} diff --git a/integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/SequencedAddress.java b/integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/SequencedAddress.java new file mode 100644 index 0000000000000..e7281cdc3fda3 --- /dev/null +++ b/integration-tests/jpa-derby/src/main/java/io/quarkus/it/jpa/derby/SequencedAddress.java @@ -0,0 +1,42 @@ +package io.quarkus.it.jpa.derby; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class SequencedAddress { + + private long id; + private String street; + + public SequencedAddress() { + } + + public SequencedAddress(String street) { + this.street = street; + } + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "addressSeq") + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getStreet() { + return street; + } + + public void setStreet(String name) { + this.street = name; + } + + public void describeFully(StringBuilder sb) { + sb.append("Address with id=").append(id).append(", street='").append(street).append("'"); + } +} diff --git a/integration-tests/jpa-derby/src/main/resources/META-INF/persistence.xml b/integration-tests/jpa-derby/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000000..e68ef2777720e --- /dev/null +++ b/integration-tests/jpa-derby/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/integration-tests/jpa-derby/src/main/resources/application.properties b/integration-tests/jpa-derby/src/main/resources/application.properties new file mode 100644 index 0000000000000..ef4cbe9fe5ac4 --- /dev/null +++ b/integration-tests/jpa-derby/src/main/resources/application.properties @@ -0,0 +1,4 @@ +quarkus.datasource.url=jdbc:derby://localhost:1527/memory:testDB;create=true +quarkus.datasource.driver=org.apache.derby.jdbc.ClientDriver +quarkus.datasource.max-size=8 +quarkus.datasource.min-size=2 \ No newline at end of file diff --git a/integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/JPAFunctionalityInGraalITCase.java b/integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/JPAFunctionalityInGraalITCase.java new file mode 100644 index 0000000000000..c5f10eef73165 --- /dev/null +++ b/integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/JPAFunctionalityInGraalITCase.java @@ -0,0 +1,11 @@ +package io.quarkus.it.jpa.derby; + +import io.quarkus.test.junit.SubstrateTest; + +/** + * Test various JPA operations running in SubstrateVM + */ +@SubstrateTest +public class JPAFunctionalityInGraalITCase extends JPAFunctionalityTest { + +} diff --git a/integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/JPAFunctionalityTest.java b/integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/JPAFunctionalityTest.java new file mode 100644 index 0000000000000..1feb4ce16be93 --- /dev/null +++ b/integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/JPAFunctionalityTest.java @@ -0,0 +1,21 @@ +package io.quarkus.it.jpa.derby; + +import static org.hamcrest.Matchers.is; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.RestAssured; + +/** + * Test connecting Hibernate ORM to Derby. + */ +@QuarkusTest +public class JPAFunctionalityTest { + + @Test + public void testJPAFunctionalityFromServlet() throws Exception { + RestAssured.when().get("/jpa-derby/testfunctionality").then().body(is("OK")); + } + +} diff --git a/integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/TestResources.java b/integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/TestResources.java new file mode 100644 index 0000000000000..dc9ff6d8de8fe --- /dev/null +++ b/integration-tests/jpa-derby/src/test/java/io/quarkus/it/jpa/derby/TestResources.java @@ -0,0 +1,8 @@ +package io.quarkus.it.jpa.derby; + +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.derby.DerbyDatabaseTestResource; + +@QuarkusTestResource(DerbyDatabaseTestResource.class) +public class TestResources { +} diff --git a/test-framework/derby/pom.xml b/test-framework/derby/pom.xml new file mode 100644 index 0000000000000..952f01927d5d0 --- /dev/null +++ b/test-framework/derby/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + + io.quarkus + quarkus-test-framework + 999-SNAPSHOT + ../ + + + quarkus-test-derby + Quarkus - Test framework - Derby Database Support + + + io.quarkus + quarkus-test-common + + + org.apache.derby + derbynet + + + org.apache.derby + derbytools + + + + diff --git a/test-framework/derby/src/main/java/io/quarkus/test/derby/DerbyDatabaseTestResource.java b/test-framework/derby/src/main/java/io/quarkus/test/derby/DerbyDatabaseTestResource.java new file mode 100644 index 0000000000000..ee55414a8c872 --- /dev/null +++ b/test-framework/derby/src/main/java/io/quarkus/test/derby/DerbyDatabaseTestResource.java @@ -0,0 +1,55 @@ +package io.quarkus.test.derby; + +import java.io.PrintWriter; +import java.util.Collections; +import java.util.Map; + +import org.apache.derby.drda.NetworkServerControl; + +import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; + +public class DerbyDatabaseTestResource implements QuarkusTestResourceLifecycleManager { + + static final int NUMBER_OF_PINGS = 10; + static final int SLEEP_BETWEEN_PINGS = 500; + + @Override + public Map start() { + try { + NetworkServerControl server = new NetworkServerControl(); + server.start(new PrintWriter(System.out)); + for (int i = 1; i <= NUMBER_OF_PINGS; i++) { + try { + System.out.println("[INFO] Attempt " + i + " to see if Derby Network server started"); + server.ping(); + break; + } catch (Exception ex) { + if (i == NUMBER_OF_PINGS) { + System.out.println("Derby Network server failed to start"); + ex.printStackTrace(); + throw ex; + } + try { + Thread.sleep(SLEEP_BETWEEN_PINGS); + } catch (InterruptedException ignore) { + } + } + } + System.out.println("[INFO] Derby database started in TCP server mode"); + } catch (Exception e) { + throw new RuntimeException(e); + } + return Collections.emptyMap(); + } + + @Override + public void stop() { + try { + NetworkServerControl server = new NetworkServerControl(); + server.shutdown(); + System.out.println("[INFO] Derby database was shut down"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} From 1bfb6812dfcb3dce92ed28947050fe451de19f35 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Mon, 14 Oct 2019 18:32:34 +0100 Subject: [PATCH 2/3] Enable the new Derby modules in parent pom files --- extensions/jdbc/pom.xml | 1 + test-framework/pom.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/extensions/jdbc/pom.xml b/extensions/jdbc/pom.xml index 636c394906df2..86ca9386fb276 100644 --- a/extensions/jdbc/pom.xml +++ b/extensions/jdbc/pom.xml @@ -15,6 +15,7 @@ pom jdbc-postgresql + jdbc-derby jdbc-h2 jdbc-mariadb jdbc-mssql diff --git a/test-framework/pom.xml b/test-framework/pom.xml index a24a6c12a6ede..6a17d9d18a5f1 100644 --- a/test-framework/pom.xml +++ b/test-framework/pom.xml @@ -16,6 +16,7 @@ common h2 + derby kubernetes-client junit5-internal junit5 From c5f91a9d4769cb93748ff8d6dca053cfe2c4092a Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Mon, 14 Oct 2019 18:32:45 +0100 Subject: [PATCH 3/3] Code style --- .../java/io/quarkus/test/derby/DerbyDatabaseTestResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-framework/derby/src/main/java/io/quarkus/test/derby/DerbyDatabaseTestResource.java b/test-framework/derby/src/main/java/io/quarkus/test/derby/DerbyDatabaseTestResource.java index ee55414a8c872..a522625a29183 100644 --- a/test-framework/derby/src/main/java/io/quarkus/test/derby/DerbyDatabaseTestResource.java +++ b/test-framework/derby/src/main/java/io/quarkus/test/derby/DerbyDatabaseTestResource.java @@ -30,7 +30,7 @@ public Map start() { throw ex; } try { - Thread.sleep(SLEEP_BETWEEN_PINGS); + Thread.sleep(SLEEP_BETWEEN_PINGS); } catch (InterruptedException ignore) { } }