Fix #837 - Use non-legacy content-type for plain json and xml accept
header
This commit is contained in:
parent
ad8eb0b939
commit
351a2fc2f1
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.rest.api;
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -19,12 +19,14 @@ package ca.uhn.fhir.rest.api;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
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 {
|
||||
|
||||
|
@ -40,39 +42,40 @@ public enum EncodingEnum {
|
|||
public IParser newParser(FhirContext theContext) {
|
||||
return theContext.newXmlParser();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
;
|
||||
|
||||
/** "json" */
|
||||
public static final String JSON_PLAIN_STRING = "json";
|
||||
private static Map<String, EncodingEnum> ourContentTypeToEncoding;
|
||||
|
||||
private static Map<String, EncodingEnum> ourContentTypeToEncodingNonLegacy;
|
||||
private static Map<String, EncodingEnum> ourContentTypeToEncodingStrict;
|
||||
/** "xml" */
|
||||
/**
|
||||
* "json"
|
||||
*/
|
||||
public static final String JSON_PLAIN_STRING = "json";
|
||||
/**
|
||||
* "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 {
|
||||
ourContentTypeToEncoding = new HashMap<String, EncodingEnum>();
|
||||
ourContentTypeToEncodingNonLegacy = new HashMap<String, EncodingEnum>();
|
||||
|
||||
ourContentTypeToEncoding = new HashMap<>();
|
||||
ourContentTypeToEncodingLegacy = new HashMap<>();
|
||||
|
||||
for (EncodingEnum next : values()) {
|
||||
ourContentTypeToEncoding.put(next.myResourceContentTypeNonLegacy, next);
|
||||
ourContentTypeToEncoding.put(next.myResourceContentTypeLegacy, next);
|
||||
ourContentTypeToEncodingNonLegacy.put(next.myResourceContentTypeNonLegacy, next);
|
||||
ourContentTypeToEncodingLegacy.put(next.myResourceContentTypeLegacy, next);
|
||||
|
||||
/*
|
||||
* See #346
|
||||
*/
|
||||
ourContentTypeToEncoding.put(next.myResourceContentTypeNonLegacy.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
|
||||
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
|
||||
|
@ -89,7 +92,7 @@ public enum EncodingEnum {
|
|||
ourContentTypeToEncoding.put(JSON_PLAIN_STRING, JSON);
|
||||
ourContentTypeToEncoding.put(XML_PLAIN_STRING, XML);
|
||||
|
||||
ourContentTypeToEncodingNonLegacy = Collections.unmodifiableMap(ourContentTypeToEncodingNonLegacy);
|
||||
ourContentTypeToEncodingLegacy = Collections.unmodifiableMap(ourContentTypeToEncodingLegacy);
|
||||
|
||||
}
|
||||
|
||||
|
@ -107,10 +110,6 @@ public enum EncodingEnum {
|
|||
return myFormatContentType;
|
||||
}
|
||||
|
||||
public String getRequestContentType() {
|
||||
return myFormatContentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will return application/xml+fhir style
|
||||
*/
|
||||
|
@ -150,7 +149,7 @@ public enum EncodingEnum {
|
|||
|
||||
/**
|
||||
* Returns the encoding for a given content type, or <code>null</code> if no encoding
|
||||
* is found.
|
||||
* is found.
|
||||
* <p>
|
||||
* <b>This method is lenient!</b> Things like "application/xml" will return {@link EncodingEnum#XML}
|
||||
* even if the "+fhir" part is missing from the expected content type.
|
||||
|
@ -163,19 +162,23 @@ public enum EncodingEnum {
|
|||
|
||||
/**
|
||||
* Returns the encoding for a given content type, or <code>null</code> if no encoding
|
||||
* is found.
|
||||
* is found.
|
||||
* <p>
|
||||
* <b>This method is NOT lenient!</b> Things like "application/xml" will return <code>null</code>
|
||||
* </p>
|
||||
*
|
||||
* @see #forContentType(String)
|
||||
*/
|
||||
public static EncodingEnum forContentTypeStrict(String 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();
|
||||
myEncoding = theEncoding;
|
||||
if (theContentType != null) {
|
||||
FhirVersionEnum ctxtEnum = theCtx.getVersion().getVersion();
|
||||
if (theContentType.equals(EncodingEnum.JSON_PLAIN_STRING) || theContentType.equals(EncodingEnum.XML_PLAIN_STRING)) {
|
||||
FhirVersionEnum ctxtEnum = theCtx.getVersion().getVersion();
|
||||
myNonLegacy = ctxtEnum.isNewerThan(FhirVersionEnum.DSTU3)
|
||||
|| (ctxtEnum.isEquivalentTo(FhirVersionEnum.DSTU3) && !"1.4.0".equals(theCtx.getVersion().getVersion().getFhirVersionString()));
|
||||
myNonLegacy = ctxtEnum.isNewerThan(FhirVersionEnum.DSTU2);
|
||||
} else {
|
||||
myNonLegacy = EncodingEnum.isNonLegacy(theContentType);
|
||||
myNonLegacy = ctxtEnum.isNewerThan(FhirVersionEnum.DSTU2) && !EncodingEnum.isLegacy(theContentType);
|
||||
}
|
||||
} else {
|
||||
FhirVersionEnum ctxtEnum = theCtx.getVersion().getVersion();
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.MyPatientWithExtensions;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.*;
|
||||
|
@ -26,23 +21,45 @@ import org.eclipse.jetty.servlet.ServletHandler;
|
|||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
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 ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.MyPatientWithExtensions;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
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 CloseableHttpClient ourClient;
|
||||
private static FhirContext ourCtx = FhirContext.forR4();
|
||||
private static int ourPort;
|
||||
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
|
||||
public void testConformanceMetadataUsesNewMimetypes() throws Exception {
|
||||
|
@ -57,25 +74,74 @@ public class ServerMimetypeR4Test {
|
|||
status.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 testCreateWithJsonLegacyNoAcceptHeader() throws Exception {
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("FAMILY");
|
||||
String enc = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_JSON + "; 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_JSON, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
assertEquals("{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"diagnostics\":\"FAMILY\"}]}", responseContent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithJsonNewNoAcceptHeader() throws Exception {
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("FAMILY");
|
||||
String enc = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_JSON_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_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
assertEquals("{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"diagnostics\":\"FAMILY\"}]}", responseContent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithJsonNewWithAcceptHeader() throws Exception {
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("FAMILY");
|
||||
String enc = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_JSON + "; charset=utf-8")));
|
||||
httpPost.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_JSON_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_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
assertEquals("{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"diagnostics\":\"FAMILY\"}]}", responseContent);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
@ -90,6 +156,47 @@ public class ServerMimetypeR4Test {
|
|||
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");
|
||||
|
@ -108,9 +215,10 @@ public class ServerMimetypeR4Test {
|
|||
@Override
|
||||
public String getMethod() {
|
||||
return "TRACK";
|
||||
}};
|
||||
}
|
||||
};
|
||||
req.setURI(new URI("http://localhost:" + ourPort + "/Patient"));
|
||||
|
||||
|
||||
CloseableHttpResponse status = ourClient.execute(req);
|
||||
try {
|
||||
ourLog.info(status.toString());
|
||||
|
@ -120,112 +228,56 @@ public class ServerMimetypeR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See #837
|
||||
*/
|
||||
@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);
|
||||
public void testResponseContentTypesJson() throws IOException {
|
||||
ourServlet.setDefaultResponseEncoding(EncodingEnum.XML);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
// None given
|
||||
assertEquals("application/fhir+xml", readAndReturnContentType(null));
|
||||
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
// Legacy given
|
||||
assertEquals("application/json+fhir", readAndReturnContentType("application/json+fhir"));
|
||||
|
||||
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);
|
||||
// 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 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);
|
||||
public void testSearchWithFormatJsonLegacy() throws Exception {
|
||||
|
||||
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 testCreateWithJsonLegacyNoAcceptHeader() throws Exception {
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("FAMILY");
|
||||
String enc = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_JSON + "; 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_JSON, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
assertEquals("{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"diagnostics\":\"FAMILY\"}]}", responseContent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithJsonNewNoAcceptHeader() throws Exception {
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("FAMILY");
|
||||
String enc = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_JSON_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_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
assertEquals("{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"diagnostics\":\"FAMILY\"}]}", responseContent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithJsonNewWithAcceptHeader() throws Exception {
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("FAMILY");
|
||||
String enc = ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.setEntity(new StringEntity(enc, ContentType.parse(Constants.CT_FHIR_JSON + "; charset=utf-8")));
|
||||
httpPost.addHeader(Constants.HEADER_ACCEPT, Constants.CT_FHIR_JSON_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_JSON_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
assertEquals("{\"resourceType\":\"OperationOutcome\",\"issue\":[{\"diagnostics\":\"FAMILY\"}]}", responseContent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithFormatXmlSimple() throws Exception {
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=xml");
|
||||
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);
|
||||
|
@ -234,9 +286,40 @@ public class ServerMimetypeR4Test {
|
|||
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(";.*", ""));
|
||||
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(";.*", ""));
|
||||
}
|
||||
|
||||
@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
|
||||
|
@ -273,77 +356,29 @@ public class ServerMimetypeR4Test {
|
|||
assertEquals(Constants.CT_FHIR_XML_NEW, status.getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* See #837
|
||||
*/
|
||||
@Test
|
||||
public void testResponseContentTypes() throws IOException {
|
||||
assertEquals("application/fhir+json", readAndReturnContentType("application/fhir+json"));
|
||||
assertEquals("application/fhir+xml", readAndReturnContentType(null));
|
||||
assertEquals("application/json+fhir", readAndReturnContentType("application/json+fhir"));
|
||||
assertEquals("application/json+fhir", readAndReturnContentType("application/json"));
|
||||
assertEquals("application/fhir+json", readAndReturnContentType("application/fhir+json,application/json;q=0.9"));
|
||||
public void testSearchWithFormatXmlSimple() throws Exception {
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_format=xml");
|
||||
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("<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 {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient");
|
||||
if (theAccept != null) {
|
||||
httpGet.addHeader(Constants.HEADER_ACCEPT, theAccept);
|
||||
private List<String> toStrings(List<CodeType> theFormat) {
|
||||
ArrayList<String> retVal = new ArrayList<String>();
|
||||
for (CodeType next : theFormat) {
|
||||
retVal.add(next.asStringValue());
|
||||
}
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
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(";.*", ""));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
@ -360,10 +395,10 @@ public class ServerMimetypeR4Test {
|
|||
PatientProvider patientProvider = new PatientProvider();
|
||||
|
||||
ServletHandler proxyHandler = new ServletHandler();
|
||||
RestfulServer servlet = new RestfulServer(ourCtx);
|
||||
ourServlet = new RestfulServer(ourCtx);
|
||||
|
||||
servlet.setResourceProviders(patientProvider);
|
||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||
ourServlet.setResourceProviders(patientProvider);
|
||||
ServletHolder servletHolder = new ServletHolder(ourServlet);
|
||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||
ourServer.setHandler(proxyHandler);
|
||||
ourServer.start();
|
||||
|
|
|
@ -334,7 +334,7 @@ public class Controller extends BaseController {
|
|||
|
||||
if (client.getEncoding() != null) {
|
||||
clientCodeJsonWriter.name("format");
|
||||
clientCodeJsonWriter.value(client.getEncoding().getRequestContentType());
|
||||
clientCodeJsonWriter.value(client.getEncoding().getFormatContentType());
|
||||
} else {
|
||||
clientCodeJsonWriter.name("format");
|
||||
clientCodeJsonWriter.nullValue();
|
||||
|
|
|
@ -98,6 +98,17 @@
|
|||
to build correctly on JDK 9.0. Currently building is supported on
|
||||
JDK 8.x and 9.x only.
|
||||
</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 version="3.2.0" date="2018-01-13">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue