From 4b7a4ac794a6c510b793349233179b495f10977b Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Wed, 7 May 2014 08:18:43 -0400 Subject: [PATCH] Lots of bug fixes and documentation tweaks - Several failing unit tests checked in, need to get these passing --- hapi-fhir-base/pom.xml | 2 + .../ca/uhn/fhir/context/ModelScanner.java | 75 +- .../ca/uhn/fhir/model/api/BundleCategory.java | 63 -- .../ca/uhn/fhir/model/api/BundleEntry.java | 17 +- .../java/ca/uhn/fhir/model/api/IResource.java | 37 +- .../main/java/ca/uhn/fhir/model/api/Tag.java | 42 +- .../java/ca/uhn/fhir/model/api/TagList.java | 13 +- .../uhn/fhir/model/api/ValueSetRegistry.java | 99 --- .../model/api/annotation/TagListParam.java | 25 + .../uhn/fhir/model/dstu/composite/AgeDt.java | 3 + .../uhn/fhir/model/dstu/resource/Binary.java | 3 - .../primitive/BoundCodeableConceptDt.java | 49 +- .../java/ca/uhn/fhir/parser/BaseParser.java | 17 + .../main/java/ca/uhn/fhir/parser/IParser.java | 46 +- .../java/ca/uhn/fhir/parser/JsonParser.java | 366 ++++---- .../java/ca/uhn/fhir/parser/ParserState.java | 185 +++- .../java/ca/uhn/fhir/parser/XmlParser.java | 107 ++- .../ca/uhn/fhir/rest/annotation/AddTags.java | 59 ++ .../uhn/fhir/rest/annotation/DeleteTags.java | 55 ++ .../ca/uhn/fhir/rest/annotation/GetTags.java | 63 ++ .../ca/uhn/fhir/rest/client/BaseClient.java | 8 +- .../rest/client/BaseClientInvocation.java | 7 +- .../BaseClientInvocationWithContents.java | 59 +- .../ca/uhn/fhir/rest/client/ClientCache.java | 124 --- .../rest/client/ClientInvocationHandler.java | 44 +- .../rest/client/DeleteClientInvocation.java | 4 +- .../uhn/fhir/rest/client/GenericClient.java | 27 +- .../fhir/rest/client/GetClientInvocation.java | 45 +- .../rest/client/PostClientInvocation.java | 12 +- .../fhir/rest/client/PutClientInvocation.java | 5 - .../fhir/rest/client/api/IRestfulClient.java | 12 + .../exceptions/NonFhirResponseException.java | 14 +- .../rest/method/AddTagsMethodBinding.java | 19 + .../BaseAddOrDeleteTagsMethodBinding.java | 207 +++++ .../fhir/rest/method/BaseMethodBinding.java | 158 +++- .../BaseOutcomeReturningMethodBinding.java | 171 ++-- ...turningMethodBindingWithResourceParam.java | 19 +- .../BaseResourceReturningMethodBinding.java | 75 +- .../rest/method/ConformanceMethodBinding.java | 14 +- .../fhir/rest/method/DeleteMethodBinding.java | 12 +- .../rest/method/DeleteTagsMethodBinding.java | 19 + .../rest/method/GetTagsMethodBinding.java | 182 ++++ .../rest/method/HistoryMethodBinding.java | 11 +- .../fhir/rest/method/ReadMethodBinding.java | 15 +- .../java/ca/uhn/fhir/rest/method/Request.java | 11 +- .../fhir/rest/method/SearchMethodBinding.java | 12 +- .../fhir/rest/method/UpdateMethodBinding.java | 17 +- .../java/ca/uhn/fhir/rest/method/Util.java | 31 - .../rest/method/ValidateMethodBinding.java | 3 +- .../ca/uhn/fhir/rest/param/IParameter.java | 1 - .../ca/uhn/fhir/rest/param/ParameterUtil.java | 167 ++-- .../uhn/fhir/rest/param/TagListParameter.java | 150 ---- .../ca/uhn/fhir/rest/server/Constants.java | 3 + .../ca/uhn/fhir/rest/server/EncodingEnum.java | 10 + .../uhn/fhir/rest/server/ResourceBinding.java | 2 +- .../uhn/fhir/rest/server/RestfulServer.java | 115 ++- .../BaseServerResponseException.java | 52 +- .../exceptions/InternalErrorException.java | 15 +- .../exceptions/InvalidRequestException.java | 7 +- .../exceptions/MethodNotAllowedException.java | 9 +- .../java/ca/uhn/fhir/util/ReflectionUtil.java | 12 +- .../ca/uhn/fhir/model/dstu/model.properties | 32 + .../example/java/example/ClientExamples.java | 22 +- .../site/example/java/example/Extensions.java | 1 + .../RestfulPatientResourceProviderMore.java | 145 +++ .../src/site/xdoc/doc_rest_client.xml | 24 +- .../src/site/xdoc/doc_rest_operations.xml | 297 +++++-- .../fhir/context/ResourceWithExtensionsA.java | 12 +- ...efaultThymeleafNarrativeGeneratorTest.java | 3 +- .../ca/uhn/fhir/parser/JsonParserTest.java | 827 +++++++++--------- .../ca/uhn/fhir/parser/XmlParserTest.java | 66 +- .../ca/uhn/fhir/rest/client/ClientTest.java | 270 +++--- .../client/InvalidClientDefinitionTest.java | 26 - .../uhn/fhir/rest/client/TagsClientTest.java | 270 ++++++ .../java/ca/uhn/fhir/rest/client/Tester.java | 2 +- .../fhir/rest/server/DocumentationTest.java | 2 +- .../rest/server/ResfulServerMethodTest.java | 17 +- .../fhir/rest/server/ResourceMethodTest.java | 10 +- .../uhn/fhir/rest/server/TagsServerTest.java | 294 +++++++ .../ca/uhn/fhir/jpa/dao/FhirResourceDao.java | 4 +- .../main/resources/META-INF/persistence.xml | 2 +- .../uhn/fhir/jpa/dao/FhirResourceDaoTest.java | 23 +- 82 files changed, 3762 insertions(+), 1793 deletions(-) delete mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleCategory.java delete mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ValueSetRegistry.java create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/annotation/TagListParam.java create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/AddTags.java create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/DeleteTags.java create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/GetTags.java delete mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/ClientCache.java create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/AddTagsMethodBinding.java create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseAddOrDeleteTagsMethodBinding.java create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DeleteTagsMethodBinding.java create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/GetTagsMethodBinding.java delete mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/TagListParameter.java create mode 100644 hapi-fhir-base/src/main/resources/ca/uhn/fhir/model/dstu/model.properties delete mode 100644 hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/InvalidClientDefinitionTest.java create mode 100644 hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/TagsClientTest.java create mode 100644 hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/TagsServerTest.java diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index ef047846f98..72a38d12f0d 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -225,6 +225,7 @@ maven-site-plugin 3.3 + + + +
- +

When implementing a server operation, there are a number of failure conditions - specified. For example, an - Instance Read request might specify an unknown - resource ID, or a Type Create request might contain an + specified. For example, an + Instance Read + request might specify an unknown + resource ID, or a + Type Create + request might contain an invalid resource which can not be created.

In these cases, an appropriate exception should be thrown. The HAPI RESTful - API includes a set of exceptions extending + API includes a set of exceptions extending BaseServerResponseException which represent specific HTTP failure codes.

- See the + See the Exceptions List - for a complete list of these exceptions. Note that these exceptions are all unchecked + for a complete list of these exceptions. Note that these exceptions are all + unchecked exceptions, so they do not need to ne explicitly declared in the method signature.

- + +
+ + + + +
+ +

+ FHIR RESTful servers may support a feature known as tagging. Tags are a set of + named flags called "terms" (with an optional accompanying human friendly name + called a "label", + and an optional namespace called a "scheme"). +

+

+ Tags have very specific semantics, which may not be + obvious simply by using the HAPI API. It is important to review the specification + pages + here + and + here + before attempting to implement tagging in your own applications. +

+ + + +

+ Tags are stored within a resource object, in the + IResource.html#getResourceMetadata() + map, under the key + TAG_LIST. +

+ +

+ In a server implementation, you may populate your tags into the + returned resource(s) and HAPI will automatically place these tags into + the response headers (for read/vread) or the bundle category tags (for search). + The following example illustrates how to return tags from a server method. This + example shows how to supply tags in a read method, but the same approach applies + to vread and search operations as well. +

+ + + + + + +

+ In a client operation, you simply call the read/vread/search method as you + normally would (as described above), and if any tags have been returned + by the server, these may be accessed from the resource metadata. +

+ + + + + + +
+ + + +

+ Within a Type Create + or Instance Update method, it is + possible for the client to specify a set of tags to be stored + along with the saved resource instance. +

+

+ Note that FHIR specifies that in an update method, any tags supplied + by the client are copied to the newly saved version, as well as any + tags the existing version had. +

+ +

+ To work with tags in a create/update method, the pattern used in the + read examples above is simply revered. In a server, the resource which + is passed in will be populated with any tags that the client supplied: +

+ + + + + + +
+ + + +

+ FHIR also provides a number of operations to interact directly + with tags. These methods may be used to retrieve lists of tags + that are available on the server, or to add or remove tags from + resources without interacting directly with those resources. +

+ +

+ On a server these methods may be placed in a plain provider, or in a resource + provider in the case of resource type specific methods. +

+ + + + + +

+ On a client, the methods are defined in the exact same way, except that + there is no method body in the client interface. +

+ +
+ +
+ diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/context/ResourceWithExtensionsA.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/context/ResourceWithExtensionsA.java index b881773720d..03ce07ac5ee 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/context/ResourceWithExtensionsA.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/context/ResourceWithExtensionsA.java @@ -100,7 +100,7 @@ public class ResourceWithExtensionsA extends BaseResource { @Override public boolean isEmpty() { - return false; // TODO: implement + return false; // not implemented } @Override @@ -110,7 +110,7 @@ public class ResourceWithExtensionsA extends BaseResource { @Override public List getAllPopulatedChildElementsOfType(Class theType) { - return ca.uhn.fhir.util.ElementUtil.allPopulatedChildElements(theType ); // TODO: implement + return ca.uhn.fhir.util.ElementUtil.allPopulatedChildElements(theType ); // not implemented } @@ -159,7 +159,7 @@ public class ResourceWithExtensionsA extends BaseResource { @Override public boolean isEmpty() { - return false; // TODO: implement + return false; // not implemented } @Override @@ -169,7 +169,7 @@ public class ResourceWithExtensionsA extends BaseResource { @Override public List getAllPopulatedChildElementsOfType(Class theType) { - return ca.uhn.fhir.util.ElementUtil.allPopulatedChildElements(theType ); // TODO: implement + return ca.uhn.fhir.util.ElementUtil.allPopulatedChildElements(theType ); // not implemented } @@ -204,7 +204,7 @@ public class ResourceWithExtensionsA extends BaseResource { @Override public boolean isEmpty() { - return false; // TODO: implement + return false; // not implemented } @Override @@ -214,7 +214,7 @@ public class ResourceWithExtensionsA extends BaseResource { @Override public List getAllPopulatedChildElementsOfType(Class theType) { - return ca.uhn.fhir.util.ElementUtil.allPopulatedChildElements(theType ); // TODO: implement + return ca.uhn.fhir.util.ElementUtil.allPopulatedChildElements(theType ); // not implemented } diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/narrative/DefaultThymeleafNarrativeGeneratorTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/narrative/DefaultThymeleafNarrativeGeneratorTest.java index 44b3629baae..0e03ceea7d8 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/narrative/DefaultThymeleafNarrativeGeneratorTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/narrative/DefaultThymeleafNarrativeGeneratorTest.java @@ -2,7 +2,6 @@ package ca.uhn.fhir.narrative; import static org.junit.Assert.*; -import java.io.IOException; import java.io.InputStreamReader; import java.util.Date; @@ -77,7 +76,7 @@ public class DefaultThymeleafNarrativeGeneratorTest { } @Test - public void testGenerateDiagnosticReportWithObservations() throws DataFormatException, IOException { + public void testGenerateDiagnosticReportWithObservations() throws DataFormatException { DiagnosticReport value = new DiagnosticReport(); value.getIssued().setValueAsString("2011-02-22T11:13:00"); diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java index 6647b82965d..e31c5f5d1b4 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/JsonParserTest.java @@ -23,6 +23,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.BundleEntry; import ca.uhn.fhir.model.api.ExtensionDt; +import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.Extension; import ca.uhn.fhir.model.api.annotation.ResourceDef; @@ -50,19 +51,73 @@ import ca.uhn.fhir.narrative.INarrativeGenerator; public class JsonParserTest { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonParserTest.class); - /** - * This sample has extra elements in that are not actually a part of the spec any more.. - */ @Test - public void testParseFuroreMetadataWithExtraElements() throws IOException { - String msg = IOUtils.toString(JsonParserTest.class.getResourceAsStream("/furore-conformance.json")); + public void testTagList() { + + //@formatter:off + String tagListStr = "{\n" + + " \"resourceType\" : \"TagList\", " + + " \"category\" : [" + + " { " + + " \"term\" : \"term0\", " + + " \"label\" : \"label0\", " + + " \"scheme\" : \"scheme0\" " + + " }," + + " { " + + " \"term\" : \"term1\", " + + " \"label\" : \"label1\", " + + " \"scheme\" : null " + + " }," + + " { " + + " \"term\" : \"term2\", " + + " \"label\" : \"label2\" " + + " }" + + " ] " + + "}"; + //@formatter:on + + TagList tagList = new FhirContext().newJsonParser().parseTagList(tagListStr); + assertEquals(3, tagList.size()); + assertEquals("term0", tagList.get(0).getTerm()); + assertEquals("label0", tagList.get(0).getLabel()); + assertEquals("scheme0", tagList.get(0).getScheme()); + assertEquals("term1", tagList.get(1).getTerm()); + assertEquals("label1", tagList.get(1).getLabel()); + assertEquals(null, tagList.get(1).getScheme()); + assertEquals("term2", tagList.get(2).getTerm()); + assertEquals("label2", tagList.get(2).getLabel()); + assertEquals(null, tagList.get(2).getScheme()); + + /* + * Encode + */ + + //@formatter:off + String expected = "{" + + "\"resourceType\":\"TagList\"," + + "\"category\":[" + + "{" + + "\"term\":\"term0\"," + + "\"label\":\"label0\"," + + "\"scheme\":\"scheme0\"" + + "}," + + "{" + + "\"term\":\"term1\"," + + "\"label\":\"label1\"" + + "}," + + "{" + + "\"term\":\"term2\"," + + "\"label\":\"label2\"" + + "}" + + "]" + + "}"; + //@formatter:on + + String encoded = new FhirContext().newJsonParser().encodeTagListToString(tagList); + assertEquals(expected,encoded); - IParser p = new FhirContext(ValueSet.class).newJsonParser(); - Conformance conf = p.parseResource(Conformance.class, msg); - RestResource res = conf.getRestFirstRep().getResourceFirstRep(); - assertEquals("_id", res.getSearchParam().get(1).getName().getValue()); } - + @Test public void testEncodeBundleCategory() { @@ -88,368 +143,6 @@ public class JsonParserTest { } - @Test - public void testBrokenPatient() { - - String resource = "{\n" + - " \"resourceType\": \"Patient\",\n" + - " \"extension\": [\n" + - " {\n" + - " \"url\": \"http://mayoweb.mayo.edu/dms-it/reference/data_standards/reg-ctable-race.html#curr_race\",\n" + - " \"valueCodeableConcept\": {\n" + - " \"coding\": [\n" + - " {\n" + - " \"system\": \"http://mayoweb.mayo.edu/dms-it/reference/data_standards/reg-ctable-race.html#curr_race\",\n" + - " \"code\": \"O\",\n" + - " \"display\": \"Other\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " },\n" + - " {\n" + - " \"url\": \"http://mayoweb.mayo.edu/dms-it/reference/data_standards/reg-ctable-race.html#curr_ethn\",\n" + - " \"valueCodeableConcept\": {\n" + - " \"coding\": [\n" + - " {\n" + - " \"system\": \"http://mayoweb.mayo.edu/dms-it/reference/data_standards/reg-ctable-race.html#curr_ethn\",\n" + - " \"code\": \"HA\",\n" + - " \"display\": \"Central American\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " }\n" + - " ],\n" + - " \"identifier\": [\n" + - " {\n" + - " \"label\": \"MAYO-CLINIC-NUMBER\",\n" + - " \"value\": \"3982540\"\n" + - " }\n" + - " ],\n" + - " \"name\": [\n" + - " {\n" + - " \"use\": \"usual\",\n" + - " \"text\": \"Hurt, Mr. John Stevens\",\n" + - " \"family\": [\n" + - " \"Hurt\"\n" + - " ],\n" + - " \"given\": [\n" + - " \"John Stevens\"\n" + - " ],\n" + - " \"prefix\": [\n" + - " \"Mr.\"\n" + - " ],\n" + - " \"suffix\": [\n" + - " null\n" + - " ]\n" + - " }\n" + - " ],\n" + - " \"telecom\": [\n" + - " {\n" + - " \"system\": \"phone\",\n" + - " \"value\": \"(507)284-0122\"\n" + - " }\n" + - " ],\n" + - " \"gender\": {\n" + - " \"coding\": [\n" + - " {\n" + - " \"system\": \"http://hl7.org/fhir/v3/AdministrativeGender\",\n" + - " \"code\": \"M\",\n" + - " \"display\": \"MALE\"\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"birthDate\": \"1986-05-01T00:00:00-05:00\",\n" + - " \"deceasedDateTime\": \"0001-01-01T00:00:00-06:00\",\n" + - " \"address\": [\n" + - " {\n" + - " \"use\": \"home\",\n" + - " \"line\": [\n" + - " \"100 Quality Control Avenue\"\n" + - " ],\n" + - " \"city\": \"Test Patient\",\n" + - " \"state\": \"MINNESOTA\",\n" + - " \"zip\": \"55905\",\n" + - " \"country\": \"USA\"\n" + - " }\n" + - " ],\n" + - " \"maritalStatus\": {\n" + - " \"coding\": [\n" + - " {\n" + - " \"system\": \"http://hl7.org/fhir/v3/MaritalStatus\",\n" + - " \"code\": \"M\",\n" + - " \"display\": \"Married\"\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"communication\": [\n" + - " {\n" + - " \"coding\": [\n" + - " {\n" + - " \"code\": \"ENG\",\n" + - " \"display\": \"ENGLISH\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " ]\n" + - "}"; - - FhirContext ctx = new FhirContext(); - Patient patient = ctx.newJsonParser().parseResource(Patient.class, resource); - System.out.println(patient.getNameFirstRep().getFamilyAsSingleString()); - - } - - - @Test - public void testEncodeExtensionWithResourceContent() throws IOException { - IParser parser = new FhirContext().newJsonParser(); - - Patient patient = new Patient(); - patient.addAddress().setUse(AddressUseEnum.HOME); - patient.addUndeclaredExtension(false, "urn:foo", new ResourceReferenceDt(Organization.class, "123")); - - String val = parser.encodeResourceToString(patient); - ourLog.info(val); - assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueResource\":{\"resource\":\"Organization/123\"}}]")); - - Patient actual = parser.parseResource(Patient.class, val); - assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum()); - List ext = actual.getUndeclaredExtensionsByUrl("urn:foo"); - assertEquals(1, ext.size()); - ResourceReferenceDt ref = (ResourceReferenceDt) ext.get(0).getValue(); - assertEquals("Organization/123", ref.getResourceUrl()); - - } - - @Test - public void testEncodeDeclaredExtensionWithResourceContent() throws IOException { - IParser parser = new FhirContext().newJsonParser(); - - MyPatientWithOneDeclaredExtension patient = new MyPatientWithOneDeclaredExtension(); - patient.addAddress().setUse(AddressUseEnum.HOME); - patient.setFoo(new ResourceReferenceDt(Organization.class, "123")); - - String val = parser.encodeResourceToString(patient); - ourLog.info(val); - assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueResource\":{\"resource\":\"Organization/123\"}}]")); - - MyPatientWithOneDeclaredExtension actual = parser.parseResource(MyPatientWithOneDeclaredExtension.class, val); - assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum()); - ResourceReferenceDt ref = actual.getFoo(); - assertEquals("Organization/123", ref.getResourceUrl()); - - } - - - @Test - public void testEncodeDeclaredExtensionWithAddressContent() throws IOException { - IParser parser = new FhirContext().newJsonParser(); - - MyPatientWithOneDeclaredAddressExtension patient = new MyPatientWithOneDeclaredAddressExtension(); - patient.addAddress().setUse(AddressUseEnum.HOME); - patient.setFoo(new AddressDt().addLine("line1")); - - String val = parser.encodeResourceToString(patient); - ourLog.info(val); - assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueAddress\":{\"line\":[\"line1\"]}}]")); - - MyPatientWithOneDeclaredAddressExtension actual = parser.parseResource(MyPatientWithOneDeclaredAddressExtension.class, val); - assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum()); - AddressDt ref = actual.getFoo(); - assertEquals("line1", ref.getLineFirstRep().getValue()); - - } - - - @Test - public void testEncodeUndeclaredExtensionWithAddressContent() throws IOException { - IParser parser = new FhirContext().newJsonParser(); - - Patient patient = new Patient(); - patient.addAddress().setUse(AddressUseEnum.HOME); - patient.addUndeclaredExtension(false, "urn:foo", new AddressDt().addLine("line1")); - - String val = parser.encodeResourceToString(patient); - ourLog.info(val); - assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueAddress\":{\"line\":[\"line1\"]}}]")); - - MyPatientWithOneDeclaredAddressExtension actual = parser.parseResource(MyPatientWithOneDeclaredAddressExtension.class, val); - assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum()); - AddressDt ref = actual.getFoo(); - assertEquals("line1", ref.getLineFirstRep().getValue()); - - } - - - @ResourceDef(name = "Patient") - public static class MyPatientWithOneDeclaredExtension extends Patient { - - @Child(order = 0, name = "foo") - @Extension(url = "urn:foo", definedLocally = true, isModifier = false) - private ResourceReferenceDt myFoo; - - public ResourceReferenceDt getFoo() { - return myFoo; - } - - public void setFoo(ResourceReferenceDt theFoo) { - myFoo = theFoo; - } - - } - - - @ResourceDef(name = "Patient") - public static class MyPatientWithOneDeclaredAddressExtension extends Patient { - - @Child(order = 0, name = "foo") - @Extension(url = "urn:foo", definedLocally = true, isModifier = false) - private AddressDt myFoo; - - public AddressDt getFoo() { - return myFoo; - } - - public void setFoo(AddressDt theFoo) { - myFoo = theFoo; - } - - } - - @Test - public void testEncodeExt() throws Exception { - - ValueSet valueSet = new ValueSet(); - Define define = valueSet.getDefine(); - DefineConcept code = define.addConcept(); - code.setCode("someCode"); - code.setDisplay("someDisplay"); - code.addUndeclaredExtension(false, "urn:alt", new StringDt("alt name")); - - String encoded = new FhirContext().newJsonParser().encodeResourceToString(valueSet); - ourLog.info(encoded); - - } - - @Test - public void testEncodeResourceRef() throws DataFormatException, IOException { - - Patient patient = new Patient(); - patient.setManagingOrganization(new ResourceReferenceDt()); - - IParser p = new FhirContext().newJsonParser(); - String str = p.encodeResourceToString(patient); - assertThat(str, IsNot.not(StringContains.containsString("managingOrganization"))); - - patient.setManagingOrganization(new ResourceReferenceDt(Organization.class, "123")); - str = p.encodeResourceToString(patient); - assertThat(str, StringContains.containsString("\"managingOrganization\":{\"resource\":\"Organization/123\"}")); - - Organization org = new Organization(); - org.addIdentifier().setSystem("foo").setValue("bar"); - patient.setManagingOrganization(new ResourceReferenceDt(org)); - str = p.encodeResourceToString(patient); - assertThat(str, StringContains.containsString("\"contained\":[{\"resourceType\":\"Organization\"")); - - } - - @Test - public void testNarrativeGeneration() throws DataFormatException, IOException { - - Patient patient = new Patient(); - patient.addName().addFamily("Smith"); - Organization org = new Organization(); - patient.getManagingOrganization().setResource(org); - - INarrativeGenerator gen = mock(INarrativeGenerator.class); - XhtmlDt xhtmlDt = new XhtmlDt("
help
"); - NarrativeDt nar = new NarrativeDt(xhtmlDt, NarrativeStatusEnum.GENERATED); - when(gen.generateNarrative(eq("http://hl7.org/fhir/profiles/Patient"), eq(patient))).thenReturn(nar); - - FhirContext context = new FhirContext(); - context.setNarrativeGenerator(gen); - IParser p = context.newJsonParser(); - p.encodeResourceToWriter(patient, new OutputStreamWriter(System.out)); - String str = p.encodeResourceToString(patient); - - ourLog.info(str); - - assertThat(str, StringContains.containsString(",\"text\":{\"status\":\"generated\",\"div\":\"
help
\"},")); - } - - @Test - public void testSimpleResourceEncode() throws IOException { - - FhirContext ctx = new FhirContext(Observation.class); - String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.xml"), Charset.forName("UTF-8")); - Patient obs = ctx.newXmlParser().parseResource(Patient.class, xmlString); - - List undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions(); - ExtensionDt undeclaredExtension = undeclaredExtensions.get(0); - assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl().getValue()); - - ctx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out)); - - IParser jsonParser = ctx.newJsonParser(); - String encoded = jsonParser.encodeResourceToString(obs); - ourLog.info(encoded); - - String jsonString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.json")); - - JSON expected = JSONSerializer.toJSON(jsonString); - JSON actual = JSONSerializer.toJSON(encoded.trim()); - - ourLog.info("Expected: {}", expected); - ourLog.info("Actual : {}", actual); - assertEquals(expected.toString(), actual.toString()); - - } - - @Test - public void testSimpleResourceEncodeWithCustomType() throws IOException { - - FhirContext ctx = new FhirContext(MyObservationWithExtensions.class); - String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.xml"), Charset.forName("UTF-8")); - MyObservationWithExtensions obs = ctx.newXmlParser().parseResource(MyObservationWithExtensions.class, xmlString); - - assertEquals(0, obs.getAllUndeclaredExtensions().size()); - assertEquals("aaaa", obs.getExtAtt().getContentType().getValue()); - assertEquals("str1", obs.getMoreExt().getStr1().getValue()); - assertEquals("2011-01-02", obs.getModExt().getValueAsString()); - - List undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions(); - ExtensionDt undeclaredExtension = undeclaredExtensions.get(0); - assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl().getValue()); - - ctx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out)); - - IParser jsonParser = ctx.newJsonParser(); - String encoded = jsonParser.encodeResourceToString(obs); - ourLog.info(encoded); - - String jsonString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.json")); - - JSON expected = JSONSerializer.toJSON(jsonString); - JSON actual = JSONSerializer.toJSON(encoded.trim()); - - ourLog.info("Expected: {}", expected); - ourLog.info("Actual : {}", actual); - assertEquals(expected.toString(), actual.toString()); - - } - - @Test - public void testSimpleBundleEncode() throws IOException { - - FhirContext ctx = new FhirContext(Observation.class, Patient.class); - String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/atom-document-large.xml"), Charset.forName("UTF-8")); - Bundle obs = ctx.newXmlParser().parseBundle(xmlString); - - String encoded = ctx.newJsonParser().encodeBundleToString(obs); - ourLog.info(encoded); - - } - @Test public void testEncodeContainedResources() throws IOException { @@ -462,69 +155,10 @@ public class JsonParserTest { ourLog.info(encoded); } - + + @Test - public void testSimpleParse() throws DataFormatException, IOException { - - String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/example-patient-general.json")); - FhirContext ctx = new FhirContext(Patient.class); - IParser p = ctx.newJsonParser(); - // ourLog.info("Reading in message: {}", msg); - Patient res = p.parseResource(Patient.class, msg); - - assertEquals(2, res.getUndeclaredExtensions().size()); - assertEquals(1, res.getUndeclaredModifierExtensions().size()); - - String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(res); - ourLog.info(encoded); - - } - - @Test - public void testParseBundle() throws DataFormatException, IOException { - - String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/atom-document-large.json")); - FhirContext ctx = new FhirContext(Patient.class); - IParser p = ctx.newJsonParser(); - Bundle bundle = p.parseBundle(msg); - - String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeBundleToString(bundle); - ourLog.info(encoded); - - assertEquals("http://fhir.healthintersections.com.au/open/DiagnosticReport/_search?_format=application/json+fhir&search-id=46d5f0e7-9240-4d4f-9f51-f8ac975c65&search-sort=_id", bundle - .getLinkSelf().getValue()); - assertEquals("urn:uuid:0b754ff9-03cf-4322-a119-15019af8a3", bundle.getBundleId().getValue()); - - BundleEntry entry = bundle.getEntries().get(0); - assertEquals("http://fhir.healthintersections.com.au/open/DiagnosticReport/101", entry.getId().getValue()); - assertEquals("http://fhir.healthintersections.com.au/open/DiagnosticReport/101/_history/1", entry.getLinkSelf().getValue()); - assertEquals("2014-03-10T11:55:59Z", entry.getUpdated().getValueAsString()); - - DiagnosticReport res = (DiagnosticReport) entry.getResource(); - assertEquals("Complete Blood Count", res.getName().getText().getValue()); - - } - - @Test - public void testParseWithContained() throws DataFormatException, IOException { - - String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/diagnostic-report.json")); - FhirContext ctx = new FhirContext(Patient.class); - IParser p = ctx.newJsonParser(); - // ourLog.info("Reading in message: {}", msg); - DiagnosticReport res = p.parseResource(DiagnosticReport.class, msg); - - String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(res); - ourLog.info(encoded); - - ResourceReferenceDt reference = res.getResult().get(1); - Observation obs = (Observation) reference.getResource(); - - assertEquals("789-8", obs.getName().getCoding().get(0).getCode().getValue()); - } - - @Test - public void testEncodeContainedResourcesMore() throws IOException { + public void testEncodeContainedResourcesMore() { DiagnosticReport rpt = new DiagnosticReport(); Specimen spm = new Specimen(); @@ -548,7 +182,85 @@ public class JsonParserTest { } @Test - public void testEncodeInvalidChildGoodException() throws IOException { + public void testEncodeDeclaredExtensionWithAddressContent() { + IParser parser = new FhirContext().newJsonParser(); + + MyPatientWithOneDeclaredAddressExtension patient = new MyPatientWithOneDeclaredAddressExtension(); + patient.addAddress().setUse(AddressUseEnum.HOME); + patient.setFoo(new AddressDt().addLine("line1")); + + String val = parser.encodeResourceToString(patient); + ourLog.info(val); + assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueAddress\":{\"line\":[\"line1\"]}}]")); + + MyPatientWithOneDeclaredAddressExtension actual = parser.parseResource(MyPatientWithOneDeclaredAddressExtension.class, val); + assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum()); + AddressDt ref = actual.getFoo(); + assertEquals("line1", ref.getLineFirstRep().getValue()); + + } + + + @Test + public void testEncodeDeclaredExtensionWithResourceContent() { + IParser parser = new FhirContext().newJsonParser(); + + MyPatientWithOneDeclaredExtension patient = new MyPatientWithOneDeclaredExtension(); + patient.addAddress().setUse(AddressUseEnum.HOME); + patient.setFoo(new ResourceReferenceDt(Organization.class, "123")); + + String val = parser.encodeResourceToString(patient); + ourLog.info(val); + assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueResource\":{\"resource\":\"Organization/123\"}}]")); + + MyPatientWithOneDeclaredExtension actual = parser.parseResource(MyPatientWithOneDeclaredExtension.class, val); + assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum()); + ResourceReferenceDt ref = actual.getFoo(); + assertEquals("Organization/123", ref.getResourceUrl()); + + } + + + @Test + public void testEncodeExt() throws Exception { + + ValueSet valueSet = new ValueSet(); + Define define = valueSet.getDefine(); + DefineConcept code = define.addConcept(); + code.setCode("someCode"); + code.setDisplay("someDisplay"); + code.addUndeclaredExtension(false, "urn:alt", new StringDt("alt name")); + + String encoded = new FhirContext().newJsonParser().encodeResourceToString(valueSet); + ourLog.info(encoded); + + } + + + @Test + public void testEncodeExtensionWithResourceContent() { + IParser parser = new FhirContext().newJsonParser(); + + Patient patient = new Patient(); + patient.addAddress().setUse(AddressUseEnum.HOME); + patient.addUndeclaredExtension(false, "urn:foo", new ResourceReferenceDt(Organization.class, "123")); + + String val = parser.encodeResourceToString(patient); + ourLog.info(val); + assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueResource\":{\"resource\":\"Organization/123\"}}]")); + + Patient actual = parser.parseResource(Patient.class, val); + assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum()); + List ext = actual.getUndeclaredExtensionsByUrl("urn:foo"); + assertEquals(1, ext.size()); + ResourceReferenceDt ref = (ResourceReferenceDt) ext.get(0).getValue(); + assertEquals("Organization/123", ref.getResourceUrl()); + + } + + + @Test + public void testEncodeInvalidChildGoodException() { Observation obs = new Observation(); obs.setValue(new DecimalDt(112.22)); @@ -560,6 +272,47 @@ public class JsonParserTest { assertThat(e.getMessage(), StringContains.containsString("PeriodDt")); } } + + @Test + public void testEncodeResourceRef() throws DataFormatException { + + Patient patient = new Patient(); + patient.setManagingOrganization(new ResourceReferenceDt()); + + IParser p = new FhirContext().newJsonParser(); + String str = p.encodeResourceToString(patient); + assertThat(str, IsNot.not(StringContains.containsString("managingOrganization"))); + + patient.setManagingOrganization(new ResourceReferenceDt(Organization.class, "123")); + str = p.encodeResourceToString(patient); + assertThat(str, StringContains.containsString("\"managingOrganization\":{\"resource\":\"Organization/123\"}")); + + Organization org = new Organization(); + org.addIdentifier().setSystem("foo").setValue("bar"); + patient.setManagingOrganization(new ResourceReferenceDt(org)); + str = p.encodeResourceToString(patient); + assertThat(str, StringContains.containsString("\"contained\":[{\"resourceType\":\"Organization\"")); + + } + + @Test + public void testEncodeUndeclaredExtensionWithAddressContent() { + IParser parser = new FhirContext().newJsonParser(); + + Patient patient = new Patient(); + patient.addAddress().setUse(AddressUseEnum.HOME); + patient.addUndeclaredExtension(false, "urn:foo", new AddressDt().addLine("line1")); + + String val = parser.encodeResourceToString(patient); + ourLog.info(val); + assertThat(val, StringContains.containsString("\"extension\":[{\"url\":\"urn:foo\",\"valueAddress\":{\"line\":[\"line1\"]}}]")); + + MyPatientWithOneDeclaredAddressExtension actual = parser.parseResource(MyPatientWithOneDeclaredAddressExtension.class, val); + assertEquals(AddressUseEnum.HOME, patient.getAddressFirstRep().getUse().getValueAsEnum()); + AddressDt ref = actual.getFoo(); + assertEquals("line1", ref.getLineFirstRep().getValue()); + + } @Test public void testExtensionOnComposite() throws Exception { @@ -654,4 +407,208 @@ public class JsonParserTest { } + @Test + public void testNarrativeGeneration() throws DataFormatException, IOException { + + Patient patient = new Patient(); + patient.addName().addFamily("Smith"); + Organization org = new Organization(); + patient.getManagingOrganization().setResource(org); + + INarrativeGenerator gen = mock(INarrativeGenerator.class); + XhtmlDt xhtmlDt = new XhtmlDt("
help
"); + NarrativeDt nar = new NarrativeDt(xhtmlDt, NarrativeStatusEnum.GENERATED); + when(gen.generateNarrative(eq("http://hl7.org/fhir/profiles/Patient"), eq(patient))).thenReturn(nar); + + FhirContext context = new FhirContext(); + context.setNarrativeGenerator(gen); + IParser p = context.newJsonParser(); + p.encodeResourceToWriter(patient, new OutputStreamWriter(System.out)); + String str = p.encodeResourceToString(patient); + + ourLog.info(str); + + assertThat(str, StringContains.containsString(",\"text\":{\"status\":\"generated\",\"div\":\"
help
\"},")); + } + + @Test + public void testParseBundle() throws DataFormatException, IOException { + + String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/atom-document-large.json")); + FhirContext ctx = new FhirContext(Patient.class); + IParser p = ctx.newJsonParser(); + Bundle bundle = p.parseBundle(msg); + + String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeBundleToString(bundle); + ourLog.info(encoded); + + assertEquals("http://fhir.healthintersections.com.au/open/DiagnosticReport/_search?_format=application/json+fhir&search-id=46d5f0e7-9240-4d4f-9f51-f8ac975c65&search-sort=_id", bundle + .getLinkSelf().getValue()); + assertEquals("urn:uuid:0b754ff9-03cf-4322-a119-15019af8a3", bundle.getBundleId().getValue()); + + BundleEntry entry = bundle.getEntries().get(0); + assertEquals("http://fhir.healthintersections.com.au/open/DiagnosticReport/101", entry.getId().getValue()); + assertEquals("http://fhir.healthintersections.com.au/open/DiagnosticReport/101/_history/1", entry.getLinkSelf().getValue()); + assertEquals("2014-03-10T11:55:59Z", entry.getUpdated().getValueAsString()); + + DiagnosticReport res = (DiagnosticReport) entry.getResource(); + assertEquals("Complete Blood Count", res.getName().getText().getValue()); + + } + + /** + * This sample has extra elements in that are not actually a part of the spec any more.. + */ + @Test + public void testParseFuroreMetadataWithExtraElements() throws IOException { + String msg = IOUtils.toString(JsonParserTest.class.getResourceAsStream("/furore-conformance.json")); + + IParser p = new FhirContext(ValueSet.class).newJsonParser(); + Conformance conf = p.parseResource(Conformance.class, msg); + RestResource res = conf.getRestFirstRep().getResourceFirstRep(); + assertEquals("_id", res.getSearchParam().get(1).getName().getValue()); + } + + @Test + public void testParseWithContained() throws DataFormatException, IOException { + + String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/diagnostic-report.json")); + FhirContext ctx = new FhirContext(Patient.class); + IParser p = ctx.newJsonParser(); + // ourLog.info("Reading in message: {}", msg); + DiagnosticReport res = p.parseResource(DiagnosticReport.class, msg); + + String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(res); + ourLog.info(encoded); + + ResourceReferenceDt reference = res.getResult().get(1); + Observation obs = (Observation) reference.getResource(); + + assertEquals("789-8", obs.getName().getCoding().get(0).getCode().getValue()); + } + + @Test + public void testSimpleBundleEncode() throws IOException { + + FhirContext ctx = new FhirContext(Observation.class, Patient.class); + String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/atom-document-large.xml"), Charset.forName("UTF-8")); + Bundle obs = ctx.newXmlParser().parseBundle(xmlString); + + String encoded = ctx.newJsonParser().encodeBundleToString(obs); + ourLog.info(encoded); + + } + + @Test + public void testSimpleParse() throws DataFormatException, IOException { + + String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/example-patient-general.json")); + FhirContext ctx = new FhirContext(Patient.class); + IParser p = ctx.newJsonParser(); + // ourLog.info("Reading in message: {}", msg); + Patient res = p.parseResource(Patient.class, msg); + + assertEquals(2, res.getUndeclaredExtensions().size()); + assertEquals(1, res.getUndeclaredModifierExtensions().size()); + + String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(res); + ourLog.info(encoded); + + } + + @Test + public void testSimpleResourceEncode() throws IOException { + + FhirContext ctx = new FhirContext(Observation.class); + String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.xml"), Charset.forName("UTF-8")); + Patient obs = ctx.newXmlParser().parseResource(Patient.class, xmlString); + + List undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions(); + ExtensionDt undeclaredExtension = undeclaredExtensions.get(0); + assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl().getValue()); + + ctx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out)); + + IParser jsonParser = ctx.newJsonParser(); + String encoded = jsonParser.encodeResourceToString(obs); + ourLog.info(encoded); + + String jsonString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.json")); + + JSON expected = JSONSerializer.toJSON(jsonString); + JSON actual = JSONSerializer.toJSON(encoded.trim()); + + ourLog.info("Expected: {}", expected); + ourLog.info("Actual : {}", actual); + assertEquals(expected.toString(), actual.toString()); + + } + + @Test + public void testSimpleResourceEncodeWithCustomType() throws IOException { + + FhirContext ctx = new FhirContext(MyObservationWithExtensions.class); + String xmlString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.xml"), Charset.forName("UTF-8")); + MyObservationWithExtensions obs = ctx.newXmlParser().parseResource(MyObservationWithExtensions.class, xmlString); + + assertEquals(0, obs.getAllUndeclaredExtensions().size()); + assertEquals("aaaa", obs.getExtAtt().getContentType().getValue()); + assertEquals("str1", obs.getMoreExt().getStr1().getValue()); + assertEquals("2011-01-02", obs.getModExt().getValueAsString()); + + List undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions(); + ExtensionDt undeclaredExtension = undeclaredExtensions.get(0); + assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl().getValue()); + + ctx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out)); + + IParser jsonParser = ctx.newJsonParser(); + String encoded = jsonParser.encodeResourceToString(obs); + ourLog.info(encoded); + + String jsonString = IOUtils.toString(JsonParser.class.getResourceAsStream("/example-patient-general.json")); + + JSON expected = JSONSerializer.toJSON(jsonString); + JSON actual = JSONSerializer.toJSON(encoded.trim()); + + ourLog.info("Expected: {}", expected); + ourLog.info("Actual : {}", actual); + assertEquals(expected.toString(), actual.toString()); + + } + + @ResourceDef(name = "Patient") + public static class MyPatientWithOneDeclaredAddressExtension extends Patient { + + @Child(order = 0, name = "foo") + @Extension(url = "urn:foo", definedLocally = true, isModifier = false) + private AddressDt myFoo; + + public AddressDt getFoo() { + return myFoo; + } + + public void setFoo(AddressDt theFoo) { + myFoo = theFoo; + } + + } + + @ResourceDef(name = "Patient") + public static class MyPatientWithOneDeclaredExtension extends Patient { + + @Child(order = 0, name = "foo") + @Extension(url = "urn:foo", definedLocally = true, isModifier = false) + private ResourceReferenceDt myFoo; + + public ResourceReferenceDt getFoo() { + return myFoo; + } + + public void setFoo(ResourceReferenceDt theFoo) { + myFoo = theFoo; + } + + } + } diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java index 107a42a8f10..c82cb8e02e2 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java @@ -31,6 +31,8 @@ import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.BundleEntry; import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; +import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.dstu.composite.AddressDt; import ca.uhn.fhir.model.dstu.composite.HumanNameDt; import ca.uhn.fhir.model.dstu.composite.NarrativeDt; @@ -49,6 +51,7 @@ import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum; import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum; import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.model.primitive.DecimalDt; +import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.XhtmlDt; import ca.uhn.fhir.narrative.INarrativeGenerator; @@ -72,6 +75,47 @@ public class XmlParserTest { } + @Test + public void testTagList() { + + //@formatter:off + String tagListStr = " \n" + + " \n" + + " \n" + + " \n" + + ""; + //@formatter:on + + TagList tagList = new FhirContext().newXmlParser().parseTagList(tagListStr); + assertEquals(3, tagList.size()); + assertEquals("term0", tagList.get(0).getTerm()); + assertEquals("label0", tagList.get(0).getLabel()); + assertEquals("scheme0", tagList.get(0).getScheme()); + assertEquals("term1", tagList.get(1).getTerm()); + assertEquals("label1", tagList.get(1).getLabel()); + assertEquals(null, tagList.get(1).getScheme()); + assertEquals("term2", tagList.get(2).getTerm()); + assertEquals("label2", tagList.get(2).getLabel()); + assertEquals(null, tagList.get(2).getScheme()); + + /* + * Encode + */ + + //@formatter:off + String expected = "" + + "" + + "" + + "" + + ""; + //@formatter:on + + String encoded = new FhirContext().newXmlParser().encodeTagListToString(tagList); + assertEquals(expected,encoded); + + } + + @Test public void testTotalResultsUsingOldNamespace() { @@ -541,7 +585,8 @@ public class XmlParserTest { " HL7, Inc (FHIR Project)\n" + " http://hl7.org/fhir\n" + " \n" + - " 2014-02-10T04:10:46.987-00:00\n" + + " 2014-02-10T04:10:46.987-00:00\n" + + " \n "+ " \n" + " \n" + " \n" + @@ -589,10 +634,29 @@ public class XmlParserTest { BundleEntry entry = bundle.getEntries().get(0); assertEquals("HL7, Inc (FHIR Project)", entry.getAuthorName().getValue()); assertEquals("http://hl7.org/fhir/valueset/256a5231-a2bb-49bd-9fea-f349d428b70d", entry.getId().getValue()); + assertEquals(1, entry.getCategories().size()); + assertEquals("term", entry.getCategories().get(0).getTerm()); + assertEquals("label", entry.getCategories().get(0).getLabel()); + assertEquals("http://foo", entry.getCategories().get(0).getScheme()); ValueSet resource = (ValueSet) entry.getResource(); assertEquals("LOINC Codes for Cholesterol", resource.getName().getValue()); assertEquals(summaryText.trim(), entry.getSummary().getValueAsString().trim()); + + TagList tl = (TagList) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST); + assertEquals(1, tl.size()); + assertEquals("term", tl.get(0).getTerm()); + assertEquals("label", tl.get(0).getLabel()); + assertEquals("http://foo", tl.get(0).getScheme()); + + assertEquals(new IdDt("256a5231-a2bb-49bd-9fea-f349d428b70d"), resource.getId()); + + msg = msg.replace("", ""); + entry = p.parseBundle(msg).getEntries().get(0); + resource = (ValueSet) entry.getResource(); + assertEquals(new IdDt("256a5231-a2bb-49bd-9fea-f349d428b70d"), resource.getId()); + assertEquals(new IdDt("12345"), resource.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION_ID)); + } @Test diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/ClientTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/ClientTest.java index 0e7223ae549..c4bfe306e34 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/ClientTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/ClientTest.java @@ -1,5 +1,6 @@ package ca.uhn.fhir.rest.client; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @@ -49,12 +50,9 @@ import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.IntegerDt; import ca.uhn.fhir.model.primitive.StringDt; -import ca.uhn.fhir.rest.annotation.Create; import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.IncludeParam; -import ca.uhn.fhir.rest.annotation.Read; import ca.uhn.fhir.rest.annotation.RequiredParam; -import ca.uhn.fhir.rest.annotation.ResourceParam; import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.client.api.IBasicClient; @@ -64,6 +62,7 @@ import ca.uhn.fhir.rest.param.QualifiedDateParam; import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.EncodingEnum; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; public class ClientTest { @@ -107,11 +106,29 @@ public class ClientTest { assertEquals("200", response.getVersionId().getValue()); } - + @Test + public void testCreateBad() throws Exception { + + Patient patient = new Patient(); + patient.addIdentifier("urn:foo", "123"); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 400, "foobar")); + when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_TEXT + "; charset=UTF-8")); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("foobar"), Charset.forName("UTF-8"))); + + try { + ctx.newRestfulClient(ITestClient.class, "http://foo").createPatient(patient); + fail(); + } catch (InvalidRequestException e) { + assertThat(e.getMessage(), StringContains.containsString("foobar")); + } + } /** - * Some servers (older ones?) return the resourcde you created instead - * of an OperationOutcome. We just need to ignore it. + * Some servers (older ones?) return the resourcde you created instead of an + * OperationOutcome. We just need to ignore it. */ @Test public void testCreateWithResourceResponse() throws Exception { @@ -135,14 +152,7 @@ public class ClientTest { assertEquals("100", response.getId().getValue()); assertEquals("200", response.getVersionId().getValue()); } - - - public interface CreateWithTagList extends IBasicClient - { - @Create - public MethodOutcome createPatient(@ResourceParam Patient thePatient, TagList theTagList); - } - + @Test public void testCreateWithTagList() throws Exception { @@ -156,44 +166,25 @@ public class ClientTest { when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); when(httpResponse.getAllHeaders()).thenReturn(toHeaderArray("Location", "http://example.com/fhir/Patient/100/_history/200")); - CreateWithTagList client = ctx.newRestfulClient(CreateWithTagList.class, "http://foo"); + ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); TagList tagList = new TagList(); - tagList.add(new Tag("Dog", "DogLabel", (String)null)); + tagList.add(new Tag("Dog", "DogLabel", (String) null)); tagList.add(new Tag("Cat", "CatLabel", "http://cats")); - MethodOutcome response = client.createPatient(patient, tagList); + patient.getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList); + + MethodOutcome response = client.createPatient(patient); assertEquals(HttpPost.class, capt.getValue().getClass()); HttpPost post = (HttpPost) capt.getValue(); assertThat(IOUtils.toString(post.getEntity().getContent()), StringContains.containsString(" capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(httpClient.execute(capt.capture())).thenReturn(httpResponse); - when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 400, "foobar")); - when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_TEXT + "; charset=UTF-8")); - when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader("foobar"), Charset.forName("UTF-8"))); - - try { - ctx.newRestfulClient(ITestClient.class, "http://foo").createPatient(patient); - fail(); - } catch (InvalidRequestException e) { - assertThat(e.getMessage(), StringContains.containsString("foobar")); - } } @Test @@ -398,7 +389,6 @@ public class ClientTest { } } - @Test public void testHistoryServer() throws Exception { InstantDt date1 = new InstantDt(new Date(20000L)); @@ -470,7 +460,7 @@ public class ClientTest { assertEquals(updExpected.getValueAsString(), updActualBundle.getValueAsString()); } } - + @Test public void testHistoryWithParams() throws Exception { @@ -488,17 +478,19 @@ public class ClientTest { return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")); } }); - - + ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); - + client.getHistoryPatientInstance(new IdDt("111"), new InstantDt("2012-01-02T00:01:02"), new IntegerDt(12)); assertEquals("http://foo/Patient/111/_history?_since=2012-01-02T00%3A01%3A02&_count=12", capt.getAllValues().get(0).getURI().toString()); - String expectedDateString= new InstantDt(new InstantDt("2012-01-02T00:01:02").getValue()).getValueAsString(); // ensures the local timezone - expectedDateString=expectedDateString.replace(":", "%3A"); + String expectedDateString = new InstantDt(new InstantDt("2012-01-02T00:01:02").getValue()).getValueAsString(); // ensures + // the + // local + // timezone + expectedDateString = expectedDateString.replace(":", "%3A"); client.getHistoryPatientInstance(new IdDt("111"), new InstantDt("2012-01-02T00:01:02").getValue(), new IntegerDt(12).getValue()); - assertEquals("http://foo/Patient/111/_history?_since="+expectedDateString+"&_count=12", capt.getAllValues().get(1).getURI().toString()); + assertEquals("http://foo/Patient/111/_history?_since=" + expectedDateString + "&_count=12", capt.getAllValues().get(1).getURI().toString()); client.getHistoryPatientInstance(new IdDt("111"), null, new IntegerDt(12)); assertEquals("http://foo/Patient/111/_history?_count=12", capt.getAllValues().get(2).getURI().toString()); @@ -514,6 +506,22 @@ public class ClientTest { } + @Test + public void testNonAnnotatedMethodFailsGracefully() { + + // TODO: remove the read annotation and make sure we get a sensible + // error message to tell the user why the method isn't working + ClientWithoutAnnotation client = new FhirContext().newRestfulClient(ClientWithoutAnnotation.class, "http://wildfhir.aegis.net/fhir"); + + try { + client.read(new IdDt("8")); + fail(); + } catch (UnsupportedOperationException e) { + assertThat(e.getMessage(), containsString("annotation")); + } + + } + @Test public void testRead() throws Exception { @@ -539,7 +547,8 @@ public class ClientTest { when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); - // Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123")); + // Patient response = client.findPatientByMrn(new + // IdentifierDt("urn:foo", "123")); Patient response = client.getPatientById(new IdDt("111")); assertEquals("http://foo/Patient/111", capt.getValue().getURI().toString()); @@ -547,10 +556,35 @@ public class ClientTest { InstantDt lm = (InstantDt) response.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED); assertEquals("2011-01-02T22:01:02", lm.getValueAsString()); - + + } + + @Test + public void testReadFailureNoCharset() throws Exception { + + //@formatter:off + String msg = ""; + //@formatter:on + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 404, "NOT FOUND")); + Header[] headers = new Header[1]; + headers[0] = new BasicHeader(Constants.HEADER_LAST_MODIFIED, "2011-01-02T22:01:02"); + when(httpResponse.getAllHeaders()).thenReturn(headers); + when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML)); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + + ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); + try { + client.getPatientById(new IdDt("111")); + fail(); + } catch (ResourceNotFoundException e) { + // good + } + } - @Test public void testReadNoCharset() throws Exception { @@ -576,7 +610,8 @@ public class ClientTest { when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); - // Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123")); + // Patient response = client.findPatientByMrn(new + // IdentifierDt("urn:foo", "123")); Patient response = client.getPatientById(new IdDt("111")); assertEquals("http://foo/Patient/111", capt.getValue().getURI().toString()); @@ -584,52 +619,9 @@ public class ClientTest { InstantDt lm = (InstantDt) response.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED); assertEquals("2011-01-02T22:01:02", lm.getValueAsString()); - - } - - private interface ClientWithoutAnnotation extends IBasicClient { - @Read - Patient read(@IdParam IdDt theId); - } - - @Test - public void testIt() { - - // TODO: remove the read annotation and make sure we get a sensible - // error message to tell the user why the method isn't working - ClientWithoutAnnotation client = new FhirContext().newRestfulClient(ClientWithoutAnnotation.class, "http://wildfhir.aegis.net/fhir"); - client.read(new IdDt("8")); - - } - - @Test - public void testReadFailureNoCharset() throws Exception { - //@formatter:off - String msg = ""; - //@formatter:on - - ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(httpClient.execute(capt.capture())).thenReturn(httpResponse); - when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 404, "NOT FOUND")); - Header[] headers = new Header[1]; - headers[0] = new BasicHeader(Constants.HEADER_LAST_MODIFIED, "2011-01-02T22:01:02"); - when(httpResponse.getAllHeaders()).thenReturn(headers); - when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML)); - when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - - ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); - Patient response = client.getPatientById(new IdDt("111")); - - assertEquals("http://foo/Patient/111", capt.getValue().getURI().toString()); - assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue()); - - InstantDt lm = (InstantDt) response.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED); - assertEquals("2011-01-02T22:01:02", lm.getValueAsString()); - } - @Test public void testSearchByDateRange() throws Exception { @@ -670,35 +662,6 @@ public class ClientTest { } - - @Test - public void testSearchWithFormatAndPrettyPrint() throws Exception { - - String msg = getPatientFeedWithOneResult(); - - ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); - when(httpClient.execute(capt.capture())).thenReturn(httpResponse); - when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); - when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); - when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); - - // TODO: document this - - ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); - client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02")); - assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02", capt.getAllValues().get(0).getURI().toString()); - - client.setEncoding(EncodingEnum.JSON); - client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02")); - assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02&_format=json", capt.getAllValues().get(1).getURI().toString()); - - client.setPrettyPrint(true); - client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02")); - assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02&_format=json&_pretty=true", capt.getAllValues().get(2).getURI().toString()); - - } - - @Test public void testSearchByToken() throws Exception { @@ -718,7 +681,6 @@ public class ClientTest { } - @Test public void testSearchComposite() throws Exception { @@ -739,7 +701,7 @@ public class ClientTest { assertEquals("http://foo/Patient?ids=foo%7Cbar%2Cbaz%7Cboz", capt.getValue().getURI().toString()); } - + @Test public void testSearchNamedQueryNoParams() throws Exception { @@ -775,7 +737,7 @@ public class ClientTest { assertEquals("http://foo/Patient?_query=someQueryOneParam¶m1=BB", capt.getValue().getURI().toString()); } - + @Test public void testSearchWithCustomType() throws Exception { @@ -813,8 +775,37 @@ public class ClientTest { assertEquals("PRP1660", response.get(0).getIdentifier().get(0).getValue().getValue()); } - - + + @Test + public void testSearchWithFormatAndPrettyPrint() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + + // TODO: document this + + ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); + client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02")); + assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02", capt.getAllValues().get(0).getURI().toString()); + + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + client.setEncoding(EncodingEnum.JSON); // this needs to be actually + // implemented + client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02")); + assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02&_format=json", capt.getAllValues().get(1).getURI().toString()); + + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + client.setPrettyPrint(true); + client.getPatientByDob(new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, "2011-01-02")); + assertEquals("http://foo/Patient?birthdate=%3E%3D2011-01-02&_format=json&_pretty=true", capt.getAllValues().get(2).getURI().toString()); + + } + @Test public void testSearchWithIncludes() throws Exception { @@ -908,7 +899,8 @@ public class ClientTest { } /** - * Return a FHIR content type, but no content and make sure we handle this without crashing + * Return a FHIR content type, but no content and make sure we handle this + * without crashing */ @Test public void testUpdateWithEmptyResponse() throws Exception { @@ -1015,7 +1007,8 @@ public class ClientTest { when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); ITestClient client = ctx.newRestfulClient(ITestClient.class, "http://foo"); - // Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123")); + // Patient response = client.findPatientByMrn(new + // IdentifierDt("urn:foo", "123")); Patient response = client.getPatientByVersionId(new IdDt("111"), new IdDt("999")); assertEquals("http://foo/Patient/111/_history/999", capt.getValue().getURI().toString()); @@ -1055,24 +1048,27 @@ public class ClientTest { return new Header[] { new BasicHeader(theName, theValue) }; } - @ResourceDef(name="Patient") - public static class CustomPatient extends Patient - { + @ResourceDef(name = "Patient") + public static class CustomPatient extends Patient { // nothing } public interface ITestClientWithCustomType extends IBasicClient { @Search() - public CustomPatient getPatientByDob(@RequiredParam(name=Patient.SP_BIRTHDATE) QualifiedDateParam theBirthDate); + public CustomPatient getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) QualifiedDateParam theBirthDate); } public interface ITestClientWithCustomTypeList extends IBasicClient { @Search() - public List getPatientByDob(@RequiredParam(name=Patient.SP_BIRTHDATE) QualifiedDateParam theBirthDate); + public List getPatientByDob(@RequiredParam(name = Patient.SP_BIRTHDATE) QualifiedDateParam theBirthDate); } public interface ITestClientWithStringIncludes extends IBasicClient { @Search() public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringDt theString, @IncludeParam String theInclude); } + + private interface ClientWithoutAnnotation extends IBasicClient { + Patient read(@IdParam IdDt theId); + } } diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/InvalidClientDefinitionTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/InvalidClientDefinitionTest.java deleted file mode 100644 index 0aa7d9c20a9..00000000000 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/InvalidClientDefinitionTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package ca.uhn.fhir.rest.client; - -import org.junit.Test; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.model.dstu.resource.Patient; -import ca.uhn.fhir.rest.annotation.RequiredParam; -import ca.uhn.fhir.rest.annotation.Search; -import ca.uhn.fhir.rest.client.ClientTest.CustomPatient; -import ca.uhn.fhir.rest.client.api.IBasicClient; -import ca.uhn.fhir.rest.param.QualifiedDateParam; - -public class InvalidClientDefinitionTest { - - @Test - public void testAnnotationTypeIsNotAssignableToMethodReturnType() { - // TODO: this should fail - new FhirContext().newRestfulClient(ITestClientWithCustomType.class, "http://example.com"); - } - - public interface ITestClientWithCustomType extends IBasicClient { - @Search(type=Patient.class) - public CustomPatient getPatientByDob(@RequiredParam(name=Patient.SP_BIRTHDATE) QualifiedDateParam theBirthDate); - } - -} diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/TagsClientTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/TagsClientTest.java new file mode 100644 index 00000000000..ae2eb580ebb --- /dev/null +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/TagsClientTest.java @@ -0,0 +1,270 @@ +package ca.uhn.fhir.rest.client; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.io.StringReader; +import java.nio.charset.Charset; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.ReaderInputStream; +import org.apache.http.HeaderElement; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicStatusLine; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.api.Tag; +import ca.uhn.fhir.model.api.TagList; +import ca.uhn.fhir.model.api.annotation.TagListParam; +import ca.uhn.fhir.model.dstu.resource.Conformance; +import ca.uhn.fhir.model.dstu.resource.Patient; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.rest.annotation.AddTags; +import ca.uhn.fhir.rest.annotation.DeleteTags; +import ca.uhn.fhir.rest.annotation.GetTags; +import ca.uhn.fhir.rest.annotation.IdParam; +import ca.uhn.fhir.rest.annotation.VersionIdParam; +import ca.uhn.fhir.rest.client.api.IBasicClient; +import ca.uhn.fhir.rest.server.Constants; + +public class TagsClientTest { + + private FhirContext ctx; + private HttpClient httpClient; + private HttpResponse httpResponse; + + // atom-document-large.xml + + @Before + public void before() { + ctx = new FhirContext(Patient.class, Conformance.class); + + httpClient = mock(HttpClient.class, new ReturnsDeepStubs()); + ctx.getRestfulClientFactory().setHttpClient(httpClient); + + httpResponse = mock(HttpResponse.class, new ReturnsDeepStubs()); + } + + @Test + public void testGetAllTags() throws Exception { + + TagList tagList = new TagList(); + tagList.add(new Tag("AAA", "BBB", "CCC")); + String ser = ctx.newXmlParser().encodeTagListToString(tagList); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(ser), Charset.forName("UTF-8"))); + + IClient client = ctx.newRestfulClient(IClient.class, "http://foo"); + TagList response = client.getAllTags(); + assertEquals(tagList, response); + + assertEquals(HttpGet.class, capt.getValue().getClass()); + HttpGet get = (HttpGet) capt.getValue(); + assertEquals("http://foo/_tags", get.getURI().toString()); + } + + @Test + public void testGetAllTagsPatient() throws Exception { + + TagList tagList = new TagList(); + tagList.add(new Tag("AAA", "BBB", "CCC")); + String ser = ctx.newXmlParser().encodeTagListToString(tagList); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(ser), Charset.forName("UTF-8"))); + + IClient client = ctx.newRestfulClient(IClient.class, "http://foo"); + TagList response = client.getAllTagsPatient(); + assertEquals(tagList, response); + + assertEquals(HttpGet.class, capt.getValue().getClass()); + HttpGet get = (HttpGet) capt.getValue(); + assertEquals("http://foo/Patient/_tags", get.getURI().toString()); + } + + @Test + public void testDeleteTagsPatient() throws Exception { + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(httpResponse.getEntity().getContentType().getElements()).thenReturn(new HeaderElement[0]); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); + + TagList tagList = new TagList(); + tagList.add(new Tag("AAA", "BBB", "CCC")); + + IClient client = ctx.newRestfulClient(IClient.class, "http://foo"); + client.deleteTags(new IdDt("111"), tagList); + + assertEquals(HttpPost.class, capt.getValue().getClass()); + HttpPost post = (HttpPost) capt.getValue(); + assertEquals("http://foo/Patient/111/_tags/_delete", post.getURI().toString()); + + String ser = IOUtils.toString(post.getEntity().getContent()); + TagList actualTagList = ctx.newXmlParser().parseTagList(ser); + assertEquals(tagList, actualTagList); + } + + @Test + public void testDeleteTagsPatientVersion() throws Exception { + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(httpResponse.getEntity().getContentType().getElements()).thenReturn(new HeaderElement[0]); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); + + TagList tagList = new TagList(); + tagList.add(new Tag("AAA", "BBB", "CCC")); + + IClient client = ctx.newRestfulClient(IClient.class, "http://foo"); + client.deleteTags(new IdDt("111"), new IdDt("222"),tagList); + + assertEquals(HttpPost.class, capt.getValue().getClass()); + HttpPost post = (HttpPost) capt.getValue(); + assertEquals("http://foo/Patient/111/_history/222/_tags/_delete", post.getURI().toString()); + + String ser = IOUtils.toString(post.getEntity().getContent()); + TagList actualTagList = ctx.newXmlParser().parseTagList(ser); + assertEquals(tagList, actualTagList); + } + + @Test + public void testAddTagsPatient() throws Exception { + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(httpResponse.getEntity().getContentType().getElements()).thenReturn(new HeaderElement[0]); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); + + TagList tagList = new TagList(); + tagList.add(new Tag("AAA", "BBB", "CCC")); + + IClient client = ctx.newRestfulClient(IClient.class, "http://foo"); + client.addTags(new IdDt("111"), tagList); + + assertEquals(HttpPost.class, capt.getValue().getClass()); + HttpPost post = (HttpPost) capt.getValue(); + assertEquals("http://foo/Patient/111/_tags", post.getURI().toString()); + + String ser = IOUtils.toString(post.getEntity().getContent()); + TagList actualTagList = ctx.newXmlParser().parseTagList(ser); + assertEquals(tagList, actualTagList); + } + + @Test + public void testAddTagsPatientVersion() throws Exception { + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(httpResponse.getEntity().getContentType().getElements()).thenReturn(new HeaderElement[0]); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(""), Charset.forName("UTF-8"))); + + TagList tagList = new TagList(); + tagList.add(new Tag("AAA", "BBB", "CCC")); + + IClient client = ctx.newRestfulClient(IClient.class, "http://foo"); + client.addTags(new IdDt("111"), new IdDt("222"),tagList); + + assertEquals(HttpPost.class, capt.getValue().getClass()); + HttpPost post = (HttpPost) capt.getValue(); + assertEquals("http://foo/Patient/111/_history/222/_tags", post.getURI().toString()); + + String ser = IOUtils.toString(post.getEntity().getContent()); + TagList actualTagList = ctx.newXmlParser().parseTagList(ser); + assertEquals(tagList, actualTagList); + } + + @Test + public void testGetAllTagsPatientId() throws Exception { + + TagList tagList = new TagList(); + tagList.add(new Tag("AAA", "BBB", "CCC")); + String ser = ctx.newXmlParser().encodeTagListToString(tagList); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(ser), Charset.forName("UTF-8"))); + + IClient client = ctx.newRestfulClient(IClient.class, "http://foo"); + TagList response = client.getAllTagsPatientId(new IdDt("111")); + assertEquals(tagList, response); + + assertEquals(HttpGet.class, capt.getValue().getClass()); + HttpGet get = (HttpGet) capt.getValue(); + assertEquals("http://foo/Patient/111/_tags", get.getURI().toString()); + } + + @Test + public void testGetAllTagsPatientIdVersion() throws Exception { + + TagList tagList = new TagList(); + tagList.add(new Tag("AAA", "BBB", "CCC")); + String ser = ctx.newXmlParser().encodeTagListToString(tagList); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(httpClient.execute(capt.capture())).thenReturn(httpResponse); + when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(ser), Charset.forName("UTF-8"))); + + IClient client = ctx.newRestfulClient(IClient.class, "http://foo"); + TagList response = client.getAllTagsPatientIdVersion(new IdDt("111"), new IdDt("222")); + assertEquals(tagList, response); + + assertEquals(HttpGet.class, capt.getValue().getClass()); + HttpGet get = (HttpGet) capt.getValue(); + assertEquals("http://foo/Patient/111/_history/222/_tags", get.getURI().toString()); + } + + private interface IClient extends IBasicClient { + + @GetTags + public TagList getAllTags(); + + @GetTags(type = Patient.class) + public TagList getAllTagsPatient(); + + @GetTags(type = Patient.class) + public TagList getAllTagsPatientId(@IdParam IdDt theId); + + @GetTags(type = Patient.class) + public TagList getAllTagsPatientIdVersion(@IdParam IdDt theId, @VersionIdParam IdDt theVersion); + + @AddTags(type = Patient.class) + public void addTags(@IdParam IdDt theId, @TagListParam TagList theTagList); + + @AddTags(type = Patient.class) + public void addTags(@IdParam IdDt theId, @VersionIdParam IdDt theVersionId, @TagListParam TagList theTagList); + + @DeleteTags(type = Patient.class) + public void deleteTags(@IdParam IdDt theId, @TagListParam TagList theTagList); + + @DeleteTags(type = Patient.class) + public void deleteTags(@IdParam IdDt theId, @VersionIdParam IdDt theVersionId, @TagListParam TagList theTagList); + + } + +} diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/Tester.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/Tester.java index 0c77965462d..7493cf90f54 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/Tester.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/Tester.java @@ -24,7 +24,7 @@ public class Tester { } catch (NonFhirResponseException e) { e.printStackTrace(); - System.out.println(e.getResponseText()); + System.out.println(e.getResponseBody()); } } diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/DocumentationTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/DocumentationTest.java index b02b455c11e..0d0e1cea25f 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/DocumentationTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/DocumentationTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.*; import java.util.Collection; import java.util.List; -import org.hamcrest.core.StringContains; import org.junit.Test; import ca.uhn.fhir.context.FhirContext; @@ -59,6 +58,7 @@ public class DocumentationTest { /** * Created by dsotnikov on 2/25/2014. */ + @SuppressWarnings("unused") public static class SearchProvider { @Search(type = Patient.class) diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResfulServerMethodTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResfulServerMethodTest.java index ea61f2fd68f..1de98e96148 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResfulServerMethodTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResfulServerMethodTest.java @@ -921,11 +921,8 @@ public class ResfulServerMethodTest { HttpPut httpPost = new HttpPut("http://localhost:" + ourPort + "/DiagnosticReport/001"); httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8"))); - HttpResponse status = ourClient.execute(httpPost); - - assertEquals(201, status.getStatusLine().getStatusCode()); - assertEquals("http://localhost:" + ourPort + "/DiagnosticReport/001/_history/002", status.getFirstHeader("Location").getValue()); - + ourClient.execute(httpPost); + fail(); } @Test @@ -1199,12 +1196,11 @@ public class ResfulServerMethodTest { return DiagnosticReport.class; } - @SuppressWarnings("unused") @Update() - public MethodOutcome updateDiagnosticReportWithNoResponse(@IdParam IdDt theId, @VersionIdParam IdDt theVersionId, @ResourceParam DiagnosticReport thePatient, TagList theTagList) { + public MethodOutcome updateDiagnosticReportWithNoResponse(@IdParam IdDt theId, @VersionIdParam IdDt theVersionId, @ResourceParam DiagnosticReport theDr) { IdDt id = theId; IdDt version = theVersionId; - myLastTags = theTagList; + myLastTags = (TagList) theDr.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST); return new MethodOutcome(id, version); } @@ -1212,12 +1208,11 @@ public class ResfulServerMethodTest { return myLastTags; } - @SuppressWarnings("unused") @Update() - public MethodOutcome updateDiagnosticReportWithVersionAndNoResponse(@IdParam IdDt theId, @ResourceParam DiagnosticReport thePatient, TagList theTagList) { + public MethodOutcome updateDiagnosticReportWithVersionAndNoResponse(@IdParam IdDt theId, @ResourceParam DiagnosticReport theDr) { IdDt id = theId; IdDt version = new IdDt("002"); - myLastTags=theTagList; + myLastTags = (TagList) theDr.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST); return new MethodOutcome(id, version); } diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResourceMethodTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResourceMethodTest.java index 5f44668b4d1..db918872d6c 100644 --- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResourceMethodTest.java +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResourceMethodTest.java @@ -46,7 +46,7 @@ public class ResourceMethodTest { inputParams.add("firstName"); inputParams.add("lastName"); - assertEquals(false, rm.matches(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // False + assertEquals(false, rm.incomingServerRequestMatchesMethod(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // False } @Test @@ -61,7 +61,7 @@ public class ResourceMethodTest { Set inputParams = new HashSet(); inputParams.add("mrn"); - assertEquals(true, rm.matches(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // True + assertEquals(true, rm.incomingServerRequestMatchesMethod(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // True } @Test @@ -78,7 +78,7 @@ public class ResourceMethodTest { inputParams.add("firstName"); inputParams.add("mrn"); - assertEquals(true, rm.matches(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // True + assertEquals(true, rm.incomingServerRequestMatchesMethod(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // True } @Test @@ -96,7 +96,7 @@ public class ResourceMethodTest { inputParams.add("lastName"); inputParams.add("mrn"); - assertEquals(true, rm.matches(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // True + assertEquals(true, rm.incomingServerRequestMatchesMethod(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // True } @Test @@ -115,6 +115,6 @@ public class ResourceMethodTest { inputParams.add("mrn"); inputParams.add("foo"); - assertEquals(false, rm.matches(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // False + assertEquals(false, rm.incomingServerRequestMatchesMethod(Request.withResourceAndParams("Patient", RequestType.GET, inputParams))); // False } } diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/TagsServerTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/TagsServerTest.java new file mode 100644 index 00000000000..1e794171aa6 --- /dev/null +++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/TagsServerTest.java @@ -0,0 +1,294 @@ +package ca.uhn.fhir.rest.server; + +import static org.junit.Assert.*; + +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.api.Tag; +import ca.uhn.fhir.model.api.TagList; +import ca.uhn.fhir.model.api.annotation.TagListParam; +import ca.uhn.fhir.model.dstu.resource.Patient; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.rest.annotation.AddTags; +import ca.uhn.fhir.rest.annotation.DeleteTags; +import ca.uhn.fhir.rest.annotation.GetTags; +import ca.uhn.fhir.rest.annotation.IdParam; +import ca.uhn.fhir.rest.annotation.VersionIdParam; +import ca.uhn.fhir.testutil.RandomServerPortProvider; + +/** + * Created by dsotnikov on 2/25/2014. + */ +public class TagsServerTest { + + private static CloseableHttpClient ourClient; + private static FhirContext ourCtx; + private static String ourLastOutcome; + private static TagList ourLastTagList; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TagsServerTest.class); + private static int ourPort; + private static DummyProvider ourProvider; + private static Server ourServer; + + @Before + public void before() { + ourLastOutcome = null; + ourLastTagList = null; + } + + @Test + public void testAddTagsById() throws Exception { + + TagList tagList = new TagList(); + tagList.addTag("term", "label", "scheme"); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/111/_tags"); + httpPost.setEntity(new StringEntity(ourCtx.newJsonParser().encodeTagListToString(tagList), ContentType.create(EncodingEnum.JSON.getResourceContentType(), "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent()); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("add111", ourLastOutcome); + assertEquals(tagList, ourLastTagList); + } + + @Test + public void testAddTagsByIdAndVersion() throws Exception { + + TagList tagList = new TagList(); + tagList.addTag("term", "label", "scheme"); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/111/_history/222/_tags"); + httpPost.setEntity(new StringEntity(ourCtx.newJsonParser().encodeTagListToString(tagList), ContentType.create(EncodingEnum.JSON.getResourceContentType(), "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent()); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("add111222", ourLastOutcome); + assertEquals(tagList, ourLastTagList); + } + + @Test + public void testEquals() { + TagList list1 = ourProvider.getAllTagsPatient(); + TagList list2 = ourProvider.getAllTagsPatient(); + assertEquals(list1, list2); + + list1 = ourProvider.getAllTagsPatient(); + list2 = ourProvider.getAllTagsPatient(); + list2.get(0).setTerm("!!!!!"); + assertNotEquals(list1, list2); + } + + @Test + public void testGetAllTags() throws Exception { + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/_tags"); + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent()); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + TagList tagList = ourCtx.newXmlParser().parseTagList(responseContent); + assertEquals(ourProvider.getAllTags(), tagList); + } + + @Test + public void testGetAllTagsPatient() throws Exception { + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/_tags"); + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent()); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + + TagList actual = ourCtx.newXmlParser().parseTagList(responseContent); + TagList expected = ourProvider.getAllTags(); + expected.get(0).setTerm("Patient"); + assertEquals(expected, actual); + } + + @Test + public void testGetAllTagsPatientId() throws Exception { + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/111/_tags"); + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent()); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + + TagList actual = ourCtx.newXmlParser().parseTagList(responseContent); + TagList expected = ourProvider.getAllTags(); + expected.get(0).setTerm("Patient111"); + assertEquals(expected, actual); + } + + @Test + public void testGetAllTagsPatientIdVersion() throws Exception { + + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/111/_history/222/_tags"); + HttpResponse status = ourClient.execute(httpGet); + + String responseContent = IOUtils.toString(status.getEntity().getContent()); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + + TagList actual = ourCtx.newXmlParser().parseTagList(responseContent); + TagList expected = ourProvider.getAllTags(); + expected.get(0).setTerm("Patient111222"); + assertEquals(expected, actual); + } + + @Test + public void testRemoveTagsById() throws Exception { + + TagList tagList = new TagList(); + tagList.addTag("term", "label", "scheme"); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/111/_tags/_delete"); + httpPost.setEntity(new StringEntity(ourCtx.newJsonParser().encodeTagListToString(tagList), ContentType.create(EncodingEnum.JSON.getResourceContentType(), "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent()); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("Remove111", ourLastOutcome); + assertEquals(tagList, ourLastTagList); + } + + @Test + public void testRemoveTagsByIdAndVersion() throws Exception { + + TagList tagList = new TagList(); + tagList.addTag("term", "label", "scheme"); + + HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient/111/_history/222/_tags/_delete"); + httpPost.setEntity(new StringEntity(ourCtx.newJsonParser().encodeTagListToString(tagList), ContentType.create(EncodingEnum.JSON.getResourceContentType(), "UTF-8"))); + HttpResponse status = ourClient.execute(httpPost); + + String responseContent = IOUtils.toString(status.getEntity().getContent()); + ourLog.info("Response was:\n{}", responseContent); + + assertEquals(200, status.getStatusLine().getStatusCode()); + assertEquals("Remove111222", ourLastOutcome); + assertEquals(tagList, ourLastTagList); + } + + @AfterClass + public static void afterClass() throws Exception { + ourServer.stop(); + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourPort = RandomServerPortProvider.findFreePort(); + ourServer = new Server(ourPort); + ourCtx = new FhirContext(Patient.class); + + ourProvider = new DummyProvider(); + + ServletHandler proxyHandler = new ServletHandler(); + RestfulServer servlet = new RestfulServer(); + servlet.setPlainProviders(ourProvider); + ServletHolder servletHolder = new ServletHolder(servlet); + proxyHandler.addServletWithMapping(servletHolder, "/*"); + ourServer.setHandler(proxyHandler); + ourServer.start(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setConnectionManager(connectionManager); + ourClient = builder.build(); + + } + + public static class DummyProvider { + + @AddTags(type = Patient.class) + public void addTagsPatient(@IdParam IdDt theId, @VersionIdParam IdDt theVersion, @TagListParam TagList theTagList) { + ourLastOutcome = "add" + theId.getValue() + theVersion.getValue(); + ourLastTagList=theTagList; + } + + @AddTags(type = Patient.class) + public void addTagsPatient(@IdParam IdDt theId, @TagListParam TagList theTagList) { + ourLastOutcome = "add" + theId.getValue(); + ourLastTagList=theTagList; + } + + @GetTags + public TagList getAllTags() { + TagList tagList = new TagList(); + tagList.add(new Tag("AllDog", "DogLabel", (String) null)); + tagList.add(new Tag("AllCat", "CatLabel", "http://cats")); + return tagList; + } + + @GetTags(type = Patient.class) + public TagList getAllTagsPatient() { + TagList tagList = new TagList(); + tagList.add(new Tag("Patient", "DogLabel", (String) null)); + tagList.add(new Tag("AllCat", "CatLabel", "http://cats")); + return tagList; + } + + @GetTags(type = Patient.class) + public TagList getAllTagsPatientId(@IdParam IdDt theId) { + TagList tagList = new TagList(); + tagList.add(new Tag("Patient" + theId.getValue(), "DogLabel", (String) null)); + tagList.add(new Tag("AllCat", "CatLabel", "http://cats")); + return tagList; + } + + @GetTags(type = Patient.class) + public TagList getAllTagsPatientIdVersion(@IdParam IdDt theId, @VersionIdParam IdDt theVersion) { + TagList tagList = new TagList(); + tagList.add(new Tag("Patient" + theId.getValue() + theVersion.getValue(), "DogLabel", (String) null)); + tagList.add(new Tag("AllCat", "CatLabel", "http://cats")); + return tagList; + } + + @DeleteTags(type = Patient.class) + public void RemoveTagsPatient(@IdParam IdDt theId, @VersionIdParam IdDt theVersion, @TagListParam TagList theTagList) { + ourLastOutcome = "Remove" + theId.getValue() + theVersion.getValue(); + ourLastTagList=theTagList; + } + + @DeleteTags(type = Patient.class) + public void RemoveTagsPatient(@IdParam IdDt theId, @TagListParam TagList theTagList) { + ourLastOutcome = "Remove" + theId.getValue(); + ourLastTagList=theTagList; + } + + } + +} diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDao.java index e37ab83ed91..83c189ff3f8 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDao.java @@ -239,7 +239,9 @@ public class FhirResourceDao String path = param.getPath(); List values = terser.getValues(resource, path); for (Object nextValue : values) { - if (nextValue.equals(nextParamEntry.getValue())) { + IQueryParameterType expectedQt = nextParamEntry.getValue(); + IQueryParameterType actualQt = (IQueryParameterType)nextValue; + if (actualQt.getValueAsQueryToken().equals(expectedQt.getValueAsQueryToken())) { shouldAdd = true; break; } diff --git a/hapi-fhir-jpaserver-base/src/main/resources/META-INF/persistence.xml b/hapi-fhir-jpaserver-base/src/main/resources/META-INF/persistence.xml index 6e053594971..733fd3af60a 100644 --- a/hapi-fhir-jpaserver-base/src/main/resources/META-INF/persistence.xml +++ b/hapi-fhir-jpaserver-base/src/main/resources/META-INF/persistence.xml @@ -6,7 +6,7 @@ org.hibernate.ejb.HibernatePersistence - ca.uhn.fhir.jpa.entity.PatientResourceTable + false diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoTest.java index 2c2dc6020fa..66971e50453 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoTest.java @@ -60,13 +60,13 @@ public class FhirResourceDaoTest { @Test - public void testCreateWithTags() { + public void testTagsWithCreateAndReadAndSearch() { Patient patient = new Patient(); - patient.addIdentifier("urn:system", "001"); + patient.addIdentifier("urn:system", "testTagsWithCreateAndReadAndSearch"); patient.addName().addFamily("Tester").addGiven("Joe"); TagList tagList= new TagList(); tagList.addTag("Dog", "Puppies", null); - tagList.addTag("Cat", "Kittens", null); + tagList.addTag("Cat", "Kittens", "http://foo"); patient.getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList); MethodOutcome outcome = ourPatientDao.create(patient); @@ -77,10 +77,27 @@ public class FhirResourceDaoTest { TagList published = (TagList) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST); assertEquals(2, published.size()); assertEquals("Dog", published.get(0).getTerm()); + assertEquals("Puppies", published.get(0).getLabel()); + assertEquals(null, published.get(0).getScheme()); assertEquals("Cat", published.get(1).getTerm()); + assertEquals("Kittens", published.get(1).getLabel()); + assertEquals("http://foo", published.get(1).getScheme()); + + List search = ourPatientDao.search(Patient.SP_IDENTIFIER, patient.getIdentifierFirstRep()); + assertEquals(1,search.size()); + retrieved = search.get(0); + published = (TagList) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST); + assertEquals("Dog", published.get(0).getTerm()); + assertEquals("Puppies", published.get(0).getLabel()); + assertEquals(null, published.get(0).getScheme()); + assertEquals("Cat", published.get(1).getTerm()); + assertEquals("Kittens", published.get(1).getLabel()); + assertEquals("http://foo", published.get(1).getScheme()); } + + @Test public void testSearchAll() { {