Get patch working (#1449)

This commit is contained in:
James Agnew 2019-08-27 05:42:15 -04:00 committed by GitHub
parent e5c8ffdc20
commit 70d0a8aa8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 0 deletions

View File

@ -21,19 +21,24 @@ package ca.uhn.fhir.jpa.dao.dstu3;
*/
import ca.uhn.fhir.jpa.dao.TransactionProcessor;
import ca.uhn.fhir.rest.api.PatchTypeEnum;
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 org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.OperationOutcome;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.dstu3.model.codesystems.IssueType;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import java.util.Date;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.isBlank;
public class TransactionProcessorVersionAdapterDstu3 implements TransactionProcessor.ITransactionProcessorVersionAdapter<Bundle, Bundle.BundleEntryComponent> {
@Override
public void setResponseStatus(Bundle.BundleEntryComponent theBundleEntry, String theStatus) {
@ -106,6 +111,22 @@ public class TransactionProcessorVersionAdapterDstu3 implements TransactionProce
if (value != null) {
retVal = value.toCode();
}
/*
* This is a workaround for the fact that PATCH isn't a valid constant for
* DSTU3 Bundle.entry.request.method (it was added in R4)
*/
if (isBlank(retVal)) {
if (theEntry.getResource() instanceof IBaseBinary) {
String contentType = ((IBaseBinary) theEntry.getResource()).getContentType();
try {
PatchTypeEnum.forContentTypeOrThrowInvalidRequestException(contentType);
retVal = "PATCH";
} catch (InvalidRequestException e) {
// ignore
}
}
}
return retVal;
}

View File

@ -4,11 +4,19 @@ import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
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.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;
@ -180,6 +188,50 @@ public class SystemProviderTransactionSearchDstu3Test extends BaseJpaDstu3Test {
assertThat(actualIds, contains(ids.subList(5, 10).toArray(new String[0])));
}
@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(ca.uhn.fhir.rest.api.Constants.CT_JSON_PATCH);
patch.setContent(patchString.getBytes(Charsets.UTF_8));
// Note that we don't set the type
Bundle input = new Bundle();
input.setType(Bundle.BundleType.TRANSACTION);
input.addEntry()
.setFullUrl(pid1.getValue())
.setResource(patch)
.getRequest().setUrl(pid1.getValue());
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(ca.uhn.fhir.rest.api.Constants.CT_FHIR_JSON_NEW+ Constants.CHARSET_UTF8_CTSUFFIX)));
try (CloseableHttpResponse response = ourHttpClient.execute(post)) {
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(responseString);
assertEquals(200, response.getStatusLine().getStatusCode());
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 testTransactionWithGetHardLimitLargeSynchronous() {
List<String> ids = create20Patients();

View File

@ -73,6 +73,12 @@
The informational message returned in an OperationOutcome when a delete failed due to cascades not being enabled
contained an incorrect example. This has been corrected.
</action>
<action type="add">
It is now possible to submit a PATCH request as a part of a FHIR transaction in DSTU3 (previously this
was only supported in R4+). This is not officially part of the DSTU3 spec, but it can now be performed by
leaving the Bundle.entry.request.method blank in DSTU3 transactions and setting the request payload
as a Binary resource containing a valid patch.
</action>
<action type="change" issue="1366">
The HAPI FHIR CLI server now uses H2 as its database platform instead of Derby.
Note that this means that data in any existing installations will need to be