Use more compatible Accept header in STU3 client. Also fixes missing
Woodstox library in android builds per #450)
This commit is contained in:
parent
a3108eba8d
commit
364c18e06e
|
@ -35,10 +35,6 @@
|
|||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.codehaus.woodstox</groupId>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -59,6 +55,11 @@
|
|||
<version>2.1-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.woodstox</groupId>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient-android</artifactId>
|
||||
|
@ -75,10 +76,6 @@
|
|||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
|
@ -98,25 +95,59 @@
|
|||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<!--
|
||||
<classpathDependencyScopeExclude>compile+runtime+test+provided</classpathDependencyScopeExclude>
|
||||
<additionalClasspathElements>
|
||||
<additionalClasspathElement>${project.build.directory}/hapi-fhir-android-${project.version}-dstu2.jar</additionalClasspathElement>
|
||||
</additionalClasspathElements>
|
||||
<classpathDependencyExcludes>
|
||||
<classpathDependencyExclude>ca.uhn.hapi.fhir:hapi-fhir-base</classpathDependencyExclude>
|
||||
<classpathDependencyExclude>org.codehaus.woodstox:*</classpathDependencyExclude>
|
||||
<classpathDependencyExclude>javax.json:*</classpathDependencyExclude>
|
||||
<classpathDependencyExclude>org.glassfish:javax.json</classpathDependencyExclude>
|
||||
</classpathDependencyExcludes>
|
||||
-->
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>dstu2_shade</id>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Dstu2ShadeIT.java</include>
|
||||
</includes>
|
||||
<additionalClasspathElements>
|
||||
<additionalClasspathElement>${basedir}/target/hapi-fhir-android-${project.version}-dstu2.jar</additionalClasspathElement>
|
||||
</additionalClasspathElements>
|
||||
<classpathDependencyExcludes>
|
||||
<classpathDependencyExclude>ca.uhn.hapi.fhir:*</classpathDependencyExclude>
|
||||
<classpathDependencyExclude>org.codehaus.woodstox:woodstox-core-asl</classpathDependencyExclude>
|
||||
<classpathDependencyExclude>org.codehaus.woodstox:stax2-api</classpathDependencyExclude>
|
||||
</classpathDependencyExcludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>dstu2</id>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Dstu2IT.java</include>
|
||||
</includes>
|
||||
<classpathDependencyExcludes>
|
||||
<classpathDependencyExclude>org.codehaus.woodstox:woodstox-core-asl</classpathDependencyExclude>
|
||||
<classpathDependencyExclude>org.codehaus.woodstox:stax2-api</classpathDependencyExclude>
|
||||
</classpathDependencyExcludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>dstu3</id>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Dstu3IT.java</include>
|
||||
</includes>
|
||||
<classpathDependencyExcludes>
|
||||
<classpathDependencyExclude>org.codehaus.woodstox:woodstox-core-asl</classpathDependencyExclude>
|
||||
<classpathDependencyExclude>org.codehaus.woodstox:stax2-api</classpathDependencyExclude>
|
||||
</classpathDependencyExcludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
@ -130,6 +161,9 @@
|
|||
<artifactSet>
|
||||
<includes combine.children="append">
|
||||
<include>ca.uhn.hapi.fhir:hapi-fhir-base</include>
|
||||
<include>org.codehaus.woodstox:woodstox-core-asl</include>
|
||||
<include>javax.xml.stream:stax-api</include>
|
||||
<include>org.codehaus.woodstox:stax2-api</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
|
@ -141,6 +175,10 @@
|
|||
<pattern>javax.json</pattern>
|
||||
<shadedPattern>ca.uhn.fhir.repackage.javax.json</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.ctc.wstx.stax</pattern>
|
||||
<shadedPattern>ca.uhn.fhir.repackage.com.ctc.wstx.stax</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<filters combine.children="append">
|
||||
<!-- Exclude server side stuff, except exceptions which are used clientside -->
|
||||
|
@ -182,8 +220,8 @@
|
|||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</goals>
|
||||
</execution>
|
||||
<!-- dstu jar -->
|
||||
<execution>
|
||||
<id>dstu</id>
|
||||
|
@ -261,6 +299,27 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<classFolders>
|
||||
<classFolder>${basedir}/target/classes</classFolder>
|
||||
</classFolders>
|
||||
<sourceFolders>
|
||||
<sourceFolder>${basedir}/src/main/java</sourceFolder>
|
||||
</sourceFolders>
|
||||
<dumpOnExit>true</dumpOnExit>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-prepare-agent</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
package ca.uhn.fhir.android;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.filefilter.WildcardFileFilter;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||
|
||||
public class BuiltJarDstu2IT {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BuiltJarDstu2IT.class);
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
System.setProperty("javax.xml.stream.XMLInputFactory", "FOO");
|
||||
System.setProperty("javax.xml.stream.XMLOutputFactory", "FOO");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParserXml() throws Exception {
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("system");
|
||||
|
||||
try {
|
||||
ctx.newXmlParser().encodeResourceToString(p);
|
||||
fail();
|
||||
} catch (ca.uhn.fhir.context.ConfigurationException e) {
|
||||
assertEquals("Unable to initialize StAX - XML processing is disabled",e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParserJson() {
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
Observation o = new Observation();
|
||||
o.getCode().setText("TEXT");
|
||||
o.setValue(new QuantityDt(123));
|
||||
o.addIdentifier().setSystem("system");
|
||||
|
||||
String str = ctx.newJsonParser().encodeResourceToString(o);
|
||||
Observation p2 = ctx.newJsonParser().parseResource(Observation.class, str);
|
||||
|
||||
assertEquals("TEXT", p2.getCode().getText());
|
||||
|
||||
QuantityDt dt = (QuantityDt) p2.getValue();
|
||||
dt.getComparatorElement().getValueAsEnum();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple client test - We try to connect to a server that doesn't exist, but
|
||||
* if we at least get the right exception it means we made it up to the HTTP/network stack
|
||||
*
|
||||
* Disabled for now - TODO: add the old version of the apache client (the one that
|
||||
* android uses) and see if this passes
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testClient() {
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
try {
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://127.0.0.1:44442/SomeBase");
|
||||
client.conformance();
|
||||
} catch (FhirClientConnectionException e) {
|
||||
// this is good
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Android does not like duplicate entries in the JAR
|
||||
*/
|
||||
@Test
|
||||
public void testJarContents() throws Exception {
|
||||
String wildcard = "hapi-fhir-android-*.jar";
|
||||
Collection<File> files = FileUtils.listFiles(new File("target"), new WildcardFileFilter(wildcard), null);
|
||||
if (files.isEmpty()) {
|
||||
throw new Exception("No files matching " + wildcard);
|
||||
}
|
||||
|
||||
for (File file : files) {
|
||||
if (file.getName().endsWith("sources.jar")) {
|
||||
continue;
|
||||
}
|
||||
if (file.getName().endsWith("javadoc.jar")) {
|
||||
continue;
|
||||
}
|
||||
if (file.getName().contains("original.jar")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ourLog.info("Testing file: {}", file);
|
||||
|
||||
ZipFile zip = new ZipFile(file);
|
||||
|
||||
int totalClasses = 0;
|
||||
int totalMethods = 0;
|
||||
TreeSet<ClassMethodCount> topMethods = new TreeSet<ClassMethodCount>();
|
||||
|
||||
try {
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Enumeration<? extends ZipEntry> iter = zip.entries(); iter.hasMoreElements();) {
|
||||
ZipEntry next = iter.nextElement();
|
||||
String nextName = next.getName();
|
||||
if (!names.add(nextName)) {
|
||||
throw new Exception("File " + file + " contains duplicate contents: " + nextName);
|
||||
}
|
||||
|
||||
if (nextName.contains("$") == false) {
|
||||
if (nextName.endsWith(".class")) {
|
||||
String className = nextName.replace("/", ".").replace(".class", "");
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className);
|
||||
int methodCount = clazz.getMethods().length;
|
||||
topMethods.add(new ClassMethodCount(className, methodCount));
|
||||
totalClasses++;
|
||||
totalMethods += methodCount;
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ourLog.info("File {} contains {} entries", file, names.size());
|
||||
ourLog.info("Total classes {} - Total methods {}", totalClasses, totalMethods);
|
||||
ourLog.info("Top classes {}", new ArrayList<ClassMethodCount>(topMethods).subList(Math.max(0, topMethods.size() - 10), topMethods.size()));
|
||||
|
||||
} finally {
|
||||
zip.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClassMethodCount implements Comparable<ClassMethodCount> {
|
||||
|
||||
private String myClassName;
|
||||
private int myMethodCount;
|
||||
|
||||
public ClassMethodCount(String theClassName, int theMethodCount) {
|
||||
myClassName = theClassName;
|
||||
myMethodCount = theMethodCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myClassName + "[" + myMethodCount + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ClassMethodCount theO) {
|
||||
return myMethodCount - theO.myMethodCount;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return myClassName;
|
||||
}
|
||||
|
||||
public void setClassName(String theClassName) {
|
||||
myClassName = theClassName;
|
||||
}
|
||||
|
||||
public int getMethodCount() {
|
||||
return myMethodCount;
|
||||
}
|
||||
|
||||
public void setMethodCount(int theMethodCount) {
|
||||
myMethodCount = theMethodCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -19,52 +19,41 @@ import ca.uhn.fhir.model.dstu2.resource.Patient;
|
|||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||
|
||||
public class BuiltJarIT {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BuiltJarIT.class);
|
||||
public class BuiltJarDstu2ShadeIT {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BuiltJarDstu2ShadeIT.class);
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
System.setProperty("javax.xml.stream.XMLInputFactory", "com.ctc.wstx.stax.WstxInputFactory");
|
||||
System.setProperty("javax.xml.stream.XMLOutputFactory", "com.ctc.wstx.stax.WstxOutputFactory");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParserXml() throws Exception {
|
||||
try {
|
||||
Class.forName("com.ctc.wstx.stax.WstxOutputFactory");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("system");
|
||||
|
||||
|
||||
String str = ctx.newXmlParser().encodeResourceToString(p);
|
||||
Patient p2 = ctx.newXmlParser().parseResource(Patient.class, str);
|
||||
|
||||
|
||||
assertEquals("system", p2.getIdentifierFirstRep().getSystemElement().getValueAsString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testParserJson() {
|
||||
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
|
||||
Observation o = new Observation();
|
||||
o.getCode().setText("TEXT");
|
||||
o.setValue(new QuantityDt(123));
|
||||
o.addIdentifier().setSystem("system");
|
||||
|
||||
|
||||
String str = ctx.newJsonParser().encodeResourceToString(o);
|
||||
Observation p2 = ctx.newJsonParser().parseResource(Observation.class, str);
|
||||
|
||||
|
||||
assertEquals("TEXT", p2.getCode().getText());
|
||||
|
||||
|
||||
QuantityDt dt = (QuantityDt) p2.getValue();
|
||||
dt.getComparatorElement().getValueAsEnum();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,7 +72,7 @@ public class BuiltJarIT {
|
|||
// this is good
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Android does not like duplicate entries in the JAR
|
||||
*/
|
||||
|
@ -105,15 +94,15 @@ public class BuiltJarIT {
|
|||
if (file.getName().contains("original.jar")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
ourLog.info("Testing file: {}", file);
|
||||
|
||||
ZipFile zip = new ZipFile(file);
|
||||
|
||||
|
||||
int totalClasses = 0;
|
||||
int totalMethods = 0;
|
||||
TreeSet<ClassMethodCount> topMethods = new TreeSet<ClassMethodCount>();
|
||||
|
||||
|
||||
try {
|
||||
Set<String> names = new HashSet<String>();
|
||||
for (Enumeration<? extends ZipEntry> iter = zip.entries(); iter.hasMoreElements();) {
|
||||
|
@ -122,16 +111,16 @@ public class BuiltJarIT {
|
|||
if (!names.add(nextName)) {
|
||||
throw new Exception("File " + file + " contains duplicate contents: " + nextName);
|
||||
}
|
||||
|
||||
|
||||
if (nextName.contains("$") == false) {
|
||||
if (nextName.endsWith(".class")) {
|
||||
String className = nextName.replace("/", ".").replace(".class", "");
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className);
|
||||
int methodCount = clazz.getMethods().length;
|
||||
topMethods.add(new ClassMethodCount(className, methodCount));
|
||||
totalClasses++;
|
||||
totalMethods += methodCount;
|
||||
Class<?> clazz = Class.forName(className);
|
||||
int methodCount = clazz.getMethods().length;
|
||||
topMethods.add(new ClassMethodCount(className, methodCount));
|
||||
totalClasses++;
|
||||
totalMethods += methodCount;
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// ignore
|
||||
} catch (ClassNotFoundException e) {
|
||||
|
@ -140,11 +129,11 @@ public class BuiltJarIT {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ourLog.info("File {} contains {} entries", file, names.size());
|
||||
ourLog.info("Total classes {} - Total methods {}", totalClasses, totalMethods);
|
||||
ourLog.info("Top classes {}", new ArrayList<ClassMethodCount>(topMethods).subList(Math.max(0,topMethods.size() - 10), topMethods.size()));
|
||||
|
||||
ourLog.info("Top classes {}", new ArrayList<ClassMethodCount>(topMethods).subList(Math.max(0, topMethods.size() - 10), topMethods.size()));
|
||||
|
||||
} finally {
|
||||
zip.close();
|
||||
}
|
||||
|
@ -155,7 +144,7 @@ public class BuiltJarIT {
|
|||
|
||||
private String myClassName;
|
||||
private int myMethodCount;
|
||||
|
||||
|
||||
public ClassMethodCount(String theClassName, int theMethodCount) {
|
||||
myClassName = theClassName;
|
||||
myMethodCount = theMethodCount;
|
||||
|
@ -186,7 +175,7 @@ public class BuiltJarIT {
|
|||
public void setMethodCount(int theMethodCount) {
|
||||
myMethodCount = theMethodCount;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,996 @@
|
|||
package ca.uhn.fhir.android.client;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
|
||||
import org.junit.*;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
|
||||
import ca.uhn.fhir.rest.client.interceptor.UserInfoInterceptor;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import ca.uhn.fhir.util.VersionUtil;
|
||||
|
||||
public class GenericClientDstu3IT {
|
||||
|
||||
|
||||
private static FhirContext ourCtx;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(GenericClientDstu3IT.class);
|
||||
private int myAnswerCount;
|
||||
private HttpClient myHttpClient;
|
||||
private HttpResponse myHttpResponse;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient);
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
myAnswerCount = 0;
|
||||
|
||||
}
|
||||
|
||||
private String expectedUserAgent() {
|
||||
return "HAPI-FHIR/" + VersionUtil.getVersion() + " (FHIR Client; FHIR " + FhirVersionEnum.DSTU3.getFhirVersionString() + "/DSTU3; apache)";
|
||||
}
|
||||
|
||||
|
||||
private String extractBodyAsString(ArgumentCaptor<HttpUriRequest> capt) throws IOException {
|
||||
String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent(), "UTF-8");
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: narratives don't work without stax
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testBinaryCreateWithFhirContentType() throws Exception {
|
||||
IParser p = ourCtx.newXmlParser();
|
||||
|
||||
OperationOutcome conf = new OperationOutcome();
|
||||
conf.getText().setDivAsString("OK!");
|
||||
|
||||
final String respString = p.encodeResourceToString(conf);
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.getText().setDivAsString("A PATIENT");
|
||||
|
||||
Binary bin = new Binary();
|
||||
bin.setContent(ourCtx.newJsonParser().encodeResourceToString(pt).getBytes("UTF-8"));
|
||||
bin.setContentType(Constants.CT_FHIR_JSON);
|
||||
client.create().resource(bin).execute();
|
||||
|
||||
ourLog.info(Arrays.asList(capt.getAllValues().get(0).getAllHeaders()).toString());
|
||||
|
||||
assertEquals("http://example.com/fhir/Binary", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
validateUserAgent(capt);
|
||||
|
||||
assertEquals("application/xml+fhir;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
|
||||
assertEquals(Constants.CT_FHIR_XML, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||
Binary output = ourCtx.newXmlParser().parseResource(Binary.class, extractBodyAsString(capt));
|
||||
assertEquals(Constants.CT_FHIR_JSON, output.getContentType());
|
||||
|
||||
Patient outputPt = (Patient) ourCtx.newJsonParser().parseResource(new String(output.getContent(), "UTF-8"));
|
||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">A PATIENT</div>", outputPt.getText().getDivAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* See #150
|
||||
*/
|
||||
@Test
|
||||
public void testNullAndEmptyParamValuesAreIgnored() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = prepareClientForSearchResponse();
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
client
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.FAMILY.matches().value((String)null))
|
||||
.and(Patient.BIRTHDATE.exactly().day((Date)null))
|
||||
.and(Patient.GENDER.exactly().code((String)null))
|
||||
.and(Patient.ORGANIZATION.hasId((String)null))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient?_format=json", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* TODO: narratives don't work without stax
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testBinaryCreateWithNoContentType() throws Exception {
|
||||
IParser p = ourCtx.newJsonParser();
|
||||
|
||||
OperationOutcome conf = new OperationOutcome();
|
||||
conf.getText().setDivAsString("OK!");
|
||||
|
||||
final String respString = p.encodeResourceToString(conf);
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON_NEW + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Binary bin = new Binary();
|
||||
bin.setContent(new byte[] { 0, 1, 2, 3, 4 });
|
||||
client.create().resource(bin).execute();
|
||||
|
||||
ourLog.info(Arrays.asList(capt.getAllValues().get(0).getAllHeaders()).toString());
|
||||
|
||||
assertEquals("http://example.com/fhir/Binary", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
validateUserAgent(capt);
|
||||
|
||||
assertEquals("application/xml+fhir;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
|
||||
assertEquals(Constants.CT_FHIR_XML, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||
assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, ourCtx.newXmlParser().parseResource(Binary.class, extractBodyAsString(capt)).getContent());
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testClientFailures() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenThrow(IllegalStateException.class, RuntimeException.class, Exception.class);
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
try {
|
||||
client.read().resource(Patient.class).withId("1").execute();
|
||||
fail();
|
||||
} catch (FhirClientConnectionException e) {
|
||||
assertEquals("java.lang.IllegalStateException", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
client.read().resource(Patient.class).withId("1").execute();
|
||||
fail();
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("java.lang.RuntimeException", e.toString());
|
||||
}
|
||||
|
||||
try {
|
||||
client.read().resource(Patient.class).withId("1").execute();
|
||||
fail();
|
||||
} catch (FhirClientConnectionException e) {
|
||||
assertEquals("java.lang.Exception", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* TODO: narratives don't work without stax
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testCreateWithPreferRepresentationServerReturnsResource() throws Exception {
|
||||
final IParser p = ourCtx.newJsonParser();
|
||||
|
||||
final Patient resp1 = new Patient();
|
||||
resp1.getText().setDivAsString("FINAL VALUE");
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
|
||||
@Override
|
||||
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
|
||||
}
|
||||
});
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON_NEW + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
myAnswerCount++;
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.getText().setDivAsString("A PATIENT");
|
||||
|
||||
MethodOutcome outcome = client.create().resource(pt).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||
|
||||
assertEquals(1, myAnswerCount);
|
||||
assertNull(outcome.getOperationOutcome());
|
||||
assertNotNull(outcome.getResource());
|
||||
|
||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
|
||||
|
||||
assertEquals(myAnswerCount, capt.getAllValues().size());
|
||||
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testForceConformance() throws Exception {
|
||||
final IParser p = ourCtx.newJsonParser();
|
||||
|
||||
final Conformance conf = new Conformance();
|
||||
conf.setCopyright("COPY");
|
||||
|
||||
final Patient patient = new Patient();
|
||||
patient.addName().addFamily("FAM");
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON_NEW + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
private int myCount = 0;
|
||||
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
final String respString;
|
||||
if (myCount == 1 || myCount == 2) {
|
||||
ourLog.info("Encoding patient");
|
||||
respString = p.encodeResourceToString(patient);
|
||||
} else {
|
||||
ourLog.info("Encoding conformance");
|
||||
respString = p.encodeResourceToString(conf);
|
||||
}
|
||||
myCount++;
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://testForceConformance.com/fhir");
|
||||
|
||||
client.read().resource("Patient").withId("1").execute();
|
||||
assertEquals(2, capt.getAllValues().size());
|
||||
assertEquals("http://testForceConformance.com/fhir/metadata?_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals("http://testForceConformance.com/fhir/Patient/1?_format=json", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||
|
||||
client.read().resource("Patient").withId("1").execute();
|
||||
assertEquals(3, capt.getAllValues().size());
|
||||
assertEquals("http://testForceConformance.com/fhir/Patient/1?_format=json", capt.getAllValues().get(2).getURI().toASCIIString());
|
||||
|
||||
client.forceConformanceCheck();
|
||||
assertEquals(4, capt.getAllValues().size());
|
||||
assertEquals("http://testForceConformance.com/fhir/metadata?_format=json", capt.getAllValues().get(3).getURI().toASCIIString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttp499() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 499, "Wacky Message"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader("HELLO"), StandardCharsets.UTF_8);
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
try {
|
||||
client.read().resource(Patient.class).withId("1").execute();
|
||||
fail();
|
||||
} catch (UnclassifiedServerFailureException e) {
|
||||
assertEquals("ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException: HTTP 499 Wacky Message", e.toString());
|
||||
assertEquals("HELLO", e.getResponseBody());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttp501() throws Exception {
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 501, "Not Implemented"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader("not implemented"), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
try {
|
||||
client.read().resource(Patient.class).withId("1").execute();
|
||||
fail();
|
||||
} catch (NotImplementedOperationException e) {
|
||||
assertEquals("HTTP 501 Not Implemented", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void testInvalidConformanceCall() {
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
try {
|
||||
client.conformance();
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Must call fetchConformance() instead of conformance() for RI/STU3+ structures", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testPutDoesntForceAllIdsJson() throws Exception {
|
||||
IParser p = ourCtx.newJsonParser();
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.setId("PATIENT1");
|
||||
patient.addName().addFamily("PATIENT1");
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.setId("BUNDLE1");
|
||||
bundle.addEntry().setResource(patient);
|
||||
|
||||
final String encoded = p.encodeResourceToString(bundle);
|
||||
assertEquals("{\"resourceType\":\"Bundle\",\"id\":\"BUNDLE1\",\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"PATIENT1\",\"name\":[{\"family\":[\"PATIENT1\"]}]}}]}", encoded);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON_NEW + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(encoded), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
//@formatter:off
|
||||
client
|
||||
.update()
|
||||
.resource(bundle)
|
||||
.prefer(PreferReturnEnum.REPRESENTATION)
|
||||
.encodedJson()
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
HttpPut httpRequest = (HttpPut) capt.getValue();
|
||||
assertEquals("http://example.com/fhir/Bundle/BUNDLE1?_format=json", httpRequest.getURI().toASCIIString());
|
||||
|
||||
String requestString = IOUtils.toString(httpRequest.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
assertEquals(encoded, requestString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseHasContentTypeMissing() throws Exception {
|
||||
IParser p = ourCtx.newJsonParser();
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("FAM");
|
||||
final String respString = p.encodeResourceToString(patient);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(null);
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
try {
|
||||
client.read().resource(Patient.class).withId("1").execute();
|
||||
fail();
|
||||
} catch (NonFhirResponseException e) {
|
||||
assertEquals("Response contains no Content-Type", e.getMessage());
|
||||
}
|
||||
|
||||
// Patient resp = client.read().resource(Patient.class).withId("1").execute();
|
||||
// assertEquals("FAM", resp.getNameFirstRep().getFamilyAsSingleString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResponseHasContentTypeNonFhir() throws Exception {
|
||||
IParser p = ourCtx.newJsonParser();
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("FAM");
|
||||
final String respString = p.encodeResourceToString(patient);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", "text/plain"));
|
||||
// when(myHttpResponse.getEntity().getContentType()).thenReturn(null);
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
try {
|
||||
client.read().resource(Patient.class).withId("1").execute();
|
||||
fail();
|
||||
} catch (NonFhirResponseException e) {
|
||||
assertEquals("Response contains non FHIR Content-Type 'text/plain' : {\"resourceType\":\"Patient\",\"name\":[{\"family\":[\"FAM\"]}]}", e.getMessage());
|
||||
}
|
||||
|
||||
// Patient resp = client.read().resource(Patient.class).withId("1").execute();
|
||||
// assertEquals("FAM", resp.getNameFirstRep().getFamilyAsSingleString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByDate() throws Exception {
|
||||
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
int idx = 0;
|
||||
|
||||
DateTimeDt now = DateTimeDt.withCurrentTime();
|
||||
String dateString = now.getValueAsString().substring(0, 10);
|
||||
|
||||
//@formatter:off
|
||||
client.search()
|
||||
.forResource("Patient")
|
||||
.where(Patient.BIRTHDATE.after().day(dateString))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient?birthdate=gt"+dateString + "&_format=json", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchByString() throws Exception {
|
||||
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
client.search()
|
||||
.forResource("Patient")
|
||||
.where(Patient.NAME.matches().value("AAA"))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient?name=AAA&_format=json", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
client.search()
|
||||
.forResource("Patient")
|
||||
.where(Patient.NAME.matches().value(new StringDt("AAA")))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient?name=AAA&_format=json", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
client.search()
|
||||
.forResource("Patient")
|
||||
.where(Patient.NAME.matches().values("AAA", "BBB"))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient?name=AAA,BBB&_format=json", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
client.search()
|
||||
.forResource("Patient")
|
||||
.where(Patient.NAME.matches().values(Arrays.asList("AAA", "BBB")))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient?name=AAA,BBB&_format=json", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
client.search()
|
||||
.forResource("Patient")
|
||||
.where(Patient.NAME.matchesExactly().value("AAA"))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient?name%3Aexact=AAA&_format=json", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
client.search()
|
||||
.forResource("Patient")
|
||||
.where(Patient.NAME.matchesExactly().value(new StringDt("AAA")))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Patient?name%3Aexact=AAA&_format=json", capt.getAllValues().get(idx).getURI().toString());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByUrl() throws Exception {
|
||||
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
client.search()
|
||||
.forResource("Device")
|
||||
.where(Device.URL.matches().value("http://foo.com"))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Device?url=http://foo.com&_format=json", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptHeaderWithEncodingSpecified() throws Exception {
|
||||
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
client.search()
|
||||
.forResource("Device")
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Device?_format=json", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||
assertEquals("application/fhir+json;q=1.0, application/json+fhir;q=0.9", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_ACCEPT).getValue());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
client.setEncoding(EncodingEnum.XML);
|
||||
client.search()
|
||||
.forResource("Device")
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Device?_format=xml", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||
assertEquals("application/fhir+xml;q=1.0, application/xml+fhir;q=0.9", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_ACCEPT).getValue());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchForUnknownType() throws Exception {
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
try {
|
||||
client.search(new UriDt("?aaaa"));
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Unable to determine the resource type from the given URI: ?aaaa", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private ArgumentCaptor<HttpUriRequest> prepareClientForSearchResponse() throws IOException, ClientProtocolException {
|
||||
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
return capt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testTransactionWithInvalidBody() throws Exception {
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
// Transaction
|
||||
try {
|
||||
client.transaction().withBundle("FOO");
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage());
|
||||
}
|
||||
|
||||
// Create
|
||||
try {
|
||||
client.create().resource("FOO").execute();
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage());
|
||||
}
|
||||
|
||||
// Update
|
||||
try {
|
||||
client.update().resource("FOO").execute();
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage());
|
||||
}
|
||||
|
||||
// Validate
|
||||
try {
|
||||
client.validate().resource("FOO").execute();
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: narratives don't work without stax
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testUpdateById() throws Exception {
|
||||
IParser p = ourCtx.newJsonParser();
|
||||
|
||||
OperationOutcome conf = new OperationOutcome();
|
||||
conf.getText().setDivAsString("OK!");
|
||||
|
||||
final String respString = p.encodeResourceToString(conf);
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON_NEW + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.setId("222");
|
||||
pt.getText().setDivAsString("A PATIENT");
|
||||
|
||||
client.update().resource(pt).withId("111").execute();
|
||||
|
||||
ourLog.info(Arrays.asList(capt.getAllValues().get(0).getAllHeaders()).toString());
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient/111", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
validateUserAgent(capt);
|
||||
|
||||
assertEquals("application/xml+fhir;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
|
||||
assertEquals(Constants.HEADER_ACCEPT_VALUE_JSON_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||
String body = extractBodyAsString(capt);
|
||||
assertThat(body, containsString("<id value=\"111\"/>"));
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: narratives don't work without stax
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testUpdateWithPreferRepresentationServerReturnsOO() throws Exception {
|
||||
final IParser p = ourCtx.newJsonParser();
|
||||
|
||||
final OperationOutcome resp0 = new OperationOutcome();
|
||||
resp0.getText().setDivAsString("OK!");
|
||||
|
||||
final Patient resp1 = new Patient();
|
||||
resp1.getText().setDivAsString("FINAL VALUE");
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
|
||||
@Override
|
||||
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
|
||||
}
|
||||
});
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON_NEW + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
if (myAnswerCount++ == 0) {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8"));
|
||||
} else {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.setId("Patient/222");
|
||||
pt.getText().setDivAsString("A PATIENT");
|
||||
|
||||
MethodOutcome outcome = client.update().resource(pt).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||
|
||||
assertEquals(2, myAnswerCount);
|
||||
assertNotNull(outcome.getOperationOutcome());
|
||||
assertNotNull(outcome.getResource());
|
||||
|
||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div>", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString());
|
||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
|
||||
|
||||
assertEquals(myAnswerCount, capt.getAllValues().size());
|
||||
assertEquals("http://example.com/fhir/Patient/222", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals("http://foo.com/base/Patient/222/_history/3", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithPreferRepresentationServerReturnsResource() throws Exception {
|
||||
final IParser p = ourCtx.newJsonParser();
|
||||
|
||||
final Patient resp1 = new Patient();
|
||||
resp1.setActive(true);
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
|
||||
@Override
|
||||
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3") };
|
||||
}
|
||||
});
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON_NEW + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
myAnswerCount++;
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.setId("Patient/222");
|
||||
pt.getText().setDivAsString("A PATIENT");
|
||||
|
||||
MethodOutcome outcome = client.update().resource(pt).prefer(PreferReturnEnum.REPRESENTATION).execute();
|
||||
|
||||
assertEquals(1, myAnswerCount);
|
||||
assertNull(outcome.getOperationOutcome());
|
||||
assertNotNull(outcome.getResource());
|
||||
|
||||
assertEquals(true, ((Patient) outcome.getResource()).getActive());
|
||||
|
||||
assertEquals(myAnswerCount, capt.getAllValues().size());
|
||||
assertEquals("http://example.com/fhir/Patient/222?_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUserAgentForConformance() throws Exception {
|
||||
IParser p = ourCtx.newJsonParser();
|
||||
|
||||
Conformance conf = new Conformance();
|
||||
conf.setCopyright("COPY");
|
||||
|
||||
final String respString = p.encodeResourceToString(conf);
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON_NEW + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
client.fetchConformance().ofType(Conformance.class).execute();
|
||||
assertEquals("http://example.com/fhir/metadata?_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
validateUserAgent(capt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO: narratives don't work without stax
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testValidate() throws Exception {
|
||||
final IParser p = ourCtx.newXmlParser();
|
||||
|
||||
final OperationOutcome resp0 = new OperationOutcome();
|
||||
resp0.getText().setDivAsString("OK!");
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer<Header[]>() {
|
||||
@Override
|
||||
public Header[] answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new Header[] {};
|
||||
}
|
||||
});
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
|
||||
@Override
|
||||
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.setId("Patient/222");
|
||||
pt.getText().setDivAsString("A PATIENT");
|
||||
|
||||
MethodOutcome outcome = client.validate().resource(pt).execute();
|
||||
|
||||
assertNotNull(outcome.getOperationOutcome());
|
||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div>", ((OperationOutcome) outcome.getOperationOutcome()).getText().getDivAsString());
|
||||
|
||||
}
|
||||
|
||||
private void validateUserAgent(ArgumentCaptor<HttpUriRequest> capt) {
|
||||
assertEquals(1, capt.getAllValues().get(0).getHeaders("User-Agent").length);
|
||||
assertEquals(expectedUserAgent(), capt.getAllValues().get(0).getHeaders("User-Agent")[0].getValue());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
|
||||
// Force StAX to fail like it will on android
|
||||
System.setProperty("javax.xml.stream.XMLInputFactory", "FOO");
|
||||
System.setProperty("javax.xml.stream.XMLOutputFactory", "FOO");
|
||||
|
||||
ourCtx = FhirContext.forDstu3();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -22,33 +20,20 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
|
||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.*;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
|
@ -67,6 +52,7 @@ import ca.uhn.fhir.rest.server.Constants;
|
|||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||
import ca.uhn.fhir.util.XmlUtil;
|
||||
|
||||
public abstract class BaseClient implements IRestfulClient {
|
||||
|
||||
|
@ -105,6 +91,11 @@ public abstract class BaseClient implements IRestfulClient {
|
|||
if ("true".equals(System.getProperty(HAPI_CLIENT_KEEPRESPONSES))) {
|
||||
setKeepResponses(true);
|
||||
}
|
||||
|
||||
if (XmlUtil.isStaxPresent() == false) {
|
||||
myEncoding = EncodingEnum.JSON;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected Map<String, List<String>> createExtraParams() {
|
||||
|
|
|
@ -63,6 +63,8 @@ public class Constants {
|
|||
public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
|
||||
public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY = CT_FHIR_XML + ";q=1.0, " + CT_FHIR_JSON + ";q=1.0";
|
||||
public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON_NON_LEGACY = CT_FHIR_XML_NEW + ";q=1.0, " + CT_FHIR_JSON_NEW + ";q=1.0, " + HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY.replace("1.0", "0.9");
|
||||
public static final String HEADER_ACCEPT_VALUE_XML_NON_LEGACY = CT_FHIR_XML_NEW + ";q=1.0, " + CT_FHIR_XML + ";q=0.9";
|
||||
public static final String HEADER_ACCEPT_VALUE_JSON_NON_LEGACY = CT_FHIR_JSON_NEW + ";q=1.0, " + CT_FHIR_JSON + ";q=0.9";
|
||||
public static final String HEADER_ALLOW = "Allow";
|
||||
public static final String HEADER_AUTHORIZATION = "Authorization";
|
||||
public static final String HEADER_AUTHORIZATION_VALPREFIX_BASIC = "Basic ";
|
||||
|
|
|
@ -787,9 +787,17 @@ public class RestfulServerUtils {
|
|||
theHttpRequest.addHeader(Constants.HEADER_ACCEPT, Constants.HEADER_ACCEPT_VALUE_XML_OR_JSON_NON_LEGACY);
|
||||
}
|
||||
} else if (theEncoding == EncodingEnum.JSON) {
|
||||
theHttpRequest.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_JSON);
|
||||
if (theContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU2) == false) {
|
||||
theHttpRequest.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_JSON);
|
||||
} else {
|
||||
theHttpRequest.addHeader(Constants.HEADER_ACCEPT, Constants.HEADER_ACCEPT_VALUE_JSON_NON_LEGACY);
|
||||
}
|
||||
} else if (theEncoding == EncodingEnum.XML) {
|
||||
theHttpRequest.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_XML);
|
||||
if (theContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU2) == false) {
|
||||
theHttpRequest.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_XML);
|
||||
} else {
|
||||
theHttpRequest.addHeader(Constants.HEADER_ACCEPT, Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,26 +19,12 @@ package ca.uhn.fhir.util;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
import java.io.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.stream.FactoryConfigurationError;
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLEventWriter;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLOutputFactory;
|
||||
import javax.xml.stream.XMLResolver;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.stream.*;
|
||||
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.codehaus.stax2.XMLOutputFactory2;
|
||||
|
@ -47,6 +33,7 @@ import org.codehaus.stax2.io.EscapingWriterFactory;
|
|||
import com.ctc.wstx.api.WstxInputProperties;
|
||||
import com.ctc.wstx.stax.WstxOutputFactory;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.util.jar.DependencyLogFactory;
|
||||
import ca.uhn.fhir.util.jar.IDependencyLog;
|
||||
|
||||
|
@ -62,6 +49,7 @@ public class XmlUtil {
|
|||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class);
|
||||
private static Throwable ourNextException;
|
||||
private static volatile XMLOutputFactory ourOutputFactory;
|
||||
private static Boolean ourStaxPresent;
|
||||
private static final Map<String, Integer> VALID_ENTITY_NAMES;
|
||||
private static final ExtendedEntityReplacingXmlResolver XML_RESOLVER = new ExtendedEntityReplacingXmlResolver();
|
||||
|
||||
|
@ -1528,8 +1516,8 @@ public class XmlUtil {
|
|||
// ok
|
||||
}
|
||||
|
||||
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
|
||||
|
||||
XMLOutputFactory outputFactory = newOutputFactory();
|
||||
|
||||
if (!ourHaveLoggedStaxImplementation) {
|
||||
logStaxImplementation(outputFactory.getClass());
|
||||
}
|
||||
|
@ -1601,8 +1589,7 @@ public class XmlUtil {
|
|||
// ok
|
||||
}
|
||||
|
||||
XMLInputFactory inputFactory;
|
||||
inputFactory = XMLInputFactory.newInstance();
|
||||
XMLInputFactory inputFactory = newInputFactory();
|
||||
|
||||
if (!ourHaveLoggedStaxImplementation) {
|
||||
logStaxImplementation(inputFactory.getClass());
|
||||
|
@ -1645,7 +1632,6 @@ public class XmlUtil {
|
|||
return ourInputFactory;
|
||||
}
|
||||
|
||||
|
||||
private static XMLOutputFactory getOrCreateOutputFactory() throws FactoryConfigurationError {
|
||||
if (ourOutputFactory == null) {
|
||||
ourOutputFactory = createOutputFactory();
|
||||
|
@ -1661,6 +1647,29 @@ public class XmlUtil {
|
|||
ourHaveLoggedStaxImplementation = true;
|
||||
}
|
||||
|
||||
|
||||
static XMLInputFactory newInputFactory() throws FactoryConfigurationError {
|
||||
XMLInputFactory inputFactory;
|
||||
try {
|
||||
inputFactory = XMLInputFactory.newInstance();
|
||||
throwUnitTestExceptionIfConfiguredToDoSo();
|
||||
} catch (Throwable e) {
|
||||
throw new ConfigurationException("Unable to initialize StAX - XML processing is disabled", e);
|
||||
}
|
||||
return inputFactory;
|
||||
}
|
||||
|
||||
static XMLOutputFactory newOutputFactory() throws FactoryConfigurationError {
|
||||
XMLOutputFactory outputFactory;
|
||||
try {
|
||||
outputFactory = XMLOutputFactory.newInstance();
|
||||
throwUnitTestExceptionIfConfiguredToDoSo();
|
||||
} catch (Throwable e) {
|
||||
throw new ConfigurationException("Unable to initialize StAX - XML processing is disabled", e);
|
||||
}
|
||||
return outputFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* FOR UNIT TESTS ONLY - Throw this exception for the next operation
|
||||
*/
|
||||
|
@ -1691,6 +1700,26 @@ public class XmlUtil {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return <code>true</code> if a StAX XML parsing library is present
|
||||
* on the classpath
|
||||
*/
|
||||
public static boolean isStaxPresent() {
|
||||
Boolean retVal = ourStaxPresent;
|
||||
if (retVal == null) {
|
||||
try {
|
||||
newInputFactory();
|
||||
ourStaxPresent = Boolean.TRUE;
|
||||
retVal = Boolean.TRUE;
|
||||
} catch (ConfigurationException e) {
|
||||
ourLog.info("StAX not detected on classpath, XML processing will be disabled");
|
||||
ourStaxPresent = Boolean.FALSE;
|
||||
retVal = Boolean.FALSE;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static class MyEscaper implements EscapingWriterFactory {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -232,6 +232,7 @@
|
|||
<include>hapi-fhir-structures-dstu3/target/jacoco.exec</include>
|
||||
<include>hapi-fhir-jpaserver-base/target/jacoco.exec</include>
|
||||
<include>hapi-fhir-client-okhttp/target/jacoco.exec</include>
|
||||
<include>hapi-fhir-android/target/jacoco.exec</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
|
|
@ -1644,7 +1644,7 @@ public class GenericJaxRsClientDstu3Test {
|
|||
assertEquals("name=james", ourRequestBodyString);
|
||||
|
||||
assertEquals("application/x-www-form-urlencoded", ourRequestContentType);
|
||||
assertEquals(Constants.CT_FHIR_JSON, ourRequestFirstHeaders.get("Accept").getValue());
|
||||
assertEquals(Constants.HEADER_ACCEPT_VALUE_JSON_NON_LEGACY, ourRequestFirstHeaders.get("Accept").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,14 +1,45 @@
|
|||
package ca.uhn.fhir.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.xml.stream.FactoryConfigurationError;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class XmlUtilTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateInputFactoryWithException() {
|
||||
XmlUtil.setThrowExceptionForUnitTest(new Error("FOO ERROR"));
|
||||
try {
|
||||
XmlUtil.newInputFactory();
|
||||
fail();
|
||||
} catch (Exception e) {
|
||||
assertEquals("Unable to initialize StAX - XML processing is disabled", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateOutputFactoryWithException() {
|
||||
XmlUtil.setThrowExceptionForUnitTest(new Error("FOO ERROR"));
|
||||
try {
|
||||
XmlUtil.newOutputFactory();
|
||||
fail();
|
||||
} catch (Exception e) {
|
||||
assertEquals("Unable to initialize StAX - XML processing is disabled", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
XmlUtil.setThrowExceptionForUnitTest(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateReader() throws Exception {
|
||||
XmlUtil.createXmlReader(new StringReader("<a/>"));
|
||||
|
@ -24,7 +55,6 @@ public class XmlUtilTest {
|
|||
XmlUtil.createXmlStreamWriter(new StringWriter());
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
|
|
|
@ -67,7 +67,7 @@ public class ClientMimetypeDstu3Test {
|
|||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
|
||||
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(Constants.CT_FHIR_XML, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
assertEquals("application/xml+fhir", capt.getAllValues().get(0).getFirstHeader("accept").getValue());
|
||||
assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getFirstHeader("accept").getValue());
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><text><div xmlns=\"http://www.w3.org/1999/xhtml\">A PATIENT</div></text></Patient>", extractBodyAsString(capt));
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ public class ClientMimetypeDstu3Test {
|
|||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
|
||||
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(Constants.CT_FHIR_XML, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
assertEquals("application/xml+fhir", capt.getAllValues().get(0).getFirstHeader("accept").getValue());
|
||||
assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getFirstHeader("accept").getValue());
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><text><div xmlns=\"http://www.w3.org/1999/xhtml\">A PATIENT</div></text></Patient>", extractBodyAsString(capt));
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ public class ClientMimetypeDstu3Test {
|
|||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
|
||||
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(Constants.CT_FHIR_JSON, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
assertEquals("application/json+fhir", capt.getAllValues().get(0).getFirstHeader("accept").getValue());
|
||||
assertEquals(Constants.HEADER_ACCEPT_VALUE_JSON_NON_LEGACY, capt.getAllValues().get(0).getFirstHeader("accept").getValue());
|
||||
assertEquals("{\"resourceType\":\"Patient\",\"text\":{\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">A PATIENT</div>\"}}", extractBodyAsString(capt));
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ public class ClientMimetypeDstu3Test {
|
|||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">FINAL VALUE</div>", ((Patient) outcome.getResource()).getText().getDivAsString());
|
||||
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(Constants.CT_FHIR_JSON, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
assertEquals("application/json+fhir", capt.getAllValues().get(0).getFirstHeader("accept").getValue());
|
||||
assertEquals(Constants.HEADER_ACCEPT_VALUE_JSON_NON_LEGACY, capt.getAllValues().get(0).getFirstHeader("accept").getValue());
|
||||
assertEquals("{\"resourceType\":\"Patient\",\"text\":{\"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">A PATIENT</div>\"}}", extractBodyAsString(capt));
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ import ca.uhn.fhir.rest.client.interceptor.CookieInterceptor;
|
|||
import ca.uhn.fhir.rest.client.interceptor.UserInfoInterceptor;
|
||||
import ca.uhn.fhir.rest.param.ParamPrefixEnum;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
@ -204,7 +205,7 @@ public class GenericClientDstu3Test {
|
|||
validateUserAgent(capt);
|
||||
|
||||
assertEquals("application/xml+fhir;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
|
||||
assertEquals(Constants.CT_FHIR_XML, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||
assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||
Binary output = ourCtx.newXmlParser().parseResource(Binary.class, extractBodyAsString(capt));
|
||||
assertEquals(Constants.CT_FHIR_JSON, output.getContentType());
|
||||
|
||||
|
@ -296,7 +297,7 @@ public class GenericClientDstu3Test {
|
|||
validateUserAgent(capt);
|
||||
|
||||
assertEquals("application/xml+fhir;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
|
||||
assertEquals(Constants.CT_FHIR_XML, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||
assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||
assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, ourCtx.newXmlParser().parseResource(Binary.class, extractBodyAsString(capt)).getContent());
|
||||
|
||||
}
|
||||
|
@ -1283,6 +1284,48 @@ public class GenericClientDstu3Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptHeaderWithEncodingSpecified() throws Exception {
|
||||
final String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8"));
|
||||
when(myHttpResponse.getEntity().getContent()).then(new Answer<InputStream>() {
|
||||
@Override
|
||||
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
|
||||
}
|
||||
});
|
||||
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
int idx = 0;
|
||||
|
||||
//@formatter:off
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
client.search()
|
||||
.forResource("Device")
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Device?_format=json", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||
assertEquals("application/fhir+json;q=1.0, application/json+fhir;q=0.9", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_ACCEPT).getValue());
|
||||
idx++;
|
||||
|
||||
//@formatter:off
|
||||
client.setEncoding(EncodingEnum.XML);
|
||||
client.search()
|
||||
.forResource("Device")
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
assertEquals("http://example.com/fhir/Device?_format=xml", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||
assertEquals("application/fhir+xml;q=1.0, application/xml+fhir;q=0.9", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_ACCEPT).getValue());
|
||||
idx++;
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchForUnknownType() throws Exception {
|
||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||
|
@ -1458,7 +1501,7 @@ public class GenericClientDstu3Test {
|
|||
validateUserAgent(capt);
|
||||
|
||||
assertEquals("application/xml+fhir;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
|
||||
assertEquals(Constants.CT_FHIR_XML, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||
assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
|
||||
String body = extractBodyAsString(capt);
|
||||
assertThat(body, containsString("<id value=\"111\"/>"));
|
||||
}
|
||||
|
|
|
@ -55,6 +55,13 @@
|
|||
parent bundle were incorrectly given the ID of the parent. Thanks
|
||||
to Filip Domazet for reporting!
|
||||
</action>
|
||||
<action type="add">
|
||||
STU clients now use an Accept header which
|
||||
indicates support for both the old MimeTypes
|
||||
(e.g. <![CDATA[<code>application/xml+fhir</code>]]>)
|
||||
and the new MimeTypes
|
||||
(e.g. <![CDATA[<code>application/fhir+xml</code>]]>)
|
||||
</action>
|
||||
</release>
|
||||
<release version="2.0" date="2016-08-30">
|
||||
<action type="fix">
|
||||
|
|
Loading…
Reference in New Issue