Remove dependency on ServletInputStream

This commit is contained in:
James Agnew 2015-06-11 14:24:40 -04:00
parent 09d97106d3
commit f40955c2cb
25 changed files with 1775 additions and 395 deletions

View File

@ -0,0 +1,89 @@
<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>
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>1.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>hapi-fhir-base-testmindeps-client</artifactId>
<packaging>jar</packaging>
<name>HAPI FHIR - Minimal Dependency Test - Client</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit_version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId>
<version>1.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>woodstox-core-asl</artifactId>
<groupId>org.codehaus.woodstox</groupId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu</artifactId>
<version>1.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>woodstox-core-asl</artifactId>
<groupId>org.codehaus.woodstox</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu2</artifactId>
<version>1.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<artifactId>woodstox-core-asl</artifactId>
<groupId>org.codehaus.woodstox</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>java-hamcrest</artifactId>
<version>${hamcrest_version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,32 @@
package ca.uhn.fhir.rest.client;
import static org.junit.Assert.fail;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
import ca.uhn.fhir.rest.gclient.ITransactionTyped;
public class ClientTest {
private static final FhirContext ctx = FhirContext.forDstu1();
@Test
public void testTransaction() {
Bundle bundle = new Bundle();
bundle.addEntry().setResource(new Patient().setId("Patient/unit_test_patient"));
IGenericClient client = ctx.newRestfulGenericClient("http://this_is_an_invalid_host_name_yes_it_is/fhir"); // won't connect
ITransactionTyped<Bundle> transaction = client.transaction().withBundle(bundle);
try {
Bundle result = transaction.encodedJson().execute();
fail();
} catch (FhirClientConnectionException e) {
// good
}
}
}

View File

@ -9,18 +9,12 @@
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>hapi-fhir-base-testmindeps</artifactId>
<artifactId>hapi-fhir-base-testmindeps-server</artifactId>
<packaging>jar</packaging>
<name>HAPI FHIR - Minimal Dependency Test</name>
<name>HAPI FHIR - Minimal Dependency Test - Server</name>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@ -46,6 +40,10 @@
<artifactId>woodstox-core-asl</artifactId>
<groupId>org.codehaus.woodstox</groupId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>

View File

@ -0,0 +1,32 @@
package ca.uhn.fhir.rest.client;
import static org.junit.Assert.fail;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
import ca.uhn.fhir.rest.gclient.ITransactionTyped;
public class ClientTest {
private static final FhirContext ctx = FhirContext.forDstu1();
@Test
public void testTransaction() {
Bundle bundle = new Bundle();
bundle.addEntry().setResource(new Patient().setId("Patient/unit_test_patient"));
IGenericClient client = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu1");
ITransactionTyped<Bundle> transaction = client.transaction().withBundle(bundle);
try {
Bundle result = transaction.encodedJson().execute();
fail();
} catch (FhirClientConnectionException e) {
// good
}
}
}

View File

@ -23,6 +23,7 @@ package ca.uhn.fhir.rest.method;
import static org.apache.commons.lang3.StringUtils.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@ -33,6 +34,8 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.servlet.ServletInputStream;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -264,7 +267,29 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
}
protected byte[] loadRequestContents(RequestDetails theRequest) throws IOException {
byte[] requestContents = IOUtils.toByteArray(theRequest.getServletRequest().getInputStream());
IRequestReader reader = ourRequestReader;
if (reader == null) {
try {
Class.forName("javax.servlet.ServletInputStream");
String className = BaseMethodBinding.class.getName() + "." + "ActiveRequestReader";
try {
reader = (IRequestReader) Class.forName(className).newInstance();
} catch (Exception e1) {
throw new ConfigurationException("Failed to instantiate class " + className, e1);
}
} catch (ClassNotFoundException e) {
String className = BaseMethodBinding.class.getName() + "." + "InactiveRequestReader";
try {
reader = (IRequestReader) Class.forName(className).newInstance();
} catch (Exception e1) {
throw new ConfigurationException("Failed to instantiate class " + className, e1);
}
}
ourRequestReader = reader;
}
InputStream inputStream = reader.getInputStream(theRequest);
byte[] requestContents = IOUtils.toByteArray(inputStream);
return requestContents;
}
@ -555,4 +580,38 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
return true;
}
/**
* @see BaseMethodBinding#loadRequestContents(RequestDetails)
*/
private static volatile IRequestReader ourRequestReader;
/**
* @see BaseMethodBinding#loadRequestContents(RequestDetails)
*/
private static interface IRequestReader {
InputStream getInputStream(RequestDetails theRequestDetails) throws IOException;
}
/**
* @see BaseMethodBinding#loadRequestContents(RequestDetails)
*/
@SuppressWarnings("unused")
private static class ActiveRequestReader implements IRequestReader {
@Override
public InputStream getInputStream(RequestDetails theRequestDetails) throws IOException {
return theRequestDetails.getServletRequest().getInputStream();
}
}
/**
* @see BaseMethodBinding#loadRequestContents(RequestDetails)
*/
@SuppressWarnings("unused")
private static class InactiveRequestReader implements IRequestReader {
@Override
public InputStream getInputStream(RequestDetails theRequestDetails) {
throw new IllegalStateException("The servlet-api JAR is not found on the classpath. Please check that this library is available.");
}
}
}

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry combineaccessrules="false" kind="src" path="/hapi-fhir-base"/>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>hapi-fhir-base-examples</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@ -1,47 +0,0 @@
<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>
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>0.6-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>hapi-fhir-base-examples</artifactId>
<packaging>jar</packaging>
<name>HAPI FHIR - Examples (for site)</name>
<dependencies>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId>
<version>0.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit_version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -49,6 +49,7 @@ import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -101,7 +102,13 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
}
}
RuntimeResourceDefinition resType = getContext().getResourceDefinition(retVal.getResourceType());
RuntimeResourceDefinition resType;
try {
resType = getContext().getResourceDefinition(retVal.getResourceType());
} catch (DataFormatException e) {
String msg = getContext().getLocalizer().getMessage(BaseFhirSystemDao.class, "transactionInvalidUrl", theAction, theUrl);
throw new InvalidRequestException(msg);
}
IFhirResourceDao<? extends IResource> dao = null;
if (resType != null) {
dao = getDao(resType.getImplementingClass());

View File

@ -11,6 +11,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
@ -20,7 +21,9 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList;
@ -29,6 +32,7 @@ import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Location;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.param.TokenParam;
@ -271,7 +275,6 @@ public class FhirSystemDaoDstu1Test {
}
@Test(expected = InvalidRequestException.class)
public void testTransactionFailsWithDuplicateIds() {
Patient patient1 = new Patient();
@ -301,7 +304,6 @@ public class FhirSystemDaoDstu1Test {
assertThat(id, not(equalToIgnoringCase("")));
}
/**
* Issue #55
*/
@ -337,6 +339,23 @@ public class FhirSystemDaoDstu1Test {
}
@Test
public void testTransactionWithCidIds2() throws Exception {
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/dstu1_bundle.xml");
String bundleStr = IOUtils.toString(bundleRes);
Bundle bundle = ourFhirContext.newXmlParser().parseBundle(bundleStr);
List<IResource> res = new ArrayList<IResource>();
for (BundleEntry next : bundle.getEntries()) {
res.add(next.getResource());
}
List<IResource> response = ourSystemDao.transaction(res);
ourLog.info(ourFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(response.get(0)));
}
@Test
public void testTransactionWithDelete() throws Exception {

View File

@ -160,6 +160,21 @@ public class FhirSystemDaoDstu2Test {
assertEquals("Patient/temp6789", p.getLink().get(0).getOther().getReference().getValue());
}
@Test
public void testTransactionFromBundle2() throws Exception {
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/brokenbundle_dstu2.json");
String bundleStr = IOUtils.toString(bundleRes);
Bundle bundle = ourFhirContext.newJsonParser().parseResource(Bundle.class, bundleStr);
try {
ourSystemDao.transaction(bundle);
fail();
} catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Unable to perform PUT, URL provided is invalid: RWB_COMP_1"));
}
}
@Test

View File

@ -58,6 +58,7 @@ import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.model.dstu2.resource.Condition;
import ca.uhn.fhir.model.dstu2.resource.DiagnosticOrder;
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
import ca.uhn.fhir.model.dstu2.resource.DocumentManifest;
import ca.uhn.fhir.model.dstu2.resource.DocumentReference;
import ca.uhn.fhir.model.dstu2.resource.Encounter;
@ -182,6 +183,33 @@ public class ResourceProviderDstu2Test {
}
@Test
public void testCreateResourceWithInvalidData() throws IOException {
String methodName = "testCreateResourceWithInvalidData";
DiagnosticReport diagRept = new DiagnosticReport();
diagRept.getResult().get(0).getReference().isEmpty();
Patient pt = new Patient();
pt.addName().addFamily(methodName);
pt.setBirthDate(new DateDt("2011-01-01"));
String resource = ourFhirCtx.newXmlParser().encodeResourceToString(pt);
HttpPost post = new HttpPost(ourServerBase + "/Patient");
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
CloseableHttpResponse response = ourHttpClient.execute(post);
IdDt id;
try {
assertEquals(201, response.getStatusLine().getStatusCode());
String newIdString = response.getFirstHeader(Constants.HEADER_LOCATION_LC).getValue();
assertThat(newIdString, startsWith(ourServerBase + "/Patient/"));
id = new IdDt(newIdString);
} finally {
response.close();
}
}
@Test
public void testCreateResourceWithNumericId() throws IOException {
String resource = "<Patient xmlns=\"http://hl7.org/fhir\"></Patient>";

View File

@ -0,0 +1,129 @@
{
"resourceType":"Bundle",
"id":"RWB_DS_BUNDLE",
"type":"transaction",
"entry":[
{
"resource":{
"resourceType":"Composition",
"id":"RWB_COMP_1",
"date":"2015-06-09T13:18:58-04:00",
"type":{
"coding":[
{
"system":"http://loinc.org",
"code":"18842-5"
}
]
},
"title":"TCLHIN Discharge Summary",
"status":"final",
"confidentiality":"N",
"subject":{
"reference":"Patient/DS-PAT1"
},
"custodian":{
"reference":"Location/LOC_RWB_TGH"
},
"encounter":{
"reference":"Encounter/VISIT_RWB_1"
}
},
"transaction":{
"method":"PUT",
"url":"RWB_COMP_1"
}
},
{
"resource":{
"resourceType":"MedicationStatement",
"contained":[
{
"resourceType":"Medication",
"id":"1",
"name":"Tylenol"
}
],
"status":"in-progress",
"medication":{
"reference":"#1"
},
"dosage":[
{
"text":"Twice a day, every day. 60% of the time, every time.",
"schedule":{
"code":{
"coding":[
{
"system":"http://hl7.org/fhir/v3/vs/GTSAbbreviation",
"code":"BID"
}
]
}
}
}
]
},
"transaction":{
"method":"PUT"
}
},
{
"resource":{
"resourceType":"Observation",
"code":{
"coding":[
{
"system":"urn:oid:1.3.6.1.4.1.12201.101.1",
"code":"SUMMARY"
}
]
},
"valueString":"Patient was seen and left because they are okay now. Everyting's fine. How are you?"
},
"transaction":{
"method":"PUT"
}
},
{
"resource":{
"resourceType":"Procedure",
"type":{
"coding":[
{
"system":"http://snomed.info/sct",
"code":"177820006"
}
]
}
},
"transaction":{
"method":"PUT"
}
},
{
"resource":{
"resourceType":"CarePlan",
"id":"RWB_CAREPLAN_1",
"status":"planned",
"notes":"This is a care plan. You should get healthy. Seriously. Get healthy."
},
"transaction":{
"method":"PUT",
"url":"RWB_CAREPLAN_1"
}
},
{
"resource":{
"resourceType":"ReferralRequest",
"id":"RWB_REFERRAL_REQUEST_1",
"status":"draft",
"description":"I need you to look at this guy's belly. Not for anything serious; it's just hilarious."
},
"transaction":{
"method":"PUT",
"url":"RWB_REFERRAL_REQUEST_1"
}
}
]
}

File diff suppressed because it is too large Load Diff

View File

@ -142,23 +142,6 @@
</span>
</div>
<!-- Includes -->
<div class="row-fluid">
<h4>Reverse Includes <small>Also include resources which reference to the search results</small></h4>
</div>
<div class="row-fluid">
<span class="includeCheckCheck">
<input type="checkbox" th:value="'*'" th:id="'revinc_STAR'" />
</span>
<span class="includeCheckName" th:text="'*'"/>
<span th:each="include : ${revincludes}" class="includeCheckContainer">
<span class="includeCheckCheck">
<input type="checkbox" th:value="${include}" th:id="'revinc_' + ${include}" />
</span>
<span class="includeCheckName" th:text="${include}"/>
</span>
</div>
<!-- Results Sorting -->
<div class="row-fluid">
<h4>Sort Results</h4>
@ -218,6 +201,22 @@
</div>
<br clear="all"/>
<!-- Reverse Includes -->
<div class="row-fluid">
<h4>Reverse Includes <small>Also include resources which reference to the search results</small></h4>
</div>
<div class="row-fluid">
<span class="includeCheckCheck">
<input type="checkbox" th:value="'*'" th:id="'revinc_STAR'" />
</span>
<span class="includeCheckName" th:text="'*'"/>
<span th:each="include : ${revincludes}" class="includeCheckContainer">
<span class="includeCheckCheck">
<input type="checkbox" th:value="${include}" th:id="'revinc_' + ${include}" />
</span>
<span class="includeCheckName" th:text="${include}"/>
</span>
</div>
</div>
</div>

View File

@ -886,7 +886,8 @@
<module>hapi-deployable-pom</module>
<module>hapi-fhir-base</module>
<!--<module>hapi-fhir-oauth2</module>-->
<module>hapi-fhir-base/testmindeps</module>
<module>hapi-fhir-base-test-mindeps-client</module>
<module>hapi-fhir-base-test-mindeps-server</module>
<module>hapi-tinder-plugin</module>
<module>hapi-tinder-test</module>
<module>hapi-fhir-structures-dstu</module>