Fix #837 - Use non-legacy content-type for plain json and xml accept
header
This commit is contained in:
parent
ad8eb0b939
commit
351a2fc2f1
|
@ -19,12 +19,14 @@ package ca.uhn.fhir.rest.api;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public enum EncodingEnum {
|
public enum EncodingEnum {
|
||||||
|
|
||||||
|
@ -40,39 +42,40 @@ public enum EncodingEnum {
|
||||||
public IParser newParser(FhirContext theContext) {
|
public IParser newParser(FhirContext theContext) {
|
||||||
return theContext.newXmlParser();
|
return theContext.newXmlParser();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
;
|
/**
|
||||||
|
* "json"
|
||||||
/** "json" */
|
*/
|
||||||
public static final String JSON_PLAIN_STRING = "json";
|
public static final String JSON_PLAIN_STRING = "json";
|
||||||
private static Map<String, EncodingEnum> ourContentTypeToEncoding;
|
/**
|
||||||
|
* "xml"
|
||||||
private static Map<String, EncodingEnum> ourContentTypeToEncodingNonLegacy;
|
*/
|
||||||
private static Map<String, EncodingEnum> ourContentTypeToEncodingStrict;
|
|
||||||
/** "xml" */
|
|
||||||
public static final String XML_PLAIN_STRING = "xml";
|
public static final String XML_PLAIN_STRING = "xml";
|
||||||
|
private static Map<String, EncodingEnum> ourContentTypeToEncoding;
|
||||||
|
private static Map<String, EncodingEnum> ourContentTypeToEncodingLegacy;
|
||||||
|
private static Map<String, EncodingEnum> ourContentTypeToEncodingStrict;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ourContentTypeToEncoding = new HashMap<String, EncodingEnum>();
|
ourContentTypeToEncoding = new HashMap<>();
|
||||||
ourContentTypeToEncodingNonLegacy = new HashMap<String, EncodingEnum>();
|
ourContentTypeToEncodingLegacy = new HashMap<>();
|
||||||
|
|
||||||
for (EncodingEnum next : values()) {
|
for (EncodingEnum next : values()) {
|
||||||
ourContentTypeToEncoding.put(next.myResourceContentTypeNonLegacy, next);
|
ourContentTypeToEncoding.put(next.myResourceContentTypeNonLegacy, next);
|
||||||
ourContentTypeToEncoding.put(next.myResourceContentTypeLegacy, next);
|
ourContentTypeToEncoding.put(next.myResourceContentTypeLegacy, next);
|
||||||
ourContentTypeToEncodingNonLegacy.put(next.myResourceContentTypeNonLegacy, next);
|
ourContentTypeToEncodingLegacy.put(next.myResourceContentTypeLegacy, next);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See #346
|
* See #346
|
||||||
*/
|
*/
|
||||||
ourContentTypeToEncoding.put(next.myResourceContentTypeNonLegacy.replace('+', ' '), next);
|
ourContentTypeToEncoding.put(next.myResourceContentTypeNonLegacy.replace('+', ' '), next);
|
||||||
ourContentTypeToEncoding.put(next.myResourceContentTypeLegacy.replace('+', ' '), next);
|
ourContentTypeToEncoding.put(next.myResourceContentTypeLegacy.replace('+', ' '), next);
|
||||||
ourContentTypeToEncodingNonLegacy.put(next.myResourceContentTypeNonLegacy.replace('+', ' '), next);
|
ourContentTypeToEncodingLegacy.put(next.myResourceContentTypeLegacy.replace('+', ' '), next);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add before we add the lenient ones
|
// Add before we add the lenient ones
|
||||||
ourContentTypeToEncodingStrict = Collections.unmodifiableMap(new HashMap<String, EncodingEnum>(ourContentTypeToEncoding));
|
ourContentTypeToEncodingStrict = Collections.unmodifiableMap(new HashMap<>(ourContentTypeToEncoding));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are wrong, but we add them just to be tolerant of other
|
* These are wrong, but we add them just to be tolerant of other
|
||||||
|
@ -89,7 +92,7 @@ public enum EncodingEnum {
|
||||||
ourContentTypeToEncoding.put(JSON_PLAIN_STRING, JSON);
|
ourContentTypeToEncoding.put(JSON_PLAIN_STRING, JSON);
|
||||||
ourContentTypeToEncoding.put(XML_PLAIN_STRING, XML);
|
ourContentTypeToEncoding.put(XML_PLAIN_STRING, XML);
|
||||||
|
|
||||||
ourContentTypeToEncodingNonLegacy = Collections.unmodifiableMap(ourContentTypeToEncodingNonLegacy);
|
ourContentTypeToEncodingLegacy = Collections.unmodifiableMap(ourContentTypeToEncodingLegacy);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,10 +110,6 @@ public enum EncodingEnum {
|
||||||
return myFormatContentType;
|
return myFormatContentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRequestContentType() {
|
|
||||||
return myFormatContentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will return application/xml+fhir style
|
* Will return application/xml+fhir style
|
||||||
*/
|
*/
|
||||||
|
@ -167,14 +166,18 @@ public enum EncodingEnum {
|
||||||
* <p>
|
* <p>
|
||||||
* <b>This method is NOT lenient!</b> Things like "application/xml" will return <code>null</code>
|
* <b>This method is NOT lenient!</b> Things like "application/xml" will return <code>null</code>
|
||||||
* </p>
|
* </p>
|
||||||
|
*
|
||||||
* @see #forContentType(String)
|
* @see #forContentType(String)
|
||||||
*/
|
*/
|
||||||
public static EncodingEnum forContentTypeStrict(String theContentType) {
|
public static EncodingEnum forContentTypeStrict(String theContentType) {
|
||||||
return ourContentTypeToEncodingStrict.get(theContentType);
|
return ourContentTypeToEncodingStrict.get(theContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isNonLegacy(String theFormat) {
|
/**
|
||||||
return ourContentTypeToEncodingNonLegacy.containsKey(theFormat);
|
* Is the given type a FHIR legacy (pre-DSTU3) content type?
|
||||||
|
*/
|
||||||
|
public static boolean isLegacy(String theFormat) {
|
||||||
|
return ourContentTypeToEncodingLegacy.containsKey(theFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -764,12 +764,11 @@ public class RestfulServerUtils {
|
||||||
super();
|
super();
|
||||||
myEncoding = theEncoding;
|
myEncoding = theEncoding;
|
||||||
if (theContentType != null) {
|
if (theContentType != null) {
|
||||||
|
FhirVersionEnum ctxtEnum = theCtx.getVersion().getVersion();
|
||||||
if (theContentType.equals(EncodingEnum.JSON_PLAIN_STRING) || theContentType.equals(EncodingEnum.XML_PLAIN_STRING)) {
|
if (theContentType.equals(EncodingEnum.JSON_PLAIN_STRING) || theContentType.equals(EncodingEnum.XML_PLAIN_STRING)) {
|
||||||
FhirVersionEnum ctxtEnum = theCtx.getVersion().getVersion();
|
myNonLegacy = ctxtEnum.isNewerThan(FhirVersionEnum.DSTU2);
|
||||||
myNonLegacy = ctxtEnum.isNewerThan(FhirVersionEnum.DSTU3)
|
|
||||||
|| (ctxtEnum.isEquivalentTo(FhirVersionEnum.DSTU3) && !"1.4.0".equals(theCtx.getVersion().getVersion().getFhirVersionString()));
|
|
||||||
} else {
|
} else {
|
||||||
myNonLegacy = EncodingEnum.isNonLegacy(theContentType);
|
myNonLegacy = ctxtEnum.isNewerThan(FhirVersionEnum.DSTU2) && !EncodingEnum.isLegacy(theContentType);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FhirVersionEnum ctxtEnum = theCtx.getVersion().getVersion();
|
FhirVersionEnum ctxtEnum = theCtx.getVersion().getVersion();
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
package ca.uhn.fhir.rest.server;
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.contains;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import ca.uhn.fhir.rest.annotation.*;
|
||||||
import static org.hamcrest.Matchers.not;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import static org.junit.Assert.assertEquals;
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
import static org.junit.Assert.assertThat;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.client.MyPatientWithExtensions;
|
||||||
import java.io.IOException;
|
import ca.uhn.fhir.util.PortUtil;
|
||||||
import java.net.URI;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.client.methods.*;
|
import org.apache.http.client.methods.*;
|
||||||
|
@ -26,23 +21,45 @@ import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.r4.model.*;
|
import org.hl7.fhir.r4.model.*;
|
||||||
import org.junit.*;
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import java.io.IOException;
|
||||||
import ca.uhn.fhir.rest.annotation.*;
|
import java.net.URI;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import java.nio.charset.StandardCharsets;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import java.util.ArrayList;
|
||||||
import ca.uhn.fhir.rest.client.MyPatientWithExtensions;
|
import java.util.List;
|
||||||
import ca.uhn.fhir.util.PortUtil;
|
import java.util.concurrent.TimeUnit;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class ServerMimetypeR4Test {
|
public class ServerMimetypeR4Test {
|
||||||
private static CloseableHttpClient ourClient;
|
|
||||||
|
|
||||||
private static FhirContext ourCtx = FhirContext.forR4();
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerMimetypeR4Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerMimetypeR4Test.class);
|
||||||
|
private static CloseableHttpClient ourClient;
|
||||||
|
private static FhirContext ourCtx = FhirContext.forR4();
|
||||||
private static int ourPort;
|
private static int ourPort;
|
||||||
private static Server ourServer;
|
private static Server ourServer;
|
||||||
|
private static RestfulServer ourServlet;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
ourServlet.setDefaultResponseEncoding(EncodingEnum.XML);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readAndReturnContentType(String theAccept) throws IOException {
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient");
|
||||||
|
if (theAccept != null) {
|
||||||
|
httpGet.addHeader(Constants.HEADER_ACCEPT, theAccept);
|
||||||
|
}
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
String contentType = status.getEntity().getContentType().getValue();
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
contentType = contentType.replaceAll(";.*", "");
|
||||||
|
return contentType;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConformanceMetadataUsesNewMimetypes() throws Exception {
|
public void testConformanceMetadataUsesNewMimetypes() throws Exception {
|
||||||
|
@ -58,109 +75,6 @@ public class ServerMimetypeR4Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private List<String> toStrings(List<CodeType> theFormat) {
|
|
||||||
ArrayList<String> retVal = new ArrayList<String>();
|
|
||||||
for (CodeType next : theFormat) {
|
|
||||||
retVal.add(next.asStringValue());
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateWithXmlLegacyNoAcceptHeader() throws Exception {
|
|
||||||
Patient p = new Patient();
|
|
||||||
p.addName().setFamily("FAMILY");
|
|
||||||
String enc = ourCtx.newXmlParser().encodeResourceToString(p);
|
|
||||||
|
|
||||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
|
||||||
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_XML + "; charset=utf-8")));
|
|
||||||
HttpResponse status = ourClient.execute(httpPost);
|
|
||||||
|
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
|
||||||
|
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
|
||||||
|
|
||||||
assertEquals(201, status.getStatusLine().getStatusCode());
|
|
||||||
assertEquals(Constants.CT_FHIR_XML, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
|
||||||
assertEquals("<OperationOutcome xmlns=\"http://hl7.org/fhir\"><issue><diagnostics value=\"FAMILY\"/></issue></OperationOutcome>", responseContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHttpTraceNotEnabled() throws Exception {
|
|
||||||
HttpTrace req = new HttpTrace("http://localhost:" + ourPort + "/Patient");
|
|
||||||
CloseableHttpResponse status = ourClient.execute(req);
|
|
||||||
try {
|
|
||||||
ourLog.info(status.toString());
|
|
||||||
assertEquals(400, status.getStatusLine().getStatusCode());
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHttpTrackNotEnabled() throws Exception {
|
|
||||||
HttpRequestBase req = new HttpRequestBase() {
|
|
||||||
@Override
|
|
||||||
public String getMethod() {
|
|
||||||
return "TRACK";
|
|
||||||
}};
|
|
||||||
req.setURI(new URI("http://localhost:" + ourPort + "/Patient"));
|
|
||||||
|
|
||||||
CloseableHttpResponse status = ourClient.execute(req);
|
|
||||||
try {
|
|
||||||
ourLog.info(status.toString());
|
|
||||||
assertEquals(400, status.getStatusLine().getStatusCode());
|
|
||||||
} finally {
|
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateWithXmlNewNoAcceptHeader() throws Exception {
|
|
||||||
Patient p = new Patient();
|
|
||||||
p.addName().setFamily("FAMILY");
|
|
||||||
String enc = ourCtx.newXmlParser().encodeResourceToString(p);
|
|
||||||
|
|
||||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
|
||||||
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_XML_NEW + "; charset=utf-8")));
|
|
||||||
HttpResponse status = ourClient.execute(httpPost);
|
|
||||||
|
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
|
||||||
|
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
|
||||||
|
|
||||||
assertEquals(201, status.getStatusLine().getStatusCode());
|
|
||||||
assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
|
||||||
assertEquals("<OperationOutcome xmlns=\"http://hl7.org/fhir\"><issue><diagnostics value=\"FAMILY\"/></issue></OperationOutcome>", responseContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCreateWithXmlNewWithAcceptHeader() throws Exception {
|
|
||||||
Patient p = new Patient();
|
|
||||||
p.addName().setFamily("FAMILY");
|
|
||||||
String enc = ourCtx.newXmlParser().encodeResourceToString(p);
|
|
||||||
|
|
||||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
|
||||||
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_XML + "; charset=utf-8")));
|
|
||||||
httpPost.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_XML_NEW);
|
|
||||||
HttpResponse status = ourClient.execute(httpPost);
|
|
||||||
|
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
|
||||||
|
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
|
||||||
|
|
||||||
assertEquals(201, status.getStatusLine().getStatusCode());
|
|
||||||
assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
|
||||||
assertEquals("<OperationOutcome xmlns=\"http://hl7.org/fhir\"><issue><diagnostics value=\"FAMILY\"/></issue></OperationOutcome>", responseContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateWithJsonLegacyNoAcceptHeader() throws Exception {
|
public void testCreateWithJsonLegacyNoAcceptHeader() throws Exception {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
|
@ -223,9 +137,147 @@ public class ServerMimetypeR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithFormatXmlSimple() throws Exception {
|
public void testCreateWithXmlLegacyNoAcceptHeader() throws Exception {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addName().setFamily("FAMILY");
|
||||||
|
String enc = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||||
|
|
||||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=xml");
|
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||||
|
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_XML + "; charset=utf-8")));
|
||||||
|
HttpResponse status = ourClient.execute(httpPost);
|
||||||
|
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
|
||||||
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
|
assertEquals(201, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals(Constants.CT_FHIR_XML, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||||
|
assertEquals("<OperationOutcome xmlns=\"http://hl7.org/fhir\"><issue><diagnostics value=\"FAMILY\"/></issue></OperationOutcome>", responseContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithXmlNewNoAcceptHeader() throws Exception {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addName().setFamily("FAMILY");
|
||||||
|
String enc = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||||
|
|
||||||
|
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||||
|
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_XML_NEW + "; charset=utf-8")));
|
||||||
|
HttpResponse status = ourClient.execute(httpPost);
|
||||||
|
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
|
||||||
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
|
assertEquals(201, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||||
|
assertEquals("<OperationOutcome xmlns=\"http://hl7.org/fhir\"><issue><diagnostics value=\"FAMILY\"/></issue></OperationOutcome>", responseContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateWithXmlNewWithAcceptHeader() throws Exception {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addName().setFamily("FAMILY");
|
||||||
|
String enc = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||||
|
|
||||||
|
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||||
|
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_XML + "; charset=utf-8")));
|
||||||
|
httpPost.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_XML_NEW);
|
||||||
|
HttpResponse status = ourClient.execute(httpPost);
|
||||||
|
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
|
||||||
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
|
assertEquals(201, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||||
|
assertEquals("<OperationOutcome xmlns=\"http://hl7.org/fhir\"><issue><diagnostics value=\"FAMILY\"/></issue></OperationOutcome>", responseContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpTraceNotEnabled() throws Exception {
|
||||||
|
HttpTrace req = new HttpTrace("http://localhost:" + ourPort + "/Patient");
|
||||||
|
CloseableHttpResponse status = ourClient.execute(req);
|
||||||
|
try {
|
||||||
|
ourLog.info(status.toString());
|
||||||
|
assertEquals(400, status.getStatusLine().getStatusCode());
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpTrackNotEnabled() throws Exception {
|
||||||
|
HttpRequestBase req = new HttpRequestBase() {
|
||||||
|
@Override
|
||||||
|
public String getMethod() {
|
||||||
|
return "TRACK";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
req.setURI(new URI("http://localhost:" + ourPort + "/Patient"));
|
||||||
|
|
||||||
|
CloseableHttpResponse status = ourClient.execute(req);
|
||||||
|
try {
|
||||||
|
ourLog.info(status.toString());
|
||||||
|
assertEquals(400, status.getStatusLine().getStatusCode());
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #837
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testResponseContentTypesJson() throws IOException {
|
||||||
|
ourServlet.setDefaultResponseEncoding(EncodingEnum.XML);
|
||||||
|
|
||||||
|
// None given
|
||||||
|
assertEquals("application/fhir+xml", readAndReturnContentType(null));
|
||||||
|
|
||||||
|
// Legacy given
|
||||||
|
assertEquals("application/json+fhir", readAndReturnContentType("application/json+fhir"));
|
||||||
|
|
||||||
|
// Everything else JSON
|
||||||
|
assertEquals("application/fhir+json", readAndReturnContentType("application/fhir+json"));
|
||||||
|
assertEquals("application/fhir+json", readAndReturnContentType("application/json"));
|
||||||
|
assertEquals("application/fhir+json", readAndReturnContentType("application/fhir+json,application/json;q=0.9"));
|
||||||
|
assertEquals("application/fhir+json", readAndReturnContentType("json"));
|
||||||
|
|
||||||
|
// Invalid
|
||||||
|
assertEquals("application/fhir+xml", readAndReturnContentType("text/plain"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #837
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testResponseContentTypesXml() throws IOException {
|
||||||
|
ourServlet.setDefaultResponseEncoding(EncodingEnum.JSON);
|
||||||
|
|
||||||
|
// None given
|
||||||
|
assertEquals("application/fhir+json", readAndReturnContentType(null));
|
||||||
|
|
||||||
|
// Legacy given
|
||||||
|
assertEquals("application/xml+fhir", readAndReturnContentType("application/xml+fhir"));
|
||||||
|
|
||||||
|
// Everything else JSON
|
||||||
|
assertEquals("application/fhir+xml", readAndReturnContentType("application/fhir+xml"));
|
||||||
|
assertEquals("application/fhir+xml", readAndReturnContentType("application/xml"));
|
||||||
|
assertEquals("application/fhir+xml", readAndReturnContentType("application/fhir+xml,application/xml;q=0.9"));
|
||||||
|
assertEquals("application/fhir+xml", readAndReturnContentType("xml"));
|
||||||
|
|
||||||
|
// Invalid
|
||||||
|
assertEquals("application/fhir+json", readAndReturnContentType("text/plain"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchWithFormatJsonLegacy() throws Exception {
|
||||||
|
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=" + Constants.CT_FHIR_JSON);
|
||||||
HttpResponse status = ourClient.execute(httpGet);
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
@ -234,9 +286,40 @@ public class ServerMimetypeR4Test {
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
assertThat(responseContent, containsString("<Patient xmlns=\"http://hl7.org/fhir\">"));
|
assertThat(responseContent, containsString("\"resourceType\""));
|
||||||
assertThat(responseContent, not(containsString("http://hl7.org/fhir/")));
|
assertEquals(Constants.CT_FHIR_JSON, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||||
assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchWithFormatJsonNew() throws Exception {
|
||||||
|
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=" + Constants.CT_FHIR_JSON_NEW);
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
|
||||||
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertThat(responseContent, containsString("\"resourceType\""));
|
||||||
|
assertEquals(Constants.CT_FHIR_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchWithFormatJsonSimple() throws Exception {
|
||||||
|
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=json");
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
|
||||||
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertThat(responseContent, containsString("\"resourceType\""));
|
||||||
|
assertEquals(Constants.CT_FHIR_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -273,77 +356,29 @@ public class ServerMimetypeR4Test {
|
||||||
assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* See #837
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testResponseContentTypes() throws IOException {
|
public void testSearchWithFormatXmlSimple() throws Exception {
|
||||||
assertEquals("application/fhir+json", readAndReturnContentType("application/fhir+json"));
|
|
||||||
assertEquals("application/fhir+xml", readAndReturnContentType(null));
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=xml");
|
||||||
assertEquals("application/json+fhir", readAndReturnContentType("application/json+fhir"));
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
assertEquals("application/json+fhir", readAndReturnContentType("application/json"));
|
|
||||||
assertEquals("application/fhir+json", readAndReturnContentType("application/fhir+json,application/json;q=0.9"));
|
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
|
||||||
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertThat(responseContent, containsString("<Patient xmlns=\"http://hl7.org/fhir\">"));
|
||||||
|
assertThat(responseContent, not(containsString("http://hl7.org/fhir/")));
|
||||||
|
assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String readAndReturnContentType(String theAccept) throws IOException {
|
private List<String> toStrings(List<CodeType> theFormat) {
|
||||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient");
|
ArrayList<String> retVal = new ArrayList<String>();
|
||||||
if (theAccept != null) {
|
for (CodeType next : theFormat) {
|
||||||
httpGet.addHeader(Constants.HEADER_ACCEPT, theAccept);
|
retVal.add(next.asStringValue());
|
||||||
}
|
}
|
||||||
HttpResponse status = ourClient.execute(httpGet);
|
return retVal;
|
||||||
String contentType = status.getEntity().getContentType().getValue();
|
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
|
||||||
contentType = contentType.replaceAll(";.*","");
|
|
||||||
return contentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSearchWithFormatJsonSimple() throws Exception {
|
|
||||||
|
|
||||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=json");
|
|
||||||
HttpResponse status = ourClient.execute(httpGet);
|
|
||||||
|
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
|
||||||
|
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
|
||||||
|
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
|
||||||
assertThat(responseContent, containsString("\"resourceType\""));
|
|
||||||
assertEquals(Constants.CT_FHIR_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSearchWithFormatJsonLegacy() throws Exception {
|
|
||||||
|
|
||||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=" + Constants.CT_FHIR_JSON);
|
|
||||||
HttpResponse status = ourClient.execute(httpGet);
|
|
||||||
|
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
|
||||||
|
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
|
||||||
|
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
|
||||||
assertThat(responseContent, containsString("\"resourceType\""));
|
|
||||||
assertEquals(Constants.CT_FHIR_JSON, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSearchWithFormatJsonNew() throws Exception {
|
|
||||||
|
|
||||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=" + Constants.CT_FHIR_JSON_NEW);
|
|
||||||
HttpResponse status = ourClient.execute(httpGet);
|
|
||||||
|
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
|
||||||
|
|
||||||
ourLog.info("Response was:\n{}", responseContent);
|
|
||||||
|
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
|
||||||
assertThat(responseContent, containsString("\"resourceType\""));
|
|
||||||
assertEquals(Constants.CT_FHIR_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
@ -360,10 +395,10 @@ public class ServerMimetypeR4Test {
|
||||||
PatientProvider patientProvider = new PatientProvider();
|
PatientProvider patientProvider = new PatientProvider();
|
||||||
|
|
||||||
ServletHandler proxyHandler = new ServletHandler();
|
ServletHandler proxyHandler = new ServletHandler();
|
||||||
RestfulServer servlet = new RestfulServer(ourCtx);
|
ourServlet = new RestfulServer(ourCtx);
|
||||||
|
|
||||||
servlet.setResourceProviders(patientProvider);
|
ourServlet.setResourceProviders(patientProvider);
|
||||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
ServletHolder servletHolder = new ServletHolder(ourServlet);
|
||||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||||
ourServer.setHandler(proxyHandler);
|
ourServer.setHandler(proxyHandler);
|
||||||
ourServer.start();
|
ourServer.start();
|
||||||
|
|
|
@ -334,7 +334,7 @@ public class Controller extends BaseController {
|
||||||
|
|
||||||
if (client.getEncoding() != null) {
|
if (client.getEncoding() != null) {
|
||||||
clientCodeJsonWriter.name("format");
|
clientCodeJsonWriter.name("format");
|
||||||
clientCodeJsonWriter.value(client.getEncoding().getRequestContentType());
|
clientCodeJsonWriter.value(client.getEncoding().getFormatContentType());
|
||||||
} else {
|
} else {
|
||||||
clientCodeJsonWriter.name("format");
|
clientCodeJsonWriter.name("format");
|
||||||
clientCodeJsonWriter.nullValue();
|
clientCodeJsonWriter.nullValue();
|
||||||
|
|
|
@ -98,6 +98,17 @@
|
||||||
to build correctly on JDK 9.0. Currently building is supported on
|
to build correctly on JDK 9.0. Currently building is supported on
|
||||||
JDK 8.x and 9.x only.
|
JDK 8.x and 9.x only.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="837">
|
||||||
|
Client requests with an
|
||||||
|
<![CDATA[<code>Accept</code>]]>
|
||||||
|
header value of
|
||||||
|
<![CDATA[<code>application/json</code>]]>
|
||||||
|
will now be served with the non-legacy content type of
|
||||||
|
<![CDATA[<code>application/fhir+json</code>]]>
|
||||||
|
instead of the legacy
|
||||||
|
<![CDATA[<code>application/json+fhir</code>]]>.
|
||||||
|
Thanks to John Grimes for reporting!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.2.0" date="2018-01-13">
|
<release version="3.2.0" date="2018-01-13">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue