From b617c7690dd4dcaa939edbeed19f85447baba94b Mon Sep 17 00:00:00 2001 From: James Agnew Date: Mon, 5 Apr 2021 17:40:10 -0400 Subject: [PATCH] Search Parameter Infrastructure Cleanup (#2522) * Search param service cleanup * Work on collapsing search param * Search param cleanup * Work on build * Test fix * Test fixes * Ongoing work * Test fix * Compile fix * Test fixes * Test fix * Test fix * License header updates * Remove fixme * Cleanup * Cleanup --- hapi-deployable-pom/pom.xml | 2 +- hapi-fhir-android/pom.xml | 2 +- hapi-fhir-base/pom.xml | 2 +- .../ca/uhn/fhir/context/ModelScanner.java | 33 +- .../uhn/fhir/context/RuntimeSearchParam.java | 89 +++-- .../ca/uhn/fhir/rest/param/ParameterUtil.java | 153 +-------- hapi-fhir-bom/pom.xml | 4 +- hapi-fhir-cli/hapi-fhir-cli-api/pom.xml | 2 +- hapi-fhir-cli/hapi-fhir-cli-app/pom.xml | 2 +- hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml | 2 +- .../ca/uhn/fhir/jpa/demo/JpaServerDemo.java | 2 +- hapi-fhir-cli/pom.xml | 2 +- hapi-fhir-client-okhttp/pom.xml | 2 +- hapi-fhir-client/pom.xml | 2 +- hapi-fhir-converter/pom.xml | 2 +- hapi-fhir-dist/pom.xml | 2 +- hapi-fhir-docs/pom.xml | 8 +- hapi-fhir-jacoco/pom.xml | 2 +- hapi-fhir-jaxrsserver-base/pom.xml | 2 +- hapi-fhir-jaxrsserver-example/pom.xml | 2 +- hapi-fhir-jpaserver-api/pom.xml | 2 +- hapi-fhir-jpaserver-base/pom.xml | 2 +- .../ca/uhn/fhir/jpa/dao/BaseStorageDao.java | 10 +- .../uhn/fhir/jpa/dao/LegacySearchBuilder.java | 11 +- ...rchParamWithInlineReferencesExtractor.java | 17 +- .../predicate/PredicateBuilderReference.java | 30 +- .../r4/FhirResourceDaoSearchParameterR4.java | 5 +- .../jpa/packages/PackageInstallerSvcImpl.java | 7 +- .../JpaCapabilityStatementProvider.java | 4 +- .../dstu3/JpaConformanceProviderDstu3.java | 8 +- .../fhir/jpa/search/builder/QueryStack.java | 303 +++++++++--------- .../jpa/search/builder/SearchBuilder.java | 23 +- .../ResourceLinkPredicateBuilder.java | 13 +- .../reindex/ResourceReindexingSvcImpl.java | 2 +- .../java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java | 5 +- .../fhir/jpa/dao/dstu2/BaseJpaDstu2Test.java | 11 +- ...ceDaoDstu2SearchCustomSearchParamTest.java | 2 +- .../fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java | 3 +- ...esourceDaoDstu3PhoneticSearchNoFtTest.java | 2 +- ...ourceDaoR4SearchCustomSearchParamTest.java | 2 +- ...esourceDaoR4SearchWithElasticSearchIT.java | 2 +- ...urceDaoR4SearchWithLuceneDisabledTest.java | 4 +- ...sourceDaoR4TerminologyElasticsearchIT.java | 2 +- ...hirResourceDaoR4UniqueSearchParamTest.java | 19 +- .../dao/r4/SearchParamExtractorR4Test.java | 31 +- .../provider/ResourceProviderDstu2Test.java | 2 +- ...sourceProviderCustomSearchParamR4Test.java | 2 + .../r4/ResourceProviderHasParamR4Test.java | 2 +- .../ResourceReindexingSvcImplTest.java | 3 +- .../jpa/searchparam/MatchUrlServiceTest.java | 6 +- .../ValueSetExpansionR4ElasticsearchIT.java | 2 +- hapi-fhir-jpaserver-batch/pom.xml | 2 +- hapi-fhir-jpaserver-cql/pom.xml | 6 +- hapi-fhir-jpaserver-mdm/pom.xml | 6 +- .../jpa/mdm/config/MdmConsumerConfig.java | 4 +- .../jpa/mdm/config/MdmSubmitterConfig.java | 4 +- .../fhir/jpa/mdm/svc/MdmSearchParamSvc.java | 2 +- hapi-fhir-jpaserver-migrate/pom.xml | 2 +- hapi-fhir-jpaserver-model/pom.xml | 2 +- hapi-fhir-jpaserver-searchparam/pom.xml | 2 +- .../fhir/jpa/cache/ResourceChangeEvent.java | 1 + .../searchparam/JpaRuntimeSearchParam.java | 88 ----- .../fhir/jpa/searchparam/MatchUrlService.java | 13 +- .../searchparam/config/SearchParamConfig.java | 2 +- .../extractor/BaseSearchParamExtractor.java | 2 +- .../extractor/SearchParamExtractorDstu2.java | 2 +- .../extractor/SearchParamExtractorDstu3.java | 2 +- .../extractor/SearchParamExtractorR4.java | 2 +- .../extractor/SearchParamExtractorR5.java | 2 +- .../SearchParamExtractorService.java | 5 +- .../matcher/InMemoryResourceMatcher.java | 2 +- .../registry/ISearchParamRegistry.java | 77 ----- .../ISearchParamRegistryController.java | 27 +- .../registry/JpaSearchParamCache.java | 61 ++-- .../registry/ReadOnlySearchParamCache.java | 76 ++--- .../registry/RuntimeSearchParamCache.java | 39 ++- .../registry/SearchParamRegistryImpl.java | 41 ++- .../SearchParameterCanonicalizer.java | 42 +-- .../jpa/searchparam/util/JpaParamUtil.java | 194 +++++++++++ .../fhir/jpa/searchparam/IndexStressTest.java | 2 +- .../SearchParamExtractorDstu3Test.java | 49 ++- .../SearchParamExtractorMegaTest.java | 30 +- .../InMemoryResourceMatcherR5Test.java | 13 +- .../registry/SearchParamRegistryImplTest.java | 3 +- hapi-fhir-jpaserver-subscription/pom.xml | 2 +- .../match/registry/SubscriptionLoader.java | 2 +- .../WebsocketConnectionValidatorTest.java | 2 +- hapi-fhir-jpaserver-test-utilities/pom.xml | 2 +- hapi-fhir-jpaserver-uhnfhirtest/pom.xml | 4 +- .../ca/uhn/fhirtest/TestRestfulServer.java | 2 +- hapi-fhir-server-mdm/pom.xml | 2 +- .../mdm/rules/config/MdmRuleValidator.java | 8 +- .../test/java/ca/uhn/fhir/mdm/BaseR4Test.java | 4 +- .../mdm/rules/svc/ResourceMatcherR4Test.java | 3 - .../ca/uhn/fhir/mdm/svc/EIDHelperR4Test.java | 5 +- hapi-fhir-server/pom.xml | 2 +- .../server/RestfulServerConfiguration.java | 14 +- .../SearchPreferHandlingInterceptor.java | 12 +- .../ServerCapabilityStatementProvider.java | 26 +- .../server/util/ISearchParamRegistry.java | 106 ++++++ .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../hapi-fhir-spring-boot-samples/pom.xml | 2 +- .../hapi-fhir-spring-boot-starter/pom.xml | 2 +- hapi-fhir-spring-boot/pom.xml | 2 +- hapi-fhir-structures-dstu2.1/pom.xml | 2 +- hapi-fhir-structures-dstu2/pom.xml | 2 +- hapi-fhir-structures-dstu3/pom.xml | 2 +- .../fhir/context/FhirContextDstu3Test.java | 2 +- hapi-fhir-structures-hl7org-dstu2/pom.xml | 2 +- hapi-fhir-structures-r4/pom.xml | 2 +- .../org/hl7/fhir/r4/model/ModelR4Test.java | 10 + hapi-fhir-structures-r5/pom.xml | 2 +- hapi-fhir-test-utilities/pom.xml | 2 +- hapi-fhir-testpage-overlay/pom.xml | 2 +- .../pom.xml | 2 +- hapi-fhir-validation-resources-dstu2/pom.xml | 2 +- hapi-fhir-validation-resources-dstu3/pom.xml | 2 +- hapi-fhir-validation-resources-r4/pom.xml | 2 +- hapi-fhir-validation-resources-r5/pom.xml | 2 +- hapi-fhir-validation/pom.xml | 2 +- hapi-tinder-plugin/pom.xml | 26 +- .../fhir/tinder/TinderJpaRestServerMojo.java | 10 +- .../fhir/tinder/model/SearchParameter.java | 4 +- .../parser/ResourceGeneratorUsingModel.java | 17 +- hapi-tinder-test/pom.xml | 2 +- pom.xml | 6 +- restful-server-example/pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- .../pom.xml | 2 +- 133 files changed, 1008 insertions(+), 974 deletions(-) delete mode 100644 hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/JpaRuntimeSearchParam.java delete mode 100644 hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ISearchParamRegistry.java rename hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRetriever.java => hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ISearchParamRegistryController.java (52%) create mode 100644 hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/util/JpaParamUtil.java create mode 100644 hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRegistry.java diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml index a73013b3dea..24b70220c38 100644 --- a/hapi-deployable-pom/pom.xml +++ b/hapi-deployable-pom/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-android/pom.xml b/hapi-fhir-android/pom.xml index d6ab5abb4ed..7799cb47af2 100644 --- a/hapi-fhir-android/pom.xml +++ b/hapi-fhir-android/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index 0854f8c8eb4..c5a761ca696 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java index fd60d389a42..69d7ed6272d 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/ModelScanner.java @@ -394,41 +394,30 @@ class ModelScanner { b.append(" provides compartment membership but is not of type 'reference'"); ourLog.warn(b.toString()); continue; -// throw new ConfigurationException(b.toString()); } providesMembershipInCompartments.add(next.name()); } + List components = null; if (paramType == RestSearchParameterTypeEnum.COMPOSITE) { - compositeFields.put(nextField, searchParam); - continue; + components = new ArrayList<>(); + for (String next : searchParam.compositeOf()) { + String ref = "http://hl7.org/fhir/SearchParameter/" + theResourceDef.getName().toLowerCase() + "-" + next; + components.add(new RuntimeSearchParam.Component(null, ref)); + } } - Collection base = Collections.singletonList(theResourceDef.getName()); - RuntimeSearchParam param = new RuntimeSearchParam(null, null, searchParam.name(), searchParam.description(), searchParam.path(), paramType, null, providesMembershipInCompartments, toTargetList(searchParam.target()), RuntimeSearchParamStatusEnum.ACTIVE, base); + String url = null; + if (theResourceDef.isStandardType()) { + url = "http://hl7.org/fhir/SearchParameter/" + theResourceDef.getName().toLowerCase() + "-" + searchParam.name(); + } + RuntimeSearchParam param = new RuntimeSearchParam(null, url, searchParam.name(), searchParam.description(), searchParam.path(), paramType, providesMembershipInCompartments, toTargetList(searchParam.target()), RuntimeSearchParamStatusEnum.ACTIVE, false, components, base); theResourceDef.addSearchParam(param); nameToParam.put(param.getName(), param); } } - for (Entry nextEntry : compositeFields.entrySet()) { - SearchParamDefinition searchParam = nextEntry.getValue(); - - List compositeOf = new ArrayList<>(); - for (String nextName : searchParam.compositeOf()) { - RuntimeSearchParam param = nameToParam.get(nextName); - if (param == null) { - ourLog.warn("Search parameter {}.{} declares that it is a composite with compositeOf value '{}' but that is not a valid parameter name itself. Valid values are: {}", - theResourceDef.getName(), searchParam.name(), nextName, nameToParam.keySet()); - continue; - } - compositeOf.add(param); - } - - RuntimeSearchParam param = new RuntimeSearchParam(null, null, searchParam.name(), searchParam.description(), searchParam.path(), RestSearchParameterTypeEnum.COMPOSITE, compositeOf, null, toTargetList(searchParam.target()), RuntimeSearchParamStatusEnum.ACTIVE); - theResourceDef.addSearchParam(param); - } } private Set toTargetList(Class[] theTarget) { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeSearchParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeSearchParam.java index 9748925d0fc..8e795c32e1a 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeSearchParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/RuntimeSearchParam.java @@ -46,7 +46,6 @@ import static org.apache.commons.lang3.StringUtils.trim; public class RuntimeSearchParam { private final IIdType myId; private final Set myBase; - private final List myCompositeOf; private final String myDescription; private final String myName; private final RestSearchParameterTypeEnum myParamType; @@ -56,21 +55,29 @@ public class RuntimeSearchParam { private final RuntimeSearchParamStatusEnum myStatus; private final String myUri; private final Map>> myExtensions = new HashMap<>(); + private final boolean myUnique; + private final List myComponents; private IPhoneticEncoder myPhoneticEncoder; /** * Constructor */ - public RuntimeSearchParam(IIdType theId, String theUri, String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, List theCompositeOf, - Set theProvidesMembershipInCompartments, Set theTargets, RuntimeSearchParamStatusEnum theStatus) { - this(theId, theUri, theName, theDescription, thePath, theParamType, theCompositeOf, theProvidesMembershipInCompartments, theTargets, theStatus, null); + public RuntimeSearchParam(IIdType theId, String theUri, String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, + Set theProvidesMembershipInCompartments, Set theTargets, RuntimeSearchParamStatusEnum theStatus, Collection theBase) { + this(theId, theUri, theName, theDescription, thePath, theParamType, theProvidesMembershipInCompartments, theTargets, theStatus, false, Collections.emptyList(), theBase); + } + + /** + * Copy constructor + */ + public RuntimeSearchParam(RuntimeSearchParam theSp) { + this(theSp.getId(), theSp.getUri(), theSp.getName(), theSp.getDescription(), theSp.getPath(), theSp.getParamType(), theSp.getProvidesMembershipInCompartments(), theSp.getTargets(), theSp.getStatus(), theSp.isUnique(), theSp.getComponents(), theSp.getBase()); } /** * Constructor */ - public RuntimeSearchParam(IIdType theId, String theUri, String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, List theCompositeOf, - Set theProvidesMembershipInCompartments, Set theTargets, RuntimeSearchParamStatusEnum theStatus, Collection theBase) { + public RuntimeSearchParam(IIdType theId, String theUri, String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, Set theProvidesMembershipInCompartments, Set theTargets, RuntimeSearchParamStatusEnum theStatus, boolean theUnique, List theComponents, Collection theBase) { super(); myId = theId; @@ -79,7 +86,6 @@ public class RuntimeSearchParam { myDescription = theDescription; myPath = thePath; myParamType = theParamType; - myCompositeOf = theCompositeOf; myStatus = theStatus; if (theProvidesMembershipInCompartments != null && !theProvidesMembershipInCompartments.isEmpty()) { myProvidesMembershipInCompartments = Collections.unmodifiableSet(theProvidesMembershipInCompartments); @@ -104,20 +110,20 @@ public class RuntimeSearchParam { } else { myBase = Collections.unmodifiableSet(new HashSet<>(theBase)); } + myUnique = theUnique; + if (theComponents != null) { + myComponents = Collections.unmodifiableList(theComponents); + } else { + myComponents = Collections.emptyList(); + } } - /** - * Constructor - */ - public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, Set theProvidesMembershipInCompartments, Set theTargets, RuntimeSearchParamStatusEnum theStatus) { - this(null, null, theName, theDescription, thePath, theParamType, null, theProvidesMembershipInCompartments, theTargets, theStatus); + public List getComponents() { + return myComponents; } - /** - * Copy constructor - */ - public RuntimeSearchParam(RuntimeSearchParam theSp) { - this(theSp.getId(), theSp.getUri(), theSp.getName(), theSp.getDescription(), theSp.getPath(), theSp.getParamType(), theSp.getCompositeOf(), theSp.getProvidesMembershipInCompartments(), theSp.getTargets(), theSp.getStatus(), theSp.getBase()); + public boolean isUnique() { + return myUnique; } /** @@ -205,10 +211,6 @@ public class RuntimeSearchParam { return myStatus; } - public List getCompositeOf() { - return myCompositeOf; - } - public String getDescription() { return myDescription; } @@ -247,13 +249,6 @@ public class RuntimeSearchParam { return myProvidesMembershipInCompartments; } - public enum RuntimeSearchParamStatusEnum { - ACTIVE, - DRAFT, - RETIRED, - UNKNOWN - } - public RuntimeSearchParam setPhoneticEncoder(IPhoneticEncoder thePhoneticEncoder) { myPhoneticEncoder = thePhoneticEncoder; return this; @@ -265,4 +260,42 @@ public class RuntimeSearchParam { } return myPhoneticEncoder.encode(theString); } + + public enum RuntimeSearchParamStatusEnum { + ACTIVE, + DRAFT, + RETIRED, + UNKNOWN + } + + public static class Component { + private final String myExpression; + private final String myReference; + + /** + * Constructor + */ + public Component(String theExpression, String theReference) { + myExpression = theExpression; + myReference = theReference; + + } + + @Override + public String toString() { + return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) + .append("expression", myExpression) + .append("reference", myReference) + .toString(); + } + + public String getExpression() { + return myExpression; + } + + public String getReference() { + return myReference; + } + } + } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java index f980a91d060..132d7a76253 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java @@ -1,5 +1,19 @@ package ca.uhn.fhir.rest.param; +import ca.uhn.fhir.context.ConfigurationException; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.api.IQueryParameterOr; +import ca.uhn.fhir.model.api.IQueryParameterType; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.model.primitive.IntegerDt; +import ca.uhn.fhir.rest.annotation.IdParam; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.QualifiedParamList; +import ca.uhn.fhir.util.ReflectionUtil; +import ca.uhn.fhir.util.UrlUtil; +import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.instance.model.api.IPrimitiveType; + import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; @@ -8,25 +22,6 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -import org.hl7.fhir.instance.model.api.IIdType; -import org.hl7.fhir.instance.model.api.IPrimitiveType; - -import ca.uhn.fhir.context.ConfigurationException; -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.RuntimeSearchParam; -import ca.uhn.fhir.model.api.IQueryParameterAnd; -import ca.uhn.fhir.model.api.IQueryParameterOr; -import ca.uhn.fhir.model.api.IQueryParameterType; -import ca.uhn.fhir.model.primitive.IdDt; -import ca.uhn.fhir.model.primitive.IntegerDt; -import ca.uhn.fhir.rest.annotation.IdParam; -import ca.uhn.fhir.rest.api.Constants; -import ca.uhn.fhir.rest.api.QualifiedParamList; -import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; -import ca.uhn.fhir.rest.param.binder.QueryParameterAndBinder; -import ca.uhn.fhir.util.ReflectionUtil; -import ca.uhn.fhir.util.UrlUtil; - /* * #%L * HAPI FHIR - Core Library @@ -59,126 +54,6 @@ public class ParameterUtil { return (T) value; } - /** - * This is a utility method intended provided to help the JPA module. - */ - public static IQueryParameterAnd parseQueryParams(FhirContext theContext, RestSearchParameterTypeEnum paramType, - String theUnqualifiedParamName, List theParameters) { - QueryParameterAndBinder binder; - switch (paramType) { - case COMPOSITE: - throw new UnsupportedOperationException(); - case DATE: - binder = new QueryParameterAndBinder(DateAndListParam.class, - Collections.emptyList()); - break; - case NUMBER: - binder = new QueryParameterAndBinder(NumberAndListParam.class, - Collections.emptyList()); - break; - case QUANTITY: - binder = new QueryParameterAndBinder(QuantityAndListParam.class, - Collections.emptyList()); - break; - case REFERENCE: - binder = new QueryParameterAndBinder(ReferenceAndListParam.class, - Collections.emptyList()); - break; - case STRING: - binder = new QueryParameterAndBinder(StringAndListParam.class, - Collections.emptyList()); - break; - case TOKEN: - binder = new QueryParameterAndBinder(TokenAndListParam.class, - Collections.emptyList()); - break; - case URI: - binder = new QueryParameterAndBinder(UriAndListParam.class, - Collections.emptyList()); - break; - case HAS: - binder = new QueryParameterAndBinder(HasAndListParam.class, - Collections.emptyList()); - break; - case SPECIAL: - binder = new QueryParameterAndBinder(SpecialAndListParam.class, - Collections.emptyList()); - break; - default: - throw new IllegalArgumentException("Parameter '" + theUnqualifiedParamName + "' has type " + paramType + " which is currently not supported."); - } - - return binder.parse(theContext, theUnqualifiedParamName, theParameters); - } - - /** - * This is a utility method intended provided to help the JPA module. - */ - public static IQueryParameterAnd parseQueryParams(FhirContext theContext, RuntimeSearchParam theParamDef, - String theUnqualifiedParamName, List theParameters) { - - RestSearchParameterTypeEnum paramType = theParamDef.getParamType(); - - if (paramType == RestSearchParameterTypeEnum.COMPOSITE) { - - List theCompositList = theParamDef.getCompositeOf(); - - if (theCompositList == null) { - throw new ConfigurationException("Search parameter of type " + theUnqualifiedParamName - + " can be found in parameter annotation, found "); - } - - if (theCompositList.size() != 2) { - throw new ConfigurationException("Search parameter of type " + theUnqualifiedParamName - + " must have 2 composite types declared in parameter annotation, found " - + theCompositList.size()); - } - - RuntimeSearchParam left = theCompositList.get(0); - RuntimeSearchParam right = theCompositList.get(1); - - @SuppressWarnings({ "unchecked", "rawtypes" }) - CompositeAndListParam cp = new CompositeAndListParam( - getCompositBindingClass(left.getParamType(), left.getName()), - getCompositBindingClass(right.getParamType(), right.getName())); - - cp.setValuesAsQueryTokens(theContext, theUnqualifiedParamName, theParameters); - - return cp; - } else { - return parseQueryParams(theContext, paramType, theUnqualifiedParamName, theParameters); - } - } - - private static Class getCompositBindingClass(RestSearchParameterTypeEnum paramType, - String theUnqualifiedParamName) { - - switch (paramType) { - case DATE: - return DateParam.class; - case NUMBER: - return NumberParam.class; - case QUANTITY: - return QuantityParam.class; - case REFERENCE: - return ReferenceParam.class; - case STRING: - return StringParam.class; - case TOKEN: - return TokenParam.class; - case URI: - return UriParam.class; - case HAS: - return HasParam.class; - case SPECIAL: - return SpecialParam.class; - - default: - throw new IllegalArgumentException("Parameter '" + theUnqualifiedParamName + "' has type " + paramType - + " which is currently not supported."); - } - } - /** * Removes :modifiers and .chains from URL parameter names */ diff --git a/hapi-fhir-bom/pom.xml b/hapi-fhir-bom/pom.xml index 19e515d26a4..4dd2fffc8f8 100644 --- a/hapi-fhir-bom/pom.xml +++ b/hapi-fhir-bom/pom.xml @@ -3,14 +3,14 @@ 4.0.0 ca.uhn.hapi.fhir hapi-fhir-bom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT pom HAPI FHIR BOM ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml index 8111acba863..0f7b6eb19c0 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml index e1635c1b9db..dd903ab4f1b 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir-cli - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml index e319c6da42a..39c3cc8e20d 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../../hapi-deployable-pom diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java index dc7d8cff645..b9ac064b29a 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/JpaServerDemo.java @@ -37,7 +37,7 @@ import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3; import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3; import ca.uhn.fhir.jpa.provider.JpaCapabilityStatementProvider; import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.model.dstu2.composite.MetaDt; import ca.uhn.fhir.model.dstu2.resource.Bundle; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; diff --git a/hapi-fhir-cli/pom.xml b/hapi-fhir-cli/pom.xml index 39a66edf090..9783866a885 100644 --- a/hapi-fhir-cli/pom.xml +++ b/hapi-fhir-cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml index 3a02ec6e5c0..6893093762d 100644 --- a/hapi-fhir-client-okhttp/pom.xml +++ b/hapi-fhir-client-okhttp/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml index a2fa46beaab..6f0efaa5903 100644 --- a/hapi-fhir-client/pom.xml +++ b/hapi-fhir-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml index 227dea350b2..20d250d8cc3 100644 --- a/hapi-fhir-converter/pom.xml +++ b/hapi-fhir-converter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-dist/pom.xml b/hapi-fhir-dist/pom.xml index e76461561f4..6b0955b04ab 100644 --- a/hapi-fhir-dist/pom.xml +++ b/hapi-fhir-dist/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml index cb1302c1487..fb13d1edbb7 100644 --- a/hapi-fhir-docs/pom.xml +++ b/hapi-fhir-docs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -78,13 +78,13 @@ ca.uhn.hapi.fhir hapi-fhir-structures-dstu2 - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT compile ca.uhn.hapi.fhir hapi-fhir-jpaserver-subscription - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT compile @@ -101,7 +101,7 @@ ca.uhn.hapi.fhir hapi-fhir-testpage-overlay - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT classes diff --git a/hapi-fhir-jacoco/pom.xml b/hapi-fhir-jacoco/pom.xml index 47bb72c223c..6090e7545d9 100644 --- a/hapi-fhir-jacoco/pom.xml +++ b/hapi-fhir-jacoco/pom.xml @@ -11,7 +11,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index de0d3afbb8a..6cfa369bfdc 100644 --- a/hapi-fhir-jaxrsserver-base/pom.xml +++ b/hapi-fhir-jaxrsserver-base/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jaxrsserver-example/pom.xml b/hapi-fhir-jaxrsserver-example/pom.xml index ace48cd8706..687d6b10dbf 100644 --- a/hapi-fhir-jaxrsserver-example/pom.xml +++ b/hapi-fhir-jaxrsserver-example/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-jpaserver-api/pom.xml b/hapi-fhir-jpaserver-api/pom.xml index b14ee8d6d6d..8cf5d00b229 100644 --- a/hapi-fhir-jpaserver-api/pom.xml +++ b/hapi-fhir-jpaserver-api/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml index 982468d6dbc..a8958f299a0 100644 --- a/hapi-fhir-jpaserver-base/pom.xml +++ b/hapi-fhir-jpaserver-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseStorageDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseStorageDao.java index b4b0530633d..0dc80bf9500 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseStorageDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseStorageDao.java @@ -21,7 +21,6 @@ package ca.uhn.fhir.jpa.dao; */ import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.interceptor.api.HookParams; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; @@ -34,7 +33,8 @@ import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster; import ca.uhn.fhir.model.api.IQueryParameterAnd; import ca.uhn.fhir.rest.api.QualifiedParamList; @@ -44,7 +44,6 @@ import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.SimplePreResourceAccessDetails; import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; -import ca.uhn.fhir.rest.param.ParameterUtil; import ca.uhn.fhir.rest.param.QualifierDetails; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; @@ -339,13 +338,12 @@ public abstract class BaseStorageDao { } // Should not be null since the check above would have caught it - RuntimeResourceDefinition resourceDef = getContext().getResourceDefinition(getResourceName()); - RuntimeSearchParam paramDef = mySearchParamRegistry.getSearchParamByName(resourceDef, qualifiedParamName.getParamName()); + RuntimeSearchParam paramDef = mySearchParamRegistry.getActiveSearchParam(getResourceName(), qualifiedParamName.getParamName()); for (String nextValue : theSource.get(nextParamName)) { QualifiedParamList qualifiedParam = QualifiedParamList.splitQueryStringByCommasIgnoreEscape(qualifiedParamName.getWholeQualifier(), nextValue); List paramList = Collections.singletonList(qualifiedParam); - IQueryParameterAnd parsedParam = ParameterUtil.parseQueryParams(getContext(), paramDef, nextParamName, paramList); + IQueryParameterAnd parsedParam = JpaParamUtil.parseQueryParams(mySearchParamRegistry, getContext(), paramDef, nextParamName, paramList); theTarget.add(qualifiedParamName.getParamName(), parsedParam); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/LegacySearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/LegacySearchBuilder.java index 4f3a2de40f5..25a5dbbc89d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/LegacySearchBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/LegacySearchBuilder.java @@ -42,7 +42,6 @@ import ca.uhn.fhir.jpa.entity.ResourceSearchView; import ca.uhn.fhir.jpa.interceptor.JpaPreResourceAccessDetails; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam; -import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedCompositeStringUnique; import ca.uhn.fhir.jpa.model.entity.ResourceLink; import ca.uhn.fhir.jpa.model.entity.ResourceTable; @@ -51,9 +50,8 @@ import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails; import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.search.lastn.IElasticsearchSvc; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.util.Dstu3DistanceHelper; import ca.uhn.fhir.jpa.searchparam.util.LastNParameterHelper; import ca.uhn.fhir.jpa.util.BaseIterator; @@ -483,8 +481,7 @@ public class LegacySearchBuilder implements ISearchBuilder { return orders; } - RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(myResourceName); - RuntimeSearchParam param = mySearchParamRegistry.getSearchParamByName(resourceDef, theSort.getParamName()); + RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam(myResourceName, theSort.getParamName()); if (param == null) { throw new InvalidRequestException("Unknown sort parameter '" + theSort.getParamName() + "'"); } @@ -757,7 +754,7 @@ public class LegacySearchBuilder implements ISearchBuilder { String paramName = nextInclude.getParamName(); if (isNotBlank(paramName)) { - param = mySearchParamRegistry.getSearchParamByName(def, paramName); + param = mySearchParamRegistry.getActiveSearchParam(resType, paramName); } else { param = null; } @@ -876,7 +873,7 @@ public class LegacySearchBuilder implements ISearchBuilder { // Since we're going to remove elements below theParams.values().forEach(nextAndList -> ensureSubListsAreWritable(nextAndList)); - List activeUniqueSearchParams = mySearchParamRegistry.getActiveUniqueSearchParams(myResourceName, theParams.keySet()); + List activeUniqueSearchParams = mySearchParamRegistry.getActiveUniqueSearchParams(myResourceName, theParams.keySet()); if (activeUniqueSearchParams.size() > 0) { StringBuilder sb = new StringBuilder(); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/SearchParamWithInlineReferencesExtractor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/SearchParamWithInlineReferencesExtractor.java index f16ae6e2fac..228b0d62303 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/SearchParamWithInlineReferencesExtractor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/index/SearchParamWithInlineReferencesExtractor.java @@ -25,26 +25,26 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.jpa.api.config.DaoConfig; -import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId; -import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao; import ca.uhn.fhir.jpa.dao.MatchResourceUrlService; import ca.uhn.fhir.jpa.dao.data.IResourceIndexedCompositeStringUniqueDao; import ca.uhn.fhir.jpa.model.config.PartitionSettings; -import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam; +import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedCompositeStringUnique; import ca.uhn.fhir.jpa.model.entity.ResourceLink; import ca.uhn.fhir.jpa.model.entity.ResourceTable; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams; import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorService; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; +import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.util.FhirTerser; import ca.uhn.fhir.util.UrlUtil; import com.google.common.annotations.VisibleForTesting; @@ -148,13 +148,14 @@ public class SearchParamWithInlineReferencesExtractor { private void extractCompositeStringUniques(ResourceTable theEntity, ResourceIndexedSearchParams theParams) { final String resourceType = theEntity.getResourceType(); - List uniqueSearchParams = mySearchParamRegistry.getActiveUniqueSearchParams(resourceType); + List uniqueSearchParams = mySearchParamRegistry.getActiveUniqueSearchParams(resourceType); - for (JpaRuntimeSearchParam next : uniqueSearchParams) { + for (RuntimeSearchParam next : uniqueSearchParams) { List> partsChoices = new ArrayList<>(); - for (RuntimeSearchParam nextCompositeOf : next.getCompositeOf()) { + List compositeComponents = JpaParamUtil.resolveComponentParameters(mySearchParamRegistry, next); + for (RuntimeSearchParam nextCompositeOf : compositeComponents) { Collection paramsListForCompositePart = null; Collection linksForCompositePart = null; Collection linksForCompositePartWantPaths = null; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderReference.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderReference.java index a973b5f52c2..bb84e96c160 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderReference.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/predicate/PredicateBuilderReference.java @@ -47,7 +47,8 @@ import ca.uhn.fhir.jpa.model.entity.ResourceLink; import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.util.SourceParam; import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster; import ca.uhn.fhir.model.api.IQueryParameterAnd; @@ -64,7 +65,6 @@ import ca.uhn.fhir.rest.param.CompositeParam; import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.HasParam; import ca.uhn.fhir.rest.param.NumberParam; -import ca.uhn.fhir.rest.param.ParameterUtil; import ca.uhn.fhir.rest.param.QuantityParam; import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.SpecialParam; @@ -315,9 +315,9 @@ class PredicateBuilderReference extends BasePredicateBuilder { boolean isMeta = ResourceMetaParams.RESOURCE_META_PARAMS.containsKey(chain); RuntimeSearchParam param = null; if (!isMeta) { - param = mySearchParamRegistry.getSearchParamByName(typeDef, chain); + param = mySearchParamRegistry.getActiveSearchParam(subResourceName, chain); if (param == null) { - ourLog.debug("Type {} doesn't have search param {}", nextType.getSimpleName(), param); + ourLog.debug("Type {} doesn't have search param {}", subResourceName, param); continue; } } @@ -397,8 +397,7 @@ class PredicateBuilderReference extends BasePredicateBuilder { } if (resourceTypes.isEmpty()) { - RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(theResourceName); - RuntimeSearchParam searchParamByName = mySearchParamRegistry.getSearchParamByName(resourceDef, theParamName); + RuntimeSearchParam searchParamByName = mySearchParamRegistry.getActiveSearchParam(theResourceName, theParamName); if (searchParamByName == null) { throw new InternalErrorException("Could not find parameter " + theParamName); } @@ -480,8 +479,7 @@ class PredicateBuilderReference extends BasePredicateBuilder { } Predicate createResourceLinkPathPredicate(String theResourceName, String theParamName, From from) { - RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(theResourceName); - RuntimeSearchParam param = mySearchParamRegistry.getSearchParamByName(resourceDef, theParamName); + RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam(theResourceName, theParamName); List path = param.getPathsSplit(); /* @@ -798,7 +796,7 @@ class PredicateBuilderReference extends BasePredicateBuilder { qp = new TokenParam(); break; case COMPOSITE: - List compositeOf = theParam.getCompositeOf(); + List compositeOf = JpaParamUtil.resolveComponentParameters(mySearchParamRegistry, theParam); if (compositeOf.size() != 2) { throw new InternalErrorException("Parameter " + theParam.getName() + " has " + compositeOf.size() + " composite parts. Don't know how handlt this."); } @@ -957,20 +955,19 @@ class PredicateBuilderReference extends BasePredicateBuilder { //Ensure that the name of the search param // (e.g. the `code` in Patient?_has:Observation:subject:code=sys|val) // exists on the target resource type. - RuntimeSearchParam owningParameterDef = mySearchParamRegistry.getSearchParamByName(targetResourceDefinition, paramName); + RuntimeSearchParam owningParameterDef = mySearchParamRegistry.getActiveSearchParam(targetResourceType, paramName); if (owningParameterDef == null) { throw new InvalidRequestException("Unknown parameter name: " + targetResourceType + ':' + parameterName); } //Ensure that the name of the back-referenced search param on the target (e.g. the `subject` in Patient?_has:Observation:subject:code=sys|val) //exists on the target resource. - owningParameterDef = mySearchParamRegistry.getSearchParamByName(targetResourceDefinition, paramReference); - if (owningParameterDef == null) { + RuntimeSearchParam joiningParameterDef = mySearchParamRegistry.getActiveSearchParam(targetResourceType, paramReference); + if (joiningParameterDef == null) { throw new InvalidRequestException("Unknown parameter name: " + targetResourceType + ':' + paramReference); } - RuntimeSearchParam paramDef = mySearchParamRegistry.getSearchParamByName(targetResourceDefinition, paramName); - IQueryParameterAnd> parsedParam = (IQueryParameterAnd>) ParameterUtil.parseQueryParams(myContext, paramDef, paramName, parameters); + IQueryParameterAnd> parsedParam = (IQueryParameterAnd>) JpaParamUtil.parseQueryParams(mySearchParamRegistry, myContext, owningParameterDef, paramName, parameters); for (IQueryParameterOr next : parsedParam.getValuesAsQueryTokens()) { orValues.addAll(next.getValuesAsQueryTokens()); @@ -1011,11 +1008,12 @@ class PredicateBuilderReference extends BasePredicateBuilder { } CompositeParam cp = (CompositeParam) or; - RuntimeSearchParam left = theParamDef.getCompositeOf().get(0); + List componentParams = JpaParamUtil.resolveComponentParameters(mySearchParamRegistry, theParamDef); + RuntimeSearchParam left = componentParams.get(0); IQueryParameterType leftValue = cp.getLeftValue(); myQueryStack.addPredicate(createCompositeParamPart(theResourceName, myQueryStack.getRootForComposite(), left, leftValue, theRequestPartitionId)); - RuntimeSearchParam right = theParamDef.getCompositeOf().get(1); + RuntimeSearchParam right = componentParams.get(1); IQueryParameterType rightValue = cp.getRightValue(); myQueryStack.addPredicate(createCompositeParamPart(theResourceName, myQueryStack.getRootForComposite(), right, rightValue, theRequestPartitionId)); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoSearchParameterR4.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoSearchParameterR4.java index 90c3dbeee0e..e6ef352724c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoSearchParameterR4.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoSearchParameterR4.java @@ -8,21 +8,18 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter; import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.parser.DataFormatException; -import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.util.ElementUtil; import ca.uhn.fhir.util.HapiExtensions; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IPrimitiveType; -import org.hl7.fhir.r4.model.CodeType; import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.SearchParameter; import org.springframework.beans.factory.annotation.Autowired; -import java.util.List; import java.util.regex.Pattern; import static org.apache.commons.lang3.StringUtils.isBlank; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java index 05962d2fcb1..b8cfc721732 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/packages/PackageInstallerSvcImpl.java @@ -36,7 +36,8 @@ import ca.uhn.fhir.jpa.model.entity.NpmPackageVersionEntity; import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistryController; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.TokenParam; @@ -106,6 +107,8 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc { @Autowired private ISearchParamRegistry mySearchParamRegistry; @Autowired + private ISearchParamRegistryController mySearchParamRegistryController; + @Autowired private PartitionSettings myPartitionSettings; /** * Constructor @@ -175,7 +178,7 @@ public class PackageInstallerSvcImpl implements IPackageInstallerSvc { install(npmPackage, theInstallationSpec, retVal); // If any SearchParameters were installed, let's load them right away - mySearchParamRegistry.refreshCacheIfNecessary(); + mySearchParamRegistryController.refreshCacheIfNecessary(); } } catch (IOException e) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaCapabilityStatementProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaCapabilityStatementProvider.java index 298e8c38239..07c0fd5769c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaCapabilityStatementProvider.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/JpaCapabilityStatementProvider.java @@ -27,7 +27,7 @@ import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.provider.ServerCapabilityStatementProvider; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.util.CoverageIgnore; import ca.uhn.fhir.util.ExtensionConstants; import ca.uhn.fhir.util.ExtensionUtil; @@ -59,7 +59,7 @@ public class JpaCapabilityStatementProvider extends ServerCapabilityStatementPro /** * Constructor */ - public JpaCapabilityStatementProvider(@Nonnull RestfulServer theRestfulServer, @Nonnull IFhirSystemDao theSystemDao, @Nonnull DaoConfig theDaoConfig, @Nonnull ISearchParamRetriever theSearchParamRegistry, IValidationSupport theValidationSupport) { + public JpaCapabilityStatementProvider(@Nonnull RestfulServer theRestfulServer, @Nonnull IFhirSystemDao theSystemDao, @Nonnull DaoConfig theDaoConfig, @Nonnull ISearchParamRegistry theSearchParamRegistry, IValidationSupport theValidationSupport) { super(theRestfulServer, theSearchParamRegistry, theValidationSupport); Validate.notNull(theRestfulServer); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaConformanceProviderDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaConformanceProviderDstu3.java index 4b3ed029b94..ba1260f24bc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaConformanceProviderDstu3.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/JpaConformanceProviderDstu3.java @@ -26,7 +26,7 @@ import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.server.RestfulServer; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.util.CoverageIgnore; import ca.uhn.fhir.util.ExtensionConstants; import org.hl7.fhir.dstu3.model.Bundle; @@ -53,7 +53,7 @@ public class JpaConformanceProviderDstu3 extends org.hl7.fhir.dstu3.hapi.rest.se private volatile CapabilityStatement myCachedValue; private DaoConfig myDaoConfig; - private ISearchParamRetriever mySearchParamRegistry; + private ISearchParamRegistry mySearchParamRegistry; private String myImplementationDescription; private boolean myIncludeResourceCounts; private RestfulServer myRestfulServer; @@ -72,7 +72,7 @@ public class JpaConformanceProviderDstu3 extends org.hl7.fhir.dstu3.hapi.rest.se /** * Constructor */ - public JpaConformanceProviderDstu3(RestfulServer theRestfulServer, IFhirSystemDao theSystemDao, DaoConfig theDaoConfig, ISearchParamRetriever theSearchParamRegistry) { + public JpaConformanceProviderDstu3(RestfulServer theRestfulServer, IFhirSystemDao theSystemDao, DaoConfig theDaoConfig, ISearchParamRegistry theSearchParamRegistry) { super(theRestfulServer); myRestfulServer = theRestfulServer; mySystemDao = theSystemDao; @@ -82,7 +82,7 @@ public class JpaConformanceProviderDstu3 extends org.hl7.fhir.dstu3.hapi.rest.se setIncludeResourceCounts(true); } - public void setSearchParamRegistry(ISearchParamRetriever theSearchParamRegistry) { + public void setSearchParamRegistry(ISearchParamRegistry theSearchParamRegistry) { mySearchParamRegistry = theSearchParamRegistry; } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/QueryStack.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/QueryStack.java index fb3489bb890..df72ae2f688 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/QueryStack.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/QueryStack.java @@ -52,9 +52,8 @@ import ca.uhn.fhir.jpa.search.builder.predicate.TokenPredicateBuilder; import ca.uhn.fhir.jpa.search.builder.predicate.UriPredicateBuilder; import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.rest.api.SearchContainedModeEnum; import ca.uhn.fhir.jpa.searchparam.extractor.BaseSearchParamExtractor; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil; import ca.uhn.fhir.jpa.searchparam.util.SourceParam; import ca.uhn.fhir.model.api.IQueryParameterAnd; import ca.uhn.fhir.model.api.IQueryParameterOr; @@ -63,13 +62,13 @@ import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; +import ca.uhn.fhir.rest.api.SearchContainedModeEnum; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.param.CompositeParam; import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.HasParam; import ca.uhn.fhir.rest.param.NumberParam; import ca.uhn.fhir.rest.param.ParamPrefixEnum; -import ca.uhn.fhir.rest.param.ParameterUtil; import ca.uhn.fhir.rest.param.QuantityParam; import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.StringParam; @@ -80,6 +79,7 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import com.google.common.collect.Lists; import com.healthmarketscience.sqlbuilder.BinaryCondition; import com.healthmarketscience.sqlbuilder.ComboCondition; @@ -298,11 +298,12 @@ public class QueryStack { } CompositeParam cp = (CompositeParam) next; - RuntimeSearchParam left = theParamDef.getCompositeOf().get(0); + List componentParams = JpaParamUtil.resolveComponentParameters(mySearchParamRegistry, theParamDef); + RuntimeSearchParam left = componentParams.get(0); IQueryParameterType leftValue = cp.getLeftValue(); Condition leftPredicate = createPredicateCompositePart(theSourceJoinColumn, theResourceName, theSpnamePrefix, left, leftValue, theRequestPartitionId); - RuntimeSearchParam right = theParamDef.getCompositeOf().get(1); + RuntimeSearchParam right = componentParams.get(1); IQueryParameterType rightValue = cp.getRightValue(); Condition rightPredicate = createPredicateCompositePart(theSourceJoinColumn, theResourceName, theSpnamePrefix, right, rightValue, theRequestPartitionId); @@ -333,9 +334,16 @@ public class QueryStack { case QUANTITY: { return createPredicateQuantity(theSourceJoinColumn, theResourceName, theSpnamePrefix, theParam, Collections.singletonList(theParamValue), null, theRequestPartitionId); } + case NUMBER: + case REFERENCE: + case COMPOSITE: + case URI: + case HAS: + case SPECIAL: + default: + throw new InvalidRequestException("Don't know how to handle composite parameter with type of " + theParam.getParamType()); } - throw new InvalidRequestException("Don't know how to handle composite parameter with type of " + theParam.getParamType()); } public Condition createPredicateCoords(@Nullable DbColumn theSourceJoinColumn, @@ -360,11 +368,11 @@ public class QueryStack { } public Condition createPredicateDate(@Nullable DbColumn theSourceJoinColumn, String theResourceName, - String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, - SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { + String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, + SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { String paramName = getParamNameWithPrefix(theSpnamePrefix, theSearchParam.getName()); - + PredicateBuilderCacheLookupResult predicateBuilderLookupResult = createOrReusePredicateBuilder(PredicateBuilderTypeEnum.DATE, theSourceJoinColumn, paramName, () -> mySqlBuilder.addDatePredicateBuilder(theSourceJoinColumn)); DatePredicateBuilder predicateBuilder = predicateBuilderLookupResult.getResult(); boolean cacheHit = predicateBuilderLookupResult.isCacheHit(); @@ -420,51 +428,56 @@ public class QueryStack { String paramName = theFilter.getParamPath().getName(); - if (paramName.equals(IAnyResource.SP_RES_ID)) { - TokenParam param = new TokenParam(); - param.setValueAsQueryToken(null, null, null, theFilter.getValue()); - return theQueryStack3.createPredicateResourceId(null, Collections.singletonList(Collections.singletonList(param)), theResourceName, theFilter.getOperation(), theRequestPartitionId); - } else if (paramName.equals(IAnyResource.SP_RES_LANGUAGE)) { - return theQueryStack3.createPredicateLanguage(Collections.singletonList(Collections.singletonList(new StringParam(theFilter.getValue()))), theFilter.getOperation()); - } else if (paramName.equals(Constants.PARAM_SOURCE)) { - TokenParam param = new TokenParam(); - param.setValueAsQueryToken(null, null, null, theFilter.getValue()); - return createPredicateSource(null, Collections.singletonList(param)); - } else { - RuntimeSearchParam searchParam = mySearchParamRegistry.getActiveSearchParam(theResourceName, paramName); - if (searchParam == null) { - Collection validNames = mySearchParamRegistry.getValidSearchParameterNamesIncludingMeta(theResourceName); - String msg = myFhirContext.getLocalizer().getMessageSanitized(BaseHapiFhirResourceDao.class, "invalidSearchParameter", paramName, theResourceName, validNames); - throw new InvalidRequestException(msg); - } - RestSearchParameterTypeEnum typeEnum = searchParam.getParamType(); - if (typeEnum == RestSearchParameterTypeEnum.URI) { - return theQueryStack3.createPredicateUri(null, theResourceName, null, searchParam, Collections.singletonList(new UriParam(theFilter.getValue())), theFilter.getOperation(), theRequest, theRequestPartitionId); - } else if (typeEnum == RestSearchParameterTypeEnum.STRING) { - return theQueryStack3.createPredicateString(null, theResourceName, null, searchParam, Collections.singletonList(new StringParam(theFilter.getValue())), theFilter.getOperation(), theRequestPartitionId); - } else if (typeEnum == RestSearchParameterTypeEnum.DATE) { - return theQueryStack3.createPredicateDate(null, theResourceName, null, searchParam, Collections.singletonList(new DateParam(fromOperation(theFilter.getOperation()), theFilter.getValue())), theFilter.getOperation(), theRequestPartitionId); - } else if (typeEnum == RestSearchParameterTypeEnum.NUMBER) { - return theQueryStack3.createPredicateNumber(null, theResourceName, null, searchParam, Collections.singletonList(new NumberParam(theFilter.getValue())), theFilter.getOperation(), theRequestPartitionId); - } else if (typeEnum == RestSearchParameterTypeEnum.REFERENCE) { - SearchFilterParser.CompareOperation operation = theFilter.getOperation(); - String resourceType = null; // The value can either have (Patient/123) or not have (123) a resource type, either way it's not needed here - String chain = (theFilter.getParamPath().getNext() != null) ? theFilter.getParamPath().getNext().toString() : null; - String value = theFilter.getValue(); - ReferenceParam referenceParam = new ReferenceParam(resourceType, chain, value); - return theQueryStack3.createPredicateReference(null, theResourceName, paramName, Collections.singletonList(referenceParam), operation, theRequest, theRequestPartitionId); - } else if (typeEnum == RestSearchParameterTypeEnum.QUANTITY) { - return theQueryStack3.createPredicateQuantity(null, theResourceName, null, searchParam, Collections.singletonList(new QuantityParam(theFilter.getValue())), theFilter.getOperation(), theRequestPartitionId); - } else if (typeEnum == RestSearchParameterTypeEnum.COMPOSITE) { - throw new InvalidRequestException("Composite search parameters not currently supported with _filter clauses"); - } else if (typeEnum == RestSearchParameterTypeEnum.TOKEN) { + switch (paramName) { + case IAnyResource.SP_RES_ID: { TokenParam param = new TokenParam(); - param.setValueAsQueryToken(null, - null, - null, - theFilter.getValue()); - return theQueryStack3.createPredicateToken(null, theResourceName, null, searchParam, Collections.singletonList(param), theFilter.getOperation(), theRequestPartitionId); + param.setValueAsQueryToken(null, null, null, theFilter.getValue()); + return theQueryStack3.createPredicateResourceId(null, Collections.singletonList(Collections.singletonList(param)), theResourceName, theFilter.getOperation(), theRequestPartitionId); } + case IAnyResource.SP_RES_LANGUAGE: { + return theQueryStack3.createPredicateLanguage(Collections.singletonList(Collections.singletonList(new StringParam(theFilter.getValue()))), theFilter.getOperation()); + } + case Constants.PARAM_SOURCE: { + TokenParam param = new TokenParam(); + param.setValueAsQueryToken(null, null, null, theFilter.getValue()); + return createPredicateSource(null, Collections.singletonList(param)); + } + default: + RuntimeSearchParam searchParam = mySearchParamRegistry.getActiveSearchParam(theResourceName, paramName); + if (searchParam == null) { + Collection validNames = mySearchParamRegistry.getValidSearchParameterNamesIncludingMeta(theResourceName); + String msg = myFhirContext.getLocalizer().getMessageSanitized(BaseHapiFhirResourceDao.class, "invalidSearchParameter", paramName, theResourceName, validNames); + throw new InvalidRequestException(msg); + } + RestSearchParameterTypeEnum typeEnum = searchParam.getParamType(); + if (typeEnum == RestSearchParameterTypeEnum.URI) { + return theQueryStack3.createPredicateUri(null, theResourceName, null, searchParam, Collections.singletonList(new UriParam(theFilter.getValue())), theFilter.getOperation(), theRequest, theRequestPartitionId); + } else if (typeEnum == RestSearchParameterTypeEnum.STRING) { + return theQueryStack3.createPredicateString(null, theResourceName, null, searchParam, Collections.singletonList(new StringParam(theFilter.getValue())), theFilter.getOperation(), theRequestPartitionId); + } else if (typeEnum == RestSearchParameterTypeEnum.DATE) { + return theQueryStack3.createPredicateDate(null, theResourceName, null, searchParam, Collections.singletonList(new DateParam(fromOperation(theFilter.getOperation()), theFilter.getValue())), theFilter.getOperation(), theRequestPartitionId); + } else if (typeEnum == RestSearchParameterTypeEnum.NUMBER) { + return theQueryStack3.createPredicateNumber(null, theResourceName, null, searchParam, Collections.singletonList(new NumberParam(theFilter.getValue())), theFilter.getOperation(), theRequestPartitionId); + } else if (typeEnum == RestSearchParameterTypeEnum.REFERENCE) { + SearchFilterParser.CompareOperation operation = theFilter.getOperation(); + String resourceType = null; // The value can either have (Patient/123) or not have (123) a resource type, either way it's not needed here + String chain = (theFilter.getParamPath().getNext() != null) ? theFilter.getParamPath().getNext().toString() : null; + String value = theFilter.getValue(); + ReferenceParam referenceParam = new ReferenceParam(resourceType, chain, value); + return theQueryStack3.createPredicateReference(null, theResourceName, paramName, Collections.singletonList(referenceParam), operation, theRequest, theRequestPartitionId); + } else if (typeEnum == RestSearchParameterTypeEnum.QUANTITY) { + return theQueryStack3.createPredicateQuantity(null, theResourceName, null, searchParam, Collections.singletonList(new QuantityParam(theFilter.getValue())), theFilter.getOperation(), theRequestPartitionId); + } else if (typeEnum == RestSearchParameterTypeEnum.COMPOSITE) { + throw new InvalidRequestException("Composite search parameters not currently supported with _filter clauses"); + } else if (typeEnum == RestSearchParameterTypeEnum.TOKEN) { + TokenParam param = new TokenParam(); + param.setValueAsQueryToken(null, + null, + null, + theFilter.getValue()); + return theQueryStack3.createPredicateToken(null, theResourceName, null, searchParam, Collections.singletonList(param), theFilter.getOperation(), theRequestPartitionId); + } + break; } return null; } @@ -493,9 +506,8 @@ public class QueryStack { continue; } - RuntimeResourceDefinition targetResourceDefinition; try { - targetResourceDefinition = myFhirContext.getResourceDefinition(targetResourceType); + myFhirContext.getResourceDefinition(targetResourceType); } catch (DataFormatException e) { throw new InvalidRequestException("Invalid resource type: " + targetResourceType); } @@ -518,20 +530,19 @@ public class QueryStack { //Ensure that the name of the search param // (e.g. the `code` in Patient?_has:Observation:subject:code=sys|val) // exists on the target resource type. - RuntimeSearchParam owningParameterDef = mySearchParamRegistry.getSearchParamByName(targetResourceDefinition, paramName); + RuntimeSearchParam owningParameterDef = mySearchParamRegistry.getActiveSearchParam(targetResourceType, paramName); if (owningParameterDef == null) { throw new InvalidRequestException("Unknown parameter name: " + targetResourceType + ':' + parameterName); } //Ensure that the name of the back-referenced search param on the target (e.g. the `subject` in Patient?_has:Observation:subject:code=sys|val) //exists on the target resource. - owningParameterDef = mySearchParamRegistry.getSearchParamByName(targetResourceDefinition, paramReference); - if (owningParameterDef == null) { + RuntimeSearchParam joiningParameterDef = mySearchParamRegistry.getActiveSearchParam(targetResourceType, paramReference); + if (joiningParameterDef == null) { throw new InvalidRequestException("Unknown parameter name: " + targetResourceType + ':' + paramReference); } - RuntimeSearchParam paramDef = mySearchParamRegistry.getSearchParamByName(targetResourceDefinition, paramName); - IQueryParameterAnd parsedParam = ParameterUtil.parseQueryParams(myFhirContext, paramDef, paramName, parameters); + IQueryParameterAnd parsedParam = JpaParamUtil.parseQueryParams(mySearchParamRegistry, myFhirContext, owningParameterDef, paramName, parameters); for (IQueryParameterOr next : parsedParam.getValuesAsQueryTokens()) { orValues.addAll(next.getValuesAsQueryTokens()); @@ -607,8 +618,8 @@ public class QueryStack { } public Condition createPredicateNumber(@Nullable DbColumn theSourceJoinColumn, String theResourceName, - String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, - SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { + String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, + SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { String paramName = getParamNameWithPrefix(theSpnamePrefix, theSearchParam.getName()); @@ -634,7 +645,7 @@ public class QueryStack { operation = toOperation(param.getPrefix()); } - + Condition predicate = join.createPredicateNumeric(theResourceName, paramName, operation, value, theRequestPartitionId, nextOr); codePredicates.add(predicate); @@ -648,8 +659,8 @@ public class QueryStack { } public Condition createPredicateQuantity(@Nullable DbColumn theSourceJoinColumn, String theResourceName, - String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, - SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { + String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, + SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { String paramName = getParamNameWithPrefix(theSpnamePrefix, theSearchParam.getName()); @@ -719,9 +730,9 @@ public class QueryStack { } private Condition createPredicateReferenceForContainedResource(@Nullable DbColumn theSourceJoinColumn, - String theResourceName, String theParamName, RuntimeSearchParam theSearchParam, - List theList, SearchFilterParser.CompareOperation theOperation, - RequestDetails theRequest, RequestPartitionId theRequestPartitionId) { + String theResourceName, String theParamName, RuntimeSearchParam theSearchParam, + List theList, SearchFilterParser.CompareOperation theOperation, + RequestDetails theRequest, RequestPartitionId theRequestPartitionId) { String spnamePrefix = theParamName; @@ -767,7 +778,7 @@ public class QueryStack { if (targetParamDefinition == null) { throw new InvalidRequestException("Unknown search parameter name: " + theSearchParam.getName() + '.' + targetParamName + "."); } - + qp = toParameterType(targetParamDefinition); qp.setValueAsQueryToken(myFhirContext, targetParamName, targetQualifier, targetValue); orValues.add(qp); @@ -777,47 +788,50 @@ public class QueryStack { if (targetParamDefinition == null) { throw new InvalidRequestException("Unknown search parameter name: " + theSearchParam.getName() + "."); } - + // 3. create the query Condition containedCondition = null; switch (targetParamDefinition.getParamType()) { - case DATE: - containedCondition = createPredicateDate(null, theResourceName, spnamePrefix, targetParamDefinition, + case DATE: + containedCondition = createPredicateDate(null, theResourceName, spnamePrefix, targetParamDefinition, orValues, theOperation, theRequestPartitionId); - break; - case NUMBER: - containedCondition = createPredicateNumber(null, theResourceName, spnamePrefix, targetParamDefinition, + break; + case NUMBER: + containedCondition = createPredicateNumber(null, theResourceName, spnamePrefix, targetParamDefinition, orValues, theOperation, theRequestPartitionId); - break; - case QUANTITY: - containedCondition = createPredicateQuantity(null, theResourceName, spnamePrefix, targetParamDefinition, + break; + case QUANTITY: + containedCondition = createPredicateQuantity(null, theResourceName, spnamePrefix, targetParamDefinition, orValues, theOperation, theRequestPartitionId); - break; - case STRING: - containedCondition = createPredicateString(null, theResourceName, spnamePrefix, targetParamDefinition, + break; + case STRING: + containedCondition = createPredicateString(null, theResourceName, spnamePrefix, targetParamDefinition, orValues, theOperation, theRequestPartitionId); - break; - case TOKEN: - containedCondition = createPredicateToken(null, theResourceName, spnamePrefix, targetParamDefinition, + break; + case TOKEN: + containedCondition = createPredicateToken(null, theResourceName, spnamePrefix, targetParamDefinition, orValues, theOperation, theRequestPartitionId); - break; - case COMPOSITE: - containedCondition = createPredicateComposite(null, theResourceName, spnamePrefix, targetParamDefinition, + break; + case COMPOSITE: + containedCondition = createPredicateComposite(null, theResourceName, spnamePrefix, targetParamDefinition, orValues, theRequestPartitionId); - break; - case URI: - containedCondition = createPredicateUri(null, theResourceName, spnamePrefix, targetParamDefinition, + break; + case URI: + containedCondition = createPredicateUri(null, theResourceName, spnamePrefix, targetParamDefinition, orValues, theOperation, theRequest, theRequestPartitionId); - break; - default: - throw new InvalidRequestException( + break; + case HAS: + case REFERENCE: + case SPECIAL: + default: + throw new InvalidRequestException( "The search type:" + targetParamDefinition.getParamType() + " is not supported."); } return containedCondition; } - + @Nullable public Condition createPredicateResourceId(@Nullable DbColumn theSourceJoinColumn, List> theValues, String theResourceName, SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { ResourceIdPredicateBuilder builder = mySqlBuilder.newResourceIdBuilder(); @@ -861,11 +875,11 @@ public class QueryStack { } public Condition createPredicateString(@Nullable DbColumn theSourceJoinColumn, String theResourceName, - String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, - SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { + String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, + SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { String paramName = getParamNameWithPrefix(theSpnamePrefix, theSearchParam.getName()); - + StringPredicateBuilder join = createOrReusePredicateBuilder(PredicateBuilderTypeEnum.STRING, theSourceJoinColumn, paramName, () -> mySqlBuilder.addStringPredicateBuilder(theSourceJoinColumn)).getResult(); if (theList.get(0).getMissing() != null) { @@ -971,8 +985,8 @@ public class QueryStack { } public Condition createPredicateToken(@Nullable DbColumn theSourceJoinColumn, String theResourceName, - String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, - SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { + String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, + SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { List tokens = new ArrayList<>(); for (IQueryParameterType nextOr : theList) { @@ -1011,7 +1025,7 @@ public class QueryStack { if (tokens.isEmpty()) { return null; } - + String paramName = getParamNameWithPrefix(theSpnamePrefix, theSearchParam.getName()); TokenPredicateBuilder join = createOrReusePredicateBuilder(PredicateBuilderTypeEnum.TOKEN, theSourceJoinColumn, paramName, () -> mySqlBuilder.addTokenPredicateBuilder(theSourceJoinColumn)).getResult(); @@ -1025,12 +1039,12 @@ public class QueryStack { } public Condition createPredicateUri(@Nullable DbColumn theSourceJoinColumn, String theResourceName, - String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, - SearchFilterParser.CompareOperation theOperation, RequestDetails theRequestDetails, - RequestPartitionId theRequestPartitionId) { + String theSpnamePrefix, RuntimeSearchParam theSearchParam, List theList, + SearchFilterParser.CompareOperation theOperation, RequestDetails theRequestDetails, + RequestPartitionId theRequestPartitionId) { String paramName = getParamNameWithPrefix(theSpnamePrefix, theSearchParam.getName()); - + UriPredicateBuilder join = mySqlBuilder.addUriPredicateBuilder(theSourceJoinColumn); if (theList.get(0).getMissing() != null) { @@ -1110,7 +1124,7 @@ public class QueryStack { for (List nextAnd : theAndOrParams) { if (theSearchContainedMode.equals(SearchContainedModeEnum.TRUE)) andPredicates.add(createPredicateReferenceForContainedResource(theSourceJoinColumn, theResourceName, theParamName, nextParamDef, nextAnd, null, theRequest, theRequestPartitionId)); - else + else andPredicates.add(createPredicateReference(theSourceJoinColumn, theResourceName, theParamName, nextAnd, null, theRequest, theRequestPartitionId)); } break; @@ -1204,6 +1218,46 @@ public class QueryStack { mySqlBuilder.addPredicate(predicate); } + private IQueryParameterType toParameterType(RuntimeSearchParam theParam) { + + IQueryParameterType qp; + switch (theParam.getParamType()) { + case DATE: + qp = new DateParam(); + break; + case NUMBER: + qp = new NumberParam(); + break; + case QUANTITY: + qp = new QuantityParam(); + break; + case STRING: + qp = new StringParam(); + break; + case TOKEN: + qp = new TokenParam(); + break; + case COMPOSITE: + List compositeOf = JpaParamUtil.resolveComponentParameters(mySearchParamRegistry, theParam); + if (compositeOf.size() != 2) { + throw new InternalErrorException("Parameter " + theParam.getName() + " has " + compositeOf.size() + " composite parts. Don't know how handlt this."); + } + IQueryParameterType leftParam = toParameterType(compositeOf.get(0)); + IQueryParameterType rightParam = toParameterType(compositeOf.get(1)); + qp = new CompositeParam<>(leftParam, rightParam); + break; + case URI: + qp = new UriParam(); + break; + case HAS: + case REFERENCE: + case SPECIAL: + default: + throw new InvalidRequestException("The search type: " + theParam.getParamType() + " is not supported."); + } + return qp; + } + private enum PredicateBuilderTypeEnum { DATE, COORDS, NUMBER, QUANTITY, REFERENCE, SOURCE, STRING, TOKEN, TAG } @@ -1343,48 +1397,11 @@ public class QueryStack { return parameter.substring(parameter.indexOf(".") + 1); } - private IQueryParameterType toParameterType(RuntimeSearchParam theParam) { - - IQueryParameterType qp; - switch (theParam.getParamType()) { - case DATE: - qp = new DateParam(); - break; - case NUMBER: - qp = new NumberParam(); - break; - case QUANTITY: - qp = new QuantityParam(); - break; - case STRING: - qp = new StringParam(); - break; - case TOKEN: - qp = new TokenParam(); - break; - case COMPOSITE: - List compositeOf = theParam.getCompositeOf(); - if (compositeOf.size() != 2) { - throw new InternalErrorException("Parameter " + theParam.getName() + " has " + compositeOf.size() + " composite parts. Don't know how handlt this."); - } - IQueryParameterType leftParam = toParameterType(compositeOf.get(0)); - IQueryParameterType rightParam = toParameterType(compositeOf.get(1)); - qp = new CompositeParam<>(leftParam, rightParam); - break; - case URI: - qp = new UriParam(); - break; - default: - throw new InvalidRequestException("The search type: " + theParam.getParamType() + " is not supported."); - } - return qp; - } - public static String getParamNameWithPrefix(String theSpnamePrefix, String theParamName) { - + if (isBlank(theSpnamePrefix)) return theParamName; - + return theSpnamePrefix + "." + theParamName; } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java index db28da9ce88..fde8a54dc16 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/SearchBuilder.java @@ -55,9 +55,9 @@ import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder; import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryExecutor; import ca.uhn.fhir.jpa.search.builder.sql.SqlObjectFactory; import ca.uhn.fhir.jpa.search.lastn.IElasticsearchSvc; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.util.Dstu3DistanceHelper; import ca.uhn.fhir.jpa.searchparam.util.LastNParameterHelper; import ca.uhn.fhir.rest.api.SearchContainedModeEnum; @@ -516,8 +516,7 @@ public class SearchBuilder implements ISearchBuilder { } else { - RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(myResourceName); - RuntimeSearchParam param = mySearchParamRegistry.getSearchParamByName(resourceDef, theSort.getParamName()); + RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam(myResourceName, theSort.getParamName()); if (param == null) { String msg = myContext.getLocalizer().getMessageSanitized(BaseHapiFhirResourceDao.class, "invalidSortParameter", theSort.getParamName(), getResourceName(), mySearchParamRegistry.getValidSearchParameterNamesIncludingMeta(getResourceName())); throw new InvalidRequestException(msg); @@ -546,17 +545,17 @@ public class SearchBuilder implements ISearchBuilder { theQueryStack.addSortOnQuantity(myResourceName, theSort.getParamName(), ascending); break; case COMPOSITE: - List compositList = param.getCompositeOf(); - if (compositList == null) { + List compositeList = JpaParamUtil.resolveComponentParameters(mySearchParamRegistry, param); + if (compositeList == null) { throw new InvalidRequestException("The composite _sort parameter " + theSort.getParamName() + " is not defined by the resource " + myResourceName); } - if (compositList.size() != 2) { + if (compositeList.size() != 2) { throw new InvalidRequestException("The composite _sort parameter " + theSort.getParamName() + " must have 2 composite types declared in parameter annotation, found " - + compositList.size()); + + compositeList.size()); } - RuntimeSearchParam left = compositList.get(0); - RuntimeSearchParam right = compositList.get(1); + RuntimeSearchParam left = compositeList.get(0); + RuntimeSearchParam right = compositeList.get(1); createCompositeSort(theQueryStack, myResourceName, left.getParamType(), left.getName(), ascending); createCompositeSort(theQueryStack, myResourceName, right.getParamType(), right.getName(), ascending); @@ -835,7 +834,7 @@ public class SearchBuilder implements ISearchBuilder { String paramName = nextInclude.getParamName(); if (isNotBlank(paramName)) { - param = mySearchParamRegistry.getSearchParamByName(def, paramName); + param = mySearchParamRegistry.getActiveSearchParam(resType, paramName); } else { param = null; } @@ -969,7 +968,7 @@ public class SearchBuilder implements ISearchBuilder { // Since we're going to remove elements below theParams.values().forEach(nextAndList -> ensureSubListsAreWritable(nextAndList)); - List activeUniqueSearchParams = mySearchParamRegistry.getActiveUniqueSearchParams(myResourceName, theParams.keySet()); + List activeUniqueSearchParams = mySearchParamRegistry.getActiveUniqueSearchParams(myResourceName, theParams.keySet()); if (activeUniqueSearchParams.size() > 0) { StringBuilder sb = new StringBuilder(); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/ResourceLinkPredicateBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/ResourceLinkPredicateBuilder.java index f37a3e428f8..f8af134ad40 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/ResourceLinkPredicateBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/ResourceLinkPredicateBuilder.java @@ -43,8 +43,9 @@ import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage; import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams; +import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil; import ca.uhn.fhir.rest.api.SearchContainedModeEnum; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.primitive.IdDt; @@ -367,7 +368,7 @@ public class ResourceLinkPredicateBuilder extends BaseJoiningPredicateBuilder { boolean isMeta = ResourceMetaParams.RESOURCE_META_PARAMS.containsKey(chain); RuntimeSearchParam param = null; if (!isMeta) { - param = mySearchParamRegistry.getSearchParamByName(typeDef, chain); + param = mySearchParamRegistry.getActiveSearchParam(nextType, chain); if (param == null) { ourLog.debug("Type {} doesn't have search param {}", nextType, param); continue; @@ -431,8 +432,7 @@ public class ResourceLinkPredicateBuilder extends BaseJoiningPredicateBuilder { } if (resourceTypes.isEmpty()) { - RuntimeResourceDefinition resourceDef = getFhirContext().getResourceDefinition(theResourceName); - RuntimeSearchParam searchParamByName = mySearchParamRegistry.getSearchParamByName(resourceDef, theParamName); + RuntimeSearchParam searchParamByName = mySearchParamRegistry.getActiveSearchParam(theResourceName, theParamName); if (searchParamByName == null) { throw new InternalErrorException("Could not find parameter " + theParamName); } @@ -495,8 +495,7 @@ public class ResourceLinkPredicateBuilder extends BaseJoiningPredicateBuilder { } public List createResourceLinkPaths(String theResourceName, String theParamName) { - RuntimeResourceDefinition resourceDef = getFhirContext().getResourceDefinition(theResourceName); - RuntimeSearchParam param = mySearchParamRegistry.getSearchParamByName(resourceDef, theParamName); + RuntimeSearchParam param = mySearchParamRegistry.getActiveSearchParam(theResourceName, theParamName); List path = param.getPathsSplit(); /* @@ -558,7 +557,7 @@ public class ResourceLinkPredicateBuilder extends BaseJoiningPredicateBuilder { qp = new TokenParam(); break; case COMPOSITE: - List compositeOf = theParam.getCompositeOf(); + List compositeOf = JpaParamUtil.resolveComponentParameters(mySearchParamRegistry, theParam); if (compositeOf.size() != 2) { throw new InternalErrorException("Parameter " + theParam.getName() + " has " + compositeOf.size() + " composite parts. Don't know how handlt this."); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImpl.java index 937f0dfb835..b4a2fb9ee0d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImpl.java @@ -36,7 +36,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.sched.HapiJob; import ca.uhn.fhir.jpa.model.sched.ISchedulerService; import ca.uhn.fhir.jpa.model.sched.ScheduledJobDefinition; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java index 8d6007c492e..8f22d6dda97 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java @@ -25,10 +25,9 @@ import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider; import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc; import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionLoader; import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionRegistry; -import ca.uhn.fhir.jpa.term.ValueSetExpansionR4Test; import ca.uhn.fhir.jpa.util.CircularQueueCaptureQueriesListener; import ca.uhn.fhir.jpa.util.MemoryCacheService; import ca.uhn.fhir.model.dstu2.resource.Bundle; @@ -50,7 +49,6 @@ import org.apache.commons.io.IOUtils; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; -import org.hibernate.jdbc.Work; import org.hibernate.search.backend.lucene.cfg.LuceneBackendSettings; import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings; import org.hibernate.search.engine.cfg.BackendSettings; @@ -71,7 +69,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.domain.Pageable; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.test.context.TestPropertySource; import org.springframework.transaction.PlatformTransactionManager; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/BaseJpaDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/BaseJpaDstu2Test.java index 87ad9c1383b..483e0874f02 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/BaseJpaDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/BaseJpaDstu2Test.java @@ -17,12 +17,12 @@ import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamTokenDao; import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao; import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; import ca.uhn.fhir.jpa.model.entity.ModelConfig; -import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistryController; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc; import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionLoader; import ca.uhn.fhir.jpa.util.ResourceCountCache; @@ -60,12 +60,10 @@ import ca.uhn.fhir.model.dstu2.resource.ValueSet; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; -import ca.uhn.fhir.util.TestUtil; import org.apache.commons.io.IOUtils; import org.hibernate.search.mapper.orm.Search; import org.hibernate.search.mapper.orm.session.SearchSession; import org.hl7.fhir.instance.model.api.IBaseResource; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; @@ -82,6 +80,7 @@ import org.springframework.transaction.support.TransactionTemplate; import javax.persistence.EntityManager; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import static org.junit.jupiter.api.Assertions.fail; @@ -94,6 +93,8 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest { @Autowired protected ISearchParamRegistry mySearchParamRegistry; @Autowired + protected ISearchParamRegistryController mySearchParamRegistryController; + @Autowired protected ApplicationContext myAppCtx; @Autowired protected IResourceReindexingSvc myResourceReindexingSvc; @@ -267,7 +268,7 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest { if (stream == null) { fail("Unable to load resource: " + resourceName); } - String string = IOUtils.toString(stream, "UTF-8"); + String string = IOUtils.toString(stream, StandardCharsets.UTF_8); IParser newJsonParser = EncodingEnum.detectEncodingNoDefault(string).newParser(myFhirCtx); return newJsonParser.parseResource(type, string); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchCustomSearchParamTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchCustomSearchParamTest.java index 0bdaad0cc29..a0edf4f6e2e 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchCustomSearchParamTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchCustomSearchParamTest.java @@ -254,7 +254,7 @@ public class FhirResourceDaoDstu2SearchCustomSearchParamTest extends BaseJpaDstu mySearchParameterDao.update(numberParameter); // This fires every 10 seconds - mySearchParamRegistry.refreshCacheIfNecessary(); + mySearchParamRegistryController.refreshCacheIfNecessary(); Patient patient = new Patient(); patient.setId("future-appointment-count-pt"); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java index 9f86a56cde1..109a59cdad0 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/BaseJpaDstu3Test.java @@ -33,13 +33,12 @@ import ca.uhn.fhir.jpa.dao.data.ITermValueSetDao; import ca.uhn.fhir.jpa.dao.dstu2.FhirResourceDaoDstu2SearchNoFtTest; import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test; import ca.uhn.fhir.jpa.model.entity.ModelConfig; -import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc; import ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl; import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3PhoneticSearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3PhoneticSearchNoFtTest.java index 68ba66f1096..bda399dbd76 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3PhoneticSearchNoFtTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3PhoneticSearchNoFtTest.java @@ -5,7 +5,7 @@ import ca.uhn.fhir.context.phonetic.PhoneticEncoderEnum; import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.util.HapiExtensions; import org.apache.commons.codec.language.Soundex; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java index 1287cc05e15..a5fd819663b 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java @@ -1605,7 +1605,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test verify(interceptor, times(1)).invoke(any(), paramsCaptor.capture()); StorageProcessingMessage msg = paramsCaptor.getValue().get(StorageProcessingMessage.class); - assertThat(msg.getMessage(), containsString("refers to unknown component foo, ignoring this parameter")); + assertThat(msg.getMessage(), containsString("ignoring this parameter")); } finally { myInterceptorRegistry.unregisterInterceptor(interceptor); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java index 252df5cfdd2..a35337b8a16 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithElasticSearchIT.java @@ -48,7 +48,7 @@ import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithLuceneDisabledTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithLuceneDisabledTest.java index 8ac8333c6c0..4f0eb913e03 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithLuceneDisabledTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchWithLuceneDisabledTest.java @@ -13,7 +13,7 @@ import ca.uhn.fhir.jpa.dao.BaseJpaTest; import ca.uhn.fhir.jpa.dao.dstu2.FhirResourceDaoDstu2SearchNoFtTest; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc; import ca.uhn.fhir.jpa.term.api.ITermReadSvc; import ca.uhn.fhir.parser.IParser; @@ -23,7 +23,6 @@ import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParamModifier; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.util.TestUtil; import org.apache.commons.io.IOUtils; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; @@ -43,7 +42,6 @@ import org.hl7.fhir.r4.model.Meta; import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.ValueSet; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyElasticsearchIT.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyElasticsearchIT.java index 751b0696713..c5ba2df8890 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyElasticsearchIT.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4TerminologyElasticsearchIT.java @@ -14,7 +14,7 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UniqueSearchParamTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UniqueSearchParamTest.java index f767a0c58ab..7f9fc10925a 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UniqueSearchParamTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4UniqueSearchParamTest.java @@ -1,5 +1,6 @@ package ca.uhn.fhir.jpa.dao.r4; +import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.interceptor.api.HookParams; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.interceptor.api.Pointcut; @@ -10,9 +11,9 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.search.reindex.ResourceReindexingSvcImpl; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.util.SpringObjectCaster; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.param.DateParam; @@ -23,11 +24,9 @@ import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.util.HapiExtensions; -import ca.uhn.fhir.util.TestUtil; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.Enumerations.PublicationStatus; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -707,7 +706,7 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test { ResourceReindexingSvcImpl svc = SpringObjectCaster.getTargetObject(myResourceReindexingSvc, ResourceReindexingSvcImpl.class); svc.initExecutor(); - List uniqueSearchParams = mySearchParamRegistry.getActiveUniqueSearchParams("Observation"); + List uniqueSearchParams = mySearchParamRegistry.getActiveUniqueSearchParams("Observation"); assertEquals(0, uniqueSearchParams.size()); Patient pt1 = new Patient(); @@ -1487,14 +1486,16 @@ public class FhirResourceDaoR4UniqueSearchParamTest extends BaseJpaR4Test { @Test public void testDetectUniqueSearchParams() { createUniqueBirthdateAndGenderSps(); - List params = mySearchParamRegistry.getActiveUniqueSearchParams("Patient"); + List params = mySearchParamRegistry.getActiveUniqueSearchParams("Patient"); assertEquals(1, params.size()); assertEquals(params.get(0).isUnique(), true); - assertEquals(2, params.get(0).getCompositeOf().size()); + assertEquals(2, params.get(0).getComponents().size()); + // Should be alphabetical order - assertEquals("birthdate", params.get(0).getCompositeOf().get(0).getName()); - assertEquals("gender", params.get(0).getCompositeOf().get(1).getName()); + List compositeParams = JpaParamUtil.resolveComponentParameters(mySearchParamRegistry, params.get(0)); + assertEquals("birthdate", compositeParams.get(0).getName()); + assertEquals("gender", compositeParams.get(1).getName()); } @Test diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java index 926a58716dd..89a2dfbbfbf 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java @@ -15,13 +15,13 @@ import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken; import ca.uhn.fhir.jpa.model.util.UcumServiceUtil; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor; import ca.uhn.fhir.jpa.searchparam.extractor.PathAndRef; import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR4; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistryController; import ca.uhn.fhir.jpa.searchparam.registry.ReadOnlySearchParamCache; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.util.HapiExtensions; import com.google.common.collect.Sets; import org.hl7.fhir.r4.model.BooleanType; @@ -37,6 +37,7 @@ import org.hl7.fhir.r4.model.Quantity; import org.hl7.fhir.r4.model.Reference; import org.hl7.fhir.r4.model.SearchParameter; import org.hl7.fhir.r4.model.StringType; +import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -44,7 +45,6 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -327,7 +327,7 @@ public class SearchParamExtractorR4Test { public void testExtensionContainingReference() { String path = "Patient.extension('http://patext').value.as(Reference)"; - RuntimeSearchParam sp = new RuntimeSearchParam("extpat", "Patient SP", path, RestSearchParameterTypeEnum.REFERENCE, new HashSet<>(), Sets.newHashSet("Patient"), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE); + RuntimeSearchParam sp = new RuntimeSearchParam(null, null, "extpat", "Patient SP", path, RestSearchParameterTypeEnum.REFERENCE, new HashSet<>(), Sets.newHashSet("Patient"), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null); mySearchParamRegistry.addSearchParam(sp); Patient patient = new Patient(); @@ -395,7 +395,7 @@ public class SearchParamExtractorR4Test { assertEquals(2, list.size()); } - private static class MySearchParamRegistry implements ISearchParamRegistry { + private static class MySearchParamRegistry implements ISearchParamRegistry, ISearchParamRegistryController { private List myExtraSearchParams = new ArrayList<>(); @@ -416,7 +416,6 @@ public class SearchParamExtractorR4Test { return new ResourceChangeResult(); } - @Override public ReadOnlySearchParamCache getActiveSearchParams() { throw new UnsupportedOperationException(); } @@ -441,12 +440,18 @@ public class SearchParamExtractorR4Test { } @Override - public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public RuntimeSearchParam getActiveSearchParamByUrl(String theUrl) { throw new UnsupportedOperationException(); } @Override - public List getActiveUniqueSearchParams(String theResourceName) { + public List getActiveUniqueSearchParams(String theResourceName) { throw new UnsupportedOperationException(); } @@ -455,16 +460,6 @@ public class SearchParamExtractorR4Test { // nothing } - @Override - public RuntimeSearchParam getSearchParamByName(RuntimeResourceDefinition theResourceDef, String theParamName) { - return null; - } - - @Override - public Collection getSearchParamsByResourceType(RuntimeResourceDefinition theResourceDef) { - return null; - } - @Override public void setPhoneticEncoder(IPhoneticEncoder thePhoneticEncoder) { // nothing diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java index 3e7b50b22d7..7f657a06266 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java @@ -189,7 +189,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test { ourClient.update().resource(numberParameter).execute(); // This fires every 10 seconds - mySearchParamRegistry.refreshCacheIfNecessary(); + mySearchParamRegistryController.refreshCacheIfNecessary(); Patient patient = new Patient(); patient.setId("future-appointment-count-pt"); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java index 991de4e3eca..ed39b28723b 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java @@ -393,7 +393,9 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide fooSp.setStatus(org.hl7.fhir.r4.model.Enumerations.PublicationStatus.ACTIVE); mySearchParameterDao.create(fooSp, mySrd); + myCaptureQueriesListener.clear(); mySearchParamRegistry.forceRefresh(); + myCaptureQueriesListener.logAllQueriesForCurrentThread(); Patient pat = new Patient(); pat.setGender(AdministrativeGender.MALE); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderHasParamR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderHasParamR4Test.java index 36e6ad17a72..e79994980ee 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderHasParamR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderHasParamR4Test.java @@ -629,7 +629,7 @@ public class ResourceProviderHasParamR4Test extends BaseResourceProviderR4Test { try (CloseableHttpResponse response = ourHttpClient.execute(get)) { String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); - ourLog.info(resp); + ourLog.info("Response was: {}", resp); Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, resp); ids = toUnqualifiedVersionlessIdValues(bundle); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImplTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImplTest.java index 3ecd9e7ad78..66fc2d75e8c 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImplTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/search/reindex/ResourceReindexingSvcImplTest.java @@ -13,11 +13,10 @@ import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; import ca.uhn.fhir.jpa.entity.ResourceReindexJobEntity; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.sched.ISchedulerService; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import org.apache.commons.lang3.time.DateUtils; import org.hl7.fhir.instance.model.api.IBaseResource; -import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.Patient; import org.junit.jupiter.api.BeforeEach; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/searchparam/MatchUrlServiceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/searchparam/MatchUrlServiceTest.java index a060380f371..5b47c24a5be 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/searchparam/MatchUrlServiceTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/searchparam/MatchUrlServiceTest.java @@ -5,14 +5,12 @@ import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.jpa.config.TestDstu3Config; import ca.uhn.fhir.jpa.dao.BaseJpaTest; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.util.Dstu3DistanceHelper; import ca.uhn.fhir.rest.param.QuantityParam; import ca.uhn.fhir.rest.param.ReferenceParam; -import ca.uhn.fhir.util.TestUtil; import org.hl7.fhir.dstu3.model.Condition; import org.hl7.fhir.dstu3.model.Location; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -41,7 +39,7 @@ public class MatchUrlServiceTest extends BaseJpaTest { public void testTranslateMatchUrl() { RuntimeResourceDefinition resourceDef = ourCtx.getResourceDefinition(Condition.class); ISearchParamRegistry searchParamRegistry = mock(ISearchParamRegistry.class); - when(searchParamRegistry.getSearchParamByName(any(RuntimeResourceDefinition.class), eq("patient"))).thenReturn(resourceDef.getSearchParam("patient")); + when(searchParamRegistry.getActiveSearchParam(any(), eq("patient"))).thenReturn(resourceDef.getSearchParam("patient")); SearchParameterMap match = myMatchUrlService.translateMatchUrl("Condition?patient=304&_lastUpdated=>2011-01-01T11:12:21.0000Z", resourceDef); assertEquals("2011-01-01T11:12:21.0000Z", match.getLastUpdated().getLowerBound().getValueAsString()); assertEquals(ReferenceParam.class, match.get("patient").get(0).get(0).getClass()); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4ElasticsearchIT.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4ElasticsearchIT.java index 84f0f663b9c..23f79370f69 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4ElasticsearchIT.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/term/ValueSetExpansionR4ElasticsearchIT.java @@ -15,7 +15,7 @@ import ca.uhn.fhir.jpa.entity.TermConcept; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4; diff --git a/hapi-fhir-jpaserver-batch/pom.xml b/hapi-fhir-jpaserver-batch/pom.xml index 4a74a2fe955..781f0e34231 100644 --- a/hapi-fhir-jpaserver-batch/pom.xml +++ b/hapi-fhir-jpaserver-batch/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-cql/pom.xml b/hapi-fhir-jpaserver-cql/pom.xml index 8c132ab6a8c..d7df70c1bea 100644 --- a/hapi-fhir-jpaserver-cql/pom.xml +++ b/hapi-fhir-jpaserver-cql/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -144,13 +144,13 @@ ca.uhn.hapi.fhir hapi-fhir-test-utilities - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT test ca.uhn.hapi.fhir hapi-fhir-jpaserver-test-utilities - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT test diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml index 4f63e20b3f2..855dfe0501a 100644 --- a/hapi-fhir-jpaserver-mdm/pom.xml +++ b/hapi-fhir-jpaserver-mdm/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml @@ -55,13 +55,13 @@ ca.uhn.hapi.fhir hapi-fhir-test-utilities - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT test ca.uhn.hapi.fhir hapi-fhir-jpaserver-test-utilities - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT test diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java index 204b27e69f1..97b2aeefad2 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmConsumerConfig.java @@ -64,7 +64,7 @@ import ca.uhn.fhir.jpa.mdm.svc.candidate.MdmGoldenResourceFindingSvc; import ca.uhn.fhir.jpa.mdm.svc.candidate.FindCandidateByEidSvc; import ca.uhn.fhir.jpa.mdm.svc.candidate.FindCandidateByLinkSvc; import ca.uhn.fhir.jpa.mdm.svc.candidate.FindCandidateByExampleSvc; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.validation.IResourceLoader; import org.slf4j.Logger; import org.springframework.context.annotation.Bean; @@ -153,7 +153,7 @@ public class MdmConsumerConfig { } @Bean - MdmRuleValidator mdmRuleValidator(FhirContext theFhirContext, ISearchParamRetriever theSearchParamRetriever) { + MdmRuleValidator mdmRuleValidator(FhirContext theFhirContext, ISearchParamRegistry theSearchParamRetriever) { return new MdmRuleValidator(theFhirContext, theSearchParamRetriever); } diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmSubmitterConfig.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmSubmitterConfig.java index dd840b3189d..be9bb320ecd 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmSubmitterConfig.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/config/MdmSubmitterConfig.java @@ -32,7 +32,7 @@ import ca.uhn.fhir.jpa.mdm.svc.MdmGoldenResourceDeletingSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmSearchParamSvc; import ca.uhn.fhir.jpa.mdm.svc.MdmSubmitSvcImpl; import ca.uhn.fhir.jpa.subscription.channel.api.IChannelFactory; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; @@ -51,7 +51,7 @@ public class MdmSubmitterConfig { } @Bean - MdmRuleValidator mdmRuleValidator(FhirContext theFhirContext, ISearchParamRetriever theSearchParamRetriever) { + MdmRuleValidator mdmRuleValidator(FhirContext theFhirContext, ISearchParamRegistry theSearchParamRetriever) { return new MdmRuleValidator(theFhirContext, theSearchParamRetriever); } diff --git a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSearchParamSvc.java b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSearchParamSvc.java index 4d8184c8a5f..944819c3163 100644 --- a/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSearchParamSvc.java +++ b/hapi-fhir-jpaserver-mdm/src/main/java/ca/uhn/fhir/jpa/mdm/svc/MdmSearchParamSvc.java @@ -30,7 +30,7 @@ import ca.uhn.fhir.jpa.dao.SearchBuilderFactory; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorService; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IBaseResource; import org.springframework.beans.factory.annotation.Autowired; diff --git a/hapi-fhir-jpaserver-migrate/pom.xml b/hapi-fhir-jpaserver-migrate/pom.xml index 1dead963b6a..767f5422571 100644 --- a/hapi-fhir-jpaserver-migrate/pom.xml +++ b/hapi-fhir-jpaserver-migrate/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml index cbefeedd228..fc6b066de31 100644 --- a/hapi-fhir-jpaserver-model/pom.xml +++ b/hapi-fhir-jpaserver-model/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml index 73b19e1e190..23fa53e26a7 100755 --- a/hapi-fhir-jpaserver-searchparam/pom.xml +++ b/hapi-fhir-jpaserver-searchparam/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeEvent.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeEvent.java index d5cd43e6048..c197da32f1e 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeEvent.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/cache/ResourceChangeEvent.java @@ -72,6 +72,7 @@ public class ResourceChangeEvent implements IResourceChangeEvent { return myDeletedResourceIds; } + @Override public boolean isEmpty() { return myCreatedResourceIds.isEmpty() && myUpdatedResourceIds.isEmpty() && myDeletedResourceIds.isEmpty(); } diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/JpaRuntimeSearchParam.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/JpaRuntimeSearchParam.java deleted file mode 100644 index 8dd99d34106..00000000000 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/JpaRuntimeSearchParam.java +++ /dev/null @@ -1,88 +0,0 @@ -package ca.uhn.fhir.jpa.searchparam; - -/*- - * #%L - * HAPI FHIR Search Parameters - * %% - * Copyright (C) 2014 - 2021 Smile CDR, Inc. - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import ca.uhn.fhir.context.RuntimeSearchParam; -import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; -import org.hl7.fhir.instance.model.api.IBaseReference; -import org.hl7.fhir.instance.model.api.IIdType; -import org.hl7.fhir.instance.model.api.IPrimitiveType; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import static org.apache.commons.lang3.StringUtils.isNotBlank; - -public class JpaRuntimeSearchParam extends RuntimeSearchParam { - - private final boolean myUnique; - private final List myComponents; - - /** - * Constructor - */ - public JpaRuntimeSearchParam(IIdType theId, String theUri, String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, Set theProvidesMembershipInCompartments, Set theTargets, RuntimeSearchParamStatusEnum theStatus, boolean theUnique, List theComponents, Collection theBase) { - super(theId, theUri, theName, theDescription, thePath, theParamType, createCompositeList(theParamType), theProvidesMembershipInCompartments, theTargets, theStatus, theBase); - myUnique = theUnique; - myComponents = Collections.unmodifiableList(theComponents); - } - - public List getComponents() { - return myComponents; - } - - public boolean isUnique() { - return myUnique; - } - - public static class Component { - private final String myExpression; - private final IBaseReference myReference; - - public Component(String theExpression, IBaseReference theReference) { - myExpression = theExpression; - myReference = theReference; - - } - - public String getExpression() { - return myExpression; - } - - public IBaseReference getReference() { - return myReference; - } - } - - private static ArrayList createCompositeList(RestSearchParameterTypeEnum theParamType) { - if (theParamType == RestSearchParameterTypeEnum.COMPOSITE) { - return new ArrayList<>(); - } else { - return null; - } - } - - -} diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java index 1927b4e9b6e..d671c3cb870 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java @@ -24,7 +24,8 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.jpa.model.util.JpaConstants; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.model.api.IQueryParameterAnd; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.Include; @@ -99,7 +100,7 @@ public class MatchUrlService { } } } else if (Constants.PARAM_HAS.equals(nextParamName)) { - IQueryParameterAnd param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.HAS, nextParamName, paramList); + IQueryParameterAnd param = JpaParamUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.HAS, nextParamName, paramList); paramMap.add(nextParamName, param); } else if (Constants.PARAM_COUNT.equals(nextParamName)) { if (paramList != null && paramList.size() > 0 && paramList.get(0).size() > 0) { @@ -127,23 +128,23 @@ public class MatchUrlService { type.setValuesAsQueryTokens(myContext, nextParamName, (paramList)); paramMap.add(nextParamName, type); } else if (Constants.PARAM_SOURCE.equals(nextParamName)) { - IQueryParameterAnd param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.TOKEN, nextParamName, paramList); + IQueryParameterAnd param = JpaParamUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.TOKEN, nextParamName, paramList); paramMap.add(nextParamName, param); } else if (JpaConstants.PARAM_DELETE_EXPUNGE.equals(nextParamName)) { paramMap.setDeleteExpunge(true); } else if (Constants.PARAM_LIST.equals(nextParamName)) { - IQueryParameterAnd param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.TOKEN, nextParamName, paramList); + IQueryParameterAnd param = JpaParamUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.TOKEN, nextParamName, paramList); paramMap.add(nextParamName, param); } else if (nextParamName.startsWith("_")) { // ignore these since they aren't search params (e.g. _sort) } else { - RuntimeSearchParam paramDef = mySearchParamRegistry.getSearchParamByName(theResourceDefinition, nextParamName); + RuntimeSearchParam paramDef = mySearchParamRegistry.getActiveSearchParam(theResourceDefinition.getName(), nextParamName); if (paramDef == null) { throw new InvalidRequestException( "Failed to parse match URL[" + theMatchUrl + "] - Resource type " + theResourceDefinition.getName() + " does not have a parameter with name: " + nextParamName); } - IQueryParameterAnd param = ParameterUtil.parseQueryParams(myContext, paramDef, nextParamName, paramList); + IQueryParameterAnd param = JpaParamUtil.parseQueryParams(mySearchParamRegistry, myContext, paramDef, nextParamName, paramList); paramMap.add(nextParamName, param); } } diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/config/SearchParamConfig.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/config/SearchParamConfig.java index dc0951d6458..d006efab38d 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/config/SearchParamConfig.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/config/SearchParamConfig.java @@ -39,7 +39,7 @@ import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorService; import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher; import ca.uhn.fhir.jpa.searchparam.matcher.IndexedSearchParamExtractor; import ca.uhn.fhir.jpa.searchparam.matcher.SearchParamMatcher; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl; import ca.uhn.fhir.jpa.searchparam.registry.SearchParameterCanonicalizer; import org.springframework.beans.factory.annotation.Autowired; diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java index 82b2ffc848d..45f9c3fbccd 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java @@ -41,7 +41,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri; import ca.uhn.fhir.jpa.model.util.UcumServiceUtil; import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.model.primitive.BoundCodeDt; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java index 70cba214b70..798a35b3f52 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java @@ -23,7 +23,7 @@ package ca.uhn.fhir.jpa.searchparam.extractor; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.ModelConfig; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.model.dstu2.composite.ContactPointDt; import ca.uhn.fhir.util.FhirTerser; import org.hl7.fhir.instance.model.api.IBase; diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java index e92e62dc9d9..f701a081ad6 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java @@ -23,7 +23,7 @@ package ca.uhn.fhir.jpa.searchparam.extractor; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.ModelConfig; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import com.google.common.annotations.VisibleForTesting; import org.hl7.fhir.dstu3.context.IWorkerContext; import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext; diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java index 5e61663ab01..c5289ad152f 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java @@ -23,7 +23,7 @@ package ca.uhn.fhir.jpa.searchparam.extractor; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.ModelConfig; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import com.google.common.annotations.VisibleForTesting; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.PathEngineException; diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java index 38e6b082f12..62498092baf 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java @@ -23,7 +23,7 @@ package ca.uhn.fhir.jpa.searchparam.extractor; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.ModelConfig; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.PathEngineException; import org.hl7.fhir.instance.model.api.IBaseResource; diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorService.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorService.java index cb5dd573f44..7f18e809b5d 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorService.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorService.java @@ -43,18 +43,15 @@ import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri; import ca.uhn.fhir.jpa.model.entity.ResourceLink; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster; import ca.uhn.fhir.parser.DataFormatException; -import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.util.FhirTerser; -import ca.uhn.fhir.util.ResourceReferenceInfo; -import ca.uhn.fhir.util.StringUtil; import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang3.StringUtils; diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java index 984989ca477..0978dd1f355 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java @@ -27,7 +27,7 @@ import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.util.SourceParam; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.Constants; diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ISearchParamRegistry.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ISearchParamRegistry.java deleted file mode 100644 index 7f8dbf07ffd..00000000000 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ISearchParamRegistry.java +++ /dev/null @@ -1,77 +0,0 @@ -package ca.uhn.fhir.jpa.searchparam.registry; - -/* - * #%L - * HAPI FHIR Search Parameters - * %% - * Copyright (C) 2014 - 2021 Smile CDR, Inc. - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import ca.uhn.fhir.context.RuntimeResourceDefinition; -import ca.uhn.fhir.context.RuntimeSearchParam; -import ca.uhn.fhir.context.phonetic.IPhoneticEncoder; -import ca.uhn.fhir.jpa.cache.ResourceChangeResult; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; - -import java.util.Collection; -import java.util.List; -import java.util.Set; - -public interface ISearchParamRegistry extends ISearchParamRetriever { - - /** - * Request that the cache be refreshed now, in the current thread - */ - void forceRefresh(); - - /** - * @return the number of search parameter entries changed - */ - ResourceChangeResult refreshCacheIfNecessary(); - - ReadOnlySearchParamCache getActiveSearchParams(); - - List getActiveUniqueSearchParams(String theResourceName, Set theParamNames); - - List getActiveUniqueSearchParams(String theResourceName); - - /** - * Request that the cache be refreshed at the next convenient time (in a different thread) - */ - void requestRefresh(); - - RuntimeSearchParam getSearchParamByName(RuntimeResourceDefinition theResourceDef, String theParamName); - - Collection getSearchParamsByResourceType(RuntimeResourceDefinition theResourceDef); - - /** - * When indexing a HumanName, if a StringEncoder is set in the context, then the "phonetic" search parameter will normalize - * the String using this encoder. - * - * @since 5.1.0 - */ - void setPhoneticEncoder(IPhoneticEncoder thePhoneticEncoder); - - /** - * Returns a collection containing all of the valid active search parameters. This method is intended for - * creating error messages for users as opposed to actual search processing. It will include meta parameters - * such as _id and _lastUpdated. - */ - default Collection getValidSearchParameterNamesIncludingMeta(String theResourceName) { - return getActiveSearchParams().getValidSearchParameterNamesIncludingMeta(theResourceName); - } -} diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRetriever.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ISearchParamRegistryController.java similarity index 52% rename from hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRetriever.java rename to hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ISearchParamRegistryController.java index a1b0a6b2a2c..d0c432dc8fa 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRetriever.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ISearchParamRegistryController.java @@ -1,8 +1,8 @@ -package ca.uhn.fhir.rest.server.util; +package ca.uhn.fhir.jpa.searchparam.registry; /*- * #%L - * HAPI FHIR - Server Framework + * HAPI FHIR Search Parameters * %% * Copyright (C) 2014 - 2021 Smile CDR, Inc. * %% @@ -18,25 +18,12 @@ package ca.uhn.fhir.rest.server.util; * See the License for the specific language governing permissions and * limitations under the License. * #L% - */ - -import ca.uhn.fhir.context.RuntimeSearchParam; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.Map; - -public interface ISearchParamRetriever { - /** - * @return Returns {@literal null} if no match */ - @Nullable - RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName); - /** - * @return Returns all active search params for the given resource - */ - @Nonnull - Map getActiveSearchParams(String theResourceName); +import ca.uhn.fhir.jpa.cache.ResourceChangeResult; + +public interface ISearchParamRegistryController { + + ResourceChangeResult refreshCacheIfNecessary(); } diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/JpaSearchParamCache.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/JpaSearchParamCache.java index a2b054295f8..e529bdcf982 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/JpaSearchParamCache.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/JpaSearchParamCache.java @@ -26,10 +26,8 @@ import ca.uhn.fhir.interceptor.api.HookParams; import ca.uhn.fhir.interceptor.api.IInterceptorService; import ca.uhn.fhir.interceptor.api.Pointcut; import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,29 +39,32 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeSet; import java.util.stream.Collectors; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + public class JpaSearchParamCache { private static final Logger ourLog = LoggerFactory.getLogger(JpaSearchParamCache.class); - private volatile Map> myActiveUniqueSearchParams = Collections.emptyMap(); - private volatile Map, List>> myActiveParamNamesToUniqueSearchParams = Collections.emptyMap(); + private volatile Map> myActiveUniqueSearchParams = Collections.emptyMap(); + private volatile Map, List>> myActiveParamNamesToUniqueSearchParams = Collections.emptyMap(); - public List getActiveUniqueSearchParams(String theResourceName) { - List retval = myActiveUniqueSearchParams.get(theResourceName); + public List getActiveUniqueSearchParams(String theResourceName) { + List retval = myActiveUniqueSearchParams.get(theResourceName); if (retval == null) { retval = Collections.emptyList(); } return retval; } - public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { - Map, List> paramNamesToParams = myActiveParamNamesToUniqueSearchParams.get(theResourceName); + public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + Map, List> paramNamesToParams = myActiveParamNamesToUniqueSearchParams.get(theResourceName); if (paramNamesToParams == null) { return Collections.emptyList(); } - List retVal = paramNamesToParams.get(theParamNames); + List retVal = paramNamesToParams.get(theParamNames); if (retVal == null) { retVal = Collections.emptyList(); } @@ -71,18 +72,18 @@ public class JpaSearchParamCache { } void populateActiveSearchParams(IInterceptorService theInterceptorBroadcaster, IPhoneticEncoder theDefaultPhoneticEncoder, RuntimeSearchParamCache theActiveSearchParams) { - Map> activeUniqueSearchParams = new HashMap<>(); - Map, List>> activeParamNamesToUniqueSearchParams = new HashMap<>(); + Map> activeUniqueSearchParams = new HashMap<>(); + Map, List>> activeParamNamesToUniqueSearchParams = new HashMap<>(); Map idToRuntimeSearchParam = new HashMap<>(); - List jpaSearchParams = new ArrayList<>(); + List jpaSearchParams = new ArrayList<>(); /* * Loop through parameters and find JPA params */ for (String theResourceName : theActiveSearchParams.getResourceNameKeys()) { Map searchParamMap = theActiveSearchParams.getSearchParamMap(theResourceName); - List uniqueSearchParams = activeUniqueSearchParams.computeIfAbsent(theResourceName, k -> new ArrayList<>()); + List uniqueSearchParams = activeUniqueSearchParams.computeIfAbsent(theResourceName, k -> new ArrayList<>()); Collection nextSearchParamsForResourceName = searchParamMap.values(); ourLog.trace("Resource {} has {} params", theResourceName, searchParamMap.size()); @@ -94,13 +95,14 @@ public class JpaSearchParamCache { if (nextCandidate.getId() != null) { idToRuntimeSearchParam.put(nextCandidate.getId().toUnqualifiedVersionless().getValue(), nextCandidate); } + if (isNotBlank(nextCandidate.getUri())) { + idToRuntimeSearchParam.put(nextCandidate.getUri(), nextCandidate); + } - if (nextCandidate instanceof JpaRuntimeSearchParam) { - JpaRuntimeSearchParam nextCandidateCasted = (JpaRuntimeSearchParam) nextCandidate; - jpaSearchParams.add(nextCandidateCasted); - if (nextCandidateCasted.isUnique()) { - uniqueSearchParams.add(nextCandidateCasted); - } + RuntimeSearchParam nextCandidateCasted = nextCandidate; + jpaSearchParams.add(nextCandidateCasted); + if (nextCandidateCasted.isUnique()) { + uniqueSearchParams.add(nextCandidateCasted); } setPhoneticEncoder(theDefaultPhoneticEncoder, nextCandidate); @@ -111,25 +113,19 @@ public class JpaSearchParamCache { ourLog.trace("Have {} search params loaded", idToRuntimeSearchParam.size()); Set haveSeen = new HashSet<>(); - for (JpaRuntimeSearchParam next : jpaSearchParams) { - if (!haveSeen.add(next.getId().toUnqualifiedVersionless().getValue())) { + for (RuntimeSearchParam next : jpaSearchParams) { + if (next.getId() != null && !haveSeen.add(next.getId().toUnqualifiedVersionless().getValue())) { continue; } - Set paramNames = new HashSet<>(); - for (JpaRuntimeSearchParam.Component nextComponent : next.getComponents()) { - String nextRef = nextComponent.getReference().getReferenceElement().toUnqualifiedVersionless().getValue(); + Set paramNames = new TreeSet<>(); + for (RuntimeSearchParam.Component nextComponent : next.getComponents()) { + String nextRef = nextComponent.getReference(); RuntimeSearchParam componentTarget = idToRuntimeSearchParam.get(nextRef); if (componentTarget != null) { - next.getCompositeOf().add(componentTarget); paramNames.add(componentTarget.getName()); } else { - String existingParams = idToRuntimeSearchParam - .keySet() - .stream() - .sorted() - .collect(Collectors.joining(", ")); - String message = "Search parameter " + next.getId().toUnqualifiedVersionless().getValue() + " refers to unknown component " + nextRef + ", ignoring this parameter (valid values: " + existingParams + ")"; + String message = "Search parameter " + next + " refers to unknown component " + nextRef + ", ignoring this parameter"; ourLog.warn(message); // Interceptor broadcast: JPA_PERFTRACE_WARNING @@ -141,8 +137,7 @@ public class JpaSearchParamCache { } } - if (next.getCompositeOf() != null) { - next.getCompositeOf().sort((theO1, theO2) -> StringUtils.compare(theO1.getName(), theO2.getName())); + if (next.isUnique()) { for (String nextBase : next.getBase()) { activeParamNamesToUniqueSearchParams.computeIfAbsent(nextBase, v -> new HashMap<>()); activeParamNamesToUniqueSearchParams.get(nextBase).computeIfAbsent(paramNames, t -> new ArrayList<>()); diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ReadOnlySearchParamCache.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ReadOnlySearchParamCache.java index 2fd7748dce6..d173693aae8 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ReadOnlySearchParamCache.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/ReadOnlySearchParamCache.java @@ -23,30 +23,53 @@ package ca.uhn.fhir.jpa.searchparam.registry; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeSearchParam; -import ca.uhn.fhir.rest.api.Constants; -import org.hl7.fhir.instance.model.api.IAnyResource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.TreeSet; import java.util.stream.Stream; public class ReadOnlySearchParamCache { - private static final Logger ourLog = LoggerFactory.getLogger(ReadOnlySearchParamCache.class); - // resourceName -> searchParamName -> searchparam - protected final Map> myMap; + // resourceName -> searchParamName -> searchparam + protected final Map> myResourceNameToSpNameToSp; + protected final Map myUrlToParam; + + /** + * Constructor + */ ReadOnlySearchParamCache() { - myMap = new HashMap<>(); + myResourceNameToSpNameToSp = new HashMap<>(); + myUrlToParam = new HashMap<>(); } + /** + * Copy constructor + */ private ReadOnlySearchParamCache(RuntimeSearchParamCache theRuntimeSearchParamCache) { - myMap = theRuntimeSearchParamCache.myMap; + myResourceNameToSpNameToSp = theRuntimeSearchParamCache.myResourceNameToSpNameToSp; + myUrlToParam = theRuntimeSearchParamCache.myUrlToParam; + } + + public Stream getSearchParamStream() { + return myResourceNameToSpNameToSp.values().stream().flatMap(entry -> entry.values().stream()); + } + + protected Map getSearchParamMap(String theResourceName) { + Map retval = myResourceNameToSpNameToSp.get(theResourceName); + if (retval == null) { + return Collections.emptyMap(); + } + return Collections.unmodifiableMap(myResourceNameToSpNameToSp.get(theResourceName)); + } + + public int size() { + return myResourceNameToSpNameToSp.size(); + } + + public RuntimeSearchParam getByUrl(String theUrl) { + return myUrlToParam.get(theUrl); } public static ReadOnlySearchParamCache fromFhirContext(FhirContext theFhirContext) { @@ -58,7 +81,7 @@ public class ReadOnlySearchParamCache { RuntimeResourceDefinition nextResDef = theFhirContext.getResourceDefinition(resourceName); String nextResourceName = nextResDef.getName(); HashMap nameToParam = new HashMap<>(); - retval.myMap.put(nextResourceName, nameToParam); + retval.myResourceNameToSpNameToSp.put(nextResourceName, nameToParam); for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) { nameToParam.put(nextSp.getName(), nextSp); @@ -70,33 +93,4 @@ public class ReadOnlySearchParamCache { public static ReadOnlySearchParamCache fromRuntimeSearchParamCache(RuntimeSearchParamCache theRuntimeSearchParamCache) { return new ReadOnlySearchParamCache(theRuntimeSearchParamCache); } - - public Stream getSearchParamStream() { - return myMap.values().stream().flatMap(entry -> entry.values().stream()); - } - - protected Map getSearchParamMap(String theResourceName) { - Map retval = myMap.get(theResourceName); - if (retval == null) { - return Collections.emptyMap(); - } - return Collections.unmodifiableMap(myMap.get(theResourceName)); - } - - public Collection getValidSearchParameterNamesIncludingMeta(String theResourceName) { - TreeSet retval; - Map searchParamMap = myMap.get(theResourceName); - if (searchParamMap == null) { - retval = new TreeSet<>(); - } else { - retval = new TreeSet<>(searchParamMap.keySet()); - } - retval.add(IAnyResource.SP_RES_ID); - retval.add(Constants.PARAM_LASTUPDATED); - return retval; - } - - public int size() { - return myMap.size(); - } } diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/RuntimeSearchParamCache.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/RuntimeSearchParamCache.java index 456a38a933f..5b431fa56e1 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/RuntimeSearchParamCache.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/RuntimeSearchParamCache.java @@ -28,35 +28,42 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + public class RuntimeSearchParamCache extends ReadOnlySearchParamCache { private static final Logger ourLog = LoggerFactory.getLogger(RuntimeSearchParamCache.class); protected RuntimeSearchParamCache() { } - public static RuntimeSearchParamCache fromReadOnlySearchParmCache(ReadOnlySearchParamCache theBuiltInSearchParams) { - RuntimeSearchParamCache retval = new RuntimeSearchParamCache(); - retval.putAll(theBuiltInSearchParams); - return retval; - } - public void add(String theResourceName, String theName, RuntimeSearchParam theSearchParam) { getSearchParamMap(theResourceName).put(theName, theSearchParam); + String uri = theSearchParam.getUri(); + if (isNotBlank(uri)) { + if (myUrlToParam.containsKey(uri)) { + ourLog.warn("Multiple search parameters have URL: {}", uri); + } + myUrlToParam.put(uri, theSearchParam); + } + if (theSearchParam.getId() != null && theSearchParam.getId().hasIdPart()) { + String value = theSearchParam.getId().toUnqualifiedVersionless().getValue(); + myUrlToParam.put(value, theSearchParam); + } } public void remove(String theResourceName, String theName) { - if (!myMap.containsKey(theResourceName)) { + if (!myResourceNameToSpNameToSp.containsKey(theResourceName)) { return; } - myMap.get(theResourceName).remove(theName); + myResourceNameToSpNameToSp.get(theResourceName).remove(theName); } private void putAll(ReadOnlySearchParamCache theReadOnlySearchParamCache) { - Set>> builtInSps = theReadOnlySearchParamCache.myMap.entrySet(); + Set>> builtInSps = theReadOnlySearchParamCache.myResourceNameToSpNameToSp.entrySet(); for (Map.Entry> nextBuiltInEntry : builtInSps) { for (RuntimeSearchParam nextParam : nextBuiltInEntry.getValue().values()) { String nextResourceName = nextBuiltInEntry.getKey(); - getSearchParamMap(nextResourceName).put(nextParam.getName(), nextParam); + add(nextResourceName, nextParam.getName(), nextParam); } ourLog.trace("Have {} built-in SPs for: {}", nextBuiltInEntry.getValue().size(), nextBuiltInEntry.getKey()); @@ -65,7 +72,7 @@ public class RuntimeSearchParamCache extends ReadOnlySearchParamCache { public RuntimeSearchParam get(String theResourceName, String theParamName) { RuntimeSearchParam retVal = null; - Map params = myMap.get(theResourceName); + Map params = myResourceNameToSpNameToSp.get(theResourceName); if (params != null) { retVal = params.get(theParamName); } @@ -73,11 +80,17 @@ public class RuntimeSearchParamCache extends ReadOnlySearchParamCache { } public Set getResourceNameKeys() { - return myMap.keySet(); + return myResourceNameToSpNameToSp.keySet(); } @Override protected Map getSearchParamMap(String theResourceName) { - return myMap.computeIfAbsent(theResourceName, k -> new HashMap<>()); + return myResourceNameToSpNameToSp.computeIfAbsent(theResourceName, k -> new HashMap<>()); + } + + public static RuntimeSearchParamCache fromReadOnlySearchParmCache(ReadOnlySearchParamCache theBuiltInSearchParams) { + RuntimeSearchParamCache retval = new RuntimeSearchParamCache(); + retval.putAll(theBuiltInSearchParams); + return retval; } } diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParamRegistryImpl.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParamRegistryImpl.java index 7dafdd74610..a6cf42636aa 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParamRegistryImpl.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParamRegistryImpl.java @@ -21,7 +21,6 @@ package ca.uhn.fhir.jpa.searchparam.registry; */ import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.phonetic.IPhoneticEncoder; import ca.uhn.fhir.interceptor.api.IInterceptorService; @@ -31,10 +30,10 @@ import ca.uhn.fhir.jpa.cache.IResourceChangeListenerCache; import ca.uhn.fhir.jpa.cache.IResourceChangeListenerRegistry; import ca.uhn.fhir.jpa.cache.ResourceChangeResult; import ca.uhn.fhir.jpa.model.entity.ModelConfig; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.util.SearchParameterUtil; import ca.uhn.fhir.util.StopWatch; import com.google.common.annotations.VisibleForTesting; @@ -46,6 +45,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import javax.annotation.Nullable; import javax.annotation.Nonnull; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -58,11 +58,13 @@ import java.util.Set; import static org.apache.commons.lang3.StringUtils.isBlank; -public class SearchParamRegistryImpl implements ISearchParamRegistry, IResourceChangeListener { +public class SearchParamRegistryImpl implements ISearchParamRegistry, IResourceChangeListener, ISearchParamRegistryController { + // TODO: JA remove unused? + private static final Logger ourLog = LoggerFactory.getLogger(SearchParamRegistryImpl.class); private static final int MAX_MANAGED_PARAM_COUNT = 10000; private static final long REFRESH_INTERVAL = DateUtils.MILLIS_PER_HOUR; - + private final JpaSearchParamCache myJpaSearchParamCache = new JpaSearchParamCache(); @Autowired private ModelConfig myModelConfig; @Autowired @@ -73,10 +75,8 @@ public class SearchParamRegistryImpl implements ISearchParamRegistry, IResourceC private SearchParameterCanonicalizer mySearchParameterCanonicalizer; @Autowired private IResourceChangeListenerRegistry myResourceChangeListenerRegistry; - private volatile ReadOnlySearchParamCache myBuiltInSearchParams; private volatile IPhoneticEncoder myPhoneticEncoder; - private final JpaSearchParamCache myJpaSearchParamCache = new JpaSearchParamCache(); private volatile RuntimeSearchParamCache myActiveSearchParams; @Autowired @@ -109,15 +109,25 @@ public class SearchParamRegistryImpl implements ISearchParamRegistry, IResourceC } @Override - public List getActiveUniqueSearchParams(String theResourceName) { + public List getActiveUniqueSearchParams(String theResourceName) { return myJpaSearchParamCache.getActiveUniqueSearchParams(theResourceName); } @Override - public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { return myJpaSearchParamCache.getActiveUniqueSearchParams(theResourceName, theParamNames); } + @Nullable + @Override + public RuntimeSearchParam getActiveSearchParamByUrl(String theUrl) { + if (myActiveSearchParams != null) { + return myActiveSearchParams.getByUrl(theUrl); + } else { + return null; + } + } + private void rebuildActiveSearchParams() { ourLog.info("Rebuilding SearchParamRegistry"); SearchParameterMap params = new SearchParameterMap(); @@ -205,26 +215,14 @@ public class SearchParamRegistryImpl implements ISearchParamRegistry, IResourceC continue; } - Map searchParamMap = theSearchParams.getSearchParamMap(nextBaseName); String name = runtimeSp.getName(); + theSearchParams.add(nextBaseName, name, runtimeSp); ourLog.debug("Adding search parameter {}.{} to SearchParamRegistry", nextBaseName, StringUtils.defaultString(name, "[composite]")); - searchParamMap.put(name, runtimeSp); retval++; } return retval; } - @Override - public RuntimeSearchParam getSearchParamByName(RuntimeResourceDefinition theResourceDef, String theParamName) { - Map params = getActiveSearchParams(theResourceDef.getName()); - return params.get(theParamName); - } - - @Override - public Collection getSearchParamsByResourceType(RuntimeResourceDefinition theResourceDef) { - return getActiveSearchParams(theResourceDef.getName()).values(); - } - @Override public void requestRefresh() { myResourceChangeListenerCache.requestRefresh(); @@ -255,7 +253,6 @@ public class SearchParamRegistryImpl implements ISearchParamRegistry, IResourceC myResourceChangeListenerRegistry.unregisterResourceResourceChangeListener(this); } - @Override public ReadOnlySearchParamCache getActiveSearchParams() { requiresActiveSearchParams(); if (myActiveSearchParams == null) { diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParameterCanonicalizer.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParameterCanonicalizer.java index d134a8c7ba9..29ec2044f90 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParameterCanonicalizer.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParameterCanonicalizer.java @@ -23,12 +23,10 @@ package ca.uhn.fhir.jpa.searchparam.registry; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.phonetic.PhoneticEncoderEnum; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.util.DatatypeUtil; -import ca.uhn.fhir.util.ExtensionUtil; import ca.uhn.fhir.util.FhirTerser; import ca.uhn.fhir.util.HapiExtensions; import org.apache.commons.lang3.EnumUtils; @@ -41,7 +39,6 @@ import org.hl7.fhir.instance.model.api.IBaseHasExtensions; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IPrimitiveType; -import org.hl7.fhir.r4.model.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -57,6 +54,7 @@ import java.util.stream.Collectors; import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank; +import static org.apache.commons.lang3.StringUtils.startsWith; @Service public class SearchParameterCanonicalizer { @@ -70,7 +68,7 @@ public class SearchParameterCanonicalizer { } protected RuntimeSearchParam canonicalizeSearchParameter(IBaseResource theSearchParameter) { - JpaRuntimeSearchParam retVal; + RuntimeSearchParam retVal; switch (myFhirContext.getVersion().getVersion()) { case DSTU2: retVal = canonicalizeSearchParameterDstu2((ca.uhn.fhir.model.dstu2.resource.SearchParameter) theSearchParameter); @@ -92,7 +90,7 @@ public class SearchParameterCanonicalizer { return retVal; } - private JpaRuntimeSearchParam canonicalizeSearchParameterDstu2(ca.uhn.fhir.model.dstu2.resource.SearchParameter theNextSp) { + private RuntimeSearchParam canonicalizeSearchParameterDstu2(ca.uhn.fhir.model.dstu2.resource.SearchParameter theNextSp) { String name = theNextSp.getCode(); String description = theNextSp.getDescription(); String path = theNextSp.getXpath(); @@ -162,12 +160,12 @@ public class SearchParameterCanonicalizer { } } - List components = Collections.emptyList(); + List components = Collections.emptyList(); Collection> base = Collections.singletonList(theNextSp.getBaseElement()); - return new JpaRuntimeSearchParam(id, uri, name, description, path, paramType, providesMembershipInCompartments, targets, status, unique, components, toStrings(base)); + return new RuntimeSearchParam(id, uri, name, description, path, paramType, providesMembershipInCompartments, targets, status, unique, components, toStrings(base)); } - private JpaRuntimeSearchParam canonicalizeSearchParameterDstu3(org.hl7.fhir.dstu3.model.SearchParameter theNextSp) { + private RuntimeSearchParam canonicalizeSearchParameterDstu3(org.hl7.fhir.dstu3.model.SearchParameter theNextSp) { String name = theNextSp.getCode(); String description = theNextSp.getDescription(); String path = theNextSp.getExpression(); @@ -242,15 +240,15 @@ public class SearchParameterCanonicalizer { } } - List components = new ArrayList<>(); + List components = new ArrayList<>(); for (SearchParameter.SearchParameterComponentComponent next : theNextSp.getComponent()) { - components.add(new JpaRuntimeSearchParam.Component(next.getExpression(), next.getDefinition())); + components.add(new RuntimeSearchParam.Component(next.getExpression(), next.getDefinition().getReferenceElement().toUnqualifiedVersionless().getValue())); } - return new JpaRuntimeSearchParam(id, uri, name, description, path, paramType, providesMembershipInCompartments, targets, status, unique, components, toStrings(theNextSp.getBase())); + return new RuntimeSearchParam(id, uri, name, description, path, paramType, providesMembershipInCompartments, targets, status, unique, components, toStrings(theNextSp.getBase())); } - private JpaRuntimeSearchParam canonicalizeSearchParameterR4Plus(IBaseResource theNextSp) { + private RuntimeSearchParam canonicalizeSearchParameterR4Plus(IBaseResource theNextSp) { FhirTerser terser = myFhirContext.newTerser(); String name = terser.getSinglePrimitiveValueOrNull(theNextSp, "code"); String description = terser.getSinglePrimitiveValueOrNull(theNextSp, "description"); @@ -318,30 +316,34 @@ public class SearchParameterCanonicalizer { String value = ((IBaseHasExtensions) theNextSp).getExtension() .stream() .filter(e -> HapiExtensions.EXT_SP_UNIQUE.equals(e.getUrl())) - .filter(t->t.getValue() instanceof IPrimitiveType) - .map(t->(IPrimitiveType)t.getValue()) - .map(t->t.getValueAsString()) + .filter(t -> t.getValue() instanceof IPrimitiveType) + .map(t -> (IPrimitiveType) t.getValue()) + .map(t -> t.getValueAsString()) .findFirst() .orElse(""); if ("true".equalsIgnoreCase(value)) { unique = true; } - List components = new ArrayList<>(); + List components = new ArrayList<>(); for (IBase next : terser.getValues(theNextSp, "component")) { String expression = terser.getSinglePrimitiveValueOrNull(next, "expression"); String definition = terser.getSinglePrimitiveValueOrNull(next, "definition"); - components.add(new JpaRuntimeSearchParam.Component(expression, new Reference(definition))); + if (startsWith(definition, "/SearchParameter/")) { + definition = definition.substring(1); + } + + components.add(new RuntimeSearchParam.Component(expression, definition)); } - return new JpaRuntimeSearchParam(id, uri, name, description, path, paramType, providesMembershipInCompartments, targets, status, unique, components, base); + return new RuntimeSearchParam(id, uri, name, description, path, paramType, providesMembershipInCompartments, targets, status, unique, components, base); } /** * Extracts any extensions from the resource and populates an extension field in the */ - protected void extractExtensions(IBaseResource theSearchParamResource, JpaRuntimeSearchParam theRuntimeSearchParam) { + protected void extractExtensions(IBaseResource theSearchParamResource, RuntimeSearchParam theRuntimeSearchParam) { if (theSearchParamResource instanceof IBaseHasExtensions) { List> extensions = ((IBaseHasExtensions) theSearchParamResource).getExtension(); for (IBaseExtension next : extensions) { @@ -356,7 +358,7 @@ public class SearchParameterCanonicalizer { } } - private void setEncoder(JpaRuntimeSearchParam theRuntimeSearchParam, IBaseDatatype theValue) { + private void setEncoder(RuntimeSearchParam theRuntimeSearchParam, IBaseDatatype theValue) { if (theValue instanceof IPrimitiveType) { String stringValue = ((IPrimitiveType) theValue).getValueAsString(); PhoneticEncoderEnum encoderEnum = EnumUtils.getEnum(PhoneticEncoderEnum.class, stringValue); diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/util/JpaParamUtil.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/util/JpaParamUtil.java new file mode 100644 index 00000000000..2f64222d586 --- /dev/null +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/util/JpaParamUtil.java @@ -0,0 +1,194 @@ +package ca.uhn.fhir.jpa.searchparam.util; + +/*- + * #%L + * HAPI FHIR Search Parameters + * %% + * Copyright (C) 2014 - 2021 Smile CDR, Inc. + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import ca.uhn.fhir.context.ConfigurationException; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.RuntimeSearchParam; +import ca.uhn.fhir.model.api.IQueryParameterAnd; +import ca.uhn.fhir.model.api.IQueryParameterType; +import ca.uhn.fhir.rest.api.QualifiedParamList; +import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; +import ca.uhn.fhir.rest.param.CompositeAndListParam; +import ca.uhn.fhir.rest.param.DateAndListParam; +import ca.uhn.fhir.rest.param.DateParam; +import ca.uhn.fhir.rest.param.HasAndListParam; +import ca.uhn.fhir.rest.param.HasParam; +import ca.uhn.fhir.rest.param.NumberAndListParam; +import ca.uhn.fhir.rest.param.NumberParam; +import ca.uhn.fhir.rest.param.QuantityAndListParam; +import ca.uhn.fhir.rest.param.QuantityParam; +import ca.uhn.fhir.rest.param.ReferenceAndListParam; +import ca.uhn.fhir.rest.param.ReferenceParam; +import ca.uhn.fhir.rest.param.SpecialAndListParam; +import ca.uhn.fhir.rest.param.SpecialParam; +import ca.uhn.fhir.rest.param.StringAndListParam; +import ca.uhn.fhir.rest.param.StringParam; +import ca.uhn.fhir.rest.param.TokenAndListParam; +import ca.uhn.fhir.rest.param.TokenParam; +import ca.uhn.fhir.rest.param.UriAndListParam; +import ca.uhn.fhir.rest.param.UriParam; +import ca.uhn.fhir.rest.param.binder.QueryParameterAndBinder; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public enum JpaParamUtil { + + ; + + /** + * This is a utility method intended provided to help the JPA module. + */ + public static IQueryParameterAnd parseQueryParams(FhirContext theContext, RestSearchParameterTypeEnum paramType, + String theUnqualifiedParamName, List theParameters) { + QueryParameterAndBinder binder; + switch (paramType) { + case COMPOSITE: + throw new UnsupportedOperationException(); + case DATE: + binder = new QueryParameterAndBinder(DateAndListParam.class, + Collections.emptyList()); + break; + case NUMBER: + binder = new QueryParameterAndBinder(NumberAndListParam.class, + Collections.emptyList()); + break; + case QUANTITY: + binder = new QueryParameterAndBinder(QuantityAndListParam.class, + Collections.emptyList()); + break; + case REFERENCE: + binder = new QueryParameterAndBinder(ReferenceAndListParam.class, + Collections.emptyList()); + break; + case STRING: + binder = new QueryParameterAndBinder(StringAndListParam.class, + Collections.emptyList()); + break; + case TOKEN: + binder = new QueryParameterAndBinder(TokenAndListParam.class, + Collections.emptyList()); + break; + case URI: + binder = new QueryParameterAndBinder(UriAndListParam.class, + Collections.emptyList()); + break; + case HAS: + binder = new QueryParameterAndBinder(HasAndListParam.class, + Collections.emptyList()); + break; + case SPECIAL: + binder = new QueryParameterAndBinder(SpecialAndListParam.class, + Collections.emptyList()); + break; + default: + throw new IllegalArgumentException("Parameter '" + theUnqualifiedParamName + "' has type " + paramType + " which is currently not supported."); + } + + return binder.parse(theContext, theUnqualifiedParamName, theParameters); + } + + /** + * This is a utility method intended provided to help the JPA module. + */ + public static IQueryParameterAnd parseQueryParams(ISearchParamRegistry theSearchParamRegistry, FhirContext theContext, RuntimeSearchParam theParamDef, + String theUnqualifiedParamName, List theParameters) { + + RestSearchParameterTypeEnum paramType = theParamDef.getParamType(); + + if (paramType == RestSearchParameterTypeEnum.COMPOSITE) { + + List compositeList = resolveComponentParameters(theSearchParamRegistry, theParamDef); + + if (compositeList.size() != 2) { + throw new ConfigurationException("Search parameter of type " + theUnqualifiedParamName + + " must have 2 composite types declared in parameter annotation, found " + + compositeList.size()); + } + + RuntimeSearchParam left = compositeList.get(0); + RuntimeSearchParam right = compositeList.get(1); + + @SuppressWarnings({"unchecked", "rawtypes"}) + CompositeAndListParam cp = new CompositeAndListParam( + getCompositeBindingClass(left.getParamType(), left.getName()), + getCompositeBindingClass(right.getParamType(), right.getName())); + + cp.setValuesAsQueryTokens(theContext, theUnqualifiedParamName, theParameters); + + return cp; + } else { + return parseQueryParams(theContext, paramType, theUnqualifiedParamName, theParameters); + } + } + + public static List resolveComponentParameters(ISearchParamRegistry theSearchParamRegistry, RuntimeSearchParam theParamDef) { + List compositeList = new ArrayList<>(); + List components = theParamDef.getComponents(); + for (RuntimeSearchParam.Component next : components) { + String url = next.getReference(); + RuntimeSearchParam componentParam = theSearchParamRegistry.getActiveSearchParamByUrl(url); + if (componentParam == null) { + throw new InternalErrorException("Can not find SearchParameter: " + url); + } + compositeList.add(componentParam); + } + + compositeList.sort((Comparator.comparing(RuntimeSearchParam::getName))); + + return compositeList; + } + + private static Class getCompositeBindingClass(RestSearchParameterTypeEnum paramType, + String theUnqualifiedParamName) { + + switch (paramType) { + case DATE: + return DateParam.class; + case NUMBER: + return NumberParam.class; + case QUANTITY: + return QuantityParam.class; + case REFERENCE: + return ReferenceParam.class; + case STRING: + return StringParam.class; + case TOKEN: + return TokenParam.class; + case URI: + return UriParam.class; + case HAS: + return HasParam.class; + case SPECIAL: + return SpecialParam.class; + + case COMPOSITE: + default: + throw new IllegalArgumentException("Parameter '" + theUnqualifiedParamName + "' has type " + paramType + + " which is currently not supported."); + } + } +} diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/IndexStressTest.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/IndexStressTest.java index bbb7ef23b6b..f1a84f721d4 100644 --- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/IndexStressTest.java +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/IndexStressTest.java @@ -7,7 +7,7 @@ import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString; import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorDstu3; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.util.StopWatch; import org.hl7.fhir.dstu3.model.Patient; import org.junit.jupiter.api.Test; diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3Test.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3Test.java index 4a6106d9fea..d1f1153d1f1 100644 --- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3Test.java +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3Test.java @@ -16,11 +16,11 @@ import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistryController; import ca.uhn.fhir.jpa.searchparam.registry.ReadOnlySearchParamCache; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.util.StringUtil; import ca.uhn.fhir.util.TestUtil; import com.google.common.collect.Sets; @@ -34,9 +34,9 @@ import org.hl7.fhir.dstu3.model.Questionnaire; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Test; +import javax.annotation.Nullable; import java.text.Normalizer; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -132,11 +132,11 @@ public class SearchParamExtractorDstu3Test { SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, searchParamRegistry); extractor.start(); - searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "", RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE)); + searchParamRegistry.addSearchParam(new RuntimeSearchParam(null, null, "foo", "foo", "", RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null)); Patient resource = new Patient(); extractor.extractSearchParamStrings(resource); - searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", null, RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE)); + searchParamRegistry.addSearchParam(new RuntimeSearchParam(null, null, "foo", "foo", null, RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null)); extractor.extractSearchParamStrings(resource); } @@ -148,7 +148,7 @@ public class SearchParamExtractorDstu3Test { SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), new PartitionSettings(), ourCtx, searchParamRegistry); extractor.start(); - searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "communication.language.coding.system | communication.language.coding.code", RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE)); + searchParamRegistry.addSearchParam(new RuntimeSearchParam(null, null, "foo", "foo", "communication.language.coding.system | communication.language.coding.code", RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null)); Patient resource = new Patient(); resource.getCommunicationFirstRep().getLanguage().getCodingFirstRep().setCode("blah"); Set strings = extractor.extractSearchParamStrings(resource); @@ -166,37 +166,37 @@ public class SearchParamExtractorDstu3Test { extractor.start(); { - searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE)); + searchParamRegistry.addSearchParam(new RuntimeSearchParam(null, null, "foo", "foo", "Patient", RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null)); Patient resource = new Patient(); ISearchParamExtractor.SearchParamSet outcome = extractor.extractSearchParamStrings(resource); assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient")); } { - searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.TOKEN, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE)); + searchParamRegistry.addSearchParam(new RuntimeSearchParam(null, null, "foo", "foo", "Patient", RestSearchParameterTypeEnum.TOKEN, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null)); Patient resource = new Patient(); ISearchParamExtractor.SearchParamSet outcome = extractor.extractSearchParamTokens(resource); assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient")); } { - searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.QUANTITY, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE)); + searchParamRegistry.addSearchParam(new RuntimeSearchParam(null, null, "foo", "foo", "Patient", RestSearchParameterTypeEnum.QUANTITY, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null)); Patient resource = new Patient(); ISearchParamExtractor.SearchParamSet outcome = extractor.extractSearchParamQuantity(resource); assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient")); } { - searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.DATE, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE)); + searchParamRegistry.addSearchParam(new RuntimeSearchParam(null, null, "foo", "foo", "Patient", RestSearchParameterTypeEnum.DATE, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null)); Patient resource = new Patient(); ISearchParamExtractor.SearchParamSet outcome = extractor.extractSearchParamDates(resource); assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient")); } { - searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.NUMBER, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE)); + searchParamRegistry.addSearchParam(new RuntimeSearchParam(null, null, "foo", "foo", "Patient", RestSearchParameterTypeEnum.NUMBER, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null)); Patient resource = new Patient(); ISearchParamExtractor.SearchParamSet outcome = extractor.extractSearchParamNumber(resource); assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient")); } { - searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.URI, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE)); + searchParamRegistry.addSearchParam(new RuntimeSearchParam(null, null, "foo", "foo", "Patient", RestSearchParameterTypeEnum.URI, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null)); Patient resource = new Patient(); ISearchParamExtractor.SearchParamSet outcome = extractor.extractSearchParamUri(resource); assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient")); @@ -222,7 +222,9 @@ public class SearchParamExtractorDstu3Test { assertEquals(longitude, coord.getLongitude(), 0.0); } - private static class MySearchParamRegistry implements ISearchParamRegistry { + private static class MySearchParamRegistry implements ISearchParamRegistry, ISearchParamRegistryController { + + // TODO: JA remove unused? private final List myAddedSearchParams = new ArrayList<>(); @@ -249,7 +251,6 @@ public class SearchParamExtractorDstu3Test { return new ResourceChangeResult(); } - @Override public ReadOnlySearchParamCache getActiveSearchParams() { throw new UnsupportedOperationException(); } @@ -268,12 +269,18 @@ public class SearchParamExtractorDstu3Test { } @Override - public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public RuntimeSearchParam getActiveSearchParamByUrl(String theUrl) { throw new UnsupportedOperationException(); } @Override - public List getActiveUniqueSearchParams(String theResourceName) { + public List getActiveUniqueSearchParams(String theResourceName) { throw new UnsupportedOperationException(); } @@ -282,16 +289,6 @@ public class SearchParamExtractorDstu3Test { // nothing } - @Override - public RuntimeSearchParam getSearchParamByName(RuntimeResourceDefinition theResourceDef, String theParamName) { - return null; - } - - @Override - public Collection getSearchParamsByResourceType(RuntimeResourceDefinition theResourceDef) { - return null; - } - @Override public void setPhoneticEncoder(IPhoneticEncoder thePhoneticEncoder) { // nothing diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorMegaTest.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorMegaTest.java index 97185778d9a..e3a24cc540b 100644 --- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorMegaTest.java +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorMegaTest.java @@ -20,9 +20,9 @@ import ca.uhn.fhir.context.phonetic.IPhoneticEncoder; import ca.uhn.fhir.jpa.cache.ResourceChangeResult; import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.entity.ModelConfig; -import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistryController; import ca.uhn.fhir.jpa.searchparam.registry.ReadOnlySearchParamCache; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseEnumeration; import org.hl7.fhir.instance.model.api.IBaseResource; @@ -32,8 +32,8 @@ import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -45,6 +45,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; // TODO JA Please fix this test. Expanding FhirContext.getResourceTypes() to cover all resource types broke this test. @Disabled public class SearchParamExtractorMegaTest { + // TODO: JA remove unused? private static final Logger ourLog = LoggerFactory.getLogger(SearchParamExtractorMegaTest.class); @@ -231,7 +232,7 @@ public class SearchParamExtractorMegaTest { } - private static class MySearchParamRegistry implements ISearchParamRegistry { + private static class MySearchParamRegistry implements ISearchParamRegistry, ISearchParamRegistryController { private final FhirContext myCtx; private List myAddedSearchParams = new ArrayList<>(); @@ -263,7 +264,6 @@ public class SearchParamExtractorMegaTest { return new ResourceChangeResult(); } - @Override public ReadOnlySearchParamCache getActiveSearchParams() { throw new UnsupportedOperationException(); } @@ -282,12 +282,18 @@ public class SearchParamExtractorMegaTest { } @Override - public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public RuntimeSearchParam getActiveSearchParamByUrl(String theUrl) { throw new UnsupportedOperationException(); } @Override - public List getActiveUniqueSearchParams(String theResourceName) { + public List getActiveUniqueSearchParams(String theResourceName) { throw new UnsupportedOperationException(); } @@ -296,16 +302,6 @@ public class SearchParamExtractorMegaTest { // nothing } - @Override - public RuntimeSearchParam getSearchParamByName(RuntimeResourceDefinition theResourceDef, String theParamName) { - return null; - } - - @Override - public Collection getSearchParamsByResourceType(RuntimeResourceDefinition theResourceDef) { - return null; - } - @Override public void setPhoneticEncoder(IPhoneticEncoder thePhoneticEncoder) { // nothing diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java index 17c1d56f707..c048ca05390 100644 --- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java @@ -7,12 +7,12 @@ import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.model.primitive.BaseDateTimeDt; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.param.ParamPrefixEnum; import ca.uhn.fhir.rest.param.TokenParamModifier; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import org.hl7.fhir.r5.model.BaseDateTimeType; import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r5.model.DateTimeType; @@ -34,8 +34,6 @@ import java.util.Date; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @ExtendWith(SpringExtension.class) @@ -60,16 +58,13 @@ public class InMemoryResourceMatcherR5Test { @BeforeEach public void before() { - RuntimeSearchParam dateSearchParam = new RuntimeSearchParam(null, null, null, null, "Observation.effective", RestSearchParameterTypeEnum.DATE, null, null, null, RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE); - when(mySearchParamRegistry.getSearchParamByName(any(), eq("date"))).thenReturn(dateSearchParam); + RuntimeSearchParam dateSearchParam = new RuntimeSearchParam(null, null, null, null, "Observation.effective", RestSearchParameterTypeEnum.DATE, null, null, RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null); when(mySearchParamRegistry.getActiveSearchParam("Observation", "date")).thenReturn(dateSearchParam); - RuntimeSearchParam codeSearchParam = new RuntimeSearchParam(null, null, null, null, "Observation.code", RestSearchParameterTypeEnum.TOKEN, null, null, null, RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE); - when(mySearchParamRegistry.getSearchParamByName(any(), eq("code"))).thenReturn(codeSearchParam); + RuntimeSearchParam codeSearchParam = new RuntimeSearchParam(null, null, null, null, "Observation.code", RestSearchParameterTypeEnum.TOKEN, null, null, RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null); when(mySearchParamRegistry.getActiveSearchParam("Observation", "code")).thenReturn(codeSearchParam); - RuntimeSearchParam encSearchParam = new RuntimeSearchParam(null, null, null, null, "Observation.encounter", RestSearchParameterTypeEnum.REFERENCE, null, null, null, RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE); - when(mySearchParamRegistry.getSearchParamByName(any(), eq("encounter"))).thenReturn(encSearchParam); + RuntimeSearchParam encSearchParam = new RuntimeSearchParam(null, null, null, null, "Observation.encounter", RestSearchParameterTypeEnum.REFERENCE, null, null, RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null); when(mySearchParamRegistry.getActiveSearchParam("Observation", "encounter")).thenReturn(encSearchParam); myObservation = new Observation(); diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParamRegistryImplTest.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParamRegistryImplTest.java index 0deeb0b7a9e..53cbc763578 100644 --- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParamRegistryImplTest.java +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/registry/SearchParamRegistryImplTest.java @@ -21,6 +21,7 @@ import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.rest.server.SimpleBundleProvider; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.r4.model.Enumerations; @@ -115,7 +116,7 @@ public class SearchParamRegistryImplTest { } @Bean - ISearchParamRegistry searchParamRegistry() { + ISearchParamRegistry searchParamRegistry() { return new SearchParamRegistryImpl(); } diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml index a0fe13f241d..e1878aacf98 100644 --- a/hapi-fhir-jpaserver-subscription/pom.xml +++ b/hapi-fhir-jpaserver-subscription/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionLoader.java b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionLoader.java index 9c17e84e23d..51093138df4 100644 --- a/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionLoader.java +++ b/hapi-fhir-jpaserver-subscription/src/main/java/ca/uhn/fhir/jpa/subscription/match/registry/SubscriptionLoader.java @@ -28,7 +28,7 @@ import ca.uhn.fhir.jpa.cache.IResourceChangeListenerCache; import ca.uhn.fhir.jpa.cache.IResourceChangeListenerRegistry; import ca.uhn.fhir.jpa.model.sched.ISchedulerService; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.retry.Retrier; import ca.uhn.fhir.jpa.subscription.match.matcher.subscriber.SubscriptionActivatingSubscriber; import ca.uhn.fhir.rest.api.server.IBundleProvider; diff --git a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/websocket/WebsocketConnectionValidatorTest.java b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/websocket/WebsocketConnectionValidatorTest.java index 5fe3911087f..6d94c5bcc07 100644 --- a/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/websocket/WebsocketConnectionValidatorTest.java +++ b/hapi-fhir-jpaserver-subscription/src/test/java/ca/uhn/fhir/jpa/subscription/module/subscriber/websocket/WebsocketConnectionValidatorTest.java @@ -11,7 +11,7 @@ import ca.uhn.fhir.jpa.model.sched.ISchedulerService; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher; import ca.uhn.fhir.jpa.searchparam.matcher.SearchParamMatcher; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig; import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelFactory; import ca.uhn.fhir.jpa.subscription.match.config.SubscriptionProcessorConfig; diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml index 786e475ab72..7f20b4b2dc5 100644 --- a/hapi-fhir-jpaserver-test-utilities/pom.xml +++ b/hapi-fhir-jpaserver-test-utilities/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml index 0aa2c29e8f1..9314f0dbd85 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml +++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml @@ -164,7 +164,7 @@ ca.uhn.hapi.fhir hapi-fhir-converter - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java index 5fa02d56807..e2c52f3b321 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java +++ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java @@ -19,7 +19,7 @@ import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3; import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4; import ca.uhn.fhir.jpa.provider.r5.JpaSystemProviderR5; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; -import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.jpa.subscription.match.config.WebsocketDispatcherConfig; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.rest.api.EncodingEnum; diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml index d45f8d70524..71c5ec9049a 100644 --- a/hapi-fhir-server-mdm/pom.xml +++ b/hapi-fhir-server-mdm/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/config/MdmRuleValidator.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/config/MdmRuleValidator.java index 27a84c92d87..bbec9526992 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/config/MdmRuleValidator.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/config/MdmRuleValidator.java @@ -33,11 +33,9 @@ import ca.uhn.fhir.mdm.rules.json.MdmResourceSearchParamJson; import ca.uhn.fhir.mdm.rules.json.MdmRulesJson; import ca.uhn.fhir.mdm.rules.json.MdmSimilarityJson; import ca.uhn.fhir.parser.DataFormatException; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.util.FhirTerser; -import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseResource; -import org.hl7.fhir.r4.model.Patient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -54,12 +52,12 @@ public class MdmRuleValidator implements IMdmRuleValidator { private static final Logger ourLog = LoggerFactory.getLogger(MdmRuleValidator.class); private final FhirContext myFhirContext; - private final ISearchParamRetriever mySearchParamRetriever; + private final ISearchParamRegistry mySearchParamRetriever; private final FhirTerser myTerser; private final IFhirPath myFhirPath; @Autowired - public MdmRuleValidator(FhirContext theFhirContext, ISearchParamRetriever theSearchParamRetriever) { + public MdmRuleValidator(FhirContext theFhirContext, ISearchParamRegistry theSearchParamRetriever) { myFhirContext = theFhirContext; myTerser = myFhirContext.newTerser(); if (myFhirContext.getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3)) { diff --git a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/BaseR4Test.java b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/BaseR4Test.java index 4c006cd3647..2597d2ad3f1 100644 --- a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/BaseR4Test.java +++ b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/BaseR4Test.java @@ -7,7 +7,7 @@ import ca.uhn.fhir.mdm.rules.config.MdmRuleValidator; import ca.uhn.fhir.mdm.rules.config.MdmSettings; import ca.uhn.fhir.mdm.rules.json.MdmRulesJson; import ca.uhn.fhir.mdm.rules.svc.MdmResourceMatcherSvc; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import org.hl7.fhir.r4.model.Patient; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; @@ -18,7 +18,7 @@ import static org.mockito.Mockito.mock; @ExtendWith(MockitoExtension.class) public abstract class BaseR4Test { protected static final FhirContext ourFhirContext = FhirContext.forR4(); - protected ISearchParamRetriever mySearchParamRetriever = mock(ISearchParamRetriever.class); + protected ISearchParamRegistry mySearchParamRetriever = mock(ISearchParamRegistry.class); protected Patient buildJohn() { Patient patient = new Patient(); diff --git a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/svc/ResourceMatcherR4Test.java b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/svc/ResourceMatcherR4Test.java index 0b105cf1892..8a2342c9398 100644 --- a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/svc/ResourceMatcherR4Test.java +++ b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/rules/svc/ResourceMatcherR4Test.java @@ -7,15 +7,12 @@ import ca.uhn.fhir.mdm.rules.json.MdmFieldMatchJson; import ca.uhn.fhir.mdm.rules.json.MdmMatcherJson; import ca.uhn.fhir.mdm.rules.json.MdmRulesJson; import ca.uhn.fhir.mdm.rules.matcher.MdmMatcherEnum; -import ca.uhn.fhir.util.StopWatch; import org.hl7.fhir.r4.model.HumanName; import org.hl7.fhir.r4.model.Patient; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/svc/EIDHelperR4Test.java b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/svc/EIDHelperR4Test.java index ae93b29fe00..7f7a17bfe78 100644 --- a/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/svc/EIDHelperR4Test.java +++ b/hapi-fhir-server-mdm/src/test/java/ca/uhn/fhir/mdm/svc/EIDHelperR4Test.java @@ -45,10 +45,7 @@ public class EIDHelperR4Test extends BaseR4Test { @BeforeEach public void before() { when(mySearchParamRetriever.getActiveSearchParam("Patient", "identifier")) - .thenReturn(new RuntimeSearchParam( - "identifier", "Description", "identifier", RestSearchParameterTypeEnum.STRING, - new HashSet<>(), new HashSet<>(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE - )); + .thenReturn(new RuntimeSearchParam(null, null, "identifier", "Description", "identifier", RestSearchParameterTypeEnum.STRING, new HashSet<>(), new HashSet<>(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE, false, null, null)); myMdmSettings = new MdmSettings(new MdmRuleValidator(ourFhirContext, mySearchParamRetriever)) { { diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml index 7a4d0e9dbfd..bdf8b874600 100644 --- a/hapi-fhir-server/pom.xml +++ b/hapi-fhir-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServerConfiguration.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServerConfiguration.java index c7bc35e1811..568e3624149 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServerConfiguration.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/RestfulServerConfiguration.java @@ -28,7 +28,7 @@ import ca.uhn.fhir.rest.server.method.BaseMethodBinding; import ca.uhn.fhir.rest.server.method.OperationMethodBinding; import ca.uhn.fhir.rest.server.method.SearchMethodBinding; import ca.uhn.fhir.rest.server.method.SearchParameter; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.util.VersionUtil; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; @@ -39,6 +39,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -55,7 +56,7 @@ import java.util.stream.Collectors; import static org.apache.commons.lang3.StringUtils.isBlank; -public class RestfulServerConfiguration implements ISearchParamRetriever { +public class RestfulServerConfiguration implements ISearchParamRegistry { private static final Logger ourLog = LoggerFactory.getLogger(RestfulServerConfiguration.class); private Collection resourceBindings; @@ -384,6 +385,12 @@ public class RestfulServerConfiguration implements ISearchParamRetriever { return retVal; } + @Nullable + @Override + public RuntimeSearchParam getActiveSearchParamByUrl(String theUrl) { + throw new UnsupportedOperationException(); + } + private void createRuntimeBinding(Map theMapToPopulate, SearchMethodBinding theSearchMethodBinding) { List parameters = theSearchMethodBinding @@ -425,12 +432,11 @@ public class RestfulServerConfiguration implements ISearchParamRetriever { String description = nextParamDescription; String path = null; RestSearchParameterTypeEnum type = nextParameter.getParamType(); - List compositeOf = Collections.emptyList(); Set providesMembershipInCompartments = Collections.emptySet(); Set targets = Collections.emptySet(); RuntimeSearchParam.RuntimeSearchParamStatusEnum status = RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE; Collection base = Collections.singletonList(theSearchMethodBinding.getResourceName()); - RuntimeSearchParam param = new RuntimeSearchParam(id, uri, nextParamName, description, path, type, compositeOf, providesMembershipInCompartments, targets, status, base); + RuntimeSearchParam param = new RuntimeSearchParam(id, uri, nextParamName, description, path, type, providesMembershipInCompartments, targets, status, false, null, base); theMapToPopulate.put(nextParamName, param); } diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/SearchPreferHandlingInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/SearchPreferHandlingInterceptor.java index cee31ba18a5..e9f0e2757e7 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/SearchPreferHandlingInterceptor.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/SearchPreferHandlingInterceptor.java @@ -35,7 +35,7 @@ import ca.uhn.fhir.rest.server.RestfulServerUtils; import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.method.SearchMethodBinding; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import org.apache.commons.lang3.Validate; import javax.annotation.Nonnull; @@ -57,7 +57,7 @@ public class SearchPreferHandlingInterceptor { @Nonnull private PreferHandlingEnum myDefaultBehaviour; @Nullable - private ISearchParamRetriever mySearchParamRetriever; + private ISearchParamRegistry mySearchParamRegistry; /** * Constructor that uses the {@link RestfulServer} itself to determine @@ -68,12 +68,12 @@ public class SearchPreferHandlingInterceptor { } /** - * Constructor that uses a dedicated {@link ISearchParamRetriever} instance. This is mainly + * Constructor that uses a dedicated {@link ISearchParamRegistry} instance. This is mainly * intended for the JPA server. */ - public SearchPreferHandlingInterceptor(ISearchParamRetriever theSearchParamRetriever) { + public SearchPreferHandlingInterceptor(ISearchParamRegistry theSearchParamRegistry) { this(); - mySearchParamRetriever = theSearchParamRetriever; + mySearchParamRegistry = theSearchParamRegistry; } @Hook(Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLER_SELECTED) @@ -105,7 +105,7 @@ public class SearchPreferHandlingInterceptor { private void removeUnwantedParams(PreferHandlingEnum theHandling, RequestDetails theRequestDetails) { - ISearchParamRetriever searchParamRetriever = mySearchParamRetriever; + ISearchParamRegistry searchParamRetriever = mySearchParamRegistry; if (searchParamRetriever == null) { searchParamRetriever = ((RestfulServer) theRequestDetails.getServer()).createConfiguration(); } diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ServerCapabilityStatementProvider.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ServerCapabilityStatementProvider.java index d64aa433ba6..59913098b86 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ServerCapabilityStatementProvider.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ServerCapabilityStatementProvider.java @@ -26,7 +26,7 @@ import ca.uhn.fhir.rest.server.method.OperationParameter; import ca.uhn.fhir.rest.server.method.SearchMethodBinding; import ca.uhn.fhir.rest.server.method.SearchParameter; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; -import ca.uhn.fhir.rest.server.util.ISearchParamRetriever; +import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.util.FhirTerser; import com.google.common.collect.TreeMultimap; import org.hl7.fhir.instance.model.api.IBase; @@ -86,7 +86,7 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv private static final Logger ourLog = LoggerFactory.getLogger(ServerCapabilityStatementProvider.class); private final FhirContext myContext; private final RestfulServer myServer; - private final ISearchParamRetriever mySearchParamRetriever; + private final ISearchParamRegistry mySearchParamRegistry; private final RestfulServerConfiguration myServerConfiguration; private final IValidationSupport myValidationSupport; private String myPublisher = "Not provided"; @@ -98,7 +98,7 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv public ServerCapabilityStatementProvider(RestfulServer theServer) { myServer = theServer; myContext = theServer.getFhirContext(); - mySearchParamRetriever = null; + mySearchParamRegistry = null; myServerConfiguration = null; myValidationSupport = null; } @@ -109,7 +109,7 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv public ServerCapabilityStatementProvider(FhirContext theContext, RestfulServerConfiguration theServerConfiguration) { myContext = theContext; myServerConfiguration = theServerConfiguration; - mySearchParamRetriever = null; + mySearchParamRegistry = null; myServer = null; myValidationSupport = null; } @@ -117,9 +117,9 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv /** * Constructor */ - public ServerCapabilityStatementProvider(RestfulServer theRestfulServer, ISearchParamRetriever theSearchParamRetriever, IValidationSupport theValidationSupport) { + public ServerCapabilityStatementProvider(RestfulServer theRestfulServer, ISearchParamRegistry theSearchParamRegistry, IValidationSupport theValidationSupport) { myContext = theRestfulServer.getFhirContext(); - mySearchParamRetriever = theSearchParamRetriever; + mySearchParamRegistry = theSearchParamRegistry; myServer = theRestfulServer; myServerConfiguration = null; myValidationSupport = theValidationSupport; @@ -349,16 +349,16 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv } - ISearchParamRetriever searchParamRetriever; - if (mySearchParamRetriever != null) { - searchParamRetriever = mySearchParamRetriever; + ISearchParamRegistry searchParamRegistry; + if (mySearchParamRegistry != null) { + searchParamRegistry = mySearchParamRegistry; } else if (myServerConfiguration != null) { - searchParamRetriever = myServerConfiguration; + searchParamRegistry = myServerConfiguration; } else { - searchParamRetriever = myServer.createConfiguration(); + searchParamRegistry = myServer.createConfiguration(); } - Map searchParams = searchParamRetriever.getActiveSearchParams(resourceName); + Map searchParams = searchParamRegistry.getActiveSearchParams(resourceName); for (RuntimeSearchParam next : searchParams.values()) { IBase searchParam = terser.addElement(resource, "searchParam"); terser.addElement(searchParam, "name", next.getName()); @@ -412,7 +412,7 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv continue; } - for (RuntimeSearchParam t : searchParamRetriever + for (RuntimeSearchParam t : searchParamRegistry .getActiveSearchParams(nextResourceName) .values()) { if (t.getParamType() == RestSearchParameterTypeEnum.REFERENCE) { diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRegistry.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRegistry.java new file mode 100644 index 00000000000..b78beffb187 --- /dev/null +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRegistry.java @@ -0,0 +1,106 @@ +package ca.uhn.fhir.rest.server.util; + +/* + * #%L + * HAPI FHIR - Server Framework + * %% + * Copyright (C) 2014 - 2021 Smile CDR, Inc. + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import ca.uhn.fhir.context.RuntimeSearchParam; +import ca.uhn.fhir.context.phonetic.IPhoneticEncoder; +import ca.uhn.fhir.rest.api.Constants; +import org.hl7.fhir.instance.model.api.IAnyResource; + +import javax.annotation.Nullable; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +// TODO: JA remove default methods +public interface ISearchParamRegistry { + + /** + * @return Returns {@literal null} if no match + */ + RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName); + + /** + * @return Returns all active search params for the given resource + */ + Map getActiveSearchParams(String theResourceName); + + /** + * Request that the cache be refreshed now, in the current thread + */ + default void forceRefresh() { + } + + ; + + /** + * Request that the cache be refreshed at the next convenient time (in a different thread) + */ + default void requestRefresh() { + } + + + /** + * When indexing a HumanName, if a StringEncoder is set in the context, then the "phonetic" search parameter will normalize + * the String using this encoder. + * + * @since 5.1.0 + */ + default void setPhoneticEncoder(IPhoneticEncoder thePhoneticEncoder) { + } + + default List getActiveUniqueSearchParams(String theResourceName) { + return Collections.emptyList(); + } + + default List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + return Collections.emptyList(); + } + + /** + * Returns a collection containing all of the valid active search parameters. This method is intended for + * creating error messages for users as opposed to actual search processing. It will include meta parameters + * such as _id and _lastUpdated. + */ + default Collection getValidSearchParameterNamesIncludingMeta(String theResourceName) { + TreeSet retval; + Map searchParamMap = getActiveSearchParams(theResourceName); + if (searchParamMap == null) { + retval = new TreeSet<>(); + } else { + retval = new TreeSet<>(searchParamMap.keySet()); + } + retval.add(IAnyResource.SP_RES_ID); + retval.add(Constants.PARAM_LASTUPDATED); + return retval; + } + + /** + * Fetch a SearchParameter by URL + * + * @return Returns null if it can't be found + */ + @Nullable + RuntimeSearchParam getActiveSearchParamByUrl(String theUrl); +} diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml index 6508b400cd3..6a615025f8d 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml index fa09b887655..cea3284ea07 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT hapi-fhir-spring-boot-sample-client-apache diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml index e7dd6a9b47e..729b752242d 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT hapi-fhir-spring-boot-sample-client-okhttp diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml index bf86d1e69ff..c70d6428ecc 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT hapi-fhir-spring-boot-sample-server-jersey diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml index e6ee6b3ee59..01709779112 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT hapi-fhir-spring-boot-samples diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml index 24c0ec50b3b..81895a5dc6c 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml index 494b6d67de4..5798cb0a6f5 100644 --- a/hapi-fhir-spring-boot/pom.xml +++ b/hapi-fhir-spring-boot/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml index aa71145412e..da1cff255bb 100644 --- a/hapi-fhir-structures-dstu2.1/pom.xml +++ b/hapi-fhir-structures-dstu2.1/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml index cefcd8081c8..108cf5a0825 100644 --- a/hapi-fhir-structures-dstu2/pom.xml +++ b/hapi-fhir-structures-dstu2/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml index cd346a7800f..f37268d1445 100644 --- a/hapi-fhir-structures-dstu3/pom.xml +++ b/hapi-fhir-structures-dstu3/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/context/FhirContextDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/context/FhirContextDstu3Test.java index 9c06874d648..ff8b4ce7cbf 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/context/FhirContextDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/context/FhirContextDstu3Test.java @@ -49,7 +49,7 @@ public class FhirContextDstu3Test { @Test public void testRuntimeSearchParamToString() { String val = ourCtx.getResourceDefinition("Patient").getSearchParam("gender").toString(); - assertEquals("RuntimeSearchParam[base=[Patient],name=gender,path=Patient.gender,id=,uri=]", val); + assertEquals("RuntimeSearchParam[base=[Patient],name=gender,path=Patient.gender,id=,uri=http://hl7.org/fhir/SearchParameter/patient-gender]", val); } @Test diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml index e324f4b62ba..cffad70ec0e 100644 --- a/hapi-fhir-structures-hl7org-dstu2/pom.xml +++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml index 213c886e3a7..fe444b0a1c9 100644 --- a/hapi-fhir-structures-r4/pom.xml +++ b/hapi-fhir-structures-r4/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/model/ModelR4Test.java b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/model/ModelR4Test.java index e1a590965ba..5ef973154bc 100644 --- a/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/model/ModelR4Test.java +++ b/hapi-fhir-structures-r4/src/test/java/org/hl7/fhir/r4/model/ModelR4Test.java @@ -1,13 +1,17 @@ package org.hl7.fhir.r4.model; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.RuntimeSearchParam; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; public class ModelR4Test { + private static final Logger ourLog = LoggerFactory.getLogger(ModelR4Test.class); private static FhirContext ourCtx = FhirContext.forR4(); @Test @@ -29,5 +33,11 @@ public class ModelR4Test { } } + @Test + public void testCompositeRuntimeSearchParamHasComponents() { + RuntimeSearchParam searchParam = ourCtx.getResourceDefinition("Observation").getSearchParam("code-value-concept"); + ourLog.info("Have params: {}", searchParam.getComponents().toString()); + assertEquals(2, searchParam.getComponents().size()); + } } diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml index ae5f6837afb..72fd8b4b0ab 100644 --- a/hapi-fhir-structures-r5/pom.xml +++ b/hapi-fhir-structures-r5/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml index fd25270a41e..bbb540c8ded 100644 --- a/hapi-fhir-test-utilities/pom.xml +++ b/hapi-fhir-test-utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml index e2b40e7befb..305b835d2d1 100644 --- a/hapi-fhir-testpage-overlay/pom.xml +++ b/hapi-fhir-testpage-overlay/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml index dcaff60c474..bef3d99f342 100644 --- a/hapi-fhir-validation-resources-dstu2.1/pom.xml +++ b/hapi-fhir-validation-resources-dstu2.1/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml index 6b836174ebb..0e98d4c8ead 100644 --- a/hapi-fhir-validation-resources-dstu2/pom.xml +++ b/hapi-fhir-validation-resources-dstu2/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml index a22a07377f5..77b38d6c862 100644 --- a/hapi-fhir-validation-resources-dstu3/pom.xml +++ b/hapi-fhir-validation-resources-dstu3/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml index 07b693a297e..222c7a6db50 100644 --- a/hapi-fhir-validation-resources-r4/pom.xml +++ b/hapi-fhir-validation-resources-r4/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r5/pom.xml b/hapi-fhir-validation-resources-r5/pom.xml index 04662967414..c3885abf4c3 100644 --- a/hapi-fhir-validation-resources-r5/pom.xml +++ b/hapi-fhir-validation-resources-r5/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml index dd8740147fa..1bbb77e484d 100644 --- a/hapi-fhir-validation/pom.xml +++ b/hapi-fhir-validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml index 0c7c2bdccf7..d21005fb478 100644 --- a/hapi-tinder-plugin/pom.xml +++ b/hapi-tinder-plugin/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml @@ -58,37 +58,37 @@ ca.uhn.hapi.fhir hapi-fhir-structures-dstu3 - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-structures-hl7org-dstu2 - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-structures-r4 - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-structures-r5 - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-validation-resources-dstu2 - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-validation-resources-dstu3 - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ca.uhn.hapi.fhir hapi-fhir-validation-resources-r4 - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT org.apache.velocity @@ -169,6 +169,7 @@ org.apache.maven maven-project + org.apache.maven maven-plugin-api - + org.apache.maven.plugin-tools maven-plugin-annotations provided - + diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderJpaRestServerMojo.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderJpaRestServerMojo.java index 82a90c6dd76..c5dedf7a164 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderJpaRestServerMojo.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderJpaRestServerMojo.java @@ -216,12 +216,14 @@ public class TinderJpaRestServerMojo extends AbstractMojo { TinderJpaRestServerMojo mojo = new TinderJpaRestServerMojo(); mojo.myProject = new MavenProject(); mojo.version = "dstu2"; - mojo.packageBase = "ca.uhn.test"; - mojo.configPackageBase = "ca.uhn.test"; + mojo.packageBase = "ca.uhn.fhir.jpa.rp.r4"; + mojo.configPackageBase = "ca.uhn.fhir.jpa.config"; mojo.baseResourceNames = new ArrayList(Arrays.asList( -// "observation" + "bundle", + "observation", // "communicationrequest" - "binary" + "binary", + "structuredefinition" )); mojo.targetDirectory = new File("target/generated/valuesets"); mojo.targetResourceDirectory = new File("target/generated/valuesets"); diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/model/SearchParameter.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/model/SearchParameter.java index 6c34a5a7813..fa651198092 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/model/SearchParameter.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/model/SearchParameter.java @@ -38,14 +38,14 @@ public class SearchParameter { public List getCompositeOf() { if (myCompositeOf == null) { - myCompositeOf = new ArrayList(); + myCompositeOf = new ArrayList<>(); } return myCompositeOf; } public List getCompositeTypes() { if (myCompositeTypes == null) { - myCompositeTypes = new ArrayList(); + myCompositeTypes = new ArrayList<>(); } return myCompositeTypes; } diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ResourceGeneratorUsingModel.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ResourceGeneratorUsingModel.java index 7ef2bb8a4a0..bef6ef51ba8 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ResourceGeneratorUsingModel.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ResourceGeneratorUsingModel.java @@ -2,7 +2,9 @@ package ca.uhn.fhir.tinder.parser; import java.io.File; import java.util.*; +import java.util.stream.Collectors; +import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import org.apache.commons.lang.WordUtils; import ca.uhn.fhir.context.RuntimeResourceDefinition; @@ -67,11 +69,20 @@ public class ResourceGeneratorUsingModel extends BaseStructureParser { for (RuntimeSearchParam nextSearchParam : def.getSearchParams()) { SearchParameter param = new SearchParameter(getVersion(), def.getName()); - + + List compositeOfParams = nextSearchParam + .getComponents() + .stream() + .map(t -> def.getSearchParams().stream().filter(y -> y.getUri().equals(t.getReference())).findFirst().orElseThrow(() -> new IllegalStateException())) + .collect(Collectors.toList()); + if (nextSearchParam.getParamType() == RestSearchParameterTypeEnum.COMPOSITE && compositeOfParams.size() != 2) { + throw new IllegalStateException("Search param " + nextSearchParam.getName() + " on base " + nextSearchParam.getBase() + " has components: " + nextSearchParam.getComponents()); + } + param.setName(nextSearchParam.getName()); param.setDescription(nextSearchParam.getDescription()); - param.setCompositeOf(toCompositeOfStrings(nextSearchParam.getCompositeOf())); - param.setCompositeTypes(toCompositeOfTypes(nextSearchParam.getCompositeOf())); + param.setCompositeOf(toCompositeOfStrings(compositeOfParams)); + param.setCompositeTypes(toCompositeOfTypes(compositeOfParams)); param.setPath(nextSearchParam.getPath()); param.setType(nextSearchParam.getParamType().getCode()); diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml index eede79deb82..9497e5e2aea 100644 --- a/hapi-tinder-test/pom.xml +++ b/hapi-tinder-test/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index feb240858a6..8dfad0cf1c8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir pom - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT HAPI-FHIR An open-source implementation of the FHIR specification in Java. https://hapifhir.io @@ -1267,12 +1267,12 @@ org.apache.maven maven-plugin-api - 3.5.0 + 3.6.3 org.apache.maven.plugin-tools maven-plugin-annotations - 3.5 + 3.6.0 org.apache.velocity diff --git a/restful-server-example/pom.xml b/restful-server-example/pom.xml index 1c31f387041..051b36516f5 100644 --- a/restful-server-example/pom.xml +++ b/restful-server-example/pom.xml @@ -8,7 +8,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../pom.xml diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml index 407594541ea..c6e0d2c9d18 100644 --- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml +++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../../pom.xml diff --git a/tests/hapi-fhir-base-test-mindeps-client/pom.xml b/tests/hapi-fhir-base-test-mindeps-client/pom.xml index ce2dcbb386f..b399e7eae87 100644 --- a/tests/hapi-fhir-base-test-mindeps-client/pom.xml +++ b/tests/hapi-fhir-base-test-mindeps-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../../pom.xml diff --git a/tests/hapi-fhir-base-test-mindeps-server/pom.xml b/tests/hapi-fhir-base-test-mindeps-server/pom.xml index bb683de985e..bb5a3413ee0 100644 --- a/tests/hapi-fhir-base-test-mindeps-server/pom.xml +++ b/tests/hapi-fhir-base-test-mindeps-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 5.4.0-PRE3-SNAPSHOT + 5.4.0-PRE4-SNAPSHOT ../../pom.xml