diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GenericClient.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GenericClient.java index 47dc4d61786..110036a116a 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GenericClient.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GenericClient.java @@ -26,9 +26,12 @@ import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -1900,7 +1903,7 @@ public class GenericClient extends BaseClient implements IGenericClient { private List myInclude = new ArrayList(); private DateRangeParam myLastUpdated; private Integer myParamLimit; - private List myProfile = new ArrayList(); + private List> myProfiles = new ArrayList>(); private String myResourceId; private String myResourceName; private Class myResourceType; @@ -1981,8 +1984,15 @@ public class GenericClient extends BaseClient implements IGenericClient { addParam(params, Constants.PARAM_SECURITY, next.getValueAsQueryToken(myContext)); } - for (String next : myProfile) { - addParam(params, Constants.PARAM_PROFILE, next); + for (Collection profileUris : myProfiles) { + StringBuilder builder = new StringBuilder(); + for (Iterator profileItr = profileUris.iterator(); profileItr.hasNext(); ) { + builder.append(profileItr.next()); + if (profileItr.hasNext()) { + builder.append(','); + } + } + addParam(params, Constants.PARAM_PROFILE, builder.toString()); } for (Include next : myInclude) { @@ -2144,7 +2154,14 @@ public class GenericClient extends BaseClient implements IGenericClient { @Override public IQuery withProfile(String theProfileUri) { Validate.notBlank(theProfileUri, "theProfileUri must not be null or empty"); - myProfile.add(theProfileUri); + myProfiles.add(Collections.singletonList(theProfileUri)); + return this; + } + + @Override + public IQuery withAnyProfile(Collection theProfileUris) { + Validate.notEmpty(theProfileUris, "theProfileUris must not be null or empty"); + myProfiles.add(theProfileUris); return this; } @@ -2365,6 +2382,7 @@ public class GenericClient extends BaseClient implements IGenericClient { return this; } + // TODO: This is not longer used.. Deprecate it or just remove it? @Override public IPatchTyped conditionalByUrl(String theSearchUrl) { mySearchUrl = validateAndEscapeConditionalUrl(theSearchUrl); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/DateClientParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/DateClientParam.java index 2a893abd9e2..8c490d56c5d 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/DateClientParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/DateClientParam.java @@ -27,6 +27,7 @@ import java.util.Date; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.primitive.DateTimeDt; +import ca.uhn.fhir.rest.gclient.DateClientParam.IDateSpecifier; import ca.uhn.fhir.rest.param.ParamPrefixEnum; /** @@ -65,10 +66,11 @@ public class DateClientParam extends BaseClientParam implements IParam { return new DateWithPrefix(ParamPrefixEnum.EQUAL); } - private class Criterion implements ICriterion, ICriterionInternal { + private class Criterion implements IDateCriterion, ICriterionInternal { private String myValue; private ParamPrefixEnum myPrefix; + private Criterion orCriterion; public Criterion(ParamPrefixEnum thePrefix, String theValue) { myPrefix = thePrefix; @@ -83,7 +85,16 @@ public class DateClientParam extends BaseClientParam implements IParam { @Override public String getParameterValue(FhirContext theContext) { StringBuilder b = new StringBuilder(); + if (orCriterion != null) { + String orValue = orCriterion.getParameterValue(theContext); + if (isNotBlank(orValue)) { + b.append(orValue); + } + } if (isNotBlank(myValue)) { + if (b.length() > 0) { + b.append(','); + } if (myPrefix != null && myPrefix != ParamPrefixEnum.EQUAL) { b.append(myPrefix.getValueForContext(theContext)); } @@ -92,69 +103,115 @@ public class DateClientParam extends BaseClientParam implements IParam { return b.toString(); } + @Override + public IDateSpecifier orAfter() { + return new DateWithPrefix(ParamPrefixEnum.GREATERTHAN, this); + } + + @Override + public IDateSpecifier orAfterOrEquals() { + return new DateWithPrefix(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, this); + } + + @Override + public IDateSpecifier orBefore() { + return new DateWithPrefix(ParamPrefixEnum.LESSTHAN, this); + } + + @Override + public IDateSpecifier orBeforeOrEquals() { + return new DateWithPrefix(ParamPrefixEnum.LESSTHAN_OR_EQUALS, this); + } + + @Override + public IDateSpecifier orExactly() { + return new DateWithPrefix(ParamPrefixEnum.EQUAL, this); + } + } private class DateWithPrefix implements IDateSpecifier { private ParamPrefixEnum myPrefix; + private Criterion previous = null; + public DateWithPrefix(ParamPrefixEnum thePrefix, Criterion previous) { + myPrefix = thePrefix; + this.previous = previous; + } + public DateWithPrefix(ParamPrefixEnum thePrefix) { myPrefix = thePrefix; } @Override - public ICriterion day(Date theValue) { + public IDateCriterion day(Date theValue) { DateTimeDt dt = new DateTimeDt(theValue); dt.setPrecision(TemporalPrecisionEnum.DAY); - String valueAsString = dt.getValueAsString(); - return new Criterion(myPrefix, valueAsString); + return constructCriterion(dt); } @Override - public ICriterion day(String theValue) { + public IDateCriterion day(String theValue) { DateTimeDt dt = new DateTimeDt(theValue); dt.setPrecision(TemporalPrecisionEnum.DAY); - String valueAsString = dt.getValueAsString(); - return new Criterion(myPrefix , valueAsString); + return constructCriterion(dt); } @Override - public ICriterion now() { + public IDateCriterion now() { DateTimeDt dt = DateTimeDt.withCurrentTime(); dt.setPrecision(TemporalPrecisionEnum.SECOND); - String valueAsString = dt.getValueAsString(); - return new Criterion(myPrefix , valueAsString); + return constructCriterion(dt); } @Override - public ICriterion second(Date theValue) { + public IDateCriterion second(Date theValue) { DateTimeDt dt = new DateTimeDt(theValue); dt.setPrecision(TemporalPrecisionEnum.SECOND); - String valueAsString = dt.getValueAsString(); - return new Criterion(myPrefix , valueAsString); + return constructCriterion(dt); } @Override - public ICriterion second(String theValue) { + public IDateCriterion second(String theValue) { DateTimeDt dt = new DateTimeDt(theValue); dt.setPrecision(TemporalPrecisionEnum.SECOND); - String valueAsString = dt.getValueAsString(); - return new Criterion(myPrefix , valueAsString); + return constructCriterion(dt); + } + + private IDateCriterion constructCriterion(DateTimeDt dt) { + String valueAsString = dt.getValueAsString(); + Criterion criterion = new Criterion(myPrefix, valueAsString); + if (previous != null) { + criterion.orCriterion = previous; + } + return criterion; } - } public interface IDateSpecifier { - ICriterion day(Date theValue); + IDateCriterion day(Date theValue); - ICriterion day(String theValue); + IDateCriterion day(String theValue); - ICriterion now(); + IDateCriterion now(); - ICriterion second(Date theValue); + IDateCriterion second(Date theValue); - ICriterion second(String theValue); + IDateCriterion second(String theValue); } + + public interface IDateCriterion extends ICriterion { + IDateSpecifier orAfter(); + + IDateSpecifier orAfterOrEquals(); + + IDateSpecifier orBefore(); + + IDateSpecifier orBeforeOrEquals(); + + IDateSpecifier orExactly(); + } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/IQuery.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/IQuery.java index 3ebcdc2e340..820888b7d52 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/IQuery.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/IQuery.java @@ -1,5 +1,7 @@ package ca.uhn.fhir.rest.gclient; +import java.util.Collection; + /* * #%L * HAPI FHIR - Core Library @@ -81,6 +83,13 @@ public interface IQuery extends IClientExecutable, T>, IBaseQuery withProfile(String theProfileUri); + /** + * Matches any of the profiles given as argument. This would result in an OR search for resources matching one or more profiles. + * To do an AND search, make multiple calls to {@link #withProfile(String)}. + * @param theProfileUris The URIs of a given profile to search for resources which match. + */ + IQuery withAnyProfile(Collection theProfileUris); + /** * Forces the query to perform the search using the given method (allowable methods are described in the * FHIR Search Specification) diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java index f78fdc1b821..0f67ed673e8 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java @@ -26,6 +26,7 @@ import java.net.Socket; import java.net.SocketTimeoutException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collections; import java.util.Arrays; import java.util.Date; import java.util.HashSet; @@ -1641,7 +1642,56 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test { } assertEquals("Expects to retrieve the 2 patients which reference the two different organizations", expectedIds, actualIds); } - + + @Test + public void testForResourcesWithProfile() { + Organization o1 = new Organization(); + o1.setName("testSearchByResourceChainName01"); + o1.getMeta().addProfile("http://profile1").addProfile("http://profile2"); + IdDt o1id = (IdDt) ourClient.create().resource(o1).execute().getId().toUnqualifiedVersionless(); + Organization o2 = new Organization(); + o2.setName("testSearchByResourceChainName02"); + o2.getMeta().addProfile("http://profile1").addProfile("http://profile3"); + IdDt o2id = (IdDt) ourClient.create().resource(o2).execute().getId().toUnqualifiedVersionless(); + //@formatter:off + Bundle actual = ourClient.search() + .forResource(Organization.class) + .withProfile("http://profile1") + .withProfile("http://profileX") + .encodedJson().prettyPrint().execute(); + //@formatter:on + assertEquals("nothing matches profile x", Collections.emptyList(), actual.getEntries()); + //@formatter:off + actual = ourClient.search() + .forResource(Organization.class) + .withProfile("http://profile1") + .withProfile("http://profile2") + .encodedJson().prettyPrint().execute(); + //@formatter:on + Set expectedIds = new HashSet(); + expectedIds.add(o1id.getIdPart()); + Set actualIds = new HashSet(); + for (BundleEntry ele : actual.getEntries()) { + actualIds.add(ele.getResource().getId().getIdPart()); + } + assertEquals("Expects to retrieve the 1 orgination matching on Org1's profiles", expectedIds, actualIds); + //@formatter:off + actual = ourClient.search() + .forResource(Organization.class) + .withProfile("http://profile1") + .withAnyProfile(Arrays.asList("http://profile3", "http://profile2")) + .encodedJson().prettyPrint().execute(); + //@formatter:on + expectedIds = new HashSet(); + expectedIds.add(o1id.getIdPart()); + expectedIds.add(o2id.getIdPart()); + actualIds = new HashSet(); + for (BundleEntry ele : actual.getEntries()) { + actualIds.add(ele.getResource().getId().getIdPart()); + } + assertEquals("Expects to retrieve the 2 orginations, since we match on (the common profile AND (Org1's second profile OR org2's second profile))", expectedIds, actualIds); + } + @Test public void testSearchLastUpdatedParamRp() throws InterruptedException { String methodName = "testSearchLastUpdatedParamRp"; diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/client/GenericClientTest.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/client/GenericClientTest.java index 29c4bccc48d..6c3d2207ca8 100644 --- a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/client/GenericClientTest.java +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/client/GenericClientTest.java @@ -1,1731 +1,1743 @@ -package ca.uhn.fhir.rest.client; - -import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.net.URLEncoder; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.input.ReaderInputStream; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.Header; -import org.apache.http.HttpResponse; -import org.apache.http.ProtocolVersion; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; -import org.apache.http.client.methods.HttpPost; -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.hamcrest.Matchers; -import org.hamcrest.core.StringContains; -import org.hl7.fhir.instance.model.api.IBaseResource; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.model.api.Bundle; -import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; -import ca.uhn.fhir.model.api.Tag; -import ca.uhn.fhir.model.api.TagList; -import ca.uhn.fhir.model.dstu.resource.Encounter; -import ca.uhn.fhir.model.dstu.resource.Observation; -import ca.uhn.fhir.model.dstu.resource.OperationOutcome; -import ca.uhn.fhir.model.dstu.resource.Organization; -import ca.uhn.fhir.model.dstu.resource.Patient; -import ca.uhn.fhir.model.dstu.resource.Provenance; -import ca.uhn.fhir.model.primitive.IdDt; -import ca.uhn.fhir.model.primitive.InstantDt; -import ca.uhn.fhir.model.primitive.UriDt; -import ca.uhn.fhir.rest.api.MethodOutcome; -import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException; -import ca.uhn.fhir.rest.method.SearchStyleEnum; -import ca.uhn.fhir.rest.server.Constants; -import ca.uhn.fhir.rest.server.EncodingEnum; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.util.TestUtil; -import ca.uhn.fhir.util.UrlUtil; - -public class GenericClientTest { - - private static FhirContext ourCtx; - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(GenericClientTest.class); - private HttpClient myHttpClient; - - private HttpResponse myHttpResponse; - - @Before - public void before() { - - myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs()); - ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient); - ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); - - myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs()); - - System.setProperty(BaseClient.HAPI_CLIENT_KEEPRESPONSES, "true"); - } - - private String extractBody(ArgumentCaptor capt, int count) throws IOException { - String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(count)).getEntity().getContent(), "UTF-8"); - return body; - } - - @Test - public void testInvalidCalls() { - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - try { - client.meta(); - fail(); - } catch (IllegalStateException e) { - assertEquals("Can not call $meta operations on a DSTU1 client", e.getMessage()); - } - try { - client.operation(); - fail(); - } catch (IllegalStateException e) { - assertEquals("Operations are only supported in FHIR DSTU2 and later. This client was created using a context configured for DSTU1", e.getMessage()); - } - } - - private String getPatientFeedWithOneResult() { - //@formatter:off - String msg = "\n" + - "\n" + - "<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" + - "<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" + - "<author>\n" + - "<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" + - "</author>\n" + - "<entry>\n" + - "<content type=\"text/xml\">" - + "<Patient xmlns=\"http://hl7.org/fhir\">" - + "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>" - + "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>" - + "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>" - + "<name><family value=\"Kramer\" /><given value=\"Doe\" /></name>" - + "<telecom><system value=\"phone\" /><value value=\"555-555-2004\" /><use value=\"work\" /></telecom>" - + "<gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\" /><code value=\"M\" /></coding></gender>" - + "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />" - + "</Patient>" - + "</content>\n" - + " </entry>\n" - + "</feed>"; - //@formatter:on - return msg; - } - - private String getResourceResult() { - //@formatter:off - String msg = - "<Patient xmlns=\"http://hl7.org/fhir\">" - + "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>" - + "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>" - + "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>" - + "<name><family value=\"Kramer\" /><given value=\"Doe\" /></name>" - + "<telecom><system value=\"phone\" /><value value=\"555-555-2004\" /><use value=\"work\" /></telecom>" - + "<gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\" /><code value=\"M\" /></coding></gender>" - + "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />" - + "</Patient>"; - //@formatter:on - return msg; - } - - @Test - public void testCreatePopulatesIsCreated() throws Exception { - - Patient p1 = new Patient(); - p1.addIdentifier("foo:bar", "12345"); - p1.addName().addFamily("Smith").addGiven("John"); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); - 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(""), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); - MethodOutcome resp = client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute(); - assertTrue(resp.getCreated()); - - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); - resp = client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute(); - assertNull(resp.getCreated()); - - ourLog.info("lastRequest: {}", ((GenericClient)client).getLastRequest()); - ourLog.info("lastResponse: {}", ((GenericClient)client).getLastResponse()); - ourLog.info("lastResponseBody: {}", ((GenericClient)client).getLastResponseBody()); - } - - @Test - public void testCreateWithStringAutoDetectsEncoding() throws Exception { - - Patient p1 = new Patient(); - p1.addIdentifier("foo:bar", "12345"); - p1.addName().addFamily("Smith").addGiven("John"); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); - when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); - 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(""), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - int count = 0; - client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute(); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - assertThat(extractBody(capt, count), containsString("value=\"John\"")); - count++; - - String resourceAsString = ourCtx.newJsonParser().encodeResourceToString(p1); - client - .create() - .resource(resourceAsString) - .execute(); - - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.JSON.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - assertThat(extractBody(capt, count), containsString("[\"John\"]")); - count++; - - /* - * e.g. Now try with reversed encoding (provide a string that's in JSON and ask the client to use XML) - */ - - client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).encodedJson().execute(); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.JSON.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - assertThat(extractBody(capt, count), containsString("[\"John\"]")); - count++; - - client.create().resource(ourCtx.newJsonParser().encodeResourceToString(p1)).encodedXml().execute(); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - assertThat(extractBody(capt, count), containsString("value=\"John\"")); - count++; - - } - @Test - public void testCreateWithTag() throws Exception { - - Patient p1 = new Patient(); - p1.addIdentifier("foo:bar", "12345"); - p1.addName().addFamily("Smith").addGiven("John"); - TagList list = new TagList(); - list.addTag("http://hl7.org/fhir/tag", "urn:happytag", "This is a happy resource"); - ResourceMetadataKeyEnum.TAG_LIST.put(p1, list); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); - when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); - 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(""), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - MethodOutcome outcome = client.create().resource(p1).execute(); - assertEquals("44", outcome.getId().getIdPart()); - assertEquals("22", outcome.getId().getVersionIdPart()); - - int count = 0; - - assertEquals("http://example.com/fhir/Patient", capt.getValue().getURI().toString()); - assertEquals("POST", capt.getValue().getMethod()); - Header catH = capt.getValue().getFirstHeader("Category"); - assertNotNull(Arrays.asList(capt.getValue().getAllHeaders()).toString(), catH); - assertEquals("urn:happytag; label=\"This is a happy resource\"; scheme=\"http://hl7.org/fhir/tag\"", catH.getValue()); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - count++; - - /* - * Try fluent options - */ - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); - client.create().resource(p1).withId("123").execute(); - assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(1).getURI().toString()); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - count++; - - String resourceText = "<Patient xmlns=\"http://hl7.org/fhir\"> </Patient>"; - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); - client.create().resource(resourceText).withId("123").execute(); - assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(2).getURI().toString()); - assertEquals(resourceText, IOUtils.toString(((HttpPost) capt.getAllValues().get(2)).getEntity().getContent())); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - count++; - } - - @Test - public void testCreateWithTagNonFluent() throws Exception { - - Patient p1 = new Patient(); - p1.addIdentifier("foo:bar", "12345"); - p1.addName().addFamily("Smith").addGiven("John"); - TagList list = new TagList(); - list.addTag("http://hl7.org/fhir/tag", "urn:happytag", "This is a happy resource"); - ResourceMetadataKeyEnum.TAG_LIST.put(p1, list); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); - when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); - 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(""), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - MethodOutcome outcome = client.create().resource(p1).execute(); - assertEquals("44", outcome.getId().getIdPart()); - assertEquals("22", outcome.getId().getVersionIdPart()); - - assertEquals("http://example.com/fhir/Patient", capt.getValue().getURI().toString()); - assertEquals("POST", capt.getValue().getMethod()); - Header catH = capt.getValue().getFirstHeader("Category"); - assertNotNull(Arrays.asList(capt.getValue().getAllHeaders()).toString(), catH); - assertEquals("urn:happytag; label=\"This is a happy resource\"; scheme=\"http://hl7.org/fhir/tag\"", catH.getValue()); - } - - /** - * Test for issue #60 - */ - @Test - public void testCreateWithUtf8Characters() throws Exception { - String name = "測試醫院"; - Organization org = new Organization(); - org.setName(name); - org.addIdentifier("urn:system", "testCreateWithUtf8Characters_01"); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); - when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); - 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(""), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - int count = 0; - client.create().resource(org).prettyPrint().encodedXml().execute(); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - assertThat(extractBody(capt, count), containsString("<name value=\"測試醫院\"/>")); - count++; - - } - - @Test - public void testDelete() throws Exception { - OperationOutcome oo = new OperationOutcome(); - oo.addIssue().addLocation().setValue("testDelete01"); - String ooStr = ourCtx.newXmlParser().encodeResourceToString(oo); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); - when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); - 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(ooStr), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - OperationOutcome outcome = (OperationOutcome) client.delete().resourceById("Patient", "123").execute(); - - assertEquals("http://example.com/fhir/Patient/123", capt.getValue().getURI().toString()); - assertEquals("DELETE", capt.getValue().getMethod()); - assertEquals("testDelete01", outcome.getIssueFirstRep().getLocationFirstRep().getValue()); - - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("LKJHLKJGLKJKLL"), Charset.forName("UTF-8"))); - outcome = (OperationOutcome) client.delete().resourceById(new IdDt("Location", "123", "456")).prettyPrint().encodedJson().execute(); - - assertEquals("http://example.com/fhir/Location/123?_pretty=true", capt.getAllValues().get(1).getURI().toString()); - assertEquals("DELETE", capt.getValue().getMethod()); - assertEquals(null, outcome); - - } - - @Test - public void testGetTags() throws Exception { - - TagList tagList = new TagList(); - tagList.add(new Tag("CCC", "AAA", "BBB")); - String msg = ourCtx.newXmlParser().encodeTagListToString(tagList); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - TagList response = client.getTags() - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/_tags", capt.getValue().getURI().toString()); - assertEquals(1, response.size()); - assertEquals("CCC", response.get(0).getScheme()); - - // Now for patient - - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - //@formatter:off - response = client.getTags().forResource(Patient.class) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient/_tags", capt.getValue().getURI().toString()); - assertEquals(1, response.size()); - assertEquals("CCC", response.get(0).getScheme()); - - } - - @Test - public void testHistory() throws Exception { - - final String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() { - @Override - public InputStream answer(InvocationOnMock theInvocation) throws Throwable { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); - } - }); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - int idx = 0; - Bundle response; - - //@formatter:off - response = client - .history() - .onServer() - .andReturnDstu1Bundle() - .execute(); - //@formatter:on - assertEquals("http://example.com/fhir/_history", capt.getAllValues().get(idx).getURI().toString()); - assertEquals(1, response.size()); - idx++; - - //@formatter:off - response = client - .history() - .onType(Patient.class) - .andReturnDstu1Bundle() - .execute(); - //@formatter:on - assertEquals("http://example.com/fhir/Patient/_history", capt.getAllValues().get(idx).getURI().toString()); - assertEquals(1, response.size()); - idx++; - - //@formatter:off - response = client - .history() - .onInstance(new IdDt("Patient", "123")) - .andReturnDstu1Bundle() - .execute(); - //@formatter:on - assertEquals("http://example.com/fhir/Patient/123/_history", capt.getAllValues().get(idx).getURI().toString()); - assertEquals(1, response.size()); - idx++; - } - - @Test - public void testMissing() throws Exception { - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); - when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() { - @Override - public InputStream answer(InvocationOnMock theInvocation) throws Throwable { - return (new ReaderInputStream(new StringReader(getPatientFeedWithOneResult()), Charset.forName("UTF-8"))); - } - }); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); - - client.search().forResource("Patient").where(Patient.NAME.isMissing(true)).execute(); - assertEquals("http://example.com/fhir/Patient?name%3Amissing=true", capt.getValue().getRequestLine().getUri()); - - client.search().forResource("Patient").where(Patient.NAME.isMissing(false)).execute(); - assertEquals("http://example.com/fhir/Patient?name%3Amissing=false", capt.getValue().getRequestLine().getUri()); - } - - @Test - public void testRead() throws Exception { - - String msg = getResourceResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"), new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"), - new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; label=\"Some tag\"") }; - when(myHttpResponse.getAllHeaders()).thenReturn(headers); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Patient response = client.read(Patient.class, new IdDt("Patient/1234")); - //@formatter:on - - assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); - - assertEquals("http://foo.com/Patient/123/_history/2333", response.getId().getValue()); - - InstantDt lm = (InstantDt) response.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED); - lm.setTimeZoneZulu(true); - assertEquals("1995-11-15T04:58:08.000Z", lm.getValueAsString()); - - TagList tags = ResourceMetadataKeyEnum.TAG_LIST.get(response); - assertNotNull(tags); - assertEquals(1, tags.size()); - assertEquals("http://foo/tagdefinition.html", tags.get(0).getTerm()); - assertEquals("http://hl7.org/fhir/tag", tags.get(0).getScheme()); - assertEquals("Some tag", tags.get(0).getLabel()); - - } - - @Test - public void testReadFluent() throws Exception { - - String msg = getResourceResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"), new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"), - new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; label=\"Some tag\"") }; - when(myHttpResponse.getAllHeaders()).thenReturn(headers); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - int count = 0; - - Patient response = client.read().resource(Patient.class).withId(new IdDt("Patient/1234")).execute(); - assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); - assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count++).getURI().toString()); - - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - response = (Patient) client.read().resource("Patient").withId("1234").execute(); - assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); - assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count++).getURI().toString()); - - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - response = (Patient) client.read().resource("Patient").withId(567L).execute(); - assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); - assertEquals("http://example.com/fhir/Patient/567", capt.getAllValues().get(count++).getURI().toString()); - - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - response = client.read().resource(Patient.class).withIdAndVersion("1234", "22").execute(); - assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); - assertEquals("http://example.com/fhir/Patient/1234/_history/22", capt.getAllValues().get(count++).getURI().toString()); - - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - response = client.read().resource(Patient.class).withUrl("http://foo/Patient/22").execute(); - assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); - assertEquals("http://foo/Patient/22", capt.getAllValues().get(count++).getURI().toString()); - - } - - @Test - public void testReadWithAbsoluteUrl() throws Exception { - - String msg = getResourceResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"), new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"), - new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; label=\"Some tag\"") }; - when(myHttpResponse.getAllHeaders()).thenReturn(headers); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - Patient response = client.read(Patient.class, new IdDt("http://somebase.com/path/to/base/Patient/1234")); - assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); - assertEquals("http://somebase.com/path/to/base/Patient/1234", capt.getAllValues().get(0).getURI().toString()); - - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - response = client.read(Patient.class, new IdDt("http://somebase.com/path/to/base/Patient/1234/_history/2222")); - assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); - assertEquals("http://somebase.com/path/to/base/Patient/1234", capt.getAllValues().get(1).getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchAllResources() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forAllResources() - .where(Patient.NAME.matches().value("james")) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/?name=james", capt.getValue().getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchAutomaticallyUsesPost() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - String longValue = StringUtils.leftPad("", 20000, 'B'); - - //@formatter:off - Bundle response = client.search() - .forResource("Patient") - .where(Patient.NAME.matches().value(longValue)) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient/_search", capt.getValue().getURI().toString()); - - HttpEntityEnclosingRequestBase enc = (HttpEntityEnclosingRequestBase) capt.getValue(); - UrlEncodedFormEntity ent = (UrlEncodedFormEntity) enc.getEntity(); - String string = IOUtils.toString(ent.getContent()); - ourLog.info(string); - assertEquals("name=" + longValue, string); - } - - @Test - public void testLoadPageAndReturnDstu1Bundle() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - - 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(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://foo"); - //@formatter:off - client - .loadPage() - .byUrl("http://example.com/page1") - .andReturnDstu1Bundle() - .execute(); - //@formatter:on - - assertEquals("http://example.com/page1", capt.getValue().getURI().toString()); - } - - - @Test - public void testSearchByCompartment() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - - 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(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://foo"); - //@formatter:off - Bundle response = client - .search() - .forResource(Patient.class) - .withIdAndCompartment("123", "fooCompartment") - .where(Patient.BIRTHDATE.afterOrEquals().day("2011-01-02")) - .execute(); - //@formatter:on - - assertEquals("http://foo/Patient/123/fooCompartment?birthdate=%3E%3D2011-01-02", capt.getValue().getURI().toString()); - assertEquals("PRP1660", response.getResources(Patient.class).get(0).getIdentifier().get(0).getValue().getValue()); - - try { - //@formatter:off - client - .search() - .forResource(Patient.class) - .withIdAndCompartment("", "fooCompartment") - .where(Patient.BIRTHDATE.afterOrEquals().day("2011-01-02")) - .execute(); - //@formatter:on - fail(); - } catch (InvalidRequestException e) { - assertThat(e.toString(), containsString("null or empty for compartment")); - } - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByComposite() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://foo"); - - //@formatter:off - Bundle response = client.search() - .forResource("Observation") - .where(Observation.NAME_VALUE_DATE - .withLeft(Observation.NAME.exactly().code("FOO$BAR")) - .withRight(Observation.VALUE_DATE.exactly().day("2001-01-01")) - ) - .execute(); - //@formatter:on - - assertEquals("http://foo/Observation?" + Observation.SP_NAME_VALUE_DATE + "=" + URLEncoder.encode("FOO\\$BAR$2001-01-01", "UTF-8"), capt.getValue().getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByDate() throws Exception { - - final String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() { - @Override - public InputStream answer(InvocationOnMock theInvocation) throws Throwable { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); - } - }); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - int idx = 0; - - //@formatter:off - @SuppressWarnings("deprecation") - Bundle response = client.search() - .forResource(Patient.class) - .encodedJson() - .where(Patient.BIRTHDATE.beforeOrEquals().day("2012-01-22")) - .and(Patient.BIRTHDATE.after().day("2011-01-01")) - .include(Patient.INCLUDE_MANAGINGORGANIZATION) - .sort().ascending(Patient.BIRTHDATE) - .sort().descending(Patient.NAME) - .sort().defaultOrder(Patient.ADDRESS) - .limitTo(123) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_sort=address&_count=123&_format=json", capt.getAllValues().get(idx++).getURI().toString()); - - //@formatter:off - response = client.search() - .forResource(Patient.class) - .encodedJson() - .where(Patient.BIRTHDATE.beforeOrEquals().day("2012-01-22")) - .and(Patient.BIRTHDATE.after().day("2011-01-01")) - .include(Patient.INCLUDE_MANAGINGORGANIZATION) - .sort().ascending(Patient.BIRTHDATE) - .sort().descending(Patient.NAME) - .sort().defaultOrder(Patient.ADDRESS) - .count(123) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_sort=address&_count=123&_format=json", capt.getAllValues().get(idx++).getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByNumberExact() throws Exception { - - String msg = ourCtx.newXmlParser().encodeBundleToString(new Bundle()); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource(Observation.class) - .where(Observation.VALUE_QUANTITY.greaterThan().number(123).andUnits("foo", "bar")) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Observation?value-quantity=%3E123%7Cfoo%7Cbar", capt.getValue().getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByProfile() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource(Patient.class) - .withProfile("http://1") - .withProfile("http://2") - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?_profile=http%3A%2F%2F1&_profile=http%3A%2F%2F2", capt.getValue().getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByQuantity() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource(Patient.class) - .where(Encounter.LENGTH.exactly().number(123)) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?length=123", capt.getValue().getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByReferenceProperty() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - //@formatter:off - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - Bundle response = client.search() - .forResource(Patient.class) - .where(Patient.PROVIDER.hasChainedProperty(Organization.NAME.matches().value("ORG0"))) - .execute(); - - assertEquals("http://example.com/fhir/Patient?provider.name=ORG0", capt.getValue().getURI().toString()); - //@formatter:on - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByReferenceSimple() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource("Patient") - .where(Patient.PROVIDER.hasId("123")) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?provider=123", capt.getValue().getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchBySecurity() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource(Patient.class) - .withSecurity("urn:foo", "123") - .withSecurity("urn:bar", "456") - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?_security=urn%3Afoo%7C123&_security=urn%3Abar%7C456", capt.getValue().getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByString() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource("Patient") - .where(Patient.NAME.matches().value("james")) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?name=james", capt.getValue().getURI().toString()); - - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - //@formatter:off - response = client.search() - .forResource("Patient") - .where(Patient.NAME.matches().values("AAA", "BBB", "C,C")) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?name=" + URLEncoder.encode("AAA,BBB,C\\,C", "UTF-8"), capt.getAllValues().get(1).getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByStringExact() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource("Patient") - .where(Patient.NAME.matchesExactly().value("james")) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?name%3Aexact=james", capt.getValue().getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByTag() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource(Patient.class) - .withTag("urn:foo", "123") - .withTag("urn:bar", "456") - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?_tag=urn%3Afoo%7C123&_tag=urn%3Abar%7C456", capt.getValue().getURI().toString()); - - } - - - @SuppressWarnings("unused") - @Test - public void testSearchByToken() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource("Patient") - .where(Patient.IDENTIFIER.exactly().systemAndCode("http://example.com/fhir", "ZZZ")) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?identifier=http%3A%2F%2Fexample.com%2Ffhir%7CZZZ", capt.getValue().getURI().toString()); - - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - //@formatter:off - response = client.search() - .forResource("Patient") - .where(Patient.IDENTIFIER.exactly().code("ZZZ")) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?identifier=ZZZ", capt.getAllValues().get(1).getURI().toString()); - - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - //@formatter:off - response = client.search() - .forResource("Patient") - .where(Patient.IDENTIFIER.exactly().identifiers(new ca.uhn.fhir.model.dstu.composite.IdentifierDt("A", "B"), new ca.uhn.fhir.model.dstu.composite.IdentifierDt("C", "D"))) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?identifier=" + URLEncoder.encode("A|B,C|D", "UTF-8"), capt.getAllValues().get(2).getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchByTokenWithSystemAndNoCode() throws Exception { - - final String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() { - @Override - public InputStream answer(InvocationOnMock theInvocation) throws Throwable { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); - } - }); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - int idx = 0; - - //@formatter:off - Bundle response = client.search() - .forResource("Patient") - .where(Patient.IDENTIFIER.hasSystemWithAnyCode("urn:foo")) - .execute(); - assertEquals("http://example.com/fhir/Patient?identifier=urn%3Afoo%7C", capt.getAllValues().get(idx++).getURI().toString()); - //@formatter:on - - //@formatter:off - response = client.search() - .forResource("Patient") - .where(Patient.IDENTIFIER.exactly().systemAndCode("urn:foo", null)) - .execute(); - assertEquals("http://example.com/fhir/Patient?identifier=urn%3Afoo%7C", capt.getAllValues().get(idx++).getURI().toString()); - //@formatter:on - - //@formatter:off - response = client.search() - .forResource("Patient") - .where(Patient.IDENTIFIER.exactly().systemAndCode("urn:foo", "")) - .execute(); - assertEquals("http://example.com/fhir/Patient?identifier=urn%3Afoo%7C", capt.getAllValues().get(idx++).getURI().toString()); - //@formatter:on - } - - /** - * Test for #192 - */ - @SuppressWarnings("unused") - @Test - public void testSearchByTokenWithEscaping() throws Exception { - final String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() { - @Override - public InputStream answer(InvocationOnMock theInvocation) throws Throwable { - return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); - } - }); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://foo"); - int index = 0; - String wantPrefix = "http://foo/Patient?identifier="; - - //@formatter:off - Bundle response = client.search() - .forResource("Patient") - .where(Patient.IDENTIFIER.exactly().systemAndCode("1", "2")) - .execute(); - String wantValue = "1|2"; - String url = capt.getAllValues().get(index).getURI().toString(); - assertThat(url, Matchers.startsWith(wantPrefix)); - assertEquals(wantValue, UrlUtil.unescape(url.substring(wantPrefix.length()))); - assertEquals(UrlUtil.escape(wantValue), url.substring(wantPrefix.length())); - index++; - //@formatter:on - - //@formatter:off - response = client.search() - .forResource("Patient") - .where(Patient.IDENTIFIER.exactly().systemAndCode("1,2", "3,4")) - .execute(); - wantValue = "1\\,2|3\\,4"; - url = capt.getAllValues().get(index).getURI().toString(); - assertThat(url, Matchers.startsWith(wantPrefix)); - assertEquals(wantValue, UrlUtil.unescape(url.substring(wantPrefix.length()))); - assertEquals(UrlUtil.escape(wantValue), url.substring(wantPrefix.length())); - index++; - //@formatter:on - - } - - @SuppressWarnings("unused") - @Test - public void testSearchIncludeRecursive() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource(Patient.class) - .include(Patient.INCLUDE_MANAGINGORGANIZATION) - .include(Patient.INCLUDE_LINK_OTHER.asRecursive()) - .include(Patient.INCLUDE_ALL.asNonRecursive()) - .execute(); - //@formatter:on - - assertThat(capt.getValue().getURI().toString(), containsString("http://example.com/fhir/Patient?")); - assertThat(capt.getValue().getURI().toString(), containsString("_include=" + Patient.INCLUDE_MANAGINGORGANIZATION.getValue())); - assertThat(capt.getValue().getURI().toString(), containsString("_include%3Arecurse=" + Patient.INCLUDE_LINK_OTHER.getValue())); - assertThat(capt.getValue().getURI().toString(), containsString("_include=*")); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchUsingGetSearch() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource("Patient") - .where(Patient.NAME.matches().value("james")) - .usingStyle(SearchStyleEnum.GET_WITH_SEARCH) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient/_search?name=james", capt.getValue().getURI().toString()); - } - - @SuppressWarnings("unused") - @Test - public void testSearchUsingPost() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource("Patient") - .where(Patient.NAME.matches().value("james")) - .usingStyle(SearchStyleEnum.POST) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient/_search", capt.getValue().getURI().toString()); - - HttpEntityEnclosingRequestBase enc = (HttpEntityEnclosingRequestBase) capt.getValue(); - UrlEncodedFormEntity ent = (UrlEncodedFormEntity) enc.getEntity(); - String string = IOUtils.toString(ent.getContent()); - ourLog.info(string); - assertEquals("name=james", string); - } - - @Test - public void testSearchWithAbsoluteUrl() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - Bundle response = client.search(new UriDt("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json")); - - assertEquals("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json", capt.getValue().getURI().toString()); - - assertEquals(1, response.size()); - } - - @Test - public void testSearchWithAbsoluteUrlAndType() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - Bundle response = client.search(Patient.class, new UriDt("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json")); - - assertEquals("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json", capt.getValue().getURI().toString()); - - assertEquals(1, response.size()); - } - - @SuppressWarnings("unused") - @Test - public void testSearchWithClientEncodingAndPrettyPrintConfig() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - GenericClient client = (GenericClient) ourCtx.newRestfulGenericClient("http://example.com/fhir"); - client.setPrettyPrint(true); - client.setEncoding(EncodingEnum.JSON); - - //@formatter:off - Bundle response = client.search() - .forResource(Patient.class) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?_format=json&_pretty=true", capt.getValue().getURI().toString()); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchWithEscapedParameters() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource("Patient") - .where(Patient.NAME.matches().values("NE,NE", "NE,NE")) - .where(Patient.NAME.matchesExactly().values("E$E")) - .where(Patient.NAME.matches().values("NE\\NE")) - .where(Patient.NAME.matchesExactly().values("E|E")) - .execute(); - //@formatter:on - - assertThat(capt.getValue().getURI().toString(), containsString("%3A")); - assertEquals("http://example.com/fhir/Patient?name=NE\\,NE,NE\\,NE&name=NE\\\\NE&name:exact=E\\$E&name:exact=E\\|E", UrlUtil.unescape(capt.getValue().getURI().toString())); - } - - @SuppressWarnings("unused") - @Test - public void testSearchWithInternalServerError() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 500, "INTERNAL ERRORS")); - when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_TEXT + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("Server Issues!"), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - try { - client.search().forResource(Patient.class).execute(); - fail(); - } catch (InternalErrorException e) { - assertEquals(e.getMessage(), "HTTP 500 INTERNAL ERRORS: Server Issues!"); - assertEquals(e.getResponseBody(), "Server Issues!"); - } - - } - - @SuppressWarnings("unused") - @Test - public void testSearchWithNonFhirResponse() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_TEXT + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("Server Issues!"), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - try { - client.search().forResource(Patient.class).execute(); - fail(); - } catch (NonFhirResponseException e) { - assertThat(e.getMessage(), StringContains.containsString("Server Issues!")); - } - - } - - @SuppressWarnings("unused") - @Test - public void testSearchWithReverseInclude() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.search() - .forResource(Patient.class) - .encodedJson() - .revInclude(Provenance.INCLUDE_TARGET) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir/Patient?_revinclude=Provenance.target&_format=json", capt.getValue().getURI().toString()); - - } - - @Test - public void testSetDefaultEncoding() throws Exception { - - String msg = ourCtx.newJsonParser().encodeResourceToString(new Patient()); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - // Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 - // GMT"), - // new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"), - // new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; - // label=\"Some tag\"") }; - // when(myHttpResponse.getAllHeaders()).thenReturn(headers); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - (client).setEncoding(EncodingEnum.JSON); - int count = 0; - - client.read(Patient.class, new IdDt("Patient/1234")); - assertEquals("http://example.com/fhir/Patient/1234?_format=json", capt.getAllValues().get(count).getURI().toString()); - count++; - - } - - @Test - public void testTransaction() throws Exception { - String bundleStr = IOUtils.toString(getClass().getResourceAsStream("/bundle.json")); - Bundle bundle = ourCtx.newJsonParser().parseBundle(bundleStr); - - ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(bundleStr), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.transaction() - .withBundle(bundle) - .execute(); - //@formatter:on - - assertEquals("http://example.com/fhir", capt.getValue().getURI().toString()); - assertEquals(bundle.getEntries().get(0).getResource().getId(), response.getEntries().get(0).getResource().getId()); - assertEquals(EncodingEnum.XML.getBundleContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(0).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - - } - - @SuppressWarnings("deprecation") - @Test - public void testTransactionOldStyle() throws Exception { - String bundleStr = IOUtils.toString(getClass().getResourceAsStream("/bundle.json")); - Bundle bundle = ourCtx.newJsonParser().parseBundle(bundleStr); - - ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(bundleStr), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - List<IBaseResource> input = new ArrayList<IBaseResource>(); - input.addAll(bundle.toListOfResources()); - client.transaction(input); - } - - @Test - public void testTransactionJson() throws Exception { - String bundleStr = IOUtils.toString(getClass().getResourceAsStream("/bundle.json")); - Bundle bundle = ourCtx.newJsonParser().parseBundle(bundleStr); - - ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(bundleStr), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - //@formatter:off - Bundle response = client.transaction() - .withBundle(bundle) - .encodedJson() - .execute(); - //@formatter:on - - HttpEntityEnclosingRequestBase value = (HttpEntityEnclosingRequestBase) capt.getValue(); - - Header ct = value.getFirstHeader(Constants.HEADER_CONTENT_TYPE); - assertNotNull(ct); - assertEquals(Constants.CT_FHIR_JSON + "; charset=UTF-8", ct.getValue()); - - assertEquals("http://example.com/fhir", value.getURI().toString()); - assertThat(IOUtils.toString(value.getEntity().getContent()), StringContains.containsString("\"resourceType\"")); - assertEquals(bundle.getEntries().get(0).getResource().getId(), response.getEntries().get(0).getResource().getId()); - } - - @Test - public void testUpdate() throws Exception { - - Patient p1 = new Patient(); - p1.addIdentifier("foo:bar", "12345"); - p1.addName().addFamily("Smith").addGiven("John"); - TagList list = new TagList(); - list.addTag("http://hl7.org/fhir/tag", "urn:happytag", "This is a happy resource"); - ResourceMetadataKeyEnum.TAG_LIST.put(p1, list); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); - when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); - 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(""), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - try { - client.update().resource(p1).execute(); - fail(); - } catch (InvalidRequestException e) { - // should happen because no ID set - } - - assertEquals(0, capt.getAllValues().size()); - - p1.setId("44"); - client.update().resource(p1).execute(); - - int count = 0; - - assertEquals(1, capt.getAllValues().size()); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - count++; - - MethodOutcome outcome = client.update().resource(p1).execute(); - assertEquals("44", outcome.getId().getIdPart()); - assertEquals("22", outcome.getId().getVersionIdPart()); - - assertEquals(2, capt.getAllValues().size()); - - assertEquals("http://example.com/fhir/Patient/44", capt.getValue().getURI().toString()); - assertEquals("PUT", capt.getValue().getMethod()); - Header catH = capt.getValue().getFirstHeader("Category"); - assertNotNull(Arrays.asList(capt.getValue().getAllHeaders()).toString(), catH); - assertEquals("urn:happytag; label=\"This is a happy resource\"; scheme=\"http://hl7.org/fhir/tag\"", catH.getValue()); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - - /* - * Try fluent options - */ - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); - client.update().resource(p1).withId("123").execute(); - assertEquals(3, capt.getAllValues().size()); - assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(2).getURI().toString()); - - String resourceText = "<Patient xmlns=\"http://hl7.org/fhir\"> </Patient>"; - when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); - client.update().resource(resourceText).withId("123").execute(); - assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(3).getURI().toString()); - assertEquals(resourceText, IOUtils.toString(((HttpPut) capt.getAllValues().get(3)).getEntity().getContent())); - assertEquals(4, capt.getAllValues().size()); - - } - - @Test - public void testUpdateWithStringAutoDetectsEncoding() throws Exception { - - Patient p1 = new Patient(); - p1.addIdentifier("foo:bar", "12345"); - p1.addName().addFamily("Smith").addGiven("John"); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); - when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); - 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(""), Charset.forName("UTF-8"))); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - int count = 0; - client.update().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).withId("1").execute(); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - assertThat(extractBody(capt, count), containsString("value=\"John\"")); - count++; - - client.update().resource(ourCtx.newJsonParser().encodeResourceToString(p1)).withId("1").execute(); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.JSON.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - assertThat(extractBody(capt, count), containsString("[\"John\"]")); - count++; - - /* - * e.g. Now try with reversed encoding (provide a string that's in JSON and ask the client to use XML) - */ - - client.update().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).withId("1").encodedJson().execute(); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.JSON.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - assertThat(extractBody(capt, count), containsString("[\"John\"]")); - count++; - - client.update().resource(ourCtx.newJsonParser().encodeResourceToString(p1)).withId("1").encodedXml().execute(); - assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); - assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); - assertThat(extractBody(capt, count), containsString("value=\"John\"")); - count++; - } - - @Test - public void testValidateNonFluent() throws Exception { - - OperationOutcome oo = new OperationOutcome(); - oo.addIssue().setDetails("OOOK"); - - ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); - when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { }); - 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(ourCtx.newXmlParser().encodeResourceToString(oo)), Charset.forName("UTF-8"))); - when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - Patient p1 = new Patient(); - p1.addIdentifier("foo:bar", "12345"); - p1.addName().addFamily("Smith").addGiven("John"); - - MethodOutcome resp = client.validate(p1); - assertEquals("http://example.com/fhir/Patient/_validate", capt.getValue().getURI().toString()); - oo = (OperationOutcome) resp.getOperationOutcome(); - assertEquals("OOOK", oo.getIssueFirstRep().getDetails().getValue()); - - } - - @Test - public void testVReadWithAbsoluteUrl() throws Exception { - - String msg = getResourceResult(); - - ArgumentCaptor<HttpUriRequest> 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.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"))); - Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"), new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"), - new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; label=\"Some tag\"") }; - when(myHttpResponse.getAllHeaders()).thenReturn(headers); - - IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); - - Patient response = client.vread(Patient.class, new IdDt("http://somebase.com/path/to/base/Patient/1234/_history/2222")); - assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); - assertEquals("http://somebase.com/path/to/base/Patient/1234/_history/2222", capt.getAllValues().get(0).getURI().toString()); - - try { - client.vread(Patient.class, new IdDt("http://somebase.com/path/to/base/Patient/1234")); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("No version specified in URL")); - } - - } - - @BeforeClass - public static void beforeClass() { - ourCtx = FhirContext.forDstu1(); - } - - - @AfterClass - public static void afterClassClearContext() { - TestUtil.clearAllStaticFieldsForUnitTest(); - } - -} +package ca.uhn.fhir.rest.client; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpPost; +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.hamcrest.Matchers; +import org.hamcrest.core.StringContains; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.api.Bundle; +import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; +import ca.uhn.fhir.model.api.Tag; +import ca.uhn.fhir.model.api.TagList; +import ca.uhn.fhir.model.dstu.resource.Encounter; +import ca.uhn.fhir.model.dstu.resource.Observation; +import ca.uhn.fhir.model.dstu.resource.OperationOutcome; +import ca.uhn.fhir.model.dstu.resource.Organization; +import ca.uhn.fhir.model.dstu.resource.Patient; +import ca.uhn.fhir.model.dstu.resource.Provenance; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.model.primitive.InstantDt; +import ca.uhn.fhir.model.primitive.UriDt; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException; +import ca.uhn.fhir.rest.method.SearchStyleEnum; +import ca.uhn.fhir.rest.server.Constants; +import ca.uhn.fhir.rest.server.EncodingEnum; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.util.TestUtil; +import ca.uhn.fhir.util.UrlUtil; + +public class GenericClientTest { + + private static FhirContext ourCtx; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(GenericClientTest.class); + private HttpClient myHttpClient; + + private HttpResponse myHttpResponse; + + @Before + public void before() { + + myHttpClient = mock(HttpClient.class, new ReturnsDeepStubs()); + ourCtx.getRestfulClientFactory().setHttpClient(myHttpClient); + ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); + + myHttpResponse = mock(HttpResponse.class, new ReturnsDeepStubs()); + + System.setProperty(BaseClient.HAPI_CLIENT_KEEPRESPONSES, "true"); + } + + private String extractBody(ArgumentCaptor<HttpUriRequest> capt, int count) throws IOException { + String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(count)).getEntity().getContent(), "UTF-8"); + return body; + } + + @Test + public void testInvalidCalls() { + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + try { + client.meta(); + fail(); + } catch (IllegalStateException e) { + assertEquals("Can not call $meta operations on a DSTU1 client", e.getMessage()); + } + try { + client.operation(); + fail(); + } catch (IllegalStateException e) { + assertEquals("Operations are only supported in FHIR DSTU2 and later. This client was created using a context configured for DSTU1", e.getMessage()); + } + } + + private String getPatientFeedWithOneResult() { + //@formatter:off + String msg = "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n" + + "<title/>\n" + + "<id>d039f91a-cc3c-4013-988e-af4d8d0614bd</id>\n" + + "<os:totalResults xmlns:os=\"http://a9.com/-/spec/opensearch/1.1/\">1</os:totalResults>\n" + + "<author>\n" + + "<name>ca.uhn.fhir.rest.server.DummyRestfulServer</name>\n" + + "</author>\n" + + "<entry>\n" + + "<content type=\"text/xml\">" + + "<Patient xmlns=\"http://hl7.org/fhir\">" + + "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>" + + "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>" + + "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>" + + "<name><family value=\"Kramer\" /><given value=\"Doe\" /></name>" + + "<telecom><system value=\"phone\" /><value value=\"555-555-2004\" /><use value=\"work\" /></telecom>" + + "<gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\" /><code value=\"M\" /></coding></gender>" + + "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />" + + "</Patient>" + + "</content>\n" + + " </entry>\n" + + "</feed>"; + //@formatter:on + return msg; + } + + private String getResourceResult() { + //@formatter:off + String msg = + "<Patient xmlns=\"http://hl7.org/fhir\">" + + "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>" + + "<identifier><label value=\"SSN\" /><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>" + + "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>" + + "<name><family value=\"Kramer\" /><given value=\"Doe\" /></name>" + + "<telecom><system value=\"phone\" /><value value=\"555-555-2004\" /><use value=\"work\" /></telecom>" + + "<gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\" /><code value=\"M\" /></coding></gender>" + + "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />" + + "</Patient>"; + //@formatter:on + return msg; + } + + @Test + public void testCreatePopulatesIsCreated() throws Exception { + + Patient p1 = new Patient(); + p1.addIdentifier("foo:bar", "12345"); + p1.addName().addFamily("Smith").addGiven("John"); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); + 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(""), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); + MethodOutcome resp = client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute(); + assertTrue(resp.getCreated()); + + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + resp = client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute(); + assertNull(resp.getCreated()); + + ourLog.info("lastRequest: {}", ((GenericClient)client).getLastRequest()); + ourLog.info("lastResponse: {}", ((GenericClient)client).getLastResponse()); + ourLog.info("lastResponseBody: {}", ((GenericClient)client).getLastResponseBody()); + } + + @Test + public void testCreateWithStringAutoDetectsEncoding() throws Exception { + + Patient p1 = new Patient(); + p1.addIdentifier("foo:bar", "12345"); + p1.addName().addFamily("Smith").addGiven("John"); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); + when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); + 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(""), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + int count = 0; + client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).execute(); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + assertThat(extractBody(capt, count), containsString("value=\"John\"")); + count++; + + String resourceAsString = ourCtx.newJsonParser().encodeResourceToString(p1); + client + .create() + .resource(resourceAsString) + .execute(); + + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.JSON.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + assertThat(extractBody(capt, count), containsString("[\"John\"]")); + count++; + + /* + * e.g. Now try with reversed encoding (provide a string that's in JSON and ask the client to use XML) + */ + + client.create().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).encodedJson().execute(); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.JSON.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + assertThat(extractBody(capt, count), containsString("[\"John\"]")); + count++; + + client.create().resource(ourCtx.newJsonParser().encodeResourceToString(p1)).encodedXml().execute(); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + assertThat(extractBody(capt, count), containsString("value=\"John\"")); + count++; + + } + @Test + public void testCreateWithTag() throws Exception { + + Patient p1 = new Patient(); + p1.addIdentifier("foo:bar", "12345"); + p1.addName().addFamily("Smith").addGiven("John"); + TagList list = new TagList(); + list.addTag("http://hl7.org/fhir/tag", "urn:happytag", "This is a happy resource"); + ResourceMetadataKeyEnum.TAG_LIST.put(p1, list); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); + when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); + 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(""), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + MethodOutcome outcome = client.create().resource(p1).execute(); + assertEquals("44", outcome.getId().getIdPart()); + assertEquals("22", outcome.getId().getVersionIdPart()); + + int count = 0; + + assertEquals("http://example.com/fhir/Patient", capt.getValue().getURI().toString()); + assertEquals("POST", capt.getValue().getMethod()); + Header catH = capt.getValue().getFirstHeader("Category"); + assertNotNull(Arrays.asList(capt.getValue().getAllHeaders()).toString(), catH); + assertEquals("urn:happytag; label=\"This is a happy resource\"; scheme=\"http://hl7.org/fhir/tag\"", catH.getValue()); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + count++; + + /* + * Try fluent options + */ + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); + client.create().resource(p1).withId("123").execute(); + assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(1).getURI().toString()); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + count++; + + String resourceText = "<Patient xmlns=\"http://hl7.org/fhir\"> </Patient>"; + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); + client.create().resource(resourceText).withId("123").execute(); + assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(2).getURI().toString()); + assertEquals(resourceText, IOUtils.toString(((HttpPost) capt.getAllValues().get(2)).getEntity().getContent())); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + count++; + } + + @Test + public void testCreateWithTagNonFluent() throws Exception { + + Patient p1 = new Patient(); + p1.addIdentifier("foo:bar", "12345"); + p1.addName().addFamily("Smith").addGiven("John"); + TagList list = new TagList(); + list.addTag("http://hl7.org/fhir/tag", "urn:happytag", "This is a happy resource"); + ResourceMetadataKeyEnum.TAG_LIST.put(p1, list); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); + when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); + 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(""), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + MethodOutcome outcome = client.create().resource(p1).execute(); + assertEquals("44", outcome.getId().getIdPart()); + assertEquals("22", outcome.getId().getVersionIdPart()); + + assertEquals("http://example.com/fhir/Patient", capt.getValue().getURI().toString()); + assertEquals("POST", capt.getValue().getMethod()); + Header catH = capt.getValue().getFirstHeader("Category"); + assertNotNull(Arrays.asList(capt.getValue().getAllHeaders()).toString(), catH); + assertEquals("urn:happytag; label=\"This is a happy resource\"; scheme=\"http://hl7.org/fhir/tag\"", catH.getValue()); + } + + /** + * Test for issue #60 + */ + @Test + public void testCreateWithUtf8Characters() throws Exception { + String name = "測試醫院"; + Organization org = new Organization(); + org.setName(name); + org.addIdentifier("urn:system", "testCreateWithUtf8Characters_01"); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); + when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); + 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(""), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + int count = 0; + client.create().resource(org).prettyPrint().encodedXml().execute(); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + assertThat(extractBody(capt, count), containsString("<name value=\"測試醫院\"/>")); + count++; + + } + + @Test + public void testDelete() throws Exception { + OperationOutcome oo = new OperationOutcome(); + oo.addIssue().addLocation().setValue("testDelete01"); + String ooStr = ourCtx.newXmlParser().encodeResourceToString(oo); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); + when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); + 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(ooStr), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + OperationOutcome outcome = (OperationOutcome) client.delete().resourceById("Patient", "123").execute(); + + assertEquals("http://example.com/fhir/Patient/123", capt.getValue().getURI().toString()); + assertEquals("DELETE", capt.getValue().getMethod()); + assertEquals("testDelete01", outcome.getIssueFirstRep().getLocationFirstRep().getValue()); + + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("LKJHLKJGLKJKLL"), Charset.forName("UTF-8"))); + outcome = (OperationOutcome) client.delete().resourceById(new IdDt("Location", "123", "456")).prettyPrint().encodedJson().execute(); + + assertEquals("http://example.com/fhir/Location/123?_pretty=true", capt.getAllValues().get(1).getURI().toString()); + assertEquals("DELETE", capt.getValue().getMethod()); + assertEquals(null, outcome); + + } + + @Test + public void testGetTags() throws Exception { + + TagList tagList = new TagList(); + tagList.add(new Tag("CCC", "AAA", "BBB")); + String msg = ourCtx.newXmlParser().encodeTagListToString(tagList); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + TagList response = client.getTags() + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/_tags", capt.getValue().getURI().toString()); + assertEquals(1, response.size()); + assertEquals("CCC", response.get(0).getScheme()); + + // Now for patient + + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + //@formatter:off + response = client.getTags().forResource(Patient.class) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient/_tags", capt.getValue().getURI().toString()); + assertEquals(1, response.size()); + assertEquals("CCC", response.get(0).getScheme()); + + } + + @Test + public void testHistory() throws Exception { + + final String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + int idx = 0; + Bundle response; + + //@formatter:off + response = client + .history() + .onServer() + .andReturnDstu1Bundle() + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/_history", capt.getAllValues().get(idx).getURI().toString()); + assertEquals(1, response.size()); + idx++; + + //@formatter:off + response = client + .history() + .onType(Patient.class) + .andReturnDstu1Bundle() + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient/_history", capt.getAllValues().get(idx).getURI().toString()); + assertEquals(1, response.size()); + idx++; + + //@formatter:off + response = client + .history() + .onInstance(new IdDt("Patient", "123")) + .andReturnDstu1Bundle() + .execute(); + //@formatter:on + assertEquals("http://example.com/fhir/Patient/123/_history", capt.getAllValues().get(idx).getURI().toString()); + assertEquals(1, response.size()); + idx++; + } + + @Test + public void testMissing() throws Exception { + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return (new ReaderInputStream(new StringReader(getPatientFeedWithOneResult()), Charset.forName("UTF-8"))); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); + + client.search().forResource("Patient").where(Patient.NAME.isMissing(true)).execute(); + assertEquals("http://example.com/fhir/Patient?name%3Amissing=true", capt.getValue().getRequestLine().getUri()); + + client.search().forResource("Patient").where(Patient.NAME.isMissing(false)).execute(); + assertEquals("http://example.com/fhir/Patient?name%3Amissing=false", capt.getValue().getRequestLine().getUri()); + } + + @Test + public void testRead() throws Exception { + + String msg = getResourceResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"), new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"), + new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; label=\"Some tag\"") }; + when(myHttpResponse.getAllHeaders()).thenReturn(headers); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Patient response = client.read(Patient.class, new IdDt("Patient/1234")); + //@formatter:on + + assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); + + assertEquals("http://foo.com/Patient/123/_history/2333", response.getId().getValue()); + + InstantDt lm = (InstantDt) response.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED); + lm.setTimeZoneZulu(true); + assertEquals("1995-11-15T04:58:08.000Z", lm.getValueAsString()); + + TagList tags = ResourceMetadataKeyEnum.TAG_LIST.get(response); + assertNotNull(tags); + assertEquals(1, tags.size()); + assertEquals("http://foo/tagdefinition.html", tags.get(0).getTerm()); + assertEquals("http://hl7.org/fhir/tag", tags.get(0).getScheme()); + assertEquals("Some tag", tags.get(0).getLabel()); + + } + + @Test + public void testReadFluent() throws Exception { + + String msg = getResourceResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"), new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"), + new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; label=\"Some tag\"") }; + when(myHttpResponse.getAllHeaders()).thenReturn(headers); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + int count = 0; + + Patient response = client.read().resource(Patient.class).withId(new IdDt("Patient/1234")).execute(); + assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); + assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count++).getURI().toString()); + + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + response = (Patient) client.read().resource("Patient").withId("1234").execute(); + assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); + assertEquals("http://example.com/fhir/Patient/1234", capt.getAllValues().get(count++).getURI().toString()); + + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + response = (Patient) client.read().resource("Patient").withId(567L).execute(); + assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); + assertEquals("http://example.com/fhir/Patient/567", capt.getAllValues().get(count++).getURI().toString()); + + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + response = client.read().resource(Patient.class).withIdAndVersion("1234", "22").execute(); + assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); + assertEquals("http://example.com/fhir/Patient/1234/_history/22", capt.getAllValues().get(count++).getURI().toString()); + + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + response = client.read().resource(Patient.class).withUrl("http://foo/Patient/22").execute(); + assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); + assertEquals("http://foo/Patient/22", capt.getAllValues().get(count++).getURI().toString()); + + } + + @Test + public void testReadWithAbsoluteUrl() throws Exception { + + String msg = getResourceResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"), new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"), + new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; label=\"Some tag\"") }; + when(myHttpResponse.getAllHeaders()).thenReturn(headers); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient response = client.read(Patient.class, new IdDt("http://somebase.com/path/to/base/Patient/1234")); + assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); + assertEquals("http://somebase.com/path/to/base/Patient/1234", capt.getAllValues().get(0).getURI().toString()); + + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + response = client.read(Patient.class, new IdDt("http://somebase.com/path/to/base/Patient/1234/_history/2222")); + assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); + assertEquals("http://somebase.com/path/to/base/Patient/1234", capt.getAllValues().get(1).getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchAllResources() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forAllResources() + .where(Patient.NAME.matches().value("james")) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/?name=james", capt.getValue().getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchAutomaticallyUsesPost() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + String longValue = StringUtils.leftPad("", 20000, 'B'); + + //@formatter:off + Bundle response = client.search() + .forResource("Patient") + .where(Patient.NAME.matches().value(longValue)) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient/_search", capt.getValue().getURI().toString()); + + HttpEntityEnclosingRequestBase enc = (HttpEntityEnclosingRequestBase) capt.getValue(); + UrlEncodedFormEntity ent = (UrlEncodedFormEntity) enc.getEntity(); + String string = IOUtils.toString(ent.getContent()); + ourLog.info(string); + assertEquals("name=" + longValue, string); + } + + @Test + public void testLoadPageAndReturnDstu1Bundle() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + + 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(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://foo"); + //@formatter:off + client + .loadPage() + .byUrl("http://example.com/page1") + .andReturnDstu1Bundle() + .execute(); + //@formatter:on + + assertEquals("http://example.com/page1", capt.getValue().getURI().toString()); + } + + + @Test + public void testSearchByCompartment() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + + 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(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://foo"); + //@formatter:off + Bundle response = client + .search() + .forResource(Patient.class) + .withIdAndCompartment("123", "fooCompartment") + .where(Patient.BIRTHDATE.afterOrEquals().day("2011-01-02")) + .execute(); + //@formatter:on + + assertEquals("http://foo/Patient/123/fooCompartment?birthdate=%3E%3D2011-01-02", capt.getValue().getURI().toString()); + assertEquals("PRP1660", response.getResources(Patient.class).get(0).getIdentifier().get(0).getValue().getValue()); + + try { + //@formatter:off + client + .search() + .forResource(Patient.class) + .withIdAndCompartment("", "fooCompartment") + .where(Patient.BIRTHDATE.afterOrEquals().day("2011-01-02")) + .execute(); + //@formatter:on + fail(); + } catch (InvalidRequestException e) { + assertThat(e.toString(), containsString("null or empty for compartment")); + } + + } + + @SuppressWarnings("unused") + @Test + public void testSearchByComposite() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://foo"); + + //@formatter:off + Bundle response = client.search() + .forResource("Observation") + .where(Observation.NAME_VALUE_DATE + .withLeft(Observation.NAME.exactly().code("FOO$BAR")) + .withRight(Observation.VALUE_DATE.exactly().day("2001-01-01")) + ) + .execute(); + //@formatter:on + + assertEquals("http://foo/Observation?" + Observation.SP_NAME_VALUE_DATE + "=" + URLEncoder.encode("FOO\\$BAR$2001-01-01", "UTF-8"), capt.getValue().getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchByDate() throws Exception { + + final String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + int idx = 0; + + //@formatter:off + @SuppressWarnings("deprecation") + Bundle response = client.search() + .forResource(Patient.class) + .encodedJson() + .where(Patient.BIRTHDATE.beforeOrEquals().day("2012-01-22")) + .and(Patient.BIRTHDATE.after().day("2011-01-01")) + .include(Patient.INCLUDE_MANAGINGORGANIZATION) + .sort().ascending(Patient.BIRTHDATE) + .sort().descending(Patient.NAME) + .sort().defaultOrder(Patient.ADDRESS) + .limitTo(123) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_sort=address&_count=123&_format=json", capt.getAllValues().get(idx++).getURI().toString()); + + //@formatter:off + response = client.search() + .forResource(Patient.class) + .encodedJson() + .where(Patient.BIRTHDATE.beforeOrEquals().day("2012-01-22")) + .and(Patient.BIRTHDATE.after().day("2011-01-01")) + .include(Patient.INCLUDE_MANAGINGORGANIZATION) + .sort().ascending(Patient.BIRTHDATE) + .sort().descending(Patient.NAME) + .sort().defaultOrder(Patient.ADDRESS) + .count(123) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_sort=address&_count=123&_format=json", capt.getAllValues().get(idx++).getURI().toString()); + + + //@formatter:off + response = client.search() + .forResource(Patient.class) + .encodedJson() + .where(Patient.BIRTHDATE.beforeOrEquals().day("2012-01-22").orAfter().day("2020-01-01")) + .and(Patient.BIRTHDATE.after().day("2011-01-01")) + .execute(); + //@formatter:on + + String comma = "%2C"; + assertEquals("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22" + comma + "%3E2020-01-01&birthdate=%3E2011-01-01&_format=json", capt.getAllValues().get(idx++).getURI().toString()); + } + + @SuppressWarnings("unused") + @Test + public void testSearchByNumberExact() throws Exception { + + String msg = ourCtx.newXmlParser().encodeBundleToString(new Bundle()); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource(Observation.class) + .where(Observation.VALUE_QUANTITY.greaterThan().number(123).andUnits("foo", "bar")) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Observation?value-quantity=%3E123%7Cfoo%7Cbar", capt.getValue().getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchByProfile() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource(Patient.class) + .withProfile("http://1") + .withProfile("http://2") + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?_profile=http%3A%2F%2F1&_profile=http%3A%2F%2F2", capt.getValue().getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchByQuantity() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource(Patient.class) + .where(Encounter.LENGTH.exactly().number(123)) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?length=123", capt.getValue().getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchByReferenceProperty() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + //@formatter:off + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Bundle response = client.search() + .forResource(Patient.class) + .where(Patient.PROVIDER.hasChainedProperty(Organization.NAME.matches().value("ORG0"))) + .execute(); + + assertEquals("http://example.com/fhir/Patient?provider.name=ORG0", capt.getValue().getURI().toString()); + //@formatter:on + + } + + @SuppressWarnings("unused") + @Test + public void testSearchByReferenceSimple() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource("Patient") + .where(Patient.PROVIDER.hasId("123")) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?provider=123", capt.getValue().getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchBySecurity() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource(Patient.class) + .withSecurity("urn:foo", "123") + .withSecurity("urn:bar", "456") + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?_security=urn%3Afoo%7C123&_security=urn%3Abar%7C456", capt.getValue().getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchByString() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource("Patient") + .where(Patient.NAME.matches().value("james")) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?name=james", capt.getValue().getURI().toString()); + + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + //@formatter:off + response = client.search() + .forResource("Patient") + .where(Patient.NAME.matches().values("AAA", "BBB", "C,C")) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?name=" + URLEncoder.encode("AAA,BBB,C\\,C", "UTF-8"), capt.getAllValues().get(1).getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchByStringExact() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource("Patient") + .where(Patient.NAME.matchesExactly().value("james")) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?name%3Aexact=james", capt.getValue().getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchByTag() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource(Patient.class) + .withTag("urn:foo", "123") + .withTag("urn:bar", "456") + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?_tag=urn%3Afoo%7C123&_tag=urn%3Abar%7C456", capt.getValue().getURI().toString()); + + } + + + @SuppressWarnings("unused") + @Test + public void testSearchByToken() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource("Patient") + .where(Patient.IDENTIFIER.exactly().systemAndCode("http://example.com/fhir", "ZZZ")) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?identifier=http%3A%2F%2Fexample.com%2Ffhir%7CZZZ", capt.getValue().getURI().toString()); + + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + //@formatter:off + response = client.search() + .forResource("Patient") + .where(Patient.IDENTIFIER.exactly().code("ZZZ")) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?identifier=ZZZ", capt.getAllValues().get(1).getURI().toString()); + + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + //@formatter:off + response = client.search() + .forResource("Patient") + .where(Patient.IDENTIFIER.exactly().identifiers(new ca.uhn.fhir.model.dstu.composite.IdentifierDt("A", "B"), new ca.uhn.fhir.model.dstu.composite.IdentifierDt("C", "D"))) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?identifier=" + URLEncoder.encode("A|B,C|D", "UTF-8"), capt.getAllValues().get(2).getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchByTokenWithSystemAndNoCode() throws Exception { + + final String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + int idx = 0; + + //@formatter:off + Bundle response = client.search() + .forResource("Patient") + .where(Patient.IDENTIFIER.hasSystemWithAnyCode("urn:foo")) + .execute(); + assertEquals("http://example.com/fhir/Patient?identifier=urn%3Afoo%7C", capt.getAllValues().get(idx++).getURI().toString()); + //@formatter:on + + //@formatter:off + response = client.search() + .forResource("Patient") + .where(Patient.IDENTIFIER.exactly().systemAndCode("urn:foo", null)) + .execute(); + assertEquals("http://example.com/fhir/Patient?identifier=urn%3Afoo%7C", capt.getAllValues().get(idx++).getURI().toString()); + //@formatter:on + + //@formatter:off + response = client.search() + .forResource("Patient") + .where(Patient.IDENTIFIER.exactly().systemAndCode("urn:foo", "")) + .execute(); + assertEquals("http://example.com/fhir/Patient?identifier=urn%3Afoo%7C", capt.getAllValues().get(idx++).getURI().toString()); + //@formatter:on + } + + /** + * Test for #192 + */ + @SuppressWarnings("unused") + @Test + public void testSearchByTokenWithEscaping() throws Exception { + final String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() { + @Override + public InputStream answer(InvocationOnMock theInvocation) throws Throwable { + return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); + } + }); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://foo"); + int index = 0; + String wantPrefix = "http://foo/Patient?identifier="; + + //@formatter:off + Bundle response = client.search() + .forResource("Patient") + .where(Patient.IDENTIFIER.exactly().systemAndCode("1", "2")) + .execute(); + String wantValue = "1|2"; + String url = capt.getAllValues().get(index).getURI().toString(); + assertThat(url, Matchers.startsWith(wantPrefix)); + assertEquals(wantValue, UrlUtil.unescape(url.substring(wantPrefix.length()))); + assertEquals(UrlUtil.escape(wantValue), url.substring(wantPrefix.length())); + index++; + //@formatter:on + + //@formatter:off + response = client.search() + .forResource("Patient") + .where(Patient.IDENTIFIER.exactly().systemAndCode("1,2", "3,4")) + .execute(); + wantValue = "1\\,2|3\\,4"; + url = capt.getAllValues().get(index).getURI().toString(); + assertThat(url, Matchers.startsWith(wantPrefix)); + assertEquals(wantValue, UrlUtil.unescape(url.substring(wantPrefix.length()))); + assertEquals(UrlUtil.escape(wantValue), url.substring(wantPrefix.length())); + index++; + //@formatter:on + + } + + @SuppressWarnings("unused") + @Test + public void testSearchIncludeRecursive() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource(Patient.class) + .include(Patient.INCLUDE_MANAGINGORGANIZATION) + .include(Patient.INCLUDE_LINK_OTHER.asRecursive()) + .include(Patient.INCLUDE_ALL.asNonRecursive()) + .execute(); + //@formatter:on + + assertThat(capt.getValue().getURI().toString(), containsString("http://example.com/fhir/Patient?")); + assertThat(capt.getValue().getURI().toString(), containsString("_include=" + Patient.INCLUDE_MANAGINGORGANIZATION.getValue())); + assertThat(capt.getValue().getURI().toString(), containsString("_include%3Arecurse=" + Patient.INCLUDE_LINK_OTHER.getValue())); + assertThat(capt.getValue().getURI().toString(), containsString("_include=*")); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchUsingGetSearch() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource("Patient") + .where(Patient.NAME.matches().value("james")) + .usingStyle(SearchStyleEnum.GET_WITH_SEARCH) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient/_search?name=james", capt.getValue().getURI().toString()); + } + + @SuppressWarnings("unused") + @Test + public void testSearchUsingPost() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource("Patient") + .where(Patient.NAME.matches().value("james")) + .usingStyle(SearchStyleEnum.POST) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient/_search", capt.getValue().getURI().toString()); + + HttpEntityEnclosingRequestBase enc = (HttpEntityEnclosingRequestBase) capt.getValue(); + UrlEncodedFormEntity ent = (UrlEncodedFormEntity) enc.getEntity(); + String string = IOUtils.toString(ent.getContent()); + ourLog.info(string); + assertEquals("name=james", string); + } + + @Test + public void testSearchWithAbsoluteUrl() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Bundle response = client.search(new UriDt("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json")); + + assertEquals("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json", capt.getValue().getURI().toString()); + + assertEquals(1, response.size()); + } + + @Test + public void testSearchWithAbsoluteUrlAndType() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Bundle response = client.search(Patient.class, new UriDt("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json")); + + assertEquals("http://example.com/fhir/Patient?birthdate=%3C%3D2012-01-22&birthdate=%3E2011-01-01&_include=Patient.managingOrganization&_sort%3Aasc=birthdate&_sort%3Adesc=name&_count=123&_format=json", capt.getValue().getURI().toString()); + + assertEquals(1, response.size()); + } + + @SuppressWarnings("unused") + @Test + public void testSearchWithClientEncodingAndPrettyPrintConfig() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + GenericClient client = (GenericClient) ourCtx.newRestfulGenericClient("http://example.com/fhir"); + client.setPrettyPrint(true); + client.setEncoding(EncodingEnum.JSON); + + //@formatter:off + Bundle response = client.search() + .forResource(Patient.class) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?_format=json&_pretty=true", capt.getValue().getURI().toString()); + + } + + @SuppressWarnings("unused") + @Test + public void testSearchWithEscapedParameters() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource("Patient") + .where(Patient.NAME.matches().values("NE,NE", "NE,NE")) + .where(Patient.NAME.matchesExactly().values("E$E")) + .where(Patient.NAME.matches().values("NE\\NE")) + .where(Patient.NAME.matchesExactly().values("E|E")) + .execute(); + //@formatter:on + + assertThat(capt.getValue().getURI().toString(), containsString("%3A")); + assertEquals("http://example.com/fhir/Patient?name=NE\\,NE,NE\\,NE&name=NE\\\\NE&name:exact=E\\$E&name:exact=E\\|E", UrlUtil.unescape(capt.getValue().getURI().toString())); + } + + @SuppressWarnings("unused") + @Test + public void testSearchWithInternalServerError() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 500, "INTERNAL ERRORS")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_TEXT + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("Server Issues!"), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + try { + client.search().forResource(Patient.class).execute(); + fail(); + } catch (InternalErrorException e) { + assertEquals(e.getMessage(), "HTTP 500 INTERNAL ERRORS: Server Issues!"); + assertEquals(e.getResponseBody(), "Server Issues!"); + } + + } + + @SuppressWarnings("unused") + @Test + public void testSearchWithNonFhirResponse() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_TEXT + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("Server Issues!"), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + try { + client.search().forResource(Patient.class).execute(); + fail(); + } catch (NonFhirResponseException e) { + assertThat(e.getMessage(), StringContains.containsString("Server Issues!")); + } + + } + + @SuppressWarnings("unused") + @Test + public void testSearchWithReverseInclude() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.search() + .forResource(Patient.class) + .encodedJson() + .revInclude(Provenance.INCLUDE_TARGET) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir/Patient?_revinclude=Provenance.target&_format=json", capt.getValue().getURI().toString()); + + } + + @Test + public void testSetDefaultEncoding() throws Exception { + + String msg = ourCtx.newJsonParser().encodeResourceToString(new Patient()); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + // Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 + // GMT"), + // new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"), + // new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; + // label=\"Some tag\"") }; + // when(myHttpResponse.getAllHeaders()).thenReturn(headers); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + (client).setEncoding(EncodingEnum.JSON); + int count = 0; + + client.read(Patient.class, new IdDt("Patient/1234")); + assertEquals("http://example.com/fhir/Patient/1234?_format=json", capt.getAllValues().get(count).getURI().toString()); + count++; + + } + + @Test + public void testTransaction() throws Exception { + String bundleStr = IOUtils.toString(getClass().getResourceAsStream("/bundle.json")); + Bundle bundle = ourCtx.newJsonParser().parseBundle(bundleStr); + + ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(bundleStr), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.transaction() + .withBundle(bundle) + .execute(); + //@formatter:on + + assertEquals("http://example.com/fhir", capt.getValue().getURI().toString()); + assertEquals(bundle.getEntries().get(0).getResource().getId(), response.getEntries().get(0).getResource().getId()); + assertEquals(EncodingEnum.XML.getBundleContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(0).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + + } + + @SuppressWarnings("deprecation") + @Test + public void testTransactionOldStyle() throws Exception { + String bundleStr = IOUtils.toString(getClass().getResourceAsStream("/bundle.json")); + Bundle bundle = ourCtx.newJsonParser().parseBundle(bundleStr); + + ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(bundleStr), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + List<IBaseResource> input = new ArrayList<IBaseResource>(); + input.addAll(bundle.toListOfResources()); + client.transaction(input); + } + + @Test + public void testTransactionJson() throws Exception { + String bundleStr = IOUtils.toString(getClass().getResourceAsStream("/bundle.json")); + Bundle bundle = ourCtx.newJsonParser().parseBundle(bundleStr); + + ArgumentCaptor<HttpUriRequest> 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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_JSON + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(bundleStr), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + //@formatter:off + Bundle response = client.transaction() + .withBundle(bundle) + .encodedJson() + .execute(); + //@formatter:on + + HttpEntityEnclosingRequestBase value = (HttpEntityEnclosingRequestBase) capt.getValue(); + + Header ct = value.getFirstHeader(Constants.HEADER_CONTENT_TYPE); + assertNotNull(ct); + assertEquals(Constants.CT_FHIR_JSON + "; charset=UTF-8", ct.getValue()); + + assertEquals("http://example.com/fhir", value.getURI().toString()); + assertThat(IOUtils.toString(value.getEntity().getContent()), StringContains.containsString("\"resourceType\"")); + assertEquals(bundle.getEntries().get(0).getResource().getId(), response.getEntries().get(0).getResource().getId()); + } + + @Test + public void testUpdate() throws Exception { + + Patient p1 = new Patient(); + p1.addIdentifier("foo:bar", "12345"); + p1.addName().addFamily("Smith").addGiven("John"); + TagList list = new TagList(); + list.addTag("http://hl7.org/fhir/tag", "urn:happytag", "This is a happy resource"); + ResourceMetadataKeyEnum.TAG_LIST.put(p1, list); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); + when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); + 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(""), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + try { + client.update().resource(p1).execute(); + fail(); + } catch (InvalidRequestException e) { + // should happen because no ID set + } + + assertEquals(0, capt.getAllValues().size()); + + p1.setId("44"); + client.update().resource(p1).execute(); + + int count = 0; + + assertEquals(1, capt.getAllValues().size()); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + count++; + + MethodOutcome outcome = client.update().resource(p1).execute(); + assertEquals("44", outcome.getId().getIdPart()); + assertEquals("22", outcome.getId().getVersionIdPart()); + + assertEquals(2, capt.getAllValues().size()); + + assertEquals("http://example.com/fhir/Patient/44", capt.getValue().getURI().toString()); + assertEquals("PUT", capt.getValue().getMethod()); + Header catH = capt.getValue().getFirstHeader("Category"); + assertNotNull(Arrays.asList(capt.getValue().getAllHeaders()).toString(), catH); + assertEquals("urn:happytag; label=\"This is a happy resource\"; scheme=\"http://hl7.org/fhir/tag\"", catH.getValue()); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + + /* + * Try fluent options + */ + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); + client.update().resource(p1).withId("123").execute(); + assertEquals(3, capt.getAllValues().size()); + assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(2).getURI().toString()); + + String resourceText = "<Patient xmlns=\"http://hl7.org/fhir\"> </Patient>"; + when(myHttpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); + client.update().resource(resourceText).withId("123").execute(); + assertEquals("http://example.com/fhir/Patient/123", capt.getAllValues().get(3).getURI().toString()); + assertEquals(resourceText, IOUtils.toString(((HttpPut) capt.getAllValues().get(3)).getEntity().getContent())); + assertEquals(4, capt.getAllValues().size()); + + } + + @Test + public void testUpdateWithStringAutoDetectsEncoding() throws Exception { + + Patient p1 = new Patient(); + p1.addIdentifier("foo:bar", "12345"); + p1.addName().addFamily("Smith").addGiven("John"); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 201, "OK")); + when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { new BasicHeader(Constants.HEADER_LOCATION, "/Patient/44/_history/22") }); + 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(""), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + int count = 0; + client.update().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).withId("1").execute(); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + assertThat(extractBody(capt, count), containsString("value=\"John\"")); + count++; + + client.update().resource(ourCtx.newJsonParser().encodeResourceToString(p1)).withId("1").execute(); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.JSON.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + assertThat(extractBody(capt, count), containsString("[\"John\"]")); + count++; + + /* + * e.g. Now try with reversed encoding (provide a string that's in JSON and ask the client to use XML) + */ + + client.update().resource(ourCtx.newXmlParser().encodeResourceToString(p1)).withId("1").encodedJson().execute(); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.JSON.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + assertThat(extractBody(capt, count), containsString("[\"John\"]")); + count++; + + client.update().resource(ourCtx.newJsonParser().encodeResourceToString(p1)).withId("1").encodedXml().execute(); + assertEquals(1, capt.getAllValues().get(count).getHeaders(Constants.HEADER_CONTENT_TYPE).length); + assertEquals(EncodingEnum.XML.getResourceContentType() + Constants.HEADER_SUFFIX_CT_UTF_8, capt.getAllValues().get(count).getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue()); + assertThat(extractBody(capt, count), containsString("value=\"John\"")); + count++; + } + + @Test + public void testValidateNonFluent() throws Exception { + + OperationOutcome oo = new OperationOutcome(); + oo.addIssue().setDetails("OOOK"); + + ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getAllHeaders()).thenReturn(new Header[] { }); + 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(ourCtx.newXmlParser().encodeResourceToString(oo)), Charset.forName("UTF-8"))); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient p1 = new Patient(); + p1.addIdentifier("foo:bar", "12345"); + p1.addName().addFamily("Smith").addGiven("John"); + + MethodOutcome resp = client.validate(p1); + assertEquals("http://example.com/fhir/Patient/_validate", capt.getValue().getURI().toString()); + oo = (OperationOutcome) resp.getOperationOutcome(); + assertEquals("OOOK", oo.getIssueFirstRep().getDetails().getValue()); + + } + + @Test + public void testVReadWithAbsoluteUrl() throws Exception { + + String msg = getResourceResult(); + + ArgumentCaptor<HttpUriRequest> 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.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"))); + Header[] headers = new Header[] { new BasicHeader(Constants.HEADER_LAST_MODIFIED, "Wed, 15 Nov 1995 04:58:08 GMT"), new BasicHeader(Constants.HEADER_CONTENT_LOCATION, "http://foo.com/Patient/123/_history/2333"), + new BasicHeader(Constants.HEADER_CATEGORY, "http://foo/tagdefinition.html; scheme=\"http://hl7.org/fhir/tag\"; label=\"Some tag\"") }; + when(myHttpResponse.getAllHeaders()).thenReturn(headers); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Patient response = client.vread(Patient.class, new IdDt("http://somebase.com/path/to/base/Patient/1234/_history/2222")); + assertThat(response.getNameFirstRep().getFamilyAsSingleString(), StringContains.containsString("Cardinal")); + assertEquals("http://somebase.com/path/to/base/Patient/1234/_history/2222", capt.getAllValues().get(0).getURI().toString()); + + try { + client.vread(Patient.class, new IdDt("http://somebase.com/path/to/base/Patient/1234")); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e.getMessage(), containsString("No version specified in URL")); + } + + } + + @BeforeClass + public static void beforeClass() { + ourCtx = FhirContext.forDstu1(); + } + + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + +}