Merge remote-tracking branch 'remotes/origin/master' into expunge-resource-hook
This commit is contained in:
commit
e634aa6d10
|
@ -21,13 +21,16 @@ package ca.uhn.fhir.rest.api;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.rest.annotation.Patch;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
|
||||
/**
|
||||
* Parameter type for methods annotated with {@link Patch}
|
||||
*/
|
||||
public enum PatchTypeEnum {
|
||||
|
||||
JSON_PATCH(Constants.CT_JSON_PATCH), XML_PATCH(Constants.CT_XML_PATCH);
|
||||
JSON_PATCH(Constants.CT_JSON_PATCH),
|
||||
XML_PATCH(Constants.CT_XML_PATCH);
|
||||
|
||||
private final String myContentType;
|
||||
|
||||
|
@ -39,4 +42,19 @@ public enum PatchTypeEnum {
|
|||
return myContentType;
|
||||
}
|
||||
|
||||
public static PatchTypeEnum forContentTypeOrThrowInvalidRequestException(String theContentType) {
|
||||
String contentType = theContentType;
|
||||
int semiColonIdx = contentType.indexOf(';');
|
||||
if (semiColonIdx != -1) {
|
||||
contentType = theContentType.substring(0, semiColonIdx);
|
||||
}
|
||||
contentType = contentType.trim();
|
||||
if (Constants.CT_JSON_PATCH.equals(contentType)) {
|
||||
return JSON_PATCH;
|
||||
} else if (Constants.CT_XML_PATCH.equals(contentType)) {
|
||||
return XML_PATCH;
|
||||
} else {
|
||||
throw new InvalidRequestException("Invalid Content-Type for PATCH operation: " + UrlUtil.sanitizeUrlPart(theContentType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,6 +97,8 @@ ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.successfulDeletes=Successfully delet
|
|||
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.invalidSearchParameter=Unknown search parameter "{0}". Value search parameters for this search are: {1}
|
||||
|
||||
ca.uhn.fhir.jpa.dao.TransactionProcessor.missingMandatoryResource=Missing required resource in Bundle.entry[{1}].resource for operation {0}
|
||||
ca.uhn.fhir.jpa.dao.TransactionProcessor.missingPatchContentType=Missing or invalid content type for PATCH operation
|
||||
ca.uhn.fhir.jpa.dao.TransactionProcessor.missingPatchBody=Unable to determine PATCH body from request
|
||||
|
||||
ca.uhn.fhir.jpa.searchparam.extractor.BaseSearchParamExtractor.externalReferenceNotAllowed=Resource contains external reference to URL "{0}" but this server is not configured to allow external references
|
||||
ca.uhn.fhir.jpa.searchparam.extractor.BaseSearchParamExtractor.failedToExtractPaths=Failed to extract values from resource using FHIRPath "{0}": {1}
|
||||
|
|
|
@ -37,10 +37,7 @@ import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
|||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.ParameterUtil;
|
||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||
|
@ -53,6 +50,7 @@ import ca.uhn.fhir.rest.server.method.BaseMethodBinding;
|
|||
import ca.uhn.fhir.rest.server.method.BaseResourceReturningMethodBinding;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import ca.uhn.fhir.util.*;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.http.NameValuePair;
|
||||
|
@ -755,9 +753,50 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
entriesToProcess.put(nextRespEntry, outcome.getEntity());
|
||||
break;
|
||||
}
|
||||
case "GET":
|
||||
default:
|
||||
case "PATCH": {
|
||||
// PATCH
|
||||
validateResourcePresent(res, order, verb);
|
||||
|
||||
String url = extractTransactionUrlOrThrowException(nextReqEntry, verb);
|
||||
UrlUtil.UrlParts parts = UrlUtil.parseUrl(url);
|
||||
|
||||
String matchUrl = toMatchUrl(nextReqEntry);
|
||||
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
|
||||
String patchBody = null;
|
||||
String contentType = null;
|
||||
|
||||
if (res instanceof IBaseBinary) {
|
||||
IBaseBinary binary = (IBaseBinary) res;
|
||||
if (binary.getContent() != null && binary.getContent().length > 0) {
|
||||
patchBody = new String(binary.getContent(), Charsets.UTF_8);
|
||||
}
|
||||
contentType = binary.getContentType();
|
||||
}
|
||||
|
||||
if (isBlank(patchBody)) {
|
||||
String msg = myContext.getLocalizer().getMessage(TransactionProcessor.class, "missingPatchBody");
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
if (isBlank(contentType)) {
|
||||
String msg = myContext.getLocalizer().getMessage(TransactionProcessor.class, "missingPatchContentType");
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
|
||||
ca.uhn.fhir.jpa.dao.IFhirResourceDao<? extends IBaseResource> dao = toDao(parts, verb, url);
|
||||
PatchTypeEnum patchType = PatchTypeEnum.forContentTypeOrThrowInvalidRequestException(contentType);
|
||||
IIdType patchId = myContext.getVersion().newIdType().setValue(parts.getResourceId());
|
||||
DaoMethodOutcome outcome = dao.patch(patchId, matchUrl, patchType, patchBody, theRequest);
|
||||
updatedEntities.add(outcome.getEntity());
|
||||
if (outcome.getResource() != null) {
|
||||
updatedResources.add(outcome.getResource());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "GET":
|
||||
break;
|
||||
default:
|
||||
throw new InvalidRequestException("Unable to handle verb in transaction: " + verb);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1051,6 +1090,7 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
* Process any DELETE interactions
|
||||
* Process any POST interactions
|
||||
* Process any PUT interactions
|
||||
* Process any PATCH interactions
|
||||
* Process any GET interactions
|
||||
*/
|
||||
//@formatter:off
|
||||
|
@ -1107,21 +1147,6 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
return o1 - o2;
|
||||
}
|
||||
|
||||
private String toMatchUrl(BUNDLEENTRY theEntry) {
|
||||
String verb = myVersionAdapter.getEntryRequestVerb(theEntry);
|
||||
if (verb.equals("POST")) {
|
||||
return myVersionAdapter.getEntryIfNoneExist(theEntry);
|
||||
}
|
||||
if (verb.equals("PUT") || verb.equals("DELETE")) {
|
||||
String url = extractTransactionUrlOrThrowException(theEntry, verb);
|
||||
UrlUtil.UrlParts parts = UrlUtil.parseUrl(url);
|
||||
if (isBlank(parts.getResourceId())) {
|
||||
return parts.getResourceType() + '?' + parts.getParams();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int toOrder(BUNDLEENTRY theO1) {
|
||||
int o1 = 0;
|
||||
if (myVersionAdapter.getEntryRequestVerb(theO1) != null) {
|
||||
|
@ -1135,9 +1160,12 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
case "PUT":
|
||||
o1 = 3;
|
||||
break;
|
||||
case "GET":
|
||||
case "PATCH":
|
||||
o1 = 4;
|
||||
break;
|
||||
case "GET":
|
||||
o1 = 5;
|
||||
break;
|
||||
default:
|
||||
o1 = 0;
|
||||
break;
|
||||
|
@ -1171,4 +1199,22 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
|
|||
return Integer.toString(theStatusCode) + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode));
|
||||
}
|
||||
|
||||
private String toMatchUrl(BUNDLEENTRY theEntry) {
|
||||
String verb = myVersionAdapter.getEntryRequestVerb(theEntry);
|
||||
if (verb.equals("POST")) {
|
||||
return myVersionAdapter.getEntryIfNoneExist(theEntry);
|
||||
}
|
||||
if (verb.equals("PATCH")) {
|
||||
return myVersionAdapter.getEntryRequestIfMatch(theEntry);
|
||||
}
|
||||
if (verb.equals("PUT") || verb.equals("DELETE")) {
|
||||
String url = extractTransactionUrlOrThrowException(theEntry, verb);
|
||||
UrlUtil.UrlParts parts = UrlUtil.parseUrl(url);
|
||||
if (isBlank(parts.getResourceId())) {
|
||||
return parts.getResourceType() + '?' + parts.getParams();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -130,9 +130,11 @@ public class JpaValidationSupportR4 implements IJpaValidationSupportR4, Applicat
|
|||
}
|
||||
} else if ("StructureDefinition".equals(resourceName)) {
|
||||
// Don't allow the core FHIR definitions to be overwritten
|
||||
String typeName = theUri.substring("http://hl7.org/fhir/StructureDefinition/".length());
|
||||
if (myR4Ctx.getElementDefinition(typeName) != null) {
|
||||
return null;
|
||||
if (theUri.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
||||
String typeName = theUri.substring("http://hl7.org/fhir/StructureDefinition/".length());
|
||||
if (myR4Ctx.getElementDefinition(typeName) != null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.setLoadSynchronousUpTo(1);
|
||||
|
|
|
@ -308,6 +308,9 @@ public class BinaryAccessProviderR4Test extends BaseResourceProviderR4Test {
|
|||
if (theSetData) {
|
||||
attachment.setData(SOME_BYTES_2);
|
||||
}
|
||||
|
||||
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(documentReference));
|
||||
|
||||
return ourClient.create().resource(documentReference).execute().getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package ca.uhn.fhir.jpa.provider.r4;
|
||||
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPatch;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.Media;
|
||||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -93,6 +93,48 @@ public class PatchProviderR4Test extends BaseResourceProviderR4Test {
|
|||
assertEquals(false, newPt.getActive());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPatchUsingJsonPatch_Transaction() throws Exception {
|
||||
String methodName = "testPatchUsingJsonPatch_Transaction";
|
||||
IIdType pid1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.setActive(true);
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("0");
|
||||
patient.addName().setFamily(methodName).addGiven("Joe");
|
||||
pid1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
String patchString = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
||||
Binary patch = new Binary();
|
||||
patch.setContentType(Constants.CT_JSON_PATCH);
|
||||
patch.setContent(patchString.getBytes(Charsets.UTF_8));
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setFullUrl(pid1.getValue())
|
||||
.setResource(patch)
|
||||
.getRequest().setUrl(pid1.getValue())
|
||||
.setMethod(Bundle.HTTPVerb.PATCH);
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase);
|
||||
String encodedRequest = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input);
|
||||
ourLog.info("Requet:\n{}", encodedRequest);
|
||||
post.setEntity(new StringEntity(encodedRequest, ContentType.parse(Constants.CT_FHIR_JSON_NEW+ Constants.CHARSET_UTF8_CTSUFFIX)));
|
||||
try (CloseableHttpResponse response = ourHttpClient.execute(post)) {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
assertThat(responseString, containsString("\"resourceType\":\"Bundle\""));
|
||||
}
|
||||
|
||||
Patient newPt = ourClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
||||
assertEquals("2", newPt.getIdElement().getVersionIdPart());
|
||||
assertEquals(false, newPt.getActive());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPatchUsingJsonPatch_Conditional_Success() throws Exception {
|
||||
String methodName = "testPatchUsingJsonPatch";
|
||||
|
@ -303,4 +345,158 @@ public class PatchProviderR4Test extends BaseResourceProviderR4Test {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPatchUsingXmlPatch_Transaction() throws Exception {
|
||||
String methodName = "testPatchUsingXmlPatch_Transaction";
|
||||
IIdType pid1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.setActive(true);
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("0");
|
||||
patient.addName().setFamily(methodName).addGiven("Joe");
|
||||
pid1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
String patchString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><diff xmlns:fhir=\"http://hl7.org/fhir\"><replace sel=\"fhir:Patient/fhir:active/@value\">false</replace></diff>";
|
||||
Binary patch = new Binary();
|
||||
patch.setContentType(Constants.CT_XML_PATCH);
|
||||
patch.setContent(patchString.getBytes(Charsets.UTF_8));
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setFullUrl(pid1.getValue())
|
||||
.setResource(patch)
|
||||
.getRequest().setUrl(pid1.getValue())
|
||||
.setMethod(Bundle.HTTPVerb.PATCH);
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase);
|
||||
post.setEntity(new StringEntity(myFhirCtx.newJsonParser().encodeResourceToString(input), ContentType.parse(Constants.CT_FHIR_JSON_NEW+ Constants.CHARSET_UTF8_CTSUFFIX)));
|
||||
try (CloseableHttpResponse response = ourHttpClient.execute(post)) {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
assertThat(responseString, containsString("\"resourceType\":\"Bundle\""));
|
||||
}
|
||||
|
||||
Patient newPt = ourClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
||||
assertEquals("2", newPt.getIdElement().getVersionIdPart());
|
||||
assertEquals(false, newPt.getActive());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testPatchInTransaction_MissingContentType() throws Exception {
|
||||
String methodName = "testPatchUsingJsonPatch_Transaction";
|
||||
IIdType pid1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.setActive(true);
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("0");
|
||||
patient.addName().setFamily(methodName).addGiven("Joe");
|
||||
pid1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
String patchString = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
||||
Binary patch = new Binary();
|
||||
patch.setContent(patchString.getBytes(Charsets.UTF_8));
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setFullUrl(pid1.getValue())
|
||||
.setResource(patch)
|
||||
.getRequest().setUrl(pid1.getValue())
|
||||
.setMethod(Bundle.HTTPVerb.PATCH);
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase);
|
||||
post.setEntity(new StringEntity(myFhirCtx.newJsonParser().encodeResourceToString(input), ContentType.parse(Constants.CT_FHIR_JSON_NEW+ Constants.CHARSET_UTF8_CTSUFFIX)));
|
||||
try (CloseableHttpResponse response = ourHttpClient.execute(post)) {
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
assertThat(responseString, containsString("Missing or invalid content type for PATCH operation"));
|
||||
}
|
||||
|
||||
Patient newPt = ourClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
||||
assertEquals("1", newPt.getIdElement().getVersionIdPart());
|
||||
assertEquals(true, newPt.getActive());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPatchInTransaction_MissingBody() throws Exception {
|
||||
String methodName = "testPatchUsingJsonPatch_Transaction";
|
||||
IIdType pid1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.setActive(true);
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("0");
|
||||
patient.addName().setFamily(methodName).addGiven("Joe");
|
||||
pid1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
String patchString = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
||||
Binary patch = new Binary();
|
||||
patch.setContentType(Constants.CT_JSON_PATCH);
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setFullUrl(pid1.getValue())
|
||||
.setResource(patch)
|
||||
.getRequest().setUrl(pid1.getValue())
|
||||
.setMethod(Bundle.HTTPVerb.PATCH);
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase);
|
||||
post.setEntity(new StringEntity(myFhirCtx.newJsonParser().encodeResourceToString(input), ContentType.parse(Constants.CT_FHIR_JSON_NEW+ Constants.CHARSET_UTF8_CTSUFFIX)));
|
||||
try (CloseableHttpResponse response = ourHttpClient.execute(post)) {
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
assertThat(responseString, containsString("Unable to determine PATCH body from request"));
|
||||
}
|
||||
|
||||
Patient newPt = ourClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
||||
assertEquals("1", newPt.getIdElement().getVersionIdPart());
|
||||
assertEquals(true, newPt.getActive());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPatchInTransaction_InvalidContentType() throws Exception {
|
||||
String methodName = "testPatchUsingJsonPatch_Transaction";
|
||||
IIdType pid1;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.setActive(true);
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("0");
|
||||
patient.addName().setFamily(methodName).addGiven("Joe");
|
||||
pid1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
String patchString = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
||||
Binary patch = new Binary();
|
||||
patch.setContentType(Constants.CT_FHIR_JSON_NEW);
|
||||
patch.setContent(patchString.getBytes(Charsets.UTF_8));
|
||||
|
||||
Bundle input = new Bundle();
|
||||
input.setType(Bundle.BundleType.TRANSACTION);
|
||||
input.addEntry()
|
||||
.setFullUrl(pid1.getValue())
|
||||
.setResource(patch)
|
||||
.getRequest().setUrl(pid1.getValue())
|
||||
.setMethod(Bundle.HTTPVerb.PATCH);
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase);
|
||||
post.setEntity(new StringEntity(myFhirCtx.newJsonParser().encodeResourceToString(input), ContentType.parse(Constants.CT_FHIR_JSON_NEW+ Constants.CHARSET_UTF8_CTSUFFIX)));
|
||||
try (CloseableHttpResponse response = ourHttpClient.execute(post)) {
|
||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
assertThat(responseString, containsString("Invalid Content-Type for PATCH operation: application/fhir+json"));
|
||||
}
|
||||
|
||||
Patient newPt = ourClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute();
|
||||
assertEquals("1", newPt.getIdElement().getVersionIdPart());
|
||||
assertEquals(true, newPt.getActive());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import ca.uhn.fhir.rest.client.api.IGenericClient;
|
|||
import ca.uhn.fhir.rest.client.api.IHttpRequest;
|
||||
import ca.uhn.fhir.rest.client.api.IHttpResponse;
|
||||
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
|
||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.gclient.StringClientParam;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
@ -3184,6 +3185,19 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
// }
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncounterWithReason() {
|
||||
Encounter enc = new Encounter();
|
||||
enc.addReasonCode()
|
||||
.addCoding().setSystem("http://myorg").setCode("hugs").setDisplay("Hugs for better wellness");
|
||||
enc.getPeriod().setStartElement(new DateTimeType("2012"));
|
||||
IIdType id = ourClient.create().resource(enc).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
enc = ourClient.read().resource(Encounter.class).withId(id).execute();
|
||||
assertEquals("hugs", enc.getReasonCodeFirstRep().getCodingFirstRep().getCode());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testTerminologyWithCompleteCs_SearchForConceptIn() throws Exception {
|
||||
|
||||
|
|
|
@ -45,19 +45,7 @@ class PatchTypeParameter implements IParameter {
|
|||
|
||||
public static PatchTypeEnum getTypeForRequestOrThrowInvalidRequestException(RequestDetails theRequest) {
|
||||
String contentTypeAll = defaultString(theRequest.getHeader(Constants.HEADER_CONTENT_TYPE));
|
||||
String contentType = contentTypeAll;
|
||||
int semiColonIdx = contentType.indexOf(';');
|
||||
if (semiColonIdx != -1) {
|
||||
contentType = contentTypeAll.substring(0, semiColonIdx);
|
||||
}
|
||||
contentType = contentType.trim();
|
||||
if (Constants.CT_JSON_PATCH.equals(contentType)) {
|
||||
return PatchTypeEnum.JSON_PATCH;
|
||||
} else if (Constants.CT_XML_PATCH.equals(contentType)) {
|
||||
return PatchTypeEnum.XML_PATCH;
|
||||
} else {
|
||||
throw new InvalidRequestException("Invalid Content-Type for PATCH operation: " + contentTypeAll);
|
||||
}
|
||||
return PatchTypeEnum.forContentTypeOrThrowInvalidRequestException(contentTypeAll);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -322,6 +322,11 @@
|
|||
words in MySQL. The database migrator tool has been updated to handle this
|
||||
change.
|
||||
</action>
|
||||
<action type="add">
|
||||
Support for PATCH operations performed within a transaction (using a Binary
|
||||
resource as the resource type in order to hold a JSONPatch or XMLPatch body)
|
||||
has been added to the JPA server.
|
||||
</action>
|
||||
</release>
|
||||
<release version="3.8.0" date="2019-05-30" description="Hippo">
|
||||
<action type="fix">
|
||||
|
|
Loading…
Reference in New Issue