Fix #206 - Don't require hl7org structures to start JPA server

This commit is contained in:
jamesagnew 2015-08-19 07:47:45 -04:00
parent 6941f92090
commit 4d04b9cc6a
8 changed files with 235 additions and 117 deletions

View File

@ -67,7 +67,6 @@
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
<version>${logback_version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -269,25 +268,21 @@
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId> <artifactId>jetty-servlets</artifactId>
<version>${jetty_version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId> <artifactId>jetty-servlet</artifactId>
<version>${jetty_version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId> <artifactId>jetty-server</artifactId>
<version>${jetty_version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId> <artifactId>jetty-util</artifactId>
<version>${jetty_version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>

View File

@ -1,30 +1,10 @@
package ca.uhn.fhir.jpa.dao; package ca.uhn.fhir.jpa.dao;
/* import javax.annotation.PostConstruct;
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed 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.
* #L%
*/
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
@ -41,11 +21,29 @@ import ca.uhn.fhir.validation.ValidationResult;
public class FhirResourceDaoQuestionnaireResponseDstu2 extends FhirResourceDaoDstu2<QuestionnaireResponse> { public class FhirResourceDaoQuestionnaireResponseDstu2 extends FhirResourceDaoDstu2<QuestionnaireResponse> {
private FhirContext myRefImplCtx = FhirContext.forDstu2Hl7Org(); private FhirContext myRefImplCtx;
private Boolean myValidateResponses;
/**
* Initialize the bean
*/
@PostConstruct
public void initialize() {
try {
Class.forName("org.hl7.fhir.instance.model.QuestionnaireResponse");
myValidateResponses = true;
myRefImplCtx = FhirContext.forDstu2Hl7Org();
} catch (ClassNotFoundException e) {
myValidateResponses = Boolean.FALSE;
}
}
@Override @Override
protected void validateResourceForStorage(IResource theResource) { protected void validateResourceForStorage(IResource theResource) {
super.validateResourceForStorage(theResource); super.validateResourceForStorage(theResource);
if (!myValidateResponses) {
return;
}
QuestionnaireResponse qa = (QuestionnaireResponse) theResource; QuestionnaireResponse qa = (QuestionnaireResponse) theResource;
if (qa == null || qa.getQuestionnaire() == null || qa.getQuestionnaire().getReference() == null || qa.getQuestionnaire().getReference().isEmpty()) { if (qa == null || qa.getQuestionnaire() == null || qa.getQuestionnaire().getReference() == null || qa.getQuestionnaire().getReference().isEmpty()) {
@ -73,7 +71,8 @@ public class FhirResourceDaoQuestionnaireResponseDstu2 extends FhirResourceDaoDs
public <T extends IBaseResource> T load(Class<T> theType, IIdType theId) throws ResourceNotFoundException { public <T extends IBaseResource> T load(Class<T> theType, IIdType theId) throws ResourceNotFoundException {
/* /*
* The QuestionnaireResponse validator uses RI structures, so for now we need to convert between that and HAPI structures. This is a bit hackish, but hopefully it will go away at some point. * The QuestionnaireResponse validator uses RI structures, so for now we need to convert between that and HAPI
* structures. This is a bit hackish, but hopefully it will go away at some point.
*/ */
if ("ValueSet".equals(theType.getSimpleName())) { if ("ValueSet".equals(theType.getSimpleName())) {
IFhirResourceDao<ValueSet> dao = getDao(ValueSet.class); IFhirResourceDao<ValueSet> dao = getDao(ValueSet.class);

View File

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"> <classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes> <attributes>
<attribute name="optional" value="true"/> <attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"> <classpathentry kind="src" path="src/test/resources"/>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes> <attributes>
<attribute name="optional" value="true"/> <attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>

View File

@ -1,14 +1,11 @@
<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/xsd/maven-4.0.0.xsd"> <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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<!-- <!-- Note: HAPI projects use the "hapi-fhir" POM as their base to provide
Note: HAPI projects use the "hapi-fhir" POM as their base to provide easy management. You do not need to use this in your own projects, so the
easy management. "parent" tag and it's contents below may be removed if you are using this
file as a basis for your own project. -->
You do not need to use this in your own projects, so the
"parent" tag and it's contents below may be removed if you
are using this file as a basis for your own project.
-->
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
@ -53,10 +50,8 @@
<version>1.2-SNAPSHOT</version> <version>1.2-SNAPSHOT</version>
</dependency> </dependency>
<!-- <!-- This dependency includes the JPA server itself, which is packaged
This dependency includes the JPA server itself, which is packaged separately from the rest of HAPI FHIR -->
separately from the rest of HAPI FHIR
-->
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-jpaserver-base</artifactId> <artifactId>hapi-fhir-jpaserver-base</artifactId>
@ -72,16 +67,13 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- <!-- HAPI-FHIR uses Logback for logging support. The logback library is
HAPI-FHIR uses Logback for logging support. The logback library is included included automatically by Maven as a part of the hapi-fhir-base dependency,
automatically by Maven as a part of the hapi-fhir-base dependency, but you but you also need to include a logging library. Logback is used here, but
also need to include a logging library. Logback is used here, but log4j log4j would also be fine. -->
would also be fine.
-->
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
<version>${logback_version}</version>
</dependency> </dependency>
<!-- Needed for JEE/Servlet support --> <!-- Needed for JEE/Servlet support -->
@ -91,10 +83,8 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- <!-- If you are using HAPI narrative generation, you will need to include
If you are using HAPI narrative generation, you will need to include Thymeleaf Thymeleaf as well. Otherwise the following can be omitted. -->
as well. Otherwise the following can be omitted.
-->
<dependency> <dependency>
<groupId>org.thymeleaf</groupId> <groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId> <artifactId>thymeleaf</artifactId>
@ -114,10 +104,7 @@
</exclusions> </exclusions>
</dependency> </dependency>
<!-- <!-- Spring Web is used to deploy the server to a web container. -->
Spring Web is used to deploy the server to a
web container.
-->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId> <artifactId>spring-web</artifactId>
@ -125,21 +112,17 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- <!-- You may not need this if you are deploying to an application server
You may not need this if you are deploying to an application server which which provides database connection pools itself. -->
provides database connection pools itself.
-->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId> <artifactId>commons-dbcp2</artifactId>
</dependency> </dependency>
<!-- <!-- This example uses Derby embedded database. If you are using another
This example uses Derby embedded database. If you are using another database such as Mysql or Oracle, you may omit the following dependencies
database such as Mysql or Oracle, you may omit the following and replace them with an appropriate database client dependency for your
dependencies and replace them with an appropriate database client database platform. -->
dependency for your database platform.
-->
<dependency> <dependency>
<groupId>org.apache.derby</groupId> <groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId> <artifactId>derby</artifactId>
@ -154,12 +137,37 @@
</dependency> </dependency>
<!-- <!--
Arquillian is just used for automated tests, you don't neccesarily need it The following dependencies are only needed for automated unit tests,
to use this example. you do not neccesarily need them to run the example.
--> -->
<dependency> <dependency>
<groupId>org.jboss.arquillian.junit</groupId> <groupId>junit</groupId>
<artifactId>arquillian-junit-container</artifactId> <artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
@ -167,17 +175,11 @@
<build> <build>
<!-- <!-- Tells Maven to name the generated WAR file as hapi-fhir-jpaserver-example.war -->
Tells Maven to name the generated WAR file as
hapi-fhir-jpaserver-example.war
-->
<finalName>hapi-fhir-jpaserver-example</finalName> <finalName>hapi-fhir-jpaserver-example</finalName>
<!-- <!-- The following is not required for the application to build, but allows
The following is not required for the application to build, but you to test it by issuing "mvn jetty:run" from the command line. -->
allows you to test it by issuing "mvn jetty:run" from the command
line.
-->
<pluginManagement> <pluginManagement>
<plugins> <plugins>
<plugin> <plugin>
@ -194,9 +196,7 @@
</pluginManagement> </pluginManagement>
<plugins> <plugins>
<!-- <!-- Tell Maven which Java source version you want to use -->
Tell Maven which Java source version you want to use
-->
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
@ -206,10 +206,8 @@
</configuration> </configuration>
</plugin> </plugin>
<!-- <!-- The configuration here tells the WAR plugin to include the FHIR Tester
The configuration here tells the WAR plugin to include the FHIR Tester overlay. You can omit it if you are not using that feature. -->
overlay. You can omit it if you are not using that feature.
-->
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId> <artifactId>maven-war-plugin</artifactId>
@ -223,10 +221,8 @@
</configuration> </configuration>
</plugin> </plugin>
<!-- <!-- This plugin is just a part of the HAPI internal build process, you
This plugin is just a part of the HAPI internal build process, you do not do not need to incude it in your own projects -->
need to incude it in your own projects
-->
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId> <artifactId>maven-deploy-plugin</artifactId>

View File

@ -42,7 +42,7 @@
</init-param> </init-param>
<init-param> <init-param>
<param-name>FhirVersion</param-name> <param-name>FhirVersion</param-name>
<param-value>DSTU1</param-value> <param-value>DSTU2</param-value>
</init-param> </init-param>
<load-on-startup>1</load-on-startup> <load-on-startup>1</load-on-startup>
</servlet> </servlet>

View File

@ -0,0 +1,36 @@
package ca.uhn.fhir.jpa.dao;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
/**
* Provides server ports
*/
public class RandomServerPortProvider {
private static List<Integer> ourPorts = new ArrayList<Integer>();
public static int findFreePort() {
ServerSocket server;
try {
server = new ServerSocket(0);
int port = server.getLocalPort();
ourPorts.add(port);
server.close();
Thread.sleep(500);
return port;
} catch (IOException e) {
throw new Error(e);
} catch (InterruptedException e) {
throw new Error(e);
}
}
public static List<Integer> list() {
return ourPorts;
}
}

View File

@ -0,0 +1,66 @@
package ca.uhn.fhir.jpa.dao;
import static org.junit.Assert.*;
import java.io.IOException;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
public class ResourceProviderDstu2Test {
private static IGenericClient ourClient;
private static final FhirContext ourCtx = FhirContext.forDstu2();
private static int ourPort;
private static Server ourServer;
@Test
public void testCreateAndRead() throws IOException {
String methodName = "testCreateResourceConditional";
Patient pt = new Patient();
pt.addName().addFamily(methodName);
IIdType id = ourClient.create().resource(pt).execute().getId();
Patient pt2 = ourClient.read().resource(Patient.class).withId(id).execute();
assertEquals(methodName, pt2.getName().get(0).getFamily().get(0).getValue());
}
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
}
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = RandomServerPortProvider.findFreePort();
ourServer = new Server(ourPort);
WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/");
webAppContext.setDescriptor("src/main/webapp/WEB-INF/web.xml");
webAppContext.setResourceBase("target/hapi-fhir-jpaserver-example");
webAppContext.setParentLoaderPriority(true);
ourServer.setHandler(webAppContext);
ourServer.start();
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
ourClient = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort + "/base");
ourClient.registerInterceptor(new LoggingInterceptor(true));
}
}

47
pom.xml
View File

@ -45,12 +45,6 @@
</description> </description>
<dependencies> <dependencies>
<dependency>
<groupId>net.sourceforge.cobertura</groupId>
<artifactId>cobertura</artifactId>
<version>2.1.1</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
<prerequisites> <prerequisites>
@ -231,6 +225,16 @@
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version> <version>3.1.0</version>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>net.sourceforge.cobertura</groupId>
<artifactId>cobertura</artifactId>
<version>2.1.1</version>
</dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId> <artifactId>commons-dbcp2</artifactId>
@ -252,9 +256,29 @@
<version>${derby_version}</version> <version>${derby_version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jboss.arquillian.junit</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>arquillian-junit-container</artifactId> <artifactId>jetty-servlets</artifactId>
<version>1.1.8.Final</version> <version>9.2.6.v20141205</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.2.6.v20141205</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.2.6.v20141205</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>9.2.6.v20141205</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>9.2.6.v20141205</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
@ -580,7 +604,7 @@
<fileset dir="hapi-fhir-cobertura/target/site/cobertura" /> <fileset dir="hapi-fhir-cobertura/target/site/cobertura" />
</copy> </copy>
<copy todir="target/site"> <copy todir="target/site">
<fileset dir="hapi-fhir-base/target/site" includes="checkstyle.*"/> <fileset dir="hapi-fhir-base/target/site" includes="checkstyle.*" />
</copy> </copy>
<echo>Fixing Checkstyle Report</echo> <echo>Fixing Checkstyle Report</echo>
<replace dir="target/site" summary="true"> <replace dir="target/site" summary="true">
@ -609,7 +633,8 @@
</div> </div>
</div>]]></replacevalue> </div>]]></replacevalue>
</replace> </replace>
<!--<replaceregexp file="target/site/checkstyle.html" byline="false" match="&lt;ul class=&quot;breadcrumb.*?&lt;/ul&gt;" replace="" flags="s"/>--> <!--<replaceregexp file="target/site/checkstyle.html" byline="false"
match="&lt;ul class=&quot;breadcrumb.*?&lt;/ul&gt;" replace="" flags="s"/> -->
</target> </target>
</configuration> </configuration>
</execution> </execution>