From 8f1e45b3f386fd280f479d7418418fd61aa76d35 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Sat, 11 Jun 2016 14:46:13 -0500 Subject: [PATCH] Fix #379 - Server generated OperationDefinitions should generate separate definitions for operations that are implemented against multiple resource types --- .../dstu2/ServerConformanceProvider.java | 23 +- .../ServerConformanceProviderDstu2Test.java | 259 +++++++++++---- .../server/ServerConformanceProvider.java | 24 +- .../ServerConformanceProviderDstu3Test.java | 294 +++++++++++++----- src/changes/changes.xml | 8 +- 5 files changed, 462 insertions(+), 146 deletions(-) diff --git a/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/rest/server/provider/dstu2/ServerConformanceProvider.java b/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/rest/server/provider/dstu2/ServerConformanceProvider.java index b4c82d8808a..9b30bca90f9 100644 --- a/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/rest/server/provider/dstu2/ServerConformanceProvider.java +++ b/hapi-fhir-structures-dstu2/src/main/java/ca/uhn/fhir/rest/server/provider/dstu2/ServerConformanceProvider.java @@ -156,7 +156,24 @@ public class ServerConformanceProvider implements IServerConformanceProvider")); } + @Test public void testMultiOptionalDocumentation() throws Exception { @@ -236,6 +252,71 @@ public class ServerConformanceProviderDstu2Test { assertNull(res.getConditionalUpdate()); } + /** See #379 */ + @Test + public void testOperationAcrossMultipleTypes() throws Exception { + RestfulServer rs = new RestfulServer(ourCtx); + rs.setProviders(new MultiTypePatientProvider(), new MultiTypeEncounterProvider()); + + ServerConformanceProvider sc = new ServerConformanceProvider(rs); + rs.setServerConformanceProvider(sc); + + rs.init(createServletConfig()); + + Conformance conformance = sc.getServerConformance(createHttpServletRequest()); + + String conf = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance); + ourLog.info(conf); + + assertEquals(4, conformance.getRest().get(0).getOperation().size()); + List operationNames = toOperationNames(conformance.getRest().get(0).getOperation()); + assertThat(operationNames, containsInAnyOrder("someOp", "validate", "someOp", "validate")); + + List operationIdParts = toOperationIdParts(conformance.getRest().get(0).getOperation()); + assertThat(operationIdParts, containsInAnyOrder("Patient_i_someOp","Encounter_i_someOp","Patient_i_validate","Encounter_i_validate")); + + { + OperationDefinition opDef = sc.readOperationDefinition(new IdDt("OperationDefinition/Patient_i_someOp")); + ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(opDef)); + Set types = toStrings(opDef.getType()); + assertEquals("someOp", opDef.getCode()); + assertEquals(true, opDef.getInstance()); + assertEquals(null, opDef.getSystem()); + assertThat(types, containsInAnyOrder("Patient")); + assertEquals(2, opDef.getParameter().size()); + assertEquals("someOpParam1", opDef.getParameter().get(0).getName()); + assertEquals("date", opDef.getParameter().get(0).getType()); + assertEquals("someOpParam2", opDef.getParameter().get(1).getName()); + assertEquals("Patient", opDef.getParameter().get(1).getType()); + } + { + OperationDefinition opDef = sc.readOperationDefinition(new IdDt("OperationDefinition/Encounter_i_someOp")); + ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(opDef)); + Set types = toStrings(opDef.getType()); + assertEquals("someOp", opDef.getCode()); + assertEquals(true, opDef.getInstance()); + assertEquals(null, opDef.getSystem()); + assertThat(types, containsInAnyOrder("Encounter")); + assertEquals(2, opDef.getParameter().size()); + assertEquals("someOpParam1", opDef.getParameter().get(0).getName()); + assertEquals("date", opDef.getParameter().get(0).getType()); + assertEquals("someOpParam2", opDef.getParameter().get(1).getName()); + assertEquals("Encounter", opDef.getParameter().get(1).getType()); + } + { + OperationDefinition opDef = sc.readOperationDefinition(new IdDt("OperationDefinition/Patient_i_validate")); + ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(opDef)); + Set types = toStrings(opDef.getType()); + assertEquals("validate", opDef.getCode()); + assertEquals(true, opDef.getInstance()); + assertEquals(null, opDef.getSystem()); + assertThat(types, containsInAnyOrder("Patient")); + assertEquals(1, opDef.getParameter().size()); + assertEquals("resource", opDef.getParameter().get(0).getName()); + assertEquals("Patient", opDef.getParameter().get(0).getType()); + } + } + @Test public void testOperationDocumentation() throws Exception { @@ -273,14 +354,14 @@ public class ServerConformanceProviderDstu2Test { rs.init(createServletConfig()); Conformance sconf = sc.getServerConformance(createHttpServletRequest()); - assertEquals("OperationDefinition/plain", sconf.getRest().get(0).getOperation().get(0).getDefinition().getReference().getValue()); + assertEquals("OperationDefinition/_is_plain", sconf.getRest().get(0).getOperation().get(0).getDefinition().getReference().getValue()); - OperationDefinition opDef = sc.readOperationDefinition(new IdDt("OperationDefinition/plain")); + OperationDefinition opDef = sc.readOperationDefinition(new IdDt("OperationDefinition/_is_plain")); String conf = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(opDef); ourLog.info(conf); - assertEquals("$plain", opDef.getCode()); + assertEquals("plain", opDef.getCode()); assertEquals(true, opDef.getIdempotent().booleanValue()); assertEquals(3, opDef.getParameter().size()); assertEquals("start", opDef.getParameter().get(0).getName()); @@ -336,8 +417,7 @@ public class ServerConformanceProviderDstu2Test { Conformance parsed = ourCtx.newJsonParser().parseResource(Conformance.class, conf); } - - + @Test public void testProviderWithRequiredAndOptional() throws Exception { @@ -444,6 +524,40 @@ public class ServerConformanceProviderDstu2Test { assertThat(conf, containsString("")); } + + /** + * See #286 + */ + @Test + public void testSearchReferenceParameterDocumentation() throws Exception { + + RestfulServer rs = new RestfulServer(ourCtx); + rs.setProviders(new PatientResourceProvider()); + + ServerConformanceProvider sc = new ServerConformanceProvider(rs); + rs.setServerConformanceProvider(sc); + + rs.init(createServletConfig()); + + boolean found = false; + Collection resourceBindings = rs.getResourceBindings(); + for (ResourceBinding resourceBinding : resourceBindings) { + if (resourceBinding.getResourceName().equals("Patient")) { + List> methodBindings = resourceBinding.getMethodBindings(); + SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0); + SearchParameter param = (SearchParameter) binding.getParameters().get(25); + assertEquals("The organization at which this person is a patient", param.getDescription()); + found = true; + } + } + assertTrue(found); + Conformance conformance = sc.getServerConformance(createHttpServletRequest()); + + String conf = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance); + ourLog.info(conf); + + } + /** * See #286 @@ -484,52 +598,6 @@ public class ServerConformanceProviderDstu2Test { assertEquals(2, param.getChain().size()); } - private RestResource findRestResource(Conformance conformance, String wantResource) throws Exception { - RestResource resource = null; - for (RestResource next : conformance.getRest().get(0).getResource()) { - if (next.getType().equals(wantResource)) { - resource = next; - } - } - if (resource == null) { - throw new Exception("Could not find resource: " + wantResource); - } - return resource; - } - - /** - * See #286 - */ - @Test - public void testSearchReferenceParameterDocumentation() throws Exception { - - RestfulServer rs = new RestfulServer(ourCtx); - rs.setProviders(new PatientResourceProvider()); - - ServerConformanceProvider sc = new ServerConformanceProvider(rs); - rs.setServerConformanceProvider(sc); - - rs.init(createServletConfig()); - - boolean found = false; - Collection resourceBindings = rs.getResourceBindings(); - for (ResourceBinding resourceBinding : resourceBindings) { - if (resourceBinding.getResourceName().equals("Patient")) { - List> methodBindings = resourceBinding.getMethodBindings(); - SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0); - SearchParameter param = (SearchParameter) binding.getParameters().get(25); - assertEquals("The organization at which this person is a patient", param.getDescription()); - found = true; - } - } - assertTrue(found); - Conformance conformance = sc.getServerConformance(createHttpServletRequest()); - - String conf = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance); - ourLog.info(conf); - - } - @Test public void testSystemHistorySupported() throws Exception { @@ -585,6 +653,35 @@ public class ServerConformanceProviderDstu2Test { ValidationResult result = ourCtx.newValidator().validateWithResult(conformance); assertTrue(result.getMessages().toString(), result.isSuccessful()); } + + private List toOperationIdParts(List theOperation) { + ArrayList retVal = Lists.newArrayList(); + for (RestOperation next : theOperation) { + retVal.add(next.getDefinition().getReference().getIdPart()); + } + return retVal; + } + + private List toOperationNames(List theOperation) { + ArrayList retVal = Lists.newArrayList(); + for (RestOperation next : theOperation) { + retVal.add(next.getName()); + } + return retVal; + } + + private Set toStrings(List theType) { + HashSet retVal = new HashSet(); + for (CodeDt next : theType) { + retVal.add(next.getValueAsString()); + } + return retVal; + } + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } public static class ConditionalProvider implements IResourceProvider { @@ -635,6 +732,46 @@ public class ServerConformanceProviderDstu2Test { } + public static class MultiTypeEncounterProvider implements IResourceProvider { + + @Operation(name = "someOp") + public ca.uhn.fhir.rest.server.IBundleProvider everything(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdDt theId, + @OperationParam(name = "someOpParam1") DateDt theStart, @OperationParam(name = "someOpParam2") Encounter theEnd) { + return null; + } + + @Override + public Class getResourceType() { + return Encounter.class; + } + + @Validate + public ca.uhn.fhir.rest.server.IBundleProvider validate(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdDt theId, @ResourceParam Encounter thePatient) { + return null; + } + + } + + public static class MultiTypePatientProvider implements IResourceProvider { + + @Operation(name = "someOp") + public ca.uhn.fhir.rest.server.IBundleProvider everything(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdDt theId, + @OperationParam(name = "someOpParam1") DateDt theStart, @OperationParam(name = "someOpParam2") Patient theEnd) { + return null; + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Validate + public ca.uhn.fhir.rest.server.IBundleProvider validate(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdDt theId, @ResourceParam Patient thePatient) { + return null; + } + + } + public static class NonConditionalProvider implements IResourceProvider { @Create diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/rest/server/ServerConformanceProvider.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/rest/server/ServerConformanceProvider.java index 4b852021281..4dffdb28946 100644 --- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/rest/server/ServerConformanceProvider.java +++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/hapi/rest/server/ServerConformanceProvider.java @@ -77,6 +77,7 @@ import ca.uhn.fhir.rest.method.OperationParameter; import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.method.SearchMethodBinding; import ca.uhn.fhir.rest.method.SearchParameter; +import ca.uhn.fhir.rest.method.ValidateMethodBindingDstu3; import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.IServerConformanceProvider; import ca.uhn.fhir.rest.server.ResourceBinding; @@ -173,7 +174,24 @@ public class ServerConformanceProvider implements IServerConformanceProvider toOperationIdParts(List theOperation) { + ArrayList retVal = Lists.newArrayList(); + for (ConformanceRestOperationComponent next : theOperation) { + retVal.add(next.getDefinition().getReferenceElement().getIdPart()); + } + return retVal; + } + + /** See #379 */ + @Test + public void testOperationAcrossMultipleTypes() throws Exception { + RestfulServer rs = new RestfulServer(ourCtx); + rs.setProviders(new MultiTypePatientProvider(), new MultiTypeEncounterProvider()); + + ServerConformanceProvider sc = new ServerConformanceProvider(rs); + rs.setServerConformanceProvider(sc); + + rs.init(createServletConfig()); + + Conformance conformance = sc.getServerConformance(createHttpServletRequest()); + + String conf = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance); + ourLog.info(conf); + + assertEquals(4, conformance.getRest().get(0).getOperation().size()); + List operationNames = toOperationNames(conformance.getRest().get(0).getOperation()); + assertThat(operationNames, containsInAnyOrder("someOp", "validate", "someOp", "validate")); + + List operationIdParts = toOperationIdParts(conformance.getRest().get(0).getOperation()); + assertThat(operationIdParts, containsInAnyOrder("Patient_i_someOp","Encounter_i_someOp","Patient_i_validate","Encounter_i_validate")); + + { + OperationDefinition opDef = sc.readOperationDefinition(new IdType("OperationDefinition/Patient_i_someOp")); + ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(opDef)); + Set types = toStrings(opDef.getType()); + assertEquals("someOp", opDef.getCode()); + assertEquals(true, opDef.getInstance()); + assertEquals(false, opDef.getSystem()); + assertThat(types, containsInAnyOrder("Patient")); + assertEquals(2, opDef.getParameter().size()); + assertEquals("someOpParam1", opDef.getParameter().get(0).getName()); + assertEquals("date", opDef.getParameter().get(0).getType()); + assertEquals("someOpParam2", opDef.getParameter().get(1).getName()); + assertEquals("Patient", opDef.getParameter().get(1).getType()); + } + { + OperationDefinition opDef = sc.readOperationDefinition(new IdType("OperationDefinition/Encounter_i_someOp")); + ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(opDef)); + Set types = toStrings(opDef.getType()); + assertEquals("someOp", opDef.getCode()); + assertEquals(true, opDef.getInstance()); + assertEquals(false, opDef.getSystem()); + assertThat(types, containsInAnyOrder("Encounter")); + assertEquals(2, opDef.getParameter().size()); + assertEquals("someOpParam1", opDef.getParameter().get(0).getName()); + assertEquals("date", opDef.getParameter().get(0).getType()); + assertEquals("someOpParam2", opDef.getParameter().get(1).getName()); + assertEquals("Encounter", opDef.getParameter().get(1).getType()); + } + { + OperationDefinition opDef = sc.readOperationDefinition(new IdType("OperationDefinition/Patient_i_validate")); + ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(opDef)); + Set types = toStrings(opDef.getType()); + assertEquals("validate", opDef.getCode()); + assertEquals(true, opDef.getInstance()); + assertEquals(false, opDef.getSystem()); + assertThat(types, containsInAnyOrder("Patient")); + assertEquals(1, opDef.getParameter().size()); + assertEquals("resource", opDef.getParameter().get(0).getName()); + assertEquals("Patient", opDef.getParameter().get(0).getType()); + } + } + @Test public void testOperationDocumentation() throws Exception { @@ -268,7 +358,7 @@ public class ServerConformanceProviderDstu3Test { rs.init(createServletConfig()); - OperationDefinition opDef = sc.readOperationDefinition(new IdType("OperationDefinition/plain")); + OperationDefinition opDef = sc.readOperationDefinition(new IdType("OperationDefinition/_is_plain")); String conf = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(opDef); ourLog.info(conf); @@ -394,58 +484,6 @@ public class ServerConformanceProviderDstu3Test { assertThat(conf, containsString("")); } - - /** - * See #286 - */ - @Test - public void testSearchReferenceParameterWithWhitelistDocumentation() throws Exception { - - RestfulServer rs = new RestfulServer(ourCtx); - rs.setProviders(new SearchProviderWithWhitelist()); - - ServerConformanceProvider sc = new ServerConformanceProvider(rs); - rs.setServerConformanceProvider(sc); - - rs.init(createServletConfig()); - - boolean found = false; - Collection resourceBindings = rs.getResourceBindings(); - for (ResourceBinding resourceBinding : resourceBindings) { - if (resourceBinding.getResourceName().equals("Patient")) { - List> methodBindings = resourceBinding.getMethodBindings(); - SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0); - SearchParameter param = (SearchParameter) binding.getParameters().get(0); - assertEquals("The organization at which this person is a patient", param.getDescription()); - found = true; - } - } - assertTrue(found); - Conformance conformance = sc.getServerConformance(createHttpServletRequest()); - - String conf = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance); - ourLog.info(conf); - - ConformanceRestResourceComponent resource = findRestResource(conformance, "Patient"); - - ConformanceRestResourceSearchParamComponent param = resource.getSearchParam().get(0); - assertEquals("bar", param.getChain().get(0).getValue()); - assertEquals("foo", param.getChain().get(1).getValue()); - assertEquals(2, param.getChain().size()); - } - - private ConformanceRestResourceComponent findRestResource(Conformance conformance, String wantResource) throws Exception { - ConformanceRestResourceComponent resource = null; - for (ConformanceRestResourceComponent next : conformance.getRest().get(0).getResource()) { - if (next.getType().equals(wantResource)) { - resource = next; - } - } - if (resource == null) { - throw new Exception("Could not find resource: " + wantResource); - } - return resource; - } /** * See #286 @@ -480,6 +518,45 @@ public class ServerConformanceProviderDstu3Test { } + /** + * See #286 + */ + @Test + public void testSearchReferenceParameterWithWhitelistDocumentation() throws Exception { + + RestfulServer rs = new RestfulServer(ourCtx); + rs.setProviders(new SearchProviderWithWhitelist()); + + ServerConformanceProvider sc = new ServerConformanceProvider(rs); + rs.setServerConformanceProvider(sc); + + rs.init(createServletConfig()); + + boolean found = false; + Collection resourceBindings = rs.getResourceBindings(); + for (ResourceBinding resourceBinding : resourceBindings) { + if (resourceBinding.getResourceName().equals("Patient")) { + List> methodBindings = resourceBinding.getMethodBindings(); + SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0); + SearchParameter param = (SearchParameter) binding.getParameters().get(0); + assertEquals("The organization at which this person is a patient", param.getDescription()); + found = true; + } + } + assertTrue(found); + Conformance conformance = sc.getServerConformance(createHttpServletRequest()); + + String conf = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance); + ourLog.info(conf); + + ConformanceRestResourceComponent resource = findRestResource(conformance, "Patient"); + + ConformanceRestResourceSearchParamComponent param = resource.getSearchParam().get(0); + assertEquals("bar", param.getChain().get(0).getValue()); + assertEquals("foo", param.getChain().get(1).getValue()); + assertEquals(2, param.getChain().size()); + } + @Test public void testSystemHistorySupported() throws Exception { @@ -536,6 +613,27 @@ public class ServerConformanceProviderDstu3Test { assertTrue(result.getMessages().toString(), result.isSuccessful()); } + private List toOperationNames(List theOperation) { + ArrayList retVal = Lists.newArrayList(); + for (ConformanceRestOperationComponent next : theOperation) { + retVal.add(next.getName()); + } + return retVal; + } + + private Set toStrings(List theType) { + HashSet retVal = new HashSet(); + for (CodeType next : theType) { + retVal.add(next.getValueAsString()); + } + return retVal; + } + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + public static class ConditionalProvider implements IResourceProvider { @Create @@ -579,7 +677,48 @@ public class ServerConformanceProviderDstu3Test { public static class MultiOptionalProvider { @Search(type = Patient.class) - public Patient findPatient(@Description(shortDefinition = "The patient's identifier") @OptionalParam(name = Patient.SP_IDENTIFIER) TokenParam theIdentifier, @Description(shortDefinition = "The patient's name") @OptionalParam(name = Patient.SP_NAME) StringParam theName) { + public Patient findPatient(@Description(shortDefinition = "The patient's identifier") @OptionalParam(name = Patient.SP_IDENTIFIER) TokenParam theIdentifier, + @Description(shortDefinition = "The patient's name") @OptionalParam(name = Patient.SP_NAME) StringParam theName) { + return null; + } + + } + + public static class MultiTypeEncounterProvider implements IResourceProvider { + + @Operation(name = "someOp") + public ca.uhn.fhir.rest.server.IBundleProvider everything(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdType theId, + @OperationParam(name = "someOpParam1") DateType theStart, @OperationParam(name = "someOpParam2") Encounter theEnd) { + return null; + } + + @Override + public Class getResourceType() { + return Encounter.class; + } + + @Validate + public ca.uhn.fhir.rest.server.IBundleProvider validate(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdType theId, @ResourceParam Encounter thePatient) { + return null; + } + + } + + public static class MultiTypePatientProvider implements IResourceProvider { + + @Operation(name = "someOp") + public ca.uhn.fhir.rest.server.IBundleProvider everything(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdType theId, + @OperationParam(name = "someOpParam1") DateType theStart, @OperationParam(name = "someOpParam2") Patient theEnd) { + return null; + } + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Validate + public ca.uhn.fhir.rest.server.IBundleProvider validate(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdType theId, @ResourceParam Patient thePatient) { return null; } @@ -612,7 +751,8 @@ public class ServerConformanceProviderDstu3Test { public static class PlainProviderWithExtendedOperationOnNoType { @Operation(name = "plain", idempotent = true, returnParameters = { @OperationParam(min = 1, max = 2, name = "out1", type = StringType.class) }) - public ca.uhn.fhir.rest.server.IBundleProvider everything(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdType theId, @OperationParam(name = "start") DateType theStart, @OperationParam(name = "end") DateType theEnd) { + public ca.uhn.fhir.rest.server.IBundleProvider everything(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdType theId, @OperationParam(name = "start") DateType theStart, + @OperationParam(name = "end") DateType theEnd) { return null; } @@ -621,7 +761,8 @@ public class ServerConformanceProviderDstu3Test { public static class ProviderWithExtendedOperationReturningBundle implements IResourceProvider { @Operation(name = "everything", idempotent = true) - public ca.uhn.fhir.rest.server.IBundleProvider everything(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdType theId, @OperationParam(name = "start") DateType theStart, @OperationParam(name = "end") DateType theEnd) { + public ca.uhn.fhir.rest.server.IBundleProvider everything(javax.servlet.http.HttpServletRequest theServletRequest, @IdParam IdType theId, @OperationParam(name = "start") DateType theStart, + @OperationParam(name = "end") DateType theEnd) { return null; } @@ -636,16 +777,14 @@ public class ServerConformanceProviderDstu3Test { @Description(shortDefinition = "This is a search for stuff!") @Search - public List findDiagnosticReportsByPatient(@RequiredParam(name = DiagnosticReport.SP_SUBJECT + '.' + Patient.SP_IDENTIFIER) TokenParam thePatientId, @OptionalParam(name = DiagnosticReport.SP_CODE) TokenOrListParam theNames, - @OptionalParam(name = DiagnosticReport.SP_DATE) DateRangeParam theDateRange, @IncludeParam(allow = { "DiagnosticReport.result" }) Set theIncludes) throws Exception { + public List findDiagnosticReportsByPatient(@RequiredParam(name = DiagnosticReport.SP_SUBJECT + '.' + Patient.SP_IDENTIFIER) TokenParam thePatientId, + @OptionalParam(name = DiagnosticReport.SP_CODE) TokenOrListParam theNames, @OptionalParam(name = DiagnosticReport.SP_DATE) DateRangeParam theDateRange, + @IncludeParam(allow = { "DiagnosticReport.result" }) Set theIncludes) throws Exception { return null; } } - /** - * Created by dsotnikov on 2/25/2014. - */ public static class ReadProvider { @Search(type = Patient.class) @@ -668,7 +807,8 @@ public class ServerConformanceProviderDstu3Test { } @Search(type = Patient.class) - public Patient findPatient2(@Description(shortDefinition = "All patients linked to the given patient") @OptionalParam(name = "link", targetTypes = { Patient.class }) ReferenceAndListParam theLink) { + public Patient findPatient2( + @Description(shortDefinition = "All patients linked to the given patient") @OptionalParam(name = "link", targetTypes = { Patient.class }) ReferenceAndListParam theLink) { return null; } @@ -677,10 +817,8 @@ public class ServerConformanceProviderDstu3Test { public static class SearchProviderWithWhitelist { @Search(type = Patient.class) - public Patient findPatient1( - @Description(shortDefinition = "The organization at which this person is a patient") - @RequiredParam(name = Patient.SP_ORGANIZATION, chainWhitelist= {"foo", "bar"}) - ReferenceAndListParam theIdentifier) { + public Patient findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION, chainWhitelist = { "foo", + "bar" }) ReferenceAndListParam theIdentifier) { return null; } diff --git a/src/changes/changes.xml b/src/changes/changes.xml index de912d34c91..8dee2608062 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -329,9 +329,15 @@ that are defined within resource/plain providers incorrectly stated that the maximum cardinality was "*" for non-collection types with no explicit maximum stated, which is not the behaviour that the JavaDoc on the - annotation describes. Thanks to Michael Lawley for reporting! + + Operations that are defined on multiple resource provider types with + the same name (e.g. "$everything") are now automatically exposed by the server + as separate OperationDefinition resources per resource type. Thanks to + Michael Lawley for reporting! +