Server now respects the If-Modified-Since header for read operations
This commit is contained in:
parent
a92d80d860
commit
45041830bc
|
@ -25,38 +25,25 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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.IBaseBinary;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.*;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.Elements;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.IRestfulServer;
|
||||
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.NotModifiedException;
|
||||
import ca.uhn.fhir.rest.server.*;
|
||||
import ca.uhn.fhir.rest.server.exceptions.*;
|
||||
import ca.uhn.fhir.util.DateUtils;
|
||||
|
||||
public class ReadMethodBinding extends BaseResourceReturningMethodBinding implements IClientResponseHandlerHandlesBinary<Object> {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ReadMethodBinding.class);
|
||||
|
@ -220,12 +207,15 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
|
|||
Object response = invokeServerMethod(theServer, theRequest, theMethodParams);
|
||||
IBundleProvider retVal = toResourceList(response);
|
||||
|
||||
if (theRequest.getServer().getETagSupport() == ETagSupportEnum.ENABLED) {
|
||||
String ifNoneMatch = theRequest.getHeader(Constants.HEADER_IF_NONE_MATCH_LC);
|
||||
if (retVal.size() == 1 && StringUtils.isNotBlank(ifNoneMatch)) {
|
||||
|
||||
if (retVal.size() == 1) {
|
||||
List<IBaseResource> responseResources = retVal.getResources(0, 1);
|
||||
IBaseResource responseResource = responseResources.get(0);
|
||||
|
||||
// If-None-Match
|
||||
if (theRequest.getServer().getETagSupport() == ETagSupportEnum.ENABLED) {
|
||||
String ifNoneMatch = theRequest.getHeader(Constants.HEADER_IF_NONE_MATCH_LC);
|
||||
if (StringUtils.isNotBlank(ifNoneMatch)) {
|
||||
ifNoneMatch = MethodUtil.parseETagValue(ifNoneMatch);
|
||||
if (responseResource.getIdElement() != null && responseResource.getIdElement().hasVersionIdPart()) {
|
||||
if (responseResource.getIdElement().getVersionIdPart().equals(ifNoneMatch)) {
|
||||
|
@ -236,6 +226,29 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
|
|||
}
|
||||
}
|
||||
|
||||
// If-Modified-Since
|
||||
String ifModifiedSince = theRequest.getHeader(Constants.HEADER_IF_MODIFIED_SINCE_LC);
|
||||
if (isNotBlank(ifModifiedSince)) {
|
||||
Date ifModifiedSinceDate = DateUtils.parseDate(ifModifiedSince);
|
||||
Date lastModified = null;
|
||||
if (responseResource instanceof IResource) {
|
||||
InstantDt lastModifiedDt = ResourceMetadataKeyEnum.UPDATED.get((IResource) responseResource);
|
||||
if (lastModifiedDt != null) {
|
||||
lastModified = lastModifiedDt.getValue();
|
||||
}
|
||||
} else {
|
||||
lastModified = ((IAnyResource)responseResource).getMeta().getLastUpdated();
|
||||
}
|
||||
|
||||
if (lastModified != null && lastModified.getTime() > ifModifiedSinceDate.getTime()) {
|
||||
ourLog.debug("Returning HTTP 301 because If-Modified-Since does not match");
|
||||
throw new NotModifiedException("Not Modified");
|
||||
}
|
||||
}
|
||||
|
||||
} // if we have at least 1 result
|
||||
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ public class Constants {
|
|||
public static final String CT_XML = "application/xml";
|
||||
public static final String CT_XML_PATCH = "application/xml-patch+xml";
|
||||
public static final String ENCODING_GZIP = "gzip";
|
||||
public static final String EXTOP_PROCESS_MESSAGE = "$process-message"; //Used in messaging
|
||||
public static final String EXTOP_VALIDATE = "$validate";
|
||||
public static final String EXTOP_VALIDATE_MODE = "mode";
|
||||
public static final String EXTOP_VALIDATE_PROFILE = "profile";
|
||||
|
@ -86,6 +87,8 @@ public class Constants {
|
|||
public static final String HEADER_ETAG_LC = HEADER_ETAG.toLowerCase();
|
||||
public static final String HEADER_IF_MATCH = "If-Match";
|
||||
public static final String HEADER_IF_MATCH_LC = HEADER_IF_MATCH.toLowerCase();
|
||||
public static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";
|
||||
public static final String HEADER_IF_MODIFIED_SINCE_LC = HEADER_IF_MODIFIED_SINCE.toLowerCase();
|
||||
public static final String HEADER_IF_NONE_EXIST = "If-None-Exist";
|
||||
public static final String HEADER_IF_NONE_EXIST_LC = HEADER_IF_NONE_EXIST.toLowerCase();
|
||||
public static final String HEADER_IF_NONE_MATCH = "If-None-Match";
|
||||
|
@ -109,6 +112,7 @@ public class Constants {
|
|||
public static final String LINK_PREVIOUS = "previous";
|
||||
public static final String LINK_SELF = "self";
|
||||
public static final String OPENSEARCH_NS_OLDER = "http://purl.org/atompub/tombstones/1.0";
|
||||
public static final String PARAM_ASYNC = "async"; //Used in messaging
|
||||
public static final String PARAM_AT = "_at";
|
||||
/**
|
||||
* Used in paging links
|
||||
|
@ -133,6 +137,7 @@ public class Constants {
|
|||
public static final String PARAM_PRETTY_VALUE_TRUE = "true";
|
||||
public static final String PARAM_PROFILE = "_profile";
|
||||
public static final String PARAM_QUERY = "_query";
|
||||
public static final String PARAM_RESPONSE_URL = "response-url"; //Used in messaging
|
||||
public static final String PARAM_REVINCLUDE = "_revinclude";
|
||||
public static final String PARAM_REVINCLUDE_RECURSE = PARAM_REVINCLUDE+PARAM_INCLUDE_QUALIFIER_RECURSE;
|
||||
public static final String PARAM_SEARCH = "_search";
|
||||
|
@ -146,9 +151,6 @@ public class Constants {
|
|||
public static final String PARAM_TAGS = "_tags";
|
||||
public static final String PARAM_TEXT = "_text";
|
||||
public static final String PARAM_VALIDATE = "_validate";
|
||||
public static final String PARAM_ASYNC = "async"; //Used in messaging
|
||||
public static final String PARAM_RESPONSE_URL = "response-url"; //Used in messaging
|
||||
public static final String EXTOP_PROCESS_MESSAGE = "$process-message"; //Used in messaging
|
||||
public static final String PARAMQUALIFIER_MISSING = ":missing";
|
||||
public static final String PARAMQUALIFIER_MISSING_FALSE = "false";
|
||||
public static final String PARAMQUALIFIER_MISSING_TRUE = "true";
|
||||
|
@ -162,8 +164,8 @@ public class Constants {
|
|||
public static final int STATUS_HTTP_400_BAD_REQUEST = 400;
|
||||
public static final int STATUS_HTTP_401_CLIENT_UNAUTHORIZED = 401;
|
||||
public static final int STATUS_HTTP_403_FORBIDDEN = 403;
|
||||
public static final int STATUS_HTTP_404_NOT_FOUND = 404;
|
||||
|
||||
public static final int STATUS_HTTP_404_NOT_FOUND = 404;
|
||||
public static final int STATUS_HTTP_405_METHOD_NOT_ALLOWED = 405;
|
||||
public static final int STATUS_HTTP_409_CONFLICT = 409;
|
||||
public static final int STATUS_HTTP_410_GONE = 410;
|
||||
|
|
|
@ -61,8 +61,6 @@ import java.util.TimeZone;
|
|||
* A utility class for parsing and formatting HTTP dates as used in cookies and
|
||||
* other headers. This class handles dates as defined by RFC 2616 section
|
||||
* 3.3.1 as well as some other common non-standard formats.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
public final class DateUtils {
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
|
@ -17,10 +18,7 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
|||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
@ -28,13 +26,10 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
|||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.server.AddProfileTagEnum;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import ca.uhn.fhir.util.*;
|
||||
|
||||
public class ReadDstu2Test {
|
||||
|
||||
|
@ -54,23 +49,48 @@ public class ReadDstu2Test {
|
|||
ourLastId = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIfModifiedSince() throws Exception {
|
||||
|
||||
CloseableHttpResponse status;
|
||||
HttpGet httpGet;
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/2");
|
||||
httpGet.addHeader(Constants.HEADER_IF_MODIFIED_SINCE, DateUtils.formatDate(new InstantDt("2012-01-01T13:00:00Z").getValue()));
|
||||
status = ourClient.execute(httpGet);
|
||||
try {
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(status);
|
||||
}
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/2");
|
||||
httpGet.addHeader(Constants.HEADER_IF_MODIFIED_SINCE, DateUtils.formatDate(new InstantDt("2012-01-01T10:00:00Z").getValue()));
|
||||
status = ourClient.execute(httpGet);
|
||||
try {
|
||||
assertEquals(304, status.getStatusLine().getStatusCode());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See #302
|
||||
*/
|
||||
@Test
|
||||
public void testAddProfile() throws Exception {
|
||||
ourCtx.setAddProfileTagWhenEncoding(AddProfileTagEnum.ALWAYS);
|
||||
ourCtx.setAddProfileTagWhenEncoding(AddProfileTagEnum.ONLY_FOR_CUSTOM);
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123?_format=xml");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), Constants.CHARSET_UTF8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertThat(responseContent, containsString("p1ReadValue"));
|
||||
assertThat(responseContent, containsString("p1ReadId"));
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><id value=\"p1ReadId\"/><meta><profile value=\"http://foo_profile\"/></meta><identifier><value value=\"p1ReadValue\"/></identifier></Patient>", responseContent);
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><id value=\"p1ReadId\"/><meta><lastUpdated value=\"2012-01-01T12:12:12Z\"/><profile value=\"http://foo_profile\"/></meta><identifier><value value=\"p1ReadValue\"/></identifier></Patient>", responseContent);
|
||||
|
||||
ourLog.info(responseContent);
|
||||
|
||||
|
@ -87,7 +107,7 @@ public class ReadDstu2Test {
|
|||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123&_format=xml");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), Constants.CHARSET_UTF8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
ourLog.info(responseContent);
|
||||
|
@ -95,7 +115,7 @@ public class ReadDstu2Test {
|
|||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertThat(responseContent, containsString("p1ReadValue"));
|
||||
assertThat(responseContent, containsString("p1ReadId"));
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><id value=\"p1ReadId\"/><meta><profile value=\"http://foo\"/><profile value=\"http://foo_profile\"/></meta><identifier><value value=\"p1ReadValue\"/></identifier></Patient>", responseContent);
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><id value=\"p1ReadId\"/><meta><lastUpdated value=\"2012-01-01T12:12:12Z\"/><profile value=\"http://foo\"/><profile value=\"http://foo_profile\"/></meta><identifier><value value=\"p1ReadValue\"/></identifier></Patient>", responseContent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,18 +123,18 @@ public class ReadDstu2Test {
|
|||
*/
|
||||
@Test
|
||||
public void testReadJson() throws Exception {
|
||||
ourCtx.setAddProfileTagWhenEncoding(AddProfileTagEnum.ALWAYS);
|
||||
ourCtx.setAddProfileTagWhenEncoding(AddProfileTagEnum.ONLY_FOR_CUSTOM);
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123?_format=json");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), Constants.CHARSET_UTF8);
|
||||
ourLog.info(responseContent);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertThat(responseContent, containsString("p1ReadValue"));
|
||||
assertThat(responseContent, containsString("p1ReadId"));
|
||||
assertThat(responseContent, containsString("\"meta\":{\"profile\":[\"http://foo_profile\"]}"));
|
||||
assertThat(responseContent, containsString("\"meta\":{\"lastUpdated\":\"2012-01-01T12:12:12Z\",\"profile\":[\"http://foo_profile\"]}"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,7 +144,7 @@ public class ReadDstu2Test {
|
|||
public void testReadXml() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123&_format=xml");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), Constants.CHARSET_UTF8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -140,13 +160,13 @@ public class ReadDstu2Test {
|
|||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/_history/1");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), Constants.CHARSET_UTF8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertThat(responseContent, containsString("p1ReadValue"));
|
||||
assertThat(responseContent, containsString("p1ReadId"));
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><id value=\"p1ReadId\"/><meta><profile value=\"http://foo_profile\"/></meta><identifier><value value=\"p1ReadValue\"/></identifier></Patient>", responseContent);
|
||||
assertEquals("<Patient xmlns=\"http://hl7.org/fhir\"><id value=\"p1ReadId\"/><meta><lastUpdated value=\"2012-01-01T12:12:12Z\"/><profile value=\"http://foo_profile\"/></meta><identifier><value value=\"p1ReadValue\"/></identifier></Patient>", responseContent);
|
||||
|
||||
ourLog.info(responseContent);
|
||||
|
||||
|
@ -196,6 +216,8 @@ public class ReadDstu2Test {
|
|||
public Patient read(@IdParam IdDt theId) {
|
||||
ourLastId = theId;
|
||||
Patient p1 = new MyPatient();
|
||||
ResourceMetadataKeyEnum.UPDATED.put(p1, new InstantDt("2012-01-01T12:12:12Z"));
|
||||
|
||||
p1.setId("p1ReadId");
|
||||
p1.addIdentifier().setValue("p1ReadValue");
|
||||
if (ourInitializeProfileList) {
|
||||
|
|
|
@ -1,46 +1,31 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
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.http.HttpResponse;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.dstu3.model.DateType;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.junit.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.annotation.Create;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
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 ca.uhn.fhir.util.*;
|
||||
|
||||
public class ReadDstu3Test {
|
||||
private static CloseableHttpClient ourClient;
|
||||
|
@ -50,7 +35,6 @@ public class ReadDstu3Test {
|
|||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
|
||||
|
||||
@Test
|
||||
public void testRead() throws Exception {
|
||||
|
||||
|
@ -66,20 +50,43 @@ public class ReadDstu3Test {
|
|||
assertEquals("http://localhost:" + ourPort + "/Patient/2/_history/2", status.getFirstHeader(Constants.HEADER_LOCATION).getValue());
|
||||
assertEquals(null, status.getFirstHeader(Constants.HEADER_CONTENT_LOCATION));
|
||||
|
||||
//@formatter:off
|
||||
assertThat(responseContent, stringContainsInOrder(
|
||||
"<Patient xmlns=\"http://hl7.org/fhir\">",
|
||||
"<id value=\"2\"/>",
|
||||
"<meta>",
|
||||
"<profile value=\"http://example.com/StructureDefinition/patient_with_extensions\"/>",
|
||||
"</meta>",
|
||||
"<modifierExtension url=\"http://example.com/ext/date\">",
|
||||
"<valueDate value=\"2011-01-01\"/>",
|
||||
"</modifierExtension>",
|
||||
" <id value=\"2\"/>",
|
||||
" <meta>",
|
||||
" <profile value=\"http://example.com/StructureDefinition/patient_with_extensions\"/>",
|
||||
" </meta>",
|
||||
" <modifierExtension url=\"http://example.com/ext/date\">",
|
||||
" <valueDate value=\"2011-01-01\"/>",
|
||||
" </modifierExtension>",
|
||||
"</Patient>"));
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIfModifiedSince() throws Exception {
|
||||
|
||||
CloseableHttpResponse status;
|
||||
HttpGet httpGet;
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/2");
|
||||
httpGet.addHeader(Constants.HEADER_IF_MODIFIED_SINCE, DateUtils.formatDate(new InstantDt("2012-01-01T13:00:00Z").getValue()));
|
||||
status = ourClient.execute(httpGet);
|
||||
try {
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(status);
|
||||
}
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/2");
|
||||
httpGet.addHeader(Constants.HEADER_IF_MODIFIED_SINCE, DateUtils.formatDate(new InstantDt("2012-01-01T10:00:00Z").getValue()));
|
||||
status = ourClient.execute(httpGet);
|
||||
try {
|
||||
assertEquals(304, status.getStatusLine().getStatusCode());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() throws Exception {
|
||||
|
@ -117,9 +124,10 @@ public class ReadDstu3Test {
|
|||
return Patient.class;
|
||||
}
|
||||
|
||||
@Read(version=true)
|
||||
@Read(version = true)
|
||||
public MyPatientWithExtensions read(@IdParam IdType theIdParam) {
|
||||
MyPatientWithExtensions p0 = new MyPatientWithExtensions();
|
||||
p0.getMeta().getLastUpdatedElement().setValueAsString("2012-01-01T12:12:12Z");
|
||||
p0.setId(theIdParam);
|
||||
if (theIdParam.hasVersionIdPart() == false) {
|
||||
p0.setIdElement(p0.getIdElement().withVersion("2"));
|
||||
|
@ -128,7 +136,6 @@ public class ReadDstu3Test {
|
|||
return p0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -101,6 +101,10 @@
|
|||
Fix issue where the JSON parser sometimes did not encode DSTU3 extensions on the root of a
|
||||
resource which have a value of type reference.
|
||||
</action>
|
||||
<action type="add">
|
||||
Server now respects the If-Modified-Since header and will return an HTTP 304 if appropriate
|
||||
for read operations.
|
||||
</action>
|
||||
</release>
|
||||
<release version="2.4" date="2017-04-19">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue