Avoid duplicate search param defs in generated CapabilityStatement (#2101)
* Avoid duplicate search param defs in generated CapabilityStatement * Add changelog
This commit is contained in:
parent
8d9aa417e2
commit
ecc09889cb
|
@ -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."
|
|
@ -332,6 +332,7 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
|||
sortSearchParameters(searchParameters);
|
||||
if (!searchParameters.isEmpty()) {
|
||||
|
||||
Set<String> paramNames = new HashSet<>();
|
||||
for (SearchParameter nextParameter : searchParameters) {
|
||||
|
||||
if (nextParameter.getParamType() == null) {
|
||||
|
@ -346,6 +347,10 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
|||
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
|
||||
}
|
||||
|
||||
if (!paramNames.add(nextParamUnchainedName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String nextParamDescription = nextParameter.getDescription();
|
||||
|
||||
/*
|
||||
|
@ -425,6 +430,8 @@ public class ServerCapabilityStatementProvider extends BaseServerCapabilityState
|
|||
param.setMin(nextParam.isRequired() ? 1 : 0);
|
||||
param.setMax("1");
|
||||
param.setName(nextParam.getName());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.ResourceDef;
|
||||
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.RestSearchParameterTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
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.QuantityParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
|
||||
|
@ -27,7 +42,8 @@ import ca.uhn.fhir.validation.ValidationResult;
|
|||
import com.google.common.collect.Lists;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
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.CapabilityStatementRestResourceComponent;
|
||||
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.SystemRestfulInteraction;
|
||||
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.IdType;
|
||||
import org.hl7.fhir.r4.model.OperationDefinition;
|
||||
import org.hl7.fhir.r4.model.OperationDefinition.OperationDefinitionParameterComponent;
|
||||
import org.hl7.fhir.r4.model.OperationDefinition.OperationKind;
|
||||
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.Test;
|
||||
|
||||
|
@ -49,6 +73,7 @@ import java.util.Collection;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
|
@ -65,8 +90,12 @@ import static org.mockito.Mockito.when;
|
|||
|
||||
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 FhirContext ourCtx;
|
||||
private static FhirValidator ourValidator;
|
||||
|
||||
static {
|
||||
|
@ -259,7 +288,9 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
assertNull(res.getConditionalUpdateElement().getValue());
|
||||
}
|
||||
|
||||
/** See #379 */
|
||||
/**
|
||||
* See #379
|
||||
*/
|
||||
@Test
|
||||
public void testOperationAcrossMultipleTypes() throws Exception {
|
||||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
|
@ -645,6 +676,46 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
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
|
||||
public void testSystemLevelNamedQueryWithParameters() throws Exception {
|
||||
RestfulServer rs = new RestfulServer(ourCtx);
|
||||
|
@ -817,11 +888,6 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
assertTrue(result.isSuccessful(), outcome);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static class ConditionalProvider implements IResourceProvider {
|
||||
|
||||
|
@ -1030,7 +1096,6 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
}
|
||||
|
||||
|
||||
|
||||
@Search()
|
||||
public List<Patient> findPatient1(@Description(shortDefinition = "The organization at which this person is a patient") @RequiredParam(name = Patient.SP_ORGANIZATION) ReferenceAndListParam theIdentifier) {
|
||||
return null;
|
||||
|
@ -1047,7 +1112,6 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
}
|
||||
|
||||
|
||||
|
||||
@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) {
|
||||
return null;
|
||||
|
@ -1055,7 +1119,6 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
|
||||
}
|
||||
|
||||
|
||||
public static class SystemHistoryProvider {
|
||||
|
||||
@History
|
||||
|
@ -1167,21 +1230,25 @@ public class ServerCapabilityStatementProviderR4Test {
|
|||
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB)
|
||||
public static class PatientSub extends Patient {}
|
||||
public static class PatientSub extends Patient {
|
||||
}
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB_SUB)
|
||||
public static class PatientSubSub extends PatientSub {}
|
||||
public static class PatientSubSub extends PatientSub {
|
||||
}
|
||||
|
||||
@ResourceDef(id = PATIENT_SUB_SUB_2)
|
||||
public static class PatientSubSub2 extends PatientSub {}
|
||||
public static class PatientSubSub2 extends PatientSub {
|
||||
}
|
||||
|
||||
@ResourceDef(id = PATIENT_TRIPLE_SUB)
|
||||
public static class PatientTripleSub extends PatientSubSub {}
|
||||
public static class PatientTripleSub extends PatientSubSub {
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue