From 42c8cd0e38281a74bbe1f8c025c9d4b066a9a7b6 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Sat, 18 Apr 2020 11:16:16 -0400 Subject: [PATCH] Add cascading delete to client (#1804) * Add cascading delete to client * Add changelog --- .../fhir/rest/api/DeleteCascadeModeEnum.java | 15 ++ .../uhn/fhir/rest/gclient/IDeleteTyped.java | 8 +- .../fhir/rest/client/impl/GenericClient.java | 27 ++- .../client/method/DeleteMethodBinding.java | 28 +-- .../method/HttpDeleteClientInvocation.java | 16 +- .../hapi/fhir/docs/GenericClientExample.java | 14 ++ .../1804-add-cascading-delete-to-client.yaml | 4 + .../hapi/fhir/docs/client/generic_client.md | 8 + .../fhir/rest/client/GenericClientR4Test.java | 209 +++++++++++++----- 9 files changed, 233 insertions(+), 96 deletions(-) create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/DeleteCascadeModeEnum.java create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/4_3_0/1804-add-cascading-delete-to-client.yaml diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/DeleteCascadeModeEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/DeleteCascadeModeEnum.java new file mode 100644 index 00000000000..0326ad124c4 --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/DeleteCascadeModeEnum.java @@ -0,0 +1,15 @@ +package ca.uhn.fhir.rest.api; + +/** + * Used by the client to indicate the cascade mode associated with a delete operation. + *

+ * Note that this is a HAPI FHIR specific feature, and may not work on other platforms. + *

+ */ +public enum DeleteCascadeModeEnum { + + NONE, + + DELETE + +} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/IDeleteTyped.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/IDeleteTyped.java index 049b1fef51c..fd8472a1aba 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/IDeleteTyped.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/IDeleteTyped.java @@ -20,10 +20,14 @@ package ca.uhn.fhir.rest.gclient; * #L% */ +import ca.uhn.fhir.rest.api.DeleteCascadeModeEnum; import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; public interface IDeleteTyped extends IClientExecutable { - - // nothing for now + + /** + * Delete cascade mode - Note that this is a HAPI FHIR specific feature and is not supported on all servers. + */ + IDeleteTyped cascade(DeleteCascadeModeEnum theDelete); } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/GenericClient.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/GenericClient.java index 00141705ceb..77b2be97c46 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/GenericClient.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/GenericClient.java @@ -610,20 +610,34 @@ public class GenericClient extends BaseClient implements IGenericClient { private IIdType myId; private String myResourceType; private String mySearchUrl; + private DeleteCascadeModeEnum myCascadeMode; @Override public IBaseOperationOutcome execute() { + + Map> additionalParams = new HashMap<>(); + if (myCascadeMode != null) { + switch (myCascadeMode) { + case DELETE: + addParam(getParamMap(), Constants.PARAMETER_CASCADE_DELETE, Constants.CASCADE_DELETE); + break; + default: + case NONE: + break; + } + } + HttpDeleteClientInvocation invocation; if (myId != null) { - invocation = DeleteMethodBinding.createDeleteInvocation(getFhirContext(), myId); + invocation = DeleteMethodBinding.createDeleteInvocation(getFhirContext(), myId, getParamMap()); } else if (myConditional) { invocation = DeleteMethodBinding.createDeleteInvocation(getFhirContext(), myResourceType, getParamMap()); } else { - invocation = DeleteMethodBinding.createDeleteInvocation(getFhirContext(), mySearchUrl); + invocation = DeleteMethodBinding.createDeleteInvocation(getFhirContext(), mySearchUrl, getParamMap()); } OperationOutcomeResponseHandler binding = new OperationOutcomeResponseHandler(); - Map> params = new HashMap>(); - return invoke(params, binding, invocation); + + return invoke(additionalParams, binding, invocation); } @Override @@ -687,6 +701,11 @@ public class GenericClient extends BaseClient implements IGenericClient { return this; } + @Override + public IDeleteTyped cascade(DeleteCascadeModeEnum theDelete) { + myCascadeMode = theDelete; + return this; + } } @SuppressWarnings({"rawtypes", "unchecked"}) diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DeleteMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DeleteMethodBinding.java index 00fb4112dd0..46391030628 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DeleteMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DeleteMethodBinding.java @@ -65,18 +65,18 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBindingWithRe @Override public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException { - IIdType idDt = (IIdType) theArgs[getIdParameterIndex()]; - if (idDt == null) { + IIdType id = (IIdType) theArgs[getIdParameterIndex()]; + if (id == null) { throw new NullPointerException("ID can not be null"); } - if (idDt.hasResourceType() == false) { - idDt = idDt.withResourceType(getResourceName()); - } else if (getResourceName().equals(idDt.getResourceType()) == false) { - throw new InvalidRequestException("ID parameter has the wrong resource type, expected '" + getResourceName() + "', found: " + idDt.getResourceType()); + if (id.hasResourceType() == false) { + id = id.withResourceType(getResourceName()); + } else if (getResourceName().equals(id.getResourceType()) == false) { + throw new InvalidRequestException("ID parameter has the wrong resource type, expected '" + getResourceName() + "', found: " + id.getResourceType()); } - HttpDeleteClientInvocation retVal = createDeleteInvocation(getContext(), idDt); + HttpDeleteClientInvocation retVal = createDeleteInvocation(getContext(), id, Collections.emptyMap()); for (int idx = 0; idx < theArgs.length; idx++) { IParameter nextParam = getParameters().get(idx); @@ -86,9 +86,8 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBindingWithRe return retVal; } - public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, IIdType theId) { - HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theContext, theId); - return retVal; + public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, IIdType theId, Map> theAdditionalParams) { + return new HttpDeleteClientInvocation(theContext, theId, theAdditionalParams); } @@ -97,13 +96,8 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBindingWithRe return null; } - public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, String theSearchUrl) { - HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theContext, theSearchUrl); - return retVal; - } - - public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, String theResourceType, Map> theParams) { - return new HttpDeleteClientInvocation(theContext, theResourceType, theParams); + public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, String theSearchUrl, Map> theParams) { + return new HttpDeleteClientInvocation(theContext, theSearchUrl, theParams); } } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpDeleteClientInvocation.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpDeleteClientInvocation.java index 911856bdb9b..1d5c49e361d 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpDeleteClientInvocation.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpDeleteClientInvocation.java @@ -36,19 +36,15 @@ public class HttpDeleteClientInvocation extends BaseHttpClientInvocation { private String myUrlPath; private Map> myParams; - public HttpDeleteClientInvocation(FhirContext theContext, IIdType theId) { + public HttpDeleteClientInvocation(FhirContext theContext, IIdType theId, Map> theAdditionalParams) { super(theContext); myUrlPath = theId.toUnqualifiedVersionless().getValue(); + myParams = theAdditionalParams; } - public HttpDeleteClientInvocation(FhirContext theContext, String theSearchUrl) { + public HttpDeleteClientInvocation(FhirContext theContext, String theSearchUrl, Map> theParams) { super(theContext); myUrlPath = theSearchUrl; - } - - public HttpDeleteClientInvocation(FhirContext theContext, String theResourceType, Map> theParams) { - super(theContext); - myUrlPath = theResourceType; myParams = theParams; } @@ -67,10 +63,4 @@ public class HttpDeleteClientInvocation extends BaseHttpClientInvocation { return createHttpRequest(b.toString(), theEncoding, RequestTypeEnum.DELETE); } - @Override - protected IHttpRequest createHttpRequest(String theUrl, EncodingEnum theEncoding, RequestTypeEnum theRequestType) { - // TODO Auto-generated method stub - return super.createHttpRequest(theUrl, theEncoding, theRequestType); - } - } diff --git a/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/GenericClientExample.java b/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/GenericClientExample.java index 29b7a8dba03..1e7154daeb3 100644 --- a/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/GenericClientExample.java +++ b/hapi-fhir-docs/src/main/java/ca/uhn/hapi/fhir/docs/GenericClientExample.java @@ -23,6 +23,7 @@ package ca.uhn.hapi.fhir.docs; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.PerformanceOptionsEnum; import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.rest.api.DeleteCascadeModeEnum; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.SearchStyleEnum; import ca.uhn.fhir.rest.api.SummaryEnum; @@ -262,6 +263,19 @@ public class GenericClientExample { .execute(); // END SNIPPET: deleteConditional } + { + // START SNIPPET: deleteCascade + client.delete() + .resourceById(new IdType("Patient/123")) + .cascade(DeleteCascadeModeEnum.DELETE) + .execute(); + + client.delete() + .resourceConditionalByType("Patient") + .where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001")) + .execute(); + // END SNIPPET: deleteCascade + } { // START SNIPPET: search Bundle response = client.search() diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/4_3_0/1804-add-cascading-delete-to-client.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/4_3_0/1804-add-cascading-delete-to-client.yaml new file mode 100644 index 00000000000..9e07670bf5f --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/4_3_0/1804-add-cascading-delete-to-client.yaml @@ -0,0 +1,4 @@ +--- +type: add +issue: 1804 +title: Support for HAPI FHIR cascading deletes has been added to the Generic Client. diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/client/generic_client.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/client/generic_client.md index 59e7badb69c..5cb269efb1d 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/client/generic_client.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/client/generic_client.md @@ -181,6 +181,14 @@ Conditional deletions are also possible, which is a form where instead of deleti {{snippet:classpath:/ca/uhn/hapi/fhir/docs/GenericClientExample.java|deleteConditional}} ``` +## Cascading Delete + +The following snippet shows now to request a cascading delete. Note that this is a HAPI FHIR specific feature and is not supported on all servers. + +```java +{{snippet:classpath:/ca/uhn/hapi/fhir/docs/GenericClientExample.java|deleteCascade}} +``` + # Update - Instance Updating a resource is similar to creating one, except that an ID must be supplied since you are updating a previously existing resource instance. diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientR4Test.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientR4Test.java index 05b3315190b..dae176eeb78 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientR4Test.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientR4Test.java @@ -9,8 +9,13 @@ import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.parser.CustomTypeR4Test; import ca.uhn.fhir.parser.CustomTypeR4Test.MyCustomPatient; import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.api.DeleteCascadeModeEnum; import ca.uhn.fhir.rest.api.Constants; -import ca.uhn.fhir.rest.api.*; +import ca.uhn.fhir.rest.api.EncodingEnum; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.api.PreferReturnEnum; +import ca.uhn.fhir.rest.api.SortOrderEnum; +import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException; @@ -39,6 +44,7 @@ import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicStatusLine; +import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.r4.model.*; @@ -56,13 +62,24 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.startsWith; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -93,7 +110,7 @@ public class GenericClientR4Test { } private String extractBodyAsString(ArgumentCaptor capt) throws IOException { - String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent(), "UTF-8"); + String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent(), StandardCharsets.UTF_8); return body; } @@ -107,7 +124,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8); } }); return capt; @@ -124,7 +141,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8); } }); @@ -183,7 +200,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -193,7 +210,7 @@ public class GenericClientR4Test { pt.getText().setDivAsString("A PATIENT"); Binary bin = new Binary(); - bin.setContent(ourCtx.newJsonParser().encodeResourceToString(pt).getBytes("UTF-8")); + bin.setContent(ourCtx.newJsonParser().encodeResourceToString(pt).getBytes(StandardCharsets.UTF_8)); bin.setContentType(Constants.CT_FHIR_JSON); client.create().resource(bin).execute(); @@ -207,7 +224,7 @@ public class GenericClientR4Test { Binary output = ourCtx.newJsonParser().parseResource(Binary.class, extractBodyAsString(capt)); assertEquals(Constants.CT_FHIR_JSON, output.getContentType()); - Patient outputPt = (Patient) ourCtx.newJsonParser().parseResource(new String(output.getContent(), "UTF-8")); + Patient outputPt = (Patient) ourCtx.newJsonParser().parseResource(new String(output.getContent(), StandardCharsets.UTF_8)); assertEquals("
A PATIENT
", outputPt.getText().getDivAsString()); } @@ -226,7 +243,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -290,7 +307,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -330,9 +347,9 @@ public class GenericClientR4Test { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { if (myAnswerCount++ == 0) { - return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), StandardCharsets.UTF_8); } else { - return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), StandardCharsets.UTF_8); } } }); @@ -379,7 +396,7 @@ public class GenericClientR4Test { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { myAnswerCount++; - return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), StandardCharsets.UTF_8); } }); @@ -400,6 +417,78 @@ public class GenericClientR4Test { assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString()); } + @Test + public void testDeleteCascade() throws Exception { + final IParser p = ourCtx.newXmlParser(); + + OperationOutcome oo = new OperationOutcome(); + oo.getText().setDivAsString("FINAL VALUE"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getAllHeaders()).thenAnswer(new Answer() { + @Override + public Header[] answer(InvocationOnMock theInvocation) { + return new Header[]{new BasicHeader(Constants.HEADER_LOCATION, "http://foo.com/base/Patient/222/_history/3")}; + } + }); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { + @Override + public ReaderInputStream answer(InvocationOnMock theInvocation) { + myAnswerCount++; + return new ReaderInputStream(new StringReader(p.encodeResourceToString(oo)), StandardCharsets.UTF_8); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + IBaseOperationOutcome outcome; + + // Regular delete + outcome = client + .delete() + .resourceById(new IdType("Patient/222")) + .execute(); + assertNotNull(outcome); + assertEquals(1, capt.getAllValues().size()); + assertEquals("http://example.com/fhir/Patient/222", capt.getAllValues().get(myAnswerCount - 1).getURI().toASCIIString()); + assertEquals("DELETE", capt.getAllValues().get(myAnswerCount - 1).getMethod()); + + // NONE Cascading delete + outcome = client + .delete() + .resourceById(new IdType("Patient/222")) + .cascade(DeleteCascadeModeEnum.NONE) + .execute(); + assertNotNull(outcome); + assertEquals(2, capt.getAllValues().size()); + assertEquals("http://example.com/fhir/Patient/222", capt.getAllValues().get(myAnswerCount - 1).getURI().toASCIIString()); + assertEquals("DELETE", capt.getAllValues().get(myAnswerCount - 1).getMethod()); + + // DELETE Cascading delete + outcome = client + .delete() + .resourceById(new IdType("Patient/222")) + .cascade(DeleteCascadeModeEnum.DELETE) + .execute(); + assertNotNull(outcome); + assertEquals(myAnswerCount, capt.getAllValues().size()); + assertEquals("http://example.com/fhir/Patient/222?" + Constants.PARAMETER_CASCADE_DELETE + "=" + Constants.CASCADE_DELETE, capt.getAllValues().get(myAnswerCount - 1).getURI().toASCIIString()); + assertEquals("DELETE", capt.getAllValues().get(myAnswerCount - 1).getMethod()); + + // DELETE Cascading delete on search URL + outcome = client + .delete() + .resourceConditionalByUrl("Patient?identifier=sys|val") + .cascade(DeleteCascadeModeEnum.DELETE) + .execute(); + assertNotNull(outcome); + assertEquals(myAnswerCount, capt.getAllValues().size()); + assertEquals("http://example.com/fhir/Patient?identifier=sys%7Cval&" + Constants.PARAMETER_CASCADE_DELETE + "=" + Constants.CASCADE_DELETE, capt.getAllValues().get(myAnswerCount - 1).getURI().toASCIIString()); + assertEquals("DELETE", capt.getAllValues().get(myAnswerCount - 1).getMethod()); + } + @Test public void testExplicitCustomTypeHistoryType() throws Exception { final String respString = CustomTypeR4Test.createBundle(CustomTypeR4Test.createResource(false)); @@ -410,7 +499,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -437,7 +526,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -482,7 +571,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -522,7 +611,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -567,7 +656,7 @@ public class GenericClientR4Test { respString = p.encodeResourceToString(conf); } myCount++; - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -615,7 +704,7 @@ public class GenericClientR4Test { respString = p.encodeResourceToString(conf); } myAnswerCount++; - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -655,7 +744,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); when(myHttpResponse.getEntity().getContent()).thenAnswer(t -> { IParser p = ourCtx.newXmlParser(); - return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), StandardCharsets.UTF_8); }); IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); @@ -816,7 +905,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -860,7 +949,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -904,7 +993,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -947,7 +1036,7 @@ public class GenericClientR4Test { when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", "text/html")); - when(myHttpResponse.getEntity().getContent()).thenAnswer(t -> new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"))); + when(myHttpResponse.getEntity().getContent()).thenAnswer(t -> new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8)); when(myHttpResponse.getAllHeaders()).thenReturn(new Header[]{ new BasicHeader("content-type", "text/html") }); @@ -982,7 +1071,7 @@ public class GenericClientR4Test { Parameters inputParams = new Parameters(); inputParams.addParameter().setName("name").setValue(new BooleanType(true)); - final byte[] respBytes = new byte[]{0,1,2,3,4,5,6,7,8,9,100}; + final byte[] respBytes = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100}; ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); @@ -1027,7 +1116,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -1081,7 +1170,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -1120,7 +1209,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -1159,7 +1248,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -1197,7 +1286,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -1235,7 +1324,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -1273,7 +1362,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -1320,7 +1409,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(encoded), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(encoded), StandardCharsets.UTF_8); } }); @@ -1365,7 +1454,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(encoded), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(encoded), StandardCharsets.UTF_8); } }); @@ -1394,7 +1483,7 @@ public class GenericClientR4Test { when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8)); IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); @@ -1423,7 +1512,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -1454,7 +1543,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -1502,7 +1591,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8); } }); @@ -1629,7 +1718,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8); } }); @@ -1739,7 +1828,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8); } }); @@ -1831,7 +1920,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8); } }); @@ -1867,12 +1956,12 @@ public class GenericClientR4Test { when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8)); IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); HashMap> params = new HashMap>(); - params.put("foo", Arrays.asList((IQueryParameterType) new DateParam("2001"))); + params.put("foo", Arrays.asList(new DateParam("2001"))); Bundle response = client .search() .forResource(Patient.class) @@ -1915,7 +2004,7 @@ public class GenericClientR4Test { when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8)); // httpResponse = new BasicHttpResponse(statusline, catalog, locale) when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); @@ -1940,7 +2029,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).then(new Answer() { @Override public InputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(msg), StandardCharsets.UTF_8); } }); @@ -1977,7 +2066,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); when(myHttpResponse.getEntity().getContent()).thenAnswer(t -> { IParser p = ourCtx.newXmlParser(); - return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), StandardCharsets.UTF_8); }); IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); @@ -2015,7 +2104,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -2068,7 +2157,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); when(myHttpResponse.getEntity().getContent()).thenAnswer(t -> { IParser p = ourCtx.newXmlParser(); - return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), StandardCharsets.UTF_8); }); IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); @@ -2147,7 +2236,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -2194,9 +2283,9 @@ public class GenericClientR4Test { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { if (myAnswerCount++ == 0) { - return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), StandardCharsets.UTF_8); } else { - return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), StandardCharsets.UTF_8); } } }); @@ -2242,7 +2331,7 @@ public class GenericClientR4Test { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { myAnswerCount++; - return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp1)), StandardCharsets.UTF_8); } }); @@ -2279,7 +2368,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -2316,7 +2405,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -2337,7 +2426,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -2372,7 +2461,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(p.encodeResourceToString(resp0)), StandardCharsets.UTF_8); } }); @@ -2405,7 +2494,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } }); @@ -2443,7 +2532,7 @@ public class GenericClientR4Test { when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer() { @Override public ReaderInputStream answer(InvocationOnMock theInvocation) { - return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8")); + return new ReaderInputStream(new StringReader(respString), StandardCharsets.UTF_8); } });