Avoid duplicate search param defs in generated CapabilityStatement (#2101)

* Avoid duplicate search param defs in generated CapabilityStatement

* Add changelog
This commit is contained in:
James Agnew 2020-09-22 19:21:34 -04:00 committed by GitHub
parent 8d9aa417e2
commit ecc09889cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 168 additions and 89 deletions

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 2101
title: "In some circumstances when using a Plain Server, the generated CapabilityStatement could have duplciate
Search Parameter definitions. This has been corrected."

View File

@ -332,6 +332,7 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
sortSearchParameters(searchParameters); sortSearchParameters(searchParameters);
if (!searchParameters.isEmpty()) { if (!searchParameters.isEmpty()) {
Set<String> paramNames = new HashSet<>();
for (SearchParameter nextParameter : searchParameters) { for (SearchParameter nextParameter : searchParameters) {
if (nextParameter.getParamType() == null) { if (nextParameter.getParamType() == null) {
@ -346,6 +347,10 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.')); nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
} }
if (!paramNames.add(nextParamUnchainedName)) {
continue;
}
String nextParamDescription = nextParameter.getDescription(); String nextParamDescription = nextParameter.getDescription();
/* /*
@ -425,6 +430,8 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
param.setMin(nextParam.isRequired() ? 1 : 0); param.setMin(nextParam.isRequired() ? 1 : 0);
param.setMax("1"); param.setMax("1");
param.setName(nextParam.getName()); param.setName(nextParam.getName());
} }
} }

View File

@ -5,11 +5,26 @@ import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.api.annotation.ResourceDef; import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.annotation.*; import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.History;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.IncludeParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.OptionalParam;
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.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.QuantityParam; import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam; import ca.uhn.fhir.rest.param.ReferenceAndListParam;
@ -27,7 +42,8 @@ import ca.uhn.fhir.validation.ValidationResult;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.hapi.rest.server.ServerCapabilityStatementProvider; import org.hl7.fhir.r4.hapi.rest.server.ServerCapabilityStatementProvider;
import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.CapabilityStatement;
import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestComponent; import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestComponent;
import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceComponent; import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceOperationComponent; import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResourceOperationComponent;
@ -35,10 +51,18 @@ import org.hl7.fhir.r4.model.CapabilityStatement.CapabilityStatementRestResource
import org.hl7.fhir.r4.model.CapabilityStatement.ConditionalDeleteStatus; import org.hl7.fhir.r4.model.CapabilityStatement.ConditionalDeleteStatus;
import org.hl7.fhir.r4.model.CapabilityStatement.SystemRestfulInteraction; import org.hl7.fhir.r4.model.CapabilityStatement.SystemRestfulInteraction;
import org.hl7.fhir.r4.model.CapabilityStatement.TypeRestfulInteraction; import org.hl7.fhir.r4.model.CapabilityStatement.TypeRestfulInteraction;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.DateType;
import org.hl7.fhir.r4.model.DiagnosticReport;
import org.hl7.fhir.r4.model.Encounter;
import org.hl7.fhir.r4.model.Enumerations.PublicationStatus; import org.hl7.fhir.r4.model.Enumerations.PublicationStatus;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.OperationDefinition;
import org.hl7.fhir.r4.model.OperationDefinition.OperationDefinitionParameterComponent; import org.hl7.fhir.r4.model.OperationDefinition.OperationDefinitionParameterComponent;
import org.hl7.fhir.r4.model.OperationDefinition.OperationKind; import org.hl7.fhir.r4.model.OperationDefinition.OperationKind;
import org.hl7.fhir.r4.model.OperationDefinition.OperationParameterUse; import org.hl7.fhir.r4.model.OperationDefinition.OperationParameterUse;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StringType;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -49,6 +73,7 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
@ -65,8 +90,12 @@ import static org.mockito.Mockito.when;
public class ServerCapabilityStatementProviderR4Test { public class ServerCapabilityStatementProviderR4Test {
private static FhirContext ourCtx; public static final String PATIENT_SUB = "PatientSub";
public static final String PATIENT_SUB_SUB = "PatientSubSub";
public static final String PATIENT_SUB_SUB_2 = "PatientSubSub2";
public static final String PATIENT_TRIPLE_SUB = "PatientTripleSub";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerCapabilityStatementProviderR4Test.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerCapabilityStatementProviderR4Test.class);
private static FhirContext ourCtx;
private static FhirValidator ourValidator; private static FhirValidator ourValidator;
static { static {
@ -259,7 +288,9 @@ public class ServerCapabilityStatementProviderR4Test {
assertNull(res.getConditionalUpdateElement().getValue()); assertNull(res.getConditionalUpdateElement().getValue());
} }
/** See #379 */ /**
* See #379
*/
@Test @Test
public void testOperationAcrossMultipleTypes() throws Exception { public void testOperationAcrossMultipleTypes() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx); RestfulServer rs = new RestfulServer(ourCtx);
@ -513,10 +544,10 @@ public class ServerCapabilityStatementProviderR4Test {
for (ResourceBinding resourceBinding : resourceBindings) { for (ResourceBinding resourceBinding : resourceBindings) {
if (resourceBinding.getResourceName().equals("Patient")) { if (resourceBinding.getResourceName().equals("Patient")) {
List<BaseMethodBinding<?>> methodBindings = resourceBinding.getMethodBindings(); List<BaseMethodBinding<?>> methodBindings = resourceBinding.getMethodBindings();
SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0); SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0);
SearchParameter param = (SearchParameter) binding.getParameters().get(25); SearchParameter param = (SearchParameter) binding.getParameters().get(25);
assertEquals("The organization at which this person is a patient", param.getDescription()); assertEquals("The organization at which this person is a patient", param.getDescription());
found = true; found = true;
} }
} }
assertTrue(found); assertTrue(found);
@ -569,7 +600,7 @@ public class ServerCapabilityStatementProviderR4Test {
@Test @Test
public void testSearchReferenceParameterWithList() throws Exception { public void testSearchReferenceParameterWithList() throws Exception {
RestfulServer rsNoType = new RestfulServer(ourCtx){ RestfulServer rsNoType = new RestfulServer(ourCtx) {
@Override @Override
public RestfulServerConfiguration createConfiguration() { public RestfulServerConfiguration createConfiguration() {
RestfulServerConfiguration retVal = super.createConfiguration(); RestfulServerConfiguration retVal = super.createConfiguration();
@ -586,7 +617,7 @@ public class ServerCapabilityStatementProviderR4Test {
String confNoType = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance); String confNoType = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance);
ourLog.info(confNoType); ourLog.info(confNoType);
RestfulServer rsWithType = new RestfulServer(ourCtx){ RestfulServer rsWithType = new RestfulServer(ourCtx) {
@Override @Override
public RestfulServerConfiguration createConfiguration() { public RestfulServerConfiguration createConfiguration() {
RestfulServerConfiguration retVal = super.createConfiguration(); RestfulServerConfiguration retVal = super.createConfiguration();
@ -645,6 +676,46 @@ public class ServerCapabilityStatementProviderR4Test {
assertThat(conf, containsString("<interaction><code value=\"" + TypeRestfulInteraction.HISTORYTYPE.toCode() + "\"/></interaction>")); assertThat(conf, containsString("<interaction><code value=\"" + TypeRestfulInteraction.HISTORYTYPE.toCode() + "\"/></interaction>"));
} }
@Test
public void testStaticIncludeChains() throws Exception {
class MyProvider implements IResourceProvider {
@Override
public Class<DiagnosticReport> getResourceType() {
return DiagnosticReport.class;
}
@Search
public List<IBaseResource> search(@RequiredParam(name = DiagnosticReport.SP_PATIENT + "." + Patient.SP_FAMILY) StringParam lastName,
@RequiredParam(name = DiagnosticReport.SP_PATIENT + "." + Patient.SP_GIVEN) StringParam firstName,
@RequiredParam(name = DiagnosticReport.SP_PATIENT + "." + Patient.SP_BIRTHDATE) DateParam dob,
@OptionalParam(name = DiagnosticReport.SP_DATE) DateRangeParam range) {
return null;
}
}
RestfulServer rs = new RestfulServer(ourCtx);
rs.setProviders(new MyProvider());
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider() {
};
rs.setServerConformanceProvider(sc);
rs.init(createServletConfig());
CapabilityStatement opDef = sc.getServerConformance(createHttpServletRequest(), createRequestDetails(rs));
String conf = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(opDef);
ourLog.info(conf);
CapabilityStatementRestResourceComponent resource = opDef.getRest().get(0).getResource().get(0);
assertEquals("DiagnosticReport", resource.getType());
List<String> searchParamNames = resource.getSearchParam().stream().map(t -> t.getName()).collect(Collectors.toList());
assertThat(searchParamNames, containsInAnyOrder("patient", "date"));
}
@Test @Test
public void testSystemLevelNamedQueryWithParameters() throws Exception { public void testSystemLevelNamedQueryWithParameters() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx); RestfulServer rs = new RestfulServer(ourCtx);
@ -729,8 +800,8 @@ public class ServerCapabilityStatementProviderR4Test {
assertThat(param.getUse(), is(OperationParameterUse.IN)); assertThat(param.getUse(), is(OperationParameterUse.IN));
CapabilityStatementRestResourceComponent patientResource = restComponent.getResource().stream() CapabilityStatementRestResourceComponent patientResource = restComponent.getResource().stream()
.filter(r -> patientResourceName.equals(r.getType())) .filter(r -> patientResourceName.equals(r.getType()))
.findAny().get(); .findAny().get();
assertThat("Named query parameters should not appear in the resource search params", patientResource.getSearchParam(), is(empty())); assertThat("Named query parameters should not appear in the resource search params", patientResource.getSearchParam(), is(empty()));
} }
@ -761,26 +832,26 @@ public class ServerCapabilityStatementProviderR4Test {
assertThat(opDef.getType(), is(true)); assertThat(opDef.getType(), is(true));
assertThat(opDef.getInstance(), is(false)); assertThat(opDef.getInstance(), is(false));
} }
@Test
public void testProfiledResourceStructureDefinitionLinks() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setResourceProviders(new ProfiledPatientProvider(), new MultipleProfilesPatientProvider());
ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider(); @Test
rs.setServerConformanceProvider(sc); public void testProfiledResourceStructureDefinitionLinks() throws Exception {
RestfulServer rs = new RestfulServer(ourCtx);
rs.setResourceProviders(new ProfiledPatientProvider(), new MultipleProfilesPatientProvider());
rs.init(createServletConfig()); ServerCapabilityStatementProvider sc = new ServerCapabilityStatementProvider();
rs.setServerConformanceProvider(sc);
CapabilityStatement conformance = sc.getServerConformance(createHttpServletRequest(), createRequestDetails(rs)); rs.init(createServletConfig());
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance));
List<CapabilityStatementRestResourceComponent> resources = conformance.getRestFirstRep().getResource(); CapabilityStatement conformance = sc.getServerConformance(createHttpServletRequest(), createRequestDetails(rs));
CapabilityStatementRestResourceComponent patientResource = resources.stream() ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(conformance));
.filter(resource -> "Patient".equals(resource.getType()))
.findFirst().get(); List<CapabilityStatementRestResourceComponent> resources = conformance.getRestFirstRep().getResource();
assertThat(patientResource.getProfile(), containsString(PATIENT_SUB)); CapabilityStatementRestResourceComponent patientResource = resources.stream()
} .filter(resource -> "Patient".equals(resource.getType()))
.findFirst().get();
assertThat(patientResource.getProfile(), containsString(PATIENT_SUB));
}
private List<String> toOperationIdParts(List<CapabilityStatementRestResourceOperationComponent> theOperation) { private List<String> toOperationIdParts(List<CapabilityStatementRestResourceOperationComponent> theOperation) {
ArrayList<String> retVal = Lists.newArrayList(); ArrayList<String> retVal = Lists.newArrayList();
@ -817,11 +888,6 @@ public class ServerCapabilityStatementProviderR4Test {
assertTrue(result.isSuccessful(), outcome); assertTrue(result.isSuccessful(), outcome);
} }
@AfterAll
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
@SuppressWarnings("unused") @SuppressWarnings("unused")
public static class ConditionalProvider implements IResourceProvider { public static class ConditionalProvider implements IResourceProvider {
@ -866,7 +932,7 @@ public class ServerCapabilityStatementProviderR4Test {
@Search(type = Patient.class) @Search(type = Patient.class)
public Patient findPatient(@Description(shortDefinition = "The patient's identifier") @OptionalParam(name = Patient.SP_IDENTIFIER) TokenParam theIdentifier, 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) { @Description(shortDefinition = "The patient's name") @OptionalParam(name = Patient.SP_NAME) StringParam theName) {
return null; return null;
} }
@ -942,7 +1008,7 @@ public class ServerCapabilityStatementProviderR4Test {
@SuppressWarnings("unused") @SuppressWarnings("unused")
public static class PlainProviderWithExtendedOperationOnNoType { public static class PlainProviderWithExtendedOperationOnNoType {
@Operation(name = "plain", idempotent = true, returnParameters = { @OperationParam(min = 1, max = 2, name = "out1", type = StringType.class) }) @Operation(name = "plain", idempotent = true, returnParameters = {@OperationParam(min = 1, max = 2, name = "out1", type = StringType.class)})
public IBundleProvider everything(HttpServletRequest theServletRequest, @IdParam IdType theId, @OperationParam(name = "start") DateType theStart, public IBundleProvider everything(HttpServletRequest theServletRequest, @IdParam IdType theId, @OperationParam(name = "start") DateType theStart,
@OperationParam(name = "end") DateType theEnd) { @OperationParam(name = "end") DateType theEnd) {
return null; return null;
@ -972,8 +1038,8 @@ public class ServerCapabilityStatementProviderR4Test {
@Description(shortDefinition = "This is a search for stuff!") @Description(shortDefinition = "This is a search for stuff!")
@Search @Search
public List<DiagnosticReport> findDiagnosticReportsByPatient(@RequiredParam(name = DiagnosticReport.SP_SUBJECT + '.' + Patient.SP_IDENTIFIER) TokenParam thePatientId, public List<DiagnosticReport> 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, @OptionalParam(name = DiagnosticReport.SP_CODE) TokenOrListParam theNames, @OptionalParam(name = DiagnosticReport.SP_DATE) DateRangeParam theDateRange,
@IncludeParam(allow = { "DiagnosticReport.result" }) Set<Include> theIncludes) throws Exception { @IncludeParam(allow = {"DiagnosticReport.result"}) Set<Include> theIncludes) throws Exception {
return null; return null;
} }
@ -1004,7 +1070,7 @@ public class ServerCapabilityStatementProviderR4Test {
@Search(type = Patient.class) @Search(type = Patient.class)
public Patient findPatient2( public Patient findPatient2(
@Description(shortDefinition = "All patients linked to the given patient") @OptionalParam(name = "link", targetTypes = { Patient.class }) ReferenceAndListParam theLink) { @Description(shortDefinition = "All patients linked to the given patient") @OptionalParam(name = "link", targetTypes = {Patient.class}) ReferenceAndListParam theLink) {
return null; return null;
} }
@ -1014,15 +1080,15 @@ public class ServerCapabilityStatementProviderR4Test {
public static class SearchProviderWithWhitelist { public static class SearchProviderWithWhitelist {
@Search(type = Patient.class) @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", public Patient findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION, chainWhitelist = {"foo",
"bar" }) ReferenceAndListParam theIdentifier) { "bar"}) ReferenceAndListParam theIdentifier) {
return null; return null;
} }
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
public static class SearchProviderWithListNoType implements IResourceProvider { public static class SearchProviderWithListNoType implements IResourceProvider {
@Override @Override
public Class<? extends IBaseResource> getResourceType() { public Class<? extends IBaseResource> getResourceType() {
@ -1030,7 +1096,6 @@ public class ServerCapabilityStatementProviderR4Test {
} }
@Search() @Search()
public List<Patient> findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION) ReferenceAndListParam theIdentifier) { public List<Patient> findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION) ReferenceAndListParam theIdentifier) {
return null; return null;
@ -1039,7 +1104,7 @@ public class ServerCapabilityStatementProviderR4Test {
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
public static class SearchProviderWithListWithType implements IResourceProvider { public static class SearchProviderWithListWithType implements IResourceProvider {
@Override @Override
public Class<? extends IBaseResource> getResourceType() { public Class<? extends IBaseResource> getResourceType() {
@ -1047,15 +1112,13 @@ public class ServerCapabilityStatementProviderR4Test {
} }
@Search(type = Patient.class)
@Search(type=Patient.class)
public List<Patient> findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION) ReferenceAndListParam theIdentifier) { public List<Patient> findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION) ReferenceAndListParam theIdentifier) {
return null; return null;
} }
} }
public static class SystemHistoryProvider { public static class SystemHistoryProvider {
@History @History
@ -1093,7 +1156,7 @@ public class ServerCapabilityStatementProviderR4Test {
} }
} }
public static class TypeLevelOperationProvider implements IResourceProvider { public static class TypeLevelOperationProvider implements IResourceProvider {
public static final String OPERATION_NAME = "op"; public static final String OPERATION_NAME = "op";
@ -1139,49 +1202,53 @@ public class ServerCapabilityStatementProviderR4Test {
} }
} }
public static class ProfiledPatientProvider implements IResourceProvider {
@Override public static class ProfiledPatientProvider implements IResourceProvider {
public Class<? extends IBaseResource> getResourceType() {
return PatientSubSub2.class;
}
@Search
public List<PatientSubSub2> find() {
return null;
}
}
public static class MultipleProfilesPatientProvider implements IResourceProvider {
@Override @Override
public Class<? extends IBaseResource> getResourceType() { public Class<? extends IBaseResource> getResourceType() {
return PatientSubSub.class; return PatientSubSub2.class;
} }
@Read(type = PatientTripleSub.class) @Search
public PatientTripleSub read(@IdParam IdType theId) { public List<PatientSubSub2> find() {
return null; return null;
} }
}
}
public static class MultipleProfilesPatientProvider implements IResourceProvider {
public static final String PATIENT_SUB = "PatientSub";
public static final String PATIENT_SUB_SUB = "PatientSubSub"; @Override
public static final String PATIENT_SUB_SUB_2 = "PatientSubSub2"; public Class<? extends IBaseResource> getResourceType() {
public static final String PATIENT_TRIPLE_SUB = "PatientTripleSub"; return PatientSubSub.class;
}
@ResourceDef(id = PATIENT_SUB)
public static class PatientSub extends Patient {} @Read(type = PatientTripleSub.class)
public PatientTripleSub read(@IdParam IdType theId) {
@ResourceDef(id = PATIENT_SUB_SUB) return null;
public static class PatientSubSub extends PatientSub {} }
@ResourceDef(id = PATIENT_SUB_SUB_2) }
public static class PatientSubSub2 extends PatientSub {}
@ResourceDef(id = PATIENT_SUB)
@ResourceDef(id = PATIENT_TRIPLE_SUB) public static class PatientSub extends Patient {
public static class PatientTripleSub extends PatientSubSub {} }
@ResourceDef(id = PATIENT_SUB_SUB)
public static class PatientSubSub extends PatientSub {
}
@ResourceDef(id = PATIENT_SUB_SUB_2)
public static class PatientSubSub2 extends PatientSub {
}
@ResourceDef(id = PATIENT_TRIPLE_SUB)
public static class PatientTripleSub extends PatientSubSub {
}
@AfterAll
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
} }