Avoid dead SearchParameter links in CapabilityStatement (#2790)

* Avoid dead SearchParameter links in CapabilityStatement

* Resolve fixmes

* Build fix

* Test fix

* Test fix

* Test fix

* Work on metadata

* Fixes

* Test fixes

* Test fix

* Test fix

* Test fixes

* Test fix

* Work on test fixes

* Test fixes

* Test fixes

* Test fixes

* Test fix

* Fix params

* Resolve fixme

* Adjust changelogs

* Version bump to 5.6.0-PRE7

* Add license header

* Bump version to 5.6.0-PRE5-SNAPSHOT
This commit is contained in:
James Agnew 2021-09-11 18:27:18 -04:00 committed by GitHub
parent a9dbf478ac
commit 5554431146
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
114 changed files with 49487 additions and 1160 deletions

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -73,7 +73,6 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
class ModelScanner { class ModelScanner {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ModelScanner.class);
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions = new HashMap<>(); private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myClassToElementDefinitions = new HashMap<>();
private FhirContext myContext; private FhirContext myContext;
private Map<String, RuntimeResourceDefinition> myIdToResourceDefinition = new HashMap<>(); private Map<String, RuntimeResourceDefinition> myIdToResourceDefinition = new HashMap<>();
@ -90,6 +89,7 @@ class ModelScanner {
@Nonnull Collection<Class<? extends IBase>> theResourceTypes) throws ConfigurationException { @Nonnull Collection<Class<? extends IBase>> theResourceTypes) throws ConfigurationException {
myContext = theContext; myContext = theContext;
myVersion = theVersion; myVersion = theVersion;
Set<Class<? extends IBase>> toScan = new HashSet<>(theResourceTypes); Set<Class<? extends IBase>> toScan = new HashSet<>(theResourceTypes);
init(theExistingDefinitions, toScan); init(theExistingDefinitions, toScan);
} }
@ -405,8 +405,8 @@ class ModelScanner {
List<RuntimeSearchParam.Component> components = null; List<RuntimeSearchParam.Component> components = null;
if (paramType == RestSearchParameterTypeEnum.COMPOSITE) { if (paramType == RestSearchParameterTypeEnum.COMPOSITE) {
components = new ArrayList<>(); components = new ArrayList<>();
for (String next : searchParam.compositeOf()) { for (String name : searchParam.compositeOf()) {
String ref = "http://hl7.org/fhir/SearchParameter/" + theResourceDef.getName().toLowerCase() + "-" + next; String ref = toCanonicalSearchParameterUri(theResourceDef, name);
components.add(new RuntimeSearchParam.Component(null, ref)); components.add(new RuntimeSearchParam.Component(null, ref));
} }
} }
@ -414,7 +414,8 @@ class ModelScanner {
Collection<String> base = Collections.singletonList(theResourceDef.getName()); Collection<String> base = Collections.singletonList(theResourceDef.getName());
String url = null; String url = null;
if (theResourceDef.isStandardType()) { if (theResourceDef.isStandardType()) {
url = "http://hl7.org/fhir/SearchParameter/" + theResourceDef.getName().toLowerCase() + "-" + searchParam.name(); String name = searchParam.name();
url = toCanonicalSearchParameterUri(theResourceDef, name);
} }
RuntimeSearchParam param = new RuntimeSearchParam(null, url, searchParam.name(), searchParam.description(), searchParam.path(), paramType, providesMembershipInCompartments, toTargetList(searchParam.target()), RuntimeSearchParamStatusEnum.ACTIVE, null, components, base); RuntimeSearchParam param = new RuntimeSearchParam(null, url, searchParam.name(), searchParam.description(), searchParam.path(), paramType, providesMembershipInCompartments, toTargetList(searchParam.target()), RuntimeSearchParamStatusEnum.ACTIVE, null, components, base);
theResourceDef.addSearchParam(param); theResourceDef.addSearchParam(param);
@ -424,6 +425,10 @@ class ModelScanner {
} }
private String toCanonicalSearchParameterUri(RuntimeResourceDefinition theResourceDef, String theName) {
return "http://hl7.org/fhir/SearchParameter/" + theResourceDef.getName() + "-" + theName;
}
private Set<String> toTargetList(Class<? extends IBaseResource>[] theTarget) { private Set<String> toTargetList(Class<? extends IBaseResource>[] theTarget) {
HashSet<String> retVal = new HashSet<>(); HashSet<String> retVal = new HashSet<>();

View File

@ -233,18 +233,7 @@ public class RuntimeSearchParam {
} }
public List<String> getPathsSplit() { public List<String> getPathsSplit() {
String path = getPath(); return getPathsSplitForResourceType(null);
if (path.indexOf('|') == -1) {
return Collections.singletonList(path);
}
List<String> retVal = new ArrayList<>();
StringTokenizer tok = new StringTokenizer(path, "|");
while (tok.hasMoreElements()) {
String nextPath = tok.nextToken().trim();
retVal.add(nextPath.trim());
}
return retVal;
} }
/** /**
@ -266,6 +255,41 @@ public class RuntimeSearchParam {
return myPhoneticEncoder.encode(theString); return myPhoneticEncoder.encode(theString);
} }
public List<String> getPathsSplitForResourceType(@Nullable String theResourceName) {
String path = getPath();
if (path.indexOf('|') == -1) {
if (theResourceName != null && !pathMatchesResourceType(theResourceName, path)) {
return Collections.emptyList();
}
return Collections.singletonList(path);
}
List<String> retVal = new ArrayList<>();
StringTokenizer tok = new StringTokenizer(path, "|");
while (tok.hasMoreElements()) {
String nextPath = tok.nextToken().trim();
if (theResourceName != null && !pathMatchesResourceType(theResourceName, nextPath)) {
continue;
}
retVal.add(nextPath.trim());
}
return retVal;
}
private boolean pathMatchesResourceType(String theResourceName, String thePath) {
if (thePath.startsWith(theResourceName + ".")) {
return true;
}
if (thePath.startsWith("Resouce.") || thePath.startsWith("DomainResource.")) {
return true;
}
if (Character.isLowerCase(thePath.charAt(0))) {
return true;
}
return false;
}
public enum RuntimeSearchParamStatusEnum { public enum RuntimeSearchParamStatusEnum {
ACTIVE, ACTIVE,
DRAFT, DRAFT,

View File

@ -28,13 +28,6 @@ import ca.uhn.fhir.rest.gclient.TokenClientParam;
*/ */
public interface IAnyResource extends IBaseResource { public interface IAnyResource extends IBaseResource {
/**
* Search parameter constant for <b>_language</b>
*/
@SearchParamDefinition(name="_language", path="", description="The language of the resource", type="string" )
String SP_RES_LANGUAGE = "_language";
/** /**
* Search parameter constant for <b>_id</b> * Search parameter constant for <b>_id</b>
*/ */

View File

@ -3,14 +3,14 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-bom</artifactId> <artifactId>hapi-fhir-bom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>HAPI FHIR BOM</name> <name>HAPI FHIR BOM</name>
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-cli</artifactId> <artifactId>hapi-fhir-cli</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom</relativePath> <relativePath>../../hapi-deployable-pom</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 2790
title: "The SearchParameter canonical URLs exported by the JPA server have been adjusted to match the URLs
specified in the FHIR specification."

View File

@ -0,0 +1,7 @@
---
type: change
issue: 2790
title: "Support for the `_language` search parameter has been dropped from the JPA server. This search parameter
was specified in FHIR DSTU1 but was dropped in later versions. It is rarely used in practice and imposes
an indexing cost, so it has now been removed. A custom search parameter may be used in order to achieve
the same functionality if needed."

View File

@ -11,7 +11,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -1228,12 +1228,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
} }
entity.setUpdated(theTransactionDetails.getTransactionDate()); entity.setUpdated(theTransactionDetails.getTransactionDate());
if (theResource instanceof IResource) {
entity.setLanguage(((IResource) theResource).getLanguage().getValue());
} else {
entity.setLanguage(((IAnyResource) theResource).getLanguageElement().getValue());
}
newParams.populateResourceTableSearchParamsPresentFlags(entity); newParams.populateResourceTableSearchParamsPresentFlags(entity);
entity.setIndexStatus(INDEX_STATUS_INDEXED); entity.setIndexStatus(INDEX_STATUS_INDEXED);
} }

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.dao; package ca.uhn.fhir.jpa.dao;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* 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 org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
/** /**

View File

@ -559,11 +559,6 @@ class PredicateBuilderReference extends BasePredicateBuilder {
myPredicateBuilder.addPredicateResourceId(theAndOrParams, theResourceName, theRequestPartitionId); myPredicateBuilder.addPredicateResourceId(theAndOrParams, theResourceName, theRequestPartitionId);
break; break;
case IAnyResource.SP_RES_LANGUAGE:
addPredicateLanguage(theAndOrParams,
null);
break;
case Constants.PARAM_HAS: case Constants.PARAM_HAS:
addPredicateHas(theResourceName, theAndOrParams, theRequest, theRequestPartitionId); addPredicateHas(theResourceName, theAndOrParams, theRequest, theRequestPartitionId);
break; break;
@ -733,9 +728,6 @@ class PredicateBuilderReference extends BasePredicateBuilder {
null, null,
theFilter.getValue()); theFilter.getValue());
return myPredicateBuilder.addPredicateResourceId(Collections.singletonList(Collections.singletonList(param)), myResourceName, theFilter.getOperation(), theRequestPartitionId); return myPredicateBuilder.addPredicateResourceId(Collections.singletonList(Collections.singletonList(param)), myResourceName, theFilter.getOperation(), theRequestPartitionId);
} else if (theFilter.getParamPath().getName().equals(IAnyResource.SP_RES_LANGUAGE)) {
return addPredicateLanguage(Collections.singletonList(Collections.singletonList(new StringParam(theFilter.getValue()))),
theFilter.getOperation());
} }
RuntimeSearchParam searchParam = mySearchParamRegistry.getActiveSearchParam(theResourceName, theFilter.getParamPath().getName()); RuntimeSearchParam searchParam = mySearchParamRegistry.getActiveSearchParam(theResourceName, theFilter.getParamPath().getName());
@ -828,45 +820,6 @@ class PredicateBuilderReference extends BasePredicateBuilder {
return qp; return qp;
} }
private Predicate addPredicateLanguage(List<List<IQueryParameterType>> theList,
SearchFilterParser.CompareOperation operation) {
for (List<? extends IQueryParameterType> nextList : theList) {
Set<String> values = new HashSet<>();
for (IQueryParameterType next : nextList) {
if (next instanceof StringParam) {
String nextValue = ((StringParam) next).getValue();
if (isBlank(nextValue)) {
continue;
}
values.add(nextValue);
} else {
throw new InternalErrorException("Language parameter must be of type " + StringParam.class.getCanonicalName() + " - Got " + next.getClass().getCanonicalName());
}
}
if (values.isEmpty()) {
continue;
}
Predicate predicate;
if ((operation == null) ||
(operation == SearchFilterParser.CompareOperation.eq)) {
predicate = myQueryStack.get("myLanguage").as(String.class).in(values);
} else if (operation == SearchFilterParser.CompareOperation.ne) {
predicate = myQueryStack.get("myLanguage").as(String.class).in(values).not();
} else {
throw new InvalidRequestException("Unsupported operator specified in language query, only \"eq\" and \"ne\" are supported");
}
myQueryStack.addPredicate(predicate);
if (operation != null) {
return predicate;
}
}
return null;
}
private void addPredicateSource(List<List<IQueryParameterType>> theAndOrParams, RequestDetails theRequest) { private void addPredicateSource(List<List<IQueryParameterType>> theAndOrParams, RequestDetails theRequest) {
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) { for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateSource(nextAnd, SearchFilterParser.CompareOperation.eq, theRequest); addPredicateSource(nextAnd, SearchFilterParser.CompareOperation.eq, theRequest);

View File

@ -261,6 +261,9 @@ class PredicateBuilderToken extends BasePredicateBuilder implements IPredicateBu
if (theSearchParam != null) { if (theSearchParam != null) {
Set<String> valueSetUris = Sets.newHashSet(); Set<String> valueSetUris = Sets.newHashSet();
for (String nextPath : theSearchParam.getPathsSplit()) { for (String nextPath : theSearchParam.getPathsSplit()) {
if (!nextPath.startsWith(myResourceType + ".")) {
continue;
}
BaseRuntimeChildDefinition def = myContext.newTerser().getDefinition(myResourceType, nextPath); BaseRuntimeChildDefinition def = myContext.newTerser().getDefinition(myResourceType, nextPath);
if (def instanceof BaseRuntimeDeclaredChildDefinition) { if (def instanceof BaseRuntimeDeclaredChildDefinition) {
String valueSet = ((BaseRuntimeDeclaredChildDefinition) def).getBindingValueSet(); String valueSet = ((BaseRuntimeDeclaredChildDefinition) def).getBindingValueSet();

View File

@ -92,8 +92,12 @@ public class FhirResourceDaoSearchParameterR4 extends BaseHapiFhirResourceDao<Se
for (IPrimitiveType<?> nextBaseType : theResource.getBase()) { for (IPrimitiveType<?> nextBaseType : theResource.getBase()) {
String nextBase = nextBaseType.getValueAsString(); String nextBase = nextBaseType.getValueAsString();
RuntimeSearchParam existingSearchParam = theSearchParamRegistry.getActiveSearchParam(nextBase, theResource.getCode()); RuntimeSearchParam existingSearchParam = theSearchParamRegistry.getActiveSearchParam(nextBase, theResource.getCode());
if (existingSearchParam != null && existingSearchParam.getId() == null) { if (existingSearchParam != null) {
throw new UnprocessableEntityException("Can not override built-in search parameter " + nextBase + ":" + theResource.getCode() + " because overriding is disabled on this server"); boolean isBuiltIn = existingSearchParam.getId() == null;
isBuiltIn |= existingSearchParam.getUri().startsWith("http://hl7.org/fhir/SearchParameter/");
if (isBuiltIn) {
throw new UnprocessableEntityException("Can not override built-in search parameter " + nextBase + ":" + theResource.getCode() + " because overriding is disabled on this server");
}
} }
} }
} }

View File

@ -434,9 +434,6 @@ public class QueryStack {
param.setValueAsQueryToken(null, null, null, theFilter.getValue()); param.setValueAsQueryToken(null, null, null, theFilter.getValue());
return theQueryStack3.createPredicateResourceId(null, Collections.singletonList(Collections.singletonList(param)), theResourceName, theFilter.getOperation(), theRequestPartitionId); 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: { case Constants.PARAM_SOURCE: {
TokenParam param = new TokenParam(); TokenParam param = new TokenParam();
param.setValueAsQueryToken(null, null, null, theFilter.getValue()); param.setValueAsQueryToken(null, null, null, theFilter.getValue());
@ -579,44 +576,6 @@ public class QueryStack {
return toAndPredicate(andPredicates); return toAndPredicate(andPredicates);
} }
public Condition createPredicateLanguage(List<List<IQueryParameterType>> theList, Object theOperation) {
ResourceTablePredicateBuilder rootTable = mySqlBuilder.getOrCreateResourceTablePredicateBuilder();
List<Condition> predicates = new ArrayList<>();
for (List<? extends IQueryParameterType> nextList : theList) {
Set<String> values = new HashSet<>();
for (IQueryParameterType next : nextList) {
if (next instanceof StringParam) {
String nextValue = ((StringParam) next).getValue();
if (isBlank(nextValue)) {
continue;
}
values.add(nextValue);
} else {
throw new InternalErrorException("Language parameter must be of type " + StringParam.class.getCanonicalName() + " - Got " + next.getClass().getCanonicalName());
}
}
if (values.isEmpty()) {
continue;
}
if ((theOperation == null) ||
(theOperation == SearchFilterParser.CompareOperation.eq)) {
predicates.add(rootTable.createLanguagePredicate(values, false));
} else if (theOperation == SearchFilterParser.CompareOperation.ne) {
predicates.add(rootTable.createLanguagePredicate(values, true));
} else {
throw new InvalidRequestException("Unsupported operator specified in language query, only \"eq\" and \"ne\" are supported");
}
}
return toAndPredicate(predicates);
}
public Condition createPredicateNumber(@Nullable DbColumn theSourceJoinColumn, String theResourceName, public Condition createPredicateNumber(@Nullable DbColumn theSourceJoinColumn, String theResourceName,
String theSpnamePrefix, RuntimeSearchParam theSearchParam, List<? extends IQueryParameterType> theList, String theSpnamePrefix, RuntimeSearchParam theSearchParam, List<? extends IQueryParameterType> theList,
SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) { SearchFilterParser.CompareOperation theOperation, RequestPartitionId theRequestPartitionId) {
@ -1099,9 +1058,6 @@ public class QueryStack {
case IAnyResource.SP_RES_ID: case IAnyResource.SP_RES_ID:
return createPredicateResourceId(theSourceJoinColumn, theAndOrParams, theResourceName, null, theRequestPartitionId); return createPredicateResourceId(theSourceJoinColumn, theAndOrParams, theResourceName, null, theRequestPartitionId);
case IAnyResource.SP_RES_LANGUAGE:
return createPredicateLanguage(theAndOrParams, null);
case Constants.PARAM_HAS: case Constants.PARAM_HAS:
return createPredicateHas(theSourceJoinColumn, theResourceName, theAndOrParams, theRequest, theRequestPartitionId); return createPredicateHas(theSourceJoinColumn, theResourceName, theAndOrParams, theRequest, theRequestPartitionId);

View File

@ -222,7 +222,7 @@ public class TokenPredicateBuilder extends BaseSearchParamPredicateBuilder {
if (retVal == null) { if (retVal == null) {
if (theSearchParam != null) { if (theSearchParam != null) {
Set<String> valueSetUris = Sets.newHashSet(); Set<String> valueSetUris = Sets.newHashSet();
for (String nextPath : theSearchParam.getPathsSplit()) { for (String nextPath : theSearchParam.getPathsSplitForResourceType(getResourceType())) {
Class<? extends IBaseResource> type = getFhirContext().getResourceDefinition(getResourceType()).getImplementingClass(); Class<? extends IBaseResource> type = getFhirContext().getResourceDefinition(getResourceType()).getImplementingClass();
BaseRuntimeChildDefinition def = getFhirContext().newTerser().getDefinition(type, nextPath); BaseRuntimeChildDefinition def = getFhirContext().newTerser().getDefinition(type, nextPath);
if (def instanceof BaseRuntimeDeclaredChildDefinition) { if (def instanceof BaseRuntimeDeclaredChildDefinition) {

View File

@ -1033,7 +1033,7 @@ public class FhirResourceDaoDstu2SearchCustomSearchParamTest extends BaseJpaDstu
myPatientDao.search(map).size(); myPatientDao.search(map).size();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, careprovider, deathdate, deceased, email, family, gender, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, careprovider, deathdate, deceased, email, family, gender, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
} }
@ -1070,7 +1070,7 @@ public class FhirResourceDaoDstu2SearchCustomSearchParamTest extends BaseJpaDstu
myPatientDao.search(map).size(); myPatientDao.search(map).size();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, careprovider, deathdate, deceased, email, family, gender, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, careprovider, deathdate, deceased, email, family, gender, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
// Try with normal gender SP // Try with normal gender SP

View File

@ -727,9 +727,6 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
params.add("_id", new StringDt("TEST")); params.add("_id", new StringDt("TEST"));
assertEquals(1, toList(myPatientDao.search(params)).size()); assertEquals(1, toList(myPatientDao.search(params)).size());
params.add("_language", new StringParam("TEST"));
assertEquals(1, toList(myPatientDao.search(params)).size());
params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST")); params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
assertEquals(1, toList(myPatientDao.search(params)).size()); assertEquals(1, toList(myPatientDao.search(params)).size());
@ -744,9 +741,6 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
params.add("_id", new StringDt("TEST")); params.add("_id", new StringDt("TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size()); assertEquals(0, toList(myPatientDao.search(params)).size());
params.add("_language", new StringParam("TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size());
params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST")); params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size()); assertEquals(0, toList(myPatientDao.search(params)).size());
@ -766,148 +760,6 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
} }
} }
@Test
public void testSearchLanguageParam() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguage().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient, mySrd).getId();
}
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguage().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().addFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient, mySrd).getId();
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(BaseResource.SP_RES_LANGUAGE, new StringParam("en_CA"));
List<IResource> patients = toList(myPatientDao.search(params));
assertEquals(1, patients.size());
assertEquals(id1.toUnqualifiedVersionless(), patients.get(0).getId().toUnqualifiedVersionless());
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(BaseResource.SP_RES_LANGUAGE, new StringParam("en_US"));
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(1, patients.size());
assertEquals(id2.toUnqualifiedVersionless(), patients.get(0).getId().toUnqualifiedVersionless());
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(BaseResource.SP_RES_LANGUAGE, new StringParam("en_GB"));
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(0, patients.size());
}
}
@Test
public void testSearchLanguageParamAndOr() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguage().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
Date betweenTime = new Date();
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguage().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().addFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(BaseResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(BaseResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
params.setLastUpdated(new DateRangeParam(betweenTime, null));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(BaseResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")));
params.add(BaseResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
params.add(BaseResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
params.add(BaseResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(BaseResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("_id", new StringParam(id1.getIdPart()));
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(BaseResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(BaseResource.SP_RES_LANGUAGE, and);
params.add("_id", new StringParam(id1.getIdPart()));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
}
@Test @Test
public void testSearchLastUpdatedParam() throws InterruptedException { public void testSearchLastUpdatedParam() throws InterruptedException {
String methodName = "testSearchLastUpdatedParam"; String methodName = "testSearchLastUpdatedParam";

View File

@ -224,7 +224,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
} }
@Test @Test
public void testCantSearchForDeletedResourceByLanguageOrTag() { public void testCantSearchForDeletedResourceByTag() {
String methodName = "testCantSearchForDeletedResourceByLanguageOrTag"; String methodName = "testCantSearchForDeletedResourceByLanguageOrTag";
Organization org = new Organization(); Organization org = new Organization();
org.setLanguage(new CodeDt("EN_ca")); org.setLanguage(new CodeDt("EN_ca"));
@ -236,9 +236,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
SearchParameterMap map = new SearchParameterMap(); SearchParameterMap map;
map.add("_language", new StringParam("EN_ca"));
assertEquals(1, myOrganizationDao.search(map).size().intValue());
map = new SearchParameterMap(); map = new SearchParameterMap();
map.add("_tag", new TokenParam(methodName, methodName)); map.add("_tag", new TokenParam(methodName, methodName));
@ -246,10 +244,6 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
myOrganizationDao.delete(orgId, mySrd); myOrganizationDao.delete(orgId, mySrd);
map = new SearchParameterMap();
map.add("_language", new StringParam("EN_ca"));
assertEquals(0, myOrganizationDao.search(map).size().intValue());
map = new SearchParameterMap(); map = new SearchParameterMap();
map.add("_tag", new TokenParam(methodName, methodName)); map.add("_tag", new TokenParam(methodName, methodName));
assertEquals(0, myOrganizationDao.search(map).size().intValue()); assertEquals(0, myOrganizationDao.search(map).size().intValue());
@ -1603,7 +1597,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
found = toList(myPatientDao.search(new SearchParameterMap().setLoadSynchronous(true).add(Patient.SP_BIRTHDATE + "AAAA", new DateParam(ParamPrefixEnum.GREATERTHAN, "2000-01-01")))); found = toList(myPatientDao.search(new SearchParameterMap().setLoadSynchronous(true).add(Patient.SP_BIRTHDATE + "AAAA", new DateParam(ParamPrefixEnum.GREATERTHAN, "2000-01-01"))));
assertEquals(0, found.size()); assertEquals(0, found.size());
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"birthdateAAAA\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, careprovider, deathdate, deceased, email, family, gender, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"birthdateAAAA\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, careprovider, deathdate, deceased, email, family, gender, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
} }

View File

@ -1015,7 +1015,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
myPatientDao.search(map).size(); myPatientDao.search(map).size();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
} }
@ -1053,7 +1053,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
myPatientDao.search(map).size(); myPatientDao.search(map).size();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
// Try with normal gender SP // Try with normal gender SP

View File

@ -1192,11 +1192,6 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
params.add("_id", new StringParam("TEST")); params.add("_id", new StringParam("TEST"));
assertEquals(1, toList(myPatientDao.search(params)).size()); assertEquals(1, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("_language", new StringParam("TEST"));
assertEquals(1, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap(); params = new SearchParameterMap();
params.setLoadSynchronous(true); params.setLoadSynchronous(true);
params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST")); params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
@ -1214,11 +1209,6 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
params.add("_id", new StringParam("TEST")); params.add("_id", new StringParam("TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size()); assertEquals(0, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("_language", new StringParam("TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap(); params = new SearchParameterMap();
params.setLoadSynchronous(true); params.setLoadSynchronous(true);
params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST")); params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
@ -1241,143 +1231,6 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
} }
} }
@Test
public void testSearchLanguageParam() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient, mySrd).getId();
}
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().setFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient, mySrd).getId();
}
SearchParameterMap params;
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_CA"));
List<IBaseResource> patients = toList(myPatientDao.search(params));
assertEquals(1, patients.size());
assertEquals(id1.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
}
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_US"));
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(1, patients.size());
assertEquals(id2.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
}
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_GB"));
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(0, patients.size());
}
}
@Test
public void testSearchLanguageParamAndOr() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
TestUtil.sleepOneClick();
Date betweenTime = new Date();
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().setFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
params.setLastUpdated(new DateRangeParam(betweenTime, null));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add("_id", new StringParam(id1.getIdPart()));
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
params.add("_id", new StringParam(id1.getIdPart()));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
}
@Test @Test
public void testSearchLastUpdatedParam() { public void testSearchLastUpdatedParam() {
String methodName = "testSearchLastUpdatedParam"; String methodName = "testSearchLastUpdatedParam";

View File

@ -206,21 +206,12 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
SearchParameterMap map = new SearchParameterMap(); SearchParameterMap map = new SearchParameterMap();
map.add("_language", new StringParam("EN_ca"));
assertEquals(1, myOrganizationDao.search(map).size().intValue());
map = new SearchParameterMap();
map.setLoadSynchronous(true); map.setLoadSynchronous(true);
map.add("_tag", new TokenParam(methodName, methodName)); map.add("_tag", new TokenParam(methodName, methodName));
assertEquals(1, myOrganizationDao.search(map).size().intValue()); assertEquals(1, myOrganizationDao.search(map).size().intValue());
myOrganizationDao.delete(orgId, mySrd); myOrganizationDao.delete(orgId, mySrd);
map = new SearchParameterMap();
map.setLoadSynchronous(true);
map.add("_language", new StringParam("EN_ca"));
assertEquals(0, myOrganizationDao.search(map).size().intValue());
map = new SearchParameterMap(); map = new SearchParameterMap();
map.setLoadSynchronous(true); map.setLoadSynchronous(true);
map.add("_tag", new TokenParam(methodName, methodName)); map.add("_tag", new TokenParam(methodName, methodName));
@ -2014,7 +2005,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_BIRTHDATE + "AAAA", new DateParam(ParamPrefixEnum.GREATERTHAN, "2000-01-01")).setLoadSynchronous(true))); found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_BIRTHDATE + "AAAA", new DateParam(ParamPrefixEnum.GREATERTHAN, "2000-01-01")).setLoadSynchronous(true)));
assertEquals(0, found.size()); assertEquals(0, found.size());
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"birthdateAAAA\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"birthdateAAAA\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
} }

View File

@ -5,6 +5,7 @@ import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel; import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized;
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil; import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
@ -28,6 +29,7 @@ import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Organization;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Quantity; import org.hl7.fhir.r4.model.Quantity;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.SampledData; import org.hl7.fhir.r4.model.SampledData;
import org.hl7.fhir.r4.model.SearchParameter; import org.hl7.fhir.r4.model.SearchParameter;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
@ -63,6 +65,30 @@ public class FhirResourceDaoR4CreateTest extends BaseJpaR4Test {
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED); myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
} }
@Test
public void testCreateLinkCreatesAppropriatePaths() {
Patient p = new Patient();
p.setId("Patient/A");
p.setActive(true);
myPatientDao.update(p, mySrd);
Observation obs = new Observation();
obs.setSubject(new Reference("Patient/A"));
myObservationDao.create(obs, mySrd);
runInTransaction(() ->{
List<ResourceLink> allLinks = myResourceLinkDao.findAll();
List<String> paths = allLinks
.stream()
.map(t -> t.getSourcePath())
.sorted()
.collect(Collectors.toList());
assertThat(paths.toString(), paths, contains("Observation.subject", "Observation.subject.where(resolve() is Patient)"));
});
}
@Test @Test
public void testConditionalCreateWithPlusInUrl() { public void testConditionalCreateWithPlusInUrl() {
Observation obs = new Observation(); Observation obs = new Observation();

View File

@ -349,28 +349,6 @@ public class FhirResourceDaoR4FilterLegacySearchBuilderTest extends BaseJpaR4Tes
} }
@Test
public void testLanguageComparatorEq() {
Patient p = new Patient();
p.setLanguage("en");
p.addName().setFamily("Smith").addGiven("John");
p.setBirthDateElement(new DateType("1955-01-01"));
p.setActive(true);
String id1 = myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap map;
List<String> found;
map = new SearchParameterMap();
map.setLoadSynchronous(true);
map.add(Constants.PARAM_FILTER, new StringParam("_language eq en"));
found = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
assertThat(found, containsInAnyOrder(id1));
}
@Test @Test
public void testStringComparatorCo() { public void testStringComparatorCo() {

View File

@ -347,28 +347,6 @@ public class FhirResourceDaoR4FilterTest extends BaseJpaR4Test {
} }
@Test
public void testLanguageComparatorEq() {
Patient p = new Patient();
p.setLanguage("en");
p.addName().setFamily("Smith").addGiven("John");
p.setBirthDateElement(new DateType("1955-01-01"));
p.setActive(true);
String id1 = myPatientDao.create(p).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap map;
List<String> found;
map = new SearchParameterMap();
map.setLoadSynchronous(true);
map.add(Constants.PARAM_FILTER, new StringParam("_language eq en"));
found = toUnqualifiedVersionlessIdValues(myPatientDao.search(map));
assertThat(found, containsInAnyOrder(id1));
}
@Test @Test
public void testStringComparatorCo() { public void testStringComparatorCo() {
@ -1254,7 +1232,7 @@ public class FhirResourceDaoR4FilterTest extends BaseJpaR4Test {
try { try {
myPatientDao.search(map); myPatientDao.search(map);
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
} }

View File

@ -2369,14 +2369,6 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test {
params.add("_id", new StringParam("TEST")); params.add("_id", new StringParam("TEST"));
assertEquals(1, toList(myPatientDao.search(params)).size()); assertEquals(1, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("_language", new StringParam("TEST"));
myCaptureQueriesListener.clear();
result = toList(myPatientDao.search(params));
myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
assertEquals(1, result.size());
params = new SearchParameterMap(); params = new SearchParameterMap();
params.setLoadSynchronous(true); params.setLoadSynchronous(true);
params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST")); params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
@ -2394,11 +2386,6 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test {
params.add("_id", new StringParam("TEST")); params.add("_id", new StringParam("TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size()); assertEquals(0, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("_language", new StringParam("TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap(); params = new SearchParameterMap();
params.setLoadSynchronous(true); params.setLoadSynchronous(true);
params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST")); params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
@ -2421,149 +2408,6 @@ public class FhirResourceDaoR4LegacySearchBuilderTest extends BaseJpaR4Test {
} }
} }
@Test
public void testSearchLanguageParam() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient, mySrd).getId();
}
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().setFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient, mySrd).getId();
}
SearchParameterMap params;
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_CA"));
myCaptureQueriesListener.clear();
List<IBaseResource> patients = toList(myPatientDao.search(params));
myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
assertEquals(1, patients.size());
assertEquals(id1.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
}
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_US"));
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(1, patients.size());
assertEquals(id2.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
}
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_GB"));
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(0, patients.size());
}
}
@Test
public void testSearchLanguageParamAndOr() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
TestUtil.sleepOneClick();
Date betweenTime = new Date();
TestUtil.sleepOneClick();
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().setFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
params.setLastUpdated(new DateRangeParam(betweenTime, null));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add("_id", new StringParam(id1.getIdPart()));
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
params.add("_id", new StringParam(id1.getIdPart()));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
}
@Test @Test
public void testSearchLastUpdatedParam() { public void testSearchLastUpdatedParam() {
String methodName = "testSearchLastUpdatedParam"; String methodName = "testSearchLastUpdatedParam";

View File

@ -1512,7 +1512,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
myPatientDao.search(map).size(); myPatientDao.search(map).size();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
// Delete the param // Delete the param
@ -1528,7 +1528,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
myPatientDao.search(map).size(); myPatientDao.search(map).size();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
} }
@ -1605,7 +1605,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
myPatientDao.search(map).size(); myPatientDao.search(map).size();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
// Try with normal gender SP // Try with normal gender SP

View File

@ -2464,14 +2464,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
params.add("_id", new StringParam("TEST")); params.add("_id", new StringParam("TEST"));
assertEquals(1, toList(myPatientDao.search(params)).size()); assertEquals(1, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("_language", new StringParam("TEST"));
myCaptureQueriesListener.clear();
result = toList(myPatientDao.search(params));
myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
assertEquals(1, result.size());
params = new SearchParameterMap(); params = new SearchParameterMap();
params.setLoadSynchronous(true); params.setLoadSynchronous(true);
params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST")); params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
@ -2489,11 +2481,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
params.add("_id", new StringParam("TEST")); params.add("_id", new StringParam("TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size()); assertEquals(0, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("_language", new StringParam("TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap(); params = new SearchParameterMap();
params.setLoadSynchronous(true); params.setLoadSynchronous(true);
params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST")); params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
@ -2516,148 +2503,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
} }
} }
@Test
public void testSearchLanguageParam() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient, mySrd).getId();
}
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().setFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient, mySrd).getId();
}
SearchParameterMap params;
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_CA"));
myCaptureQueriesListener.clear();
List<IBaseResource> patients = toList(myPatientDao.search(params));
myCaptureQueriesListener.logSelectQueriesForCurrentThread(0);
assertEquals(1, patients.size());
assertEquals(id1.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
}
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_US"));
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(1, patients.size());
assertEquals(id2.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
}
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_GB"));
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(0, patients.size());
}
}
@Test
public void testSearchLanguageParamAndOr() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
TestUtil.sleepOneClick();
Date betweenTime = new Date();
TestUtil.sleepOneClick();
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().setFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
params.setLastUpdated(new DateRangeParam(betweenTime, null));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add("_id", new StringParam(id1.getIdPart()));
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
params.add("_id", new StringParam(id1.getIdPart()));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
}
@Test @Test
public void testSearchLastUpdatedParam() { public void testSearchLastUpdatedParam() {

View File

@ -12,6 +12,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri;
import ca.uhn.fhir.jpa.model.entity.ResourceLink; import ca.uhn.fhir.jpa.model.entity.ResourceLink;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.jpa.util.TestUtil;
@ -43,8 +44,6 @@ import ca.uhn.fhir.rest.param.UriParam;
import ca.uhn.fhir.rest.param.UriParamQualifierEnum; import ca.uhn.fhir.rest.param.UriParamQualifierEnum;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
@ -144,8 +143,8 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
myDaoConfig.setFetchSizeDefaultMaximum(new DaoConfig().getFetchSizeDefaultMaximum()); myDaoConfig.setFetchSizeDefaultMaximum(new DaoConfig().getFetchSizeDefaultMaximum());
myDaoConfig.setAllowContainsSearches(new DaoConfig().isAllowContainsSearches()); myDaoConfig.setAllowContainsSearches(new DaoConfig().isAllowContainsSearches());
myDaoConfig.setDisableHashBasedSearches(false); myDaoConfig.setDisableHashBasedSearches(false);
myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED); myModelConfig.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED);
} }
@BeforeEach @BeforeEach
public void beforeInitialize() { public void beforeInitialize() {
@ -1201,8 +1200,8 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
.setCode(new CodeableConcept().addCoding(new Coding().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm"))) .setCode(new CodeableConcept().addCoding(new Coding().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm")))
.setValue(new Quantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm").setValue(1.2)); .setValue(new Quantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm").setValue(1.2));
o1.addComponent() o1.addComponent()
.setCode(new CodeableConcept().addCoding(new Coding().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("m"))) .setCode(new CodeableConcept().addCoding(new Coding().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("m")))
.setValue(new Quantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("mm").setValue(2)); .setValue(new Quantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("mm").setValue(2));
IIdType id1 = myObservationDao.create(o1, mySrd).getId().toUnqualifiedVersionless(); IIdType id1 = myObservationDao.create(o1, mySrd).getId().toUnqualifiedVersionless();
String param = Observation.SP_COMPONENT_VALUE_QUANTITY; String param = Observation.SP_COMPONENT_VALUE_QUANTITY;
@ -1214,7 +1213,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
assertThat("Got: " + toUnqualifiedVersionlessIdValues(result), toUnqualifiedVersionlessIdValues(result), containsInAnyOrder(id1.getValue())); assertThat("Got: " + toUnqualifiedVersionlessIdValues(result), toUnqualifiedVersionlessIdValues(result), containsInAnyOrder(id1.getValue()));
} }
} }
@Test @Test
public void testComponentQuantityWithNormalizedQuantityStorageSupported() { public void testComponentQuantityWithNormalizedQuantityStorageSupported() {
@ -1224,8 +1223,8 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
.setCode(new CodeableConcept().addCoding(new Coding().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm"))) .setCode(new CodeableConcept().addCoding(new Coding().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm")))
.setValue(new Quantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm").setValue(1.2)); .setValue(new Quantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm").setValue(1.2));
o1.addComponent() o1.addComponent()
.setCode(new CodeableConcept().addCoding(new Coding().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("m"))) .setCode(new CodeableConcept().addCoding(new Coding().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("m")))
.setValue(new Quantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("mm").setValue(2)); .setValue(new Quantity().setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("mm").setValue(2));
IIdType id1 = myObservationDao.create(o1, mySrd).getId().toUnqualifiedVersionless(); IIdType id1 = myObservationDao.create(o1, mySrd).getId().toUnqualifiedVersionless();
String param = Observation.SP_COMPONENT_VALUE_QUANTITY; String param = Observation.SP_COMPONENT_VALUE_QUANTITY;
@ -1237,7 +1236,7 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
assertThat("Got: " + toUnqualifiedVersionlessIdValues(result), toUnqualifiedVersionlessIdValues(result), containsInAnyOrder(id1.getValue())); assertThat("Got: " + toUnqualifiedVersionlessIdValues(result), toUnqualifiedVersionlessIdValues(result), containsInAnyOrder(id1.getValue()));
} }
} }
@Test @Test
public void testSearchCompositeParamQuantity() { public void testSearchCompositeParamQuantity() {
Observation o1 = new Observation(); Observation o1 = new Observation();
@ -1344,9 +1343,9 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
IBundleProvider result = myObservationDao.search(new SearchParameterMap().setLoadSynchronous(true).add(param, val)); IBundleProvider result = myObservationDao.search(new SearchParameterMap().setLoadSynchronous(true).add(param, val));
assertThat(toUnqualifiedVersionlessIdValues(result), empty()); assertThat(toUnqualifiedVersionlessIdValues(result), empty());
} }
} }
@Test @Test
public void testSearchDateWrongParam() { public void testSearchDateWrongParam() {
Patient p1 = new Patient(); Patient p1 = new Patient();
@ -1391,11 +1390,6 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
params.add("_id", new StringParam("TEST")); params.add("_id", new StringParam("TEST"));
assertEquals(1, toList(myPatientDao.search(params)).size()); assertEquals(1, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("_language", new StringParam("TEST"));
assertEquals(1, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap(); params = new SearchParameterMap();
params.setLoadSynchronous(true); params.setLoadSynchronous(true);
params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST")); params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
@ -1413,11 +1407,6 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
params.add("_id", new StringParam("TEST")); params.add("_id", new StringParam("TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size()); assertEquals(0, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("_language", new StringParam("TEST"));
assertEquals(0, toList(myPatientDao.search(params)).size());
params = new SearchParameterMap(); params = new SearchParameterMap();
params.setLoadSynchronous(true); params.setLoadSynchronous(true);
params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST")); params.add(Patient.SP_IDENTIFIER, new TokenParam("TEST", "TEST"));
@ -1440,145 +1429,6 @@ public class FhirResourceDaoR4SearchNoHashesTest extends BaseJpaR4Test {
} }
} }
@Test
public void testSearchLanguageParam() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient, mySrd).getId();
}
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().setFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient, mySrd).getId();
}
SearchParameterMap params;
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_CA"));
List<IBaseResource> patients = toList(myPatientDao.search(params));
assertEquals(1, patients.size());
assertEquals(id1.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
}
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_US"));
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(1, patients.size());
assertEquals(id2.toUnqualifiedVersionless(), patients.get(0).getIdElement().toUnqualifiedVersionless());
}
{
params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_GB"));
List<Patient> patients = toList(myPatientDao.search(params));
assertEquals(0, patients.size());
}
}
@Test
public void testSearchLanguageParamAndOr() {
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("testSearchLanguageParam").addGiven("Joe");
id1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
TestUtil.sleepOneClick();
Date betweenTime = new Date();
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_US");
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().setFamily("testSearchLanguageParam").addGiven("John");
id2 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1, id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("en_US")));
params.setLastUpdated(new DateRangeParam(betweenTime, null));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("ZZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), empty());
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
params.add("_id", new StringParam(id1.getIdPart()));
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
{
SearchParameterMap params = new SearchParameterMap();
StringAndListParam and = new StringAndListParam();
and.addAnd(new StringOrListParam().addOr(new StringParam("en_CA")).addOr(new StringParam("ZZZZ")));
and.addAnd(new StringOrListParam().addOr(new StringParam("")).addOr(new StringParam(null)));
params.add(IAnyResource.SP_RES_LANGUAGE, and);
params.add("_id", new StringParam(id1.getIdPart()));
assertThat(toUnqualifiedVersionlessIds(myPatientDao.search(params)), containsInAnyOrder(id1));
}
}
@Test @Test
public void testSearchLastUpdatedParam() { public void testSearchLastUpdatedParam() {
String methodName = "testSearchLastUpdatedParam"; String methodName = "testSearchLastUpdatedParam";

View File

@ -422,9 +422,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
SearchParameterMap map = new SearchParameterMap(); SearchParameterMap map;
map.add("_language", new StringParam("EN_ca"));
assertEquals(1, myOrganizationDao.search(map).size().intValue());
map = new SearchParameterMap(); map = new SearchParameterMap();
map.setLoadSynchronous(true); map.setLoadSynchronous(true);
@ -433,11 +431,6 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
myOrganizationDao.delete(orgId, mySrd); myOrganizationDao.delete(orgId, mySrd);
map = new SearchParameterMap();
map.setLoadSynchronous(true);
map.add("_language", new StringParam("EN_ca"));
assertEquals(0, myOrganizationDao.search(map).size().intValue());
map = new SearchParameterMap(); map = new SearchParameterMap();
map.setLoadSynchronous(true); map.setLoadSynchronous(true);
map.add("_tag", new TokenParam(methodName, methodName)); map.add("_tag", new TokenParam(methodName, methodName));
@ -2576,7 +2569,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_BIRTHDATE + "AAAA", new DateParam(ParamPrefixEnum.GREATERTHAN, "2000-01-01")).setLoadSynchronous(true))); found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_BIRTHDATE + "AAAA", new DateParam(ParamPrefixEnum.GREATERTHAN, "2000-01-01")).setLoadSynchronous(true)));
assertEquals(0, found.size()); assertEquals(0, found.size());
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown search parameter \"birthdateAAAA\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage()); assertEquals("Unknown search parameter \"birthdateAAAA\" for resource type \"Patient\". Valid search parameters for this search are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
} }
} }
@ -3342,7 +3335,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
myObservationDao.search(pm); myObservationDao.search(pm);
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown _sort parameter value \"hello\" for resource type \"Observation\" (Note: sort parameters values must use a valid Search Parameter). Valid values for this search are: [_id, _language, _lastUpdated, based-on, category, code, code-value-concept, code-value-date, code-value-quantity, code-value-string, combo-code, combo-code-value-concept, combo-code-value-quantity, combo-data-absent-reason, combo-value-concept, combo-value-quantity, component-code, component-code-value-concept, component-code-value-quantity, component-data-absent-reason, component-value-concept, component-value-quantity, data-absent-reason, date, derived-from, device, encounter, focus, has-member, identifier, method, part-of, patient, performer, specimen, status, subject, value-concept, value-date, value-quantity, value-string]", e.getMessage()); assertEquals("Unknown _sort parameter value \"hello\" for resource type \"Observation\" (Note: sort parameters values must use a valid Search Parameter). Valid values for this search are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, based-on, category, code, code-value-concept, code-value-date, code-value-quantity, code-value-string, combo-code, combo-code-value-concept, combo-code-value-quantity, combo-data-absent-reason, combo-value-concept, combo-value-quantity, component-code, component-code-value-concept, component-code-value-quantity, component-data-absent-reason, component-value-concept, component-value-quantity, data-absent-reason, date, derived-from, device, encounter, focus, has-member, identifier, method, part-of, patient, performer, specimen, status, subject, value-concept, value-date, value-quantity, value-string]", e.getMessage());
} }
} }

View File

@ -50,9 +50,6 @@ public class FhirResourceDaoSearchParameterR4Test {
if (nextp.getName().equals("_id")) { if (nextp.getName().equals("_id")) {
continue; continue;
} }
if (nextp.getName().equals("_language")) {
continue;
}
if (isBlank(nextp.getPath())) { if (isBlank(nextp.getPath())) {
continue; continue;
} }

View File

@ -79,6 +79,7 @@ import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.matchesPattern; import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.startsWith;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals;
@ -409,7 +410,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
// HFJ_SPIDX_STRING // HFJ_SPIDX_STRING
List<ResourceIndexedSearchParamString> strings = myResourceIndexedSearchParamStringDao.findAllForResourceId(patientId); List<ResourceIndexedSearchParamString> strings = myResourceIndexedSearchParamStringDao.findAllForResourceId(patientId);
ourLog.info("\n * {}", strings.stream().map(ResourceIndexedSearchParamString::toString).collect(Collectors.joining("\n * "))); ourLog.info("\n * {}", strings.stream().map(ResourceIndexedSearchParamString::toString).collect(Collectors.joining("\n * ")));
assertEquals(10, strings.size()); assertEquals(9, strings.size());
assertEquals(myPartitionId, strings.get(0).getPartitionId().getPartitionId().intValue()); assertEquals(myPartitionId, strings.get(0).getPartitionId().getPartitionId().intValue());
assertEquals(myPartitionDate, strings.get(0).getPartitionId().getPartitionDate()); assertEquals(myPartitionDate, strings.get(0).getPartitionId().getPartitionDate());
@ -492,8 +493,11 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
// HFJ_SPIDX_STRING // HFJ_SPIDX_STRING
List<ResourceIndexedSearchParamString> strings = myResourceIndexedSearchParamStringDao.findAllForResourceId(patientId); List<ResourceIndexedSearchParamString> strings = myResourceIndexedSearchParamStringDao.findAllForResourceId(patientId);
ourLog.info("\n * {}", strings.stream().map(ResourceIndexedSearchParamString::toString).collect(Collectors.joining("\n * "))); String stringsDesc = strings.stream().map(ResourceIndexedSearchParamString::toString).sorted().collect(Collectors.joining("\n * "));
assertEquals(10, strings.size()); ourLog.info("\n * {}", stringsDesc);
assertThat(stringsDesc, not(containsString("_text")));
assertThat(stringsDesc, not(containsString("_content")));
assertEquals(9, strings.size(), stringsDesc);
assertEquals(null, strings.get(0).getPartitionId().getPartitionId()); assertEquals(null, strings.get(0).getPartitionId().getPartitionId());
assertEquals(myPartitionDate, strings.get(0).getPartitionId().getPartitionDate()); assertEquals(myPartitionDate, strings.get(0).getPartitionId().getPartitionDate());
@ -701,7 +705,7 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test {
// HFJ_SPIDX_STRING // HFJ_SPIDX_STRING
List<ResourceIndexedSearchParamString> strings = myResourceIndexedSearchParamStringDao.findAllForResourceId(patientId); List<ResourceIndexedSearchParamString> strings = myResourceIndexedSearchParamStringDao.findAllForResourceId(patientId);
ourLog.info("\n * {}", strings.stream().map(ResourceIndexedSearchParamString::toString).collect(Collectors.joining("\n * "))); ourLog.info("\n * {}", strings.stream().map(ResourceIndexedSearchParamString::toString).collect(Collectors.joining("\n * ")));
assertEquals(10, strings.size()); assertEquals(9, strings.size());
assertEquals(myPartitionId, strings.get(0).getPartitionId().getPartitionId().intValue()); assertEquals(myPartitionId, strings.get(0).getPartitionId().getPartitionId().intValue());
assertEquals(myPartitionDate, strings.get(0).getPartitionId().getPartitionDate()); assertEquals(myPartitionDate, strings.get(0).getPartitionId().getPartitionDate());

View File

@ -106,7 +106,7 @@ public class JpaStorageServicesTest extends BaseJpaR4Test {
mySvc.listResources(mySrd, "Appointment", Collections.singletonList(argument), result); mySvc.listResources(mySrd, "Appointment", Collections.singletonList(argument), result);
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertEquals("Unknown GraphQL argument \"test\". Value GraphQL argument for this type are: [_id, _language, actor, appointment_type, based_on, date, identifier, location, part_status, patient, practitioner, reason_code, reason_reference, service_category, service_type, slot, specialty, status, supporting_info]", e.getMessage()); assertEquals("Unknown GraphQL argument \"test\". Value GraphQL argument for this type are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, actor, appointment_type, based_on, date, identifier, location, part_status, patient, practitioner, reason_code, reason_reference, service_category, service_type, slot, specialty, status, supporting_info]", e.getMessage());
} }
} }

View File

@ -62,7 +62,7 @@ public class SearchPreferHandlingInterceptorJpaTest extends BaseResourceProvider
.execute(); .execute();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]")); assertThat(e.getMessage(), containsString("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]"));
} }
} }
@ -81,7 +81,7 @@ public class SearchPreferHandlingInterceptorJpaTest extends BaseResourceProvider
.execute(); .execute();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]")); assertThat(e.getMessage(), containsString("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]"));
} }
} }
@ -100,7 +100,7 @@ public class SearchPreferHandlingInterceptorJpaTest extends BaseResourceProvider
.execute(); .execute();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]")); assertThat(e.getMessage(), containsString("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]"));
} }
} }
@ -136,7 +136,7 @@ public class SearchPreferHandlingInterceptorJpaTest extends BaseResourceProvider
.execute(); .execute();
fail(); fail();
} catch (InvalidRequestException e) { } catch (InvalidRequestException e) {
assertThat(e.getMessage(), containsString("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _language, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]")); assertThat(e.getMessage(), containsString("Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_content, _id, _lastUpdated, _profile, _security, _source, _tag, _text, active, address, address-city, address-country, address-postalcode, address-state, address-use, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]"));
} }
} }

View File

@ -5,6 +5,10 @@ import ca.uhn.fhir.jpa.packages.PackageInstallationSpec;
import ca.uhn.fhir.rest.api.CacheControlDirective; import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.server.provider.ServerCapabilityStatementProvider; import ca.uhn.fhir.rest.server.provider.ServerCapabilityStatementProvider;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.r4.model.Bundle;
import org.hamcrest.Matchers;
import org.hl7.fhir.r4.model.CapabilityStatement; import org.hl7.fhir.r4.model.CapabilityStatement;
import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.SearchParameter; import org.hl7.fhir.r4.model.SearchParameter;
@ -17,8 +21,10 @@ import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
@ -26,11 +32,42 @@ import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
public class ServerCapabilityStatementProviderJpaR4Test extends BaseResourceProviderR4Test { public class ServerCapabilityStatementProviderJpaR4Test extends BaseResourceProviderR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(ServerCapabilityStatementProviderJpaR4Test.class); private static final Logger ourLog = LoggerFactory.getLogger(ServerCapabilityStatementProviderJpaR4Test.class);
@Test
public void testBuiltInSearchParameters() {
CapabilityStatement cs = myClient.capabilities().ofType(CapabilityStatement.class).execute();
CapabilityStatement.CapabilityStatementRestResourceComponent resource = cs.getRest().get(0).getResource().get(0);
List<String> definitions = resource.getSearchParam()
.stream()
.filter(t -> isNotBlank(t.getDefinition()))
.map(t->t.getDefinition())
.sorted()
.collect(Collectors.toList());
assertThat(definitions.toString(), definitions, Matchers.contains(
"http://hl7.org/fhir/SearchParameter/Account-identifier",
"http://hl7.org/fhir/SearchParameter/Account-name",
"http://hl7.org/fhir/SearchParameter/Account-owner",
"http://hl7.org/fhir/SearchParameter/Account-patient",
"http://hl7.org/fhir/SearchParameter/Account-period",
"http://hl7.org/fhir/SearchParameter/Account-status",
"http://hl7.org/fhir/SearchParameter/Account-subject",
"http://hl7.org/fhir/SearchParameter/Account-type",
"http://hl7.org/fhir/SearchParameter/DomainResource-text",
"http://hl7.org/fhir/SearchParameter/Resource-content",
"http://hl7.org/fhir/SearchParameter/Resource-id",
"http://hl7.org/fhir/SearchParameter/Resource-lastUpdated",
"http://hl7.org/fhir/SearchParameter/Resource-profile",
"http://hl7.org/fhir/SearchParameter/Resource-security",
"http://hl7.org/fhir/SearchParameter/Resource-source",
"http://hl7.org/fhir/SearchParameter/Resource-tag"
));
}
@Test @Test
public void testCorrectResourcesReflected() { public void testCorrectResourcesReflected() {
CapabilityStatement cs = myClient.capabilities().ofType(CapabilityStatement.class).execute(); CapabilityStatement cs = myClient.capabilities().ofType(CapabilityStatement.class).execute();
@ -104,8 +141,8 @@ public class ServerCapabilityStatementProviderJpaR4Test extends BaseResourceProv
List<CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent> fooSearchParams = findSearchParams(cs, "Patient", "_lastUpdated"); List<CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent> fooSearchParams = findSearchParams(cs, "Patient", "_lastUpdated");
assertEquals(1, fooSearchParams.size()); assertEquals(1, fooSearchParams.size());
assertEquals("_lastUpdated", fooSearchParams.get(0).getName()); assertEquals("_lastUpdated", fooSearchParams.get(0).getName());
assertEquals("http://localhost:" + ourPort + "/fhir/context/SearchParameter/Patient-_lastUpdated", fooSearchParams.get(0).getDefinition()); assertEquals("http://hl7.org/fhir/SearchParameter/Resource-lastUpdated", fooSearchParams.get(0).getDefinition());
assertEquals("Only return resources which were last updated as specified by the given range", fooSearchParams.get(0).getDocumentation()); assertEquals("When the resource version last changed", fooSearchParams.get(0).getDocumentation());
assertEquals(Enumerations.SearchParamType.DATE, fooSearchParams.get(0).getType()); assertEquals(Enumerations.SearchParamType.DATE, fooSearchParams.get(0).getType());
} }
@ -265,6 +302,35 @@ public class ServerCapabilityStatementProviderJpaR4Test extends BaseResourceProv
assertThat(findSearchParams(cs, "Patient", Constants.PARAM_FILTER), hasSize(0)); assertThat(findSearchParams(cs, "Patient", Constants.PARAM_FILTER), hasSize(0));
} }
@Test
public void testBuiltInParametersHaveAppropriateUrl() throws IOException {
Bundle allSearchParamBundle = loadResourceFromClasspath(Bundle.class, "org/hl7/fhir/r4/model/sp/search-parameters.json");
Set<String> allSearchParamUrls = allSearchParamBundle
.getEntry()
.stream()
.map(t -> (SearchParameter) t.getResource())
.map(t -> t.getUrl())
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
CapabilityStatement cs = myClient.capabilities().ofType(CapabilityStatement.class).execute();
for (CapabilityStatement.CapabilityStatementRestResourceComponent nextResource : cs.getRestFirstRep().getResource()) {
for (CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent nextSp : nextResource.getSearchParam()) {
if (nextSp.getName().equals("_has")) {
if (nextSp.getDefinition() == null) {
continue;
}
}
if (!allSearchParamUrls.contains(nextSp.getDefinition())) {
fail("Invalid search parameter: " + nextSp.getName() + " has definition URL: " + nextSp.getDefinition());
}
}
}
}
@Nonnull @Nonnull
private List<String> findSupportedProfiles(CapabilityStatement theCapabilityStatement, String theResourceType) { private List<String> findSupportedProfiles(CapabilityStatement theCapabilityStatement, String theResourceType) {
assertEquals(1, theCapabilityStatement.getRest().size()); assertEquals(1, theCapabilityStatement.getRest().size());

View File

@ -36,6 +36,7 @@ import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR4;
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorService; import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorService;
import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher; import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl; import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl;
import ca.uhn.fhir.jpa.searchparam.registry.SearchParameterCanonicalizer;
import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl; import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
@ -218,6 +219,7 @@ public class GiantTransactionPerfTest {
mySearchParamRegistry = new SearchParamRegistryImpl(); mySearchParamRegistry = new SearchParamRegistryImpl();
mySearchParamRegistry.setResourceChangeListenerRegistry(myResourceChangeListenerRegistry); mySearchParamRegistry.setResourceChangeListenerRegistry(myResourceChangeListenerRegistry);
mySearchParamRegistry.setSearchParameterCanonicalizerForUnitTest(new SearchParameterCanonicalizer(myCtx));
mySearchParamRegistry.setFhirContext(myCtx); mySearchParamRegistry.setFhirContext(myCtx);
mySearchParamRegistry.setModelConfig(myDaoConfig.getModelConfig()); mySearchParamRegistry.setModelConfig(myDaoConfig.getModelConfig());
mySearchParamRegistry.registerListener(); mySearchParamRegistry.registerListener();

View File

@ -338,18 +338,6 @@ public class InMemorySubscriptionMatcherR4Test {
assertNotMatched(o1, params); assertNotMatched(o1, params);
} }
@Test
public void testLanguageNotSupported() {
Patient patient = new Patient();
patient.getLanguageElement().setValue("en_CA");
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().setFamily("testSearchLanguageParam").addGiven("Joe");
SearchParameterMap params;
params = new SearchParameterMap();
params.add(IAnyResource.SP_RES_LANGUAGE, new StringParam("en_CA"));
assertUnsupported(patient, params);
}
@Test @Test
public void testLocationPositionNotSupported() { public void testLocationPositionNotSupported() {
Location loc = new Location(); Location loc = new Location();

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -122,6 +122,12 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
cmbTokNuTable.addColumn("20210722.1", "PARTITION_ID").nullable().type(ColumnTypeEnum.INT); cmbTokNuTable.addColumn("20210722.1", "PARTITION_ID").nullable().type(ColumnTypeEnum.INT);
cmbTokNuTable.addColumn("20210722.2", "PARTITION_DATE").nullable().type(ColumnTypeEnum.DATE_ONLY); cmbTokNuTable.addColumn("20210722.2", "PARTITION_DATE").nullable().type(ColumnTypeEnum.DATE_ONLY);
cmbTokNuTable.modifyColumn("20210722.3", "RES_ID").nullable().withType(ColumnTypeEnum.LONG); cmbTokNuTable.modifyColumn("20210722.3", "RES_ID").nullable().withType(ColumnTypeEnum.LONG);
// Dropping index on the language column, as it's no longer in use.
// TODO: After 2 releases from 5.5.0, drop the column too
version.onTable("HFJ_RESOURCE")
.dropIndex("20210908.1", "IDX_RES_LANG");
} }
private void init540() { private void init540() {

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -55,7 +55,6 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
@Entity @Entity
@Table(name = "HFJ_RESOURCE", uniqueConstraints = {}, indexes = { @Table(name = "HFJ_RESOURCE", uniqueConstraints = {}, indexes = {
@Index(name = "IDX_RES_DATE", columnList = "RES_UPDATED"), @Index(name = "IDX_RES_DATE", columnList = "RES_UPDATED"),
@Index(name = "IDX_RES_LANG", columnList = "RES_TYPE,RES_LANGUAGE"),
@Index(name = "IDX_RES_TYPE", columnList = "RES_TYPE"), @Index(name = "IDX_RES_TYPE", columnList = "RES_TYPE"),
@Index(name = "IDX_INDEXSTATUS", columnList = "SP_INDEX_STATUS") @Index(name = "IDX_INDEXSTATUS", columnList = "SP_INDEX_STATUS")
}) })
@ -100,6 +99,7 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
@OptimisticLock(excluded = true) @OptimisticLock(excluded = true)
private Long myIndexStatus; private Long myIndexStatus;
// TODO: Removed in 5.5.0. Drop in a future release.
@Column(name = "RES_LANGUAGE", length = MAX_LANGUAGE_LENGTH, nullable = true) @Column(name = "RES_LANGUAGE", length = MAX_LANGUAGE_LENGTH, nullable = true)
@OptimisticLock(excluded = true) @OptimisticLock(excluded = true)
private String myLanguage; private String myLanguage;
@ -310,17 +310,6 @@ public class ResourceTable extends BaseHasResource implements Serializable, IBas
myIndexStatus = theIndexStatus; myIndexStatus = theIndexStatus;
} }
public String getLanguage() {
return myLanguage;
}
public void setLanguage(String theLanguage) {
if (defaultString(theLanguage).length() > MAX_LANGUAGE_LENGTH) {
throw new UnprocessableEntityException("Language exceeds maximum length of " + MAX_LANGUAGE_LENGTH + " chars: " + theLanguage);
}
myLanguage = theLanguage;
}
public Collection<ResourceIndexedComboStringUnique> getParamsComboStringUnique() { public Collection<ResourceIndexedComboStringUnique> getParamsComboStringUnique() {
if (myParamsComboStringUnique == null) { if (myParamsComboStringUnique == null) {
myParamsComboStringUnique = new ArrayList<>(); myParamsComboStringUnique = new ArrayList<>();

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -52,8 +52,6 @@ public class ResourceMetaParams {
Map<String, Class<? extends IQueryParameterAnd<?>>> resourceMetaAndParams = new HashMap<>(); Map<String, Class<? extends IQueryParameterAnd<?>>> resourceMetaAndParams = new HashMap<>();
resourceMetaParams.put(IAnyResource.SP_RES_ID, StringParam.class); resourceMetaParams.put(IAnyResource.SP_RES_ID, StringParam.class);
resourceMetaAndParams.put(IAnyResource.SP_RES_ID, StringAndListParam.class); resourceMetaAndParams.put(IAnyResource.SP_RES_ID, StringAndListParam.class);
resourceMetaParams.put(IAnyResource.SP_RES_LANGUAGE, StringParam.class);
resourceMetaAndParams.put(IAnyResource.SP_RES_LANGUAGE, StringAndListParam.class);
resourceMetaParams.put(Constants.PARAM_TAG, TokenParam.class); resourceMetaParams.put(Constants.PARAM_TAG, TokenParam.class);
resourceMetaAndParams.put(Constants.PARAM_TAG, TokenAndListParam.class); resourceMetaAndParams.put(Constants.PARAM_TAG, TokenAndListParam.class);
resourceMetaParams.put(Constants.PARAM_PROFILE, UriParam.class); resourceMetaParams.put(Constants.PARAM_PROFILE, UriParam.class);

View File

@ -225,7 +225,7 @@ public final class ResourceIndexedSearchParams {
resourceParams = myDateParams; resourceParams = myDateParams;
break; break;
case REFERENCE: case REFERENCE:
return matchResourceLinks(theModelConfig, theResourceName, theParamName, value, theParamDef.getPath()); return matchResourceLinks(theModelConfig, theResourceName, theParamName, value, theParamDef.getPathsSplitForResourceType(theResourceName));
case COMPOSITE: case COMPOSITE:
case HAS: case HAS:
case SPECIAL: case SPECIAL:
@ -256,6 +256,15 @@ public final class ResourceIndexedSearchParams {
return matchResourceLinks(new ModelConfig(), theResourceName, theParamName, theParam, theParamPath); return matchResourceLinks(new ModelConfig(), theResourceName, theParamName, theParam, theParamPath);
} }
public boolean matchResourceLinks(ModelConfig theModelConfig, String theResourceName, String theParamName, IQueryParameterType theParam, List<String> theParamPaths) {
for (String nextPath : theParamPaths) {
if (matchResourceLinks(theModelConfig, theResourceName, theParamName, theParam, nextPath)) {
return true;
}
}
return false;
}
// KHS This needs to be public as libraries outside of hapi call it directly // KHS This needs to be public as libraries outside of hapi call it directly
public boolean matchResourceLinks(ModelConfig theModelConfig, String theResourceName, String theParamName, IQueryParameterType theParam, String theParamPath) { public boolean matchResourceLinks(ModelConfig theModelConfig, String theResourceName, String theParamName, IQueryParameterType theParam, String theParamPath) {
ReferenceParam reference = (ReferenceParam) theParam; ReferenceParam reference = (ReferenceParam) theParam;
@ -331,6 +340,10 @@ public final class ResourceIndexedSearchParams {
Collection<RT> paramCollection) { Collection<RT> paramCollection) {
for (Map.Entry<String, RuntimeSearchParam> nextEntry : activeSearchParams) { for (Map.Entry<String, RuntimeSearchParam> nextEntry : activeSearchParams) {
String nextParamName = nextEntry.getKey(); String nextParamName = nextEntry.getKey();
if (nextParamName == null || nextParamName.startsWith("_")) {
continue;
}
if (nextEntry.getValue().getParamType() == type) { if (nextEntry.getValue().getParamType() == type) {
boolean haveParam = false; boolean haveParam = false;
for (BaseResourceIndexedSearchParam nextParam : paramCollection) { for (BaseResourceIndexedSearchParam nextParam : paramCollection) {

View File

@ -164,7 +164,6 @@ public class InMemoryResourceMatcher {
case IAnyResource.SP_RES_ID: case IAnyResource.SP_RES_ID:
return InMemoryMatchResult.fromBoolean(matchIdsAndOr(theAndOrParams, theResource)); return InMemoryMatchResult.fromBoolean(matchIdsAndOr(theAndOrParams, theResource));
case IAnyResource.SP_RES_LANGUAGE:
case Constants.PARAM_HAS: case Constants.PARAM_HAS:
case Constants.PARAM_TAG: case Constants.PARAM_TAG:
case Constants.PARAM_PROFILE: case Constants.PARAM_PROFILE:

View File

@ -21,10 +21,17 @@ package ca.uhn.fhir.jpa.searchparam.registry;
*/ */
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.ClasspathUtil;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang3.tuple.Pair;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -73,22 +80,42 @@ public class ReadOnlySearchParamCache {
return myUrlToParam.get(theUrl); return myUrlToParam.get(theUrl);
} }
public static ReadOnlySearchParamCache fromFhirContext(FhirContext theFhirContext) { public static ReadOnlySearchParamCache fromFhirContext(FhirContext theFhirContext, SearchParameterCanonicalizer theCanonicalizer) {
ReadOnlySearchParamCache retval = new ReadOnlySearchParamCache(); assert theCanonicalizer != null;
ReadOnlySearchParamCache retVal = new ReadOnlySearchParamCache();
Set<String> resourceNames = theFhirContext.getResourceTypes(); Set<String> resourceNames = theFhirContext.getResourceTypes();
if (theFhirContext.getVersion().getVersion() == FhirVersionEnum.R4) {
IBaseBundle allSearchParameterBundle = (IBaseBundle) theFhirContext.newJsonParser().parseResource(ClasspathUtil.loadResourceAsStream("org/hl7/fhir/r4/model/sp/search-parameters.json"));
for (IBaseResource next : BundleUtil.toListOfResources(theFhirContext, allSearchParameterBundle)) {
RuntimeSearchParam nextCanonical = theCanonicalizer.canonicalizeSearchParameter(next);
if (nextCanonical != null) {
Collection<String> base = nextCanonical.getBase();
if (base.contains("Resource") || base.contains("DomainResource")) {
base = resourceNames;
}
for (String nextBase : base) {
Map<String, RuntimeSearchParam> nameToParam = retVal.myResourceNameToSpNameToSp.computeIfAbsent(nextBase, t -> new HashMap<>());
String nextName = nextCanonical.getName();
nameToParam.putIfAbsent(nextName, nextCanonical);
}
}
}
}
for (String resourceName : resourceNames) { for (String resourceName : resourceNames) {
RuntimeResourceDefinition nextResDef = theFhirContext.getResourceDefinition(resourceName); RuntimeResourceDefinition nextResDef = theFhirContext.getResourceDefinition(resourceName);
String nextResourceName = nextResDef.getName(); String nextResourceName = nextResDef.getName();
HashMap<String, RuntimeSearchParam> nameToParam = new HashMap<>();
retval.myResourceNameToSpNameToSp.put(nextResourceName, nameToParam);
Map<String, RuntimeSearchParam> nameToParam = retVal.myResourceNameToSpNameToSp.computeIfAbsent(nextResourceName, t-> new HashMap<>());
for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) { for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) {
nameToParam.put(nextSp.getName(), nextSp); nameToParam.putIfAbsent(nextSp.getName(), nextSp);
} }
} }
return retval; return retVal;
} }
public static ReadOnlySearchParamCache fromRuntimeSearchParamCache(RuntimeSearchParamCache theRuntimeSearchParamCache) { public static ReadOnlySearchParamCache fromRuntimeSearchParamCache(RuntimeSearchParamCache theRuntimeSearchParamCache) {

View File

@ -167,7 +167,7 @@ public class SearchParamRegistryImpl implements ISearchParamRegistry, IResourceC
private ReadOnlySearchParamCache getBuiltInSearchParams() { private ReadOnlySearchParamCache getBuiltInSearchParams() {
if (myBuiltInSearchParams == null) { if (myBuiltInSearchParams == null) {
myBuiltInSearchParams = ReadOnlySearchParamCache.fromFhirContext(myFhirContext); myBuiltInSearchParams = ReadOnlySearchParamCache.fromFhirContext(myFhirContext, mySearchParameterCanonicalizer);
} }
return myBuiltInSearchParams; return myBuiltInSearchParams;
} }
@ -314,4 +314,9 @@ public class SearchParamRegistryImpl implements ISearchParamRegistry, IResourceC
handleInit(Collections.emptyList()); handleInit(Collections.emptyList());
} }
@VisibleForTesting
public void setSearchParameterCanonicalizerForUnitTest(SearchParameterCanonicalizer theSearchParameterCanonicalizerForUnitTest) {
mySearchParameterCanonicalizer = theSearchParameterCanonicalizerForUnitTest;
}
} }

View File

@ -87,7 +87,11 @@ public class SearchParameterCanonicalizer {
default: default:
throw new InternalErrorException("SearchParameter canonicalization not supported for FHIR version" + myFhirContext.getVersion().getVersion()); throw new InternalErrorException("SearchParameter canonicalization not supported for FHIR version" + myFhirContext.getVersion().getVersion());
} }
extractExtensions(theSearchParameter, retVal);
if (retVal != null) {
extractExtensions(theSearchParameter, retVal);
}
return retVal; return retVal;
} }
@ -309,7 +313,9 @@ public class SearchParameterCanonicalizer {
Set<String> targets = terser.getValues(theNextSp, "target", IPrimitiveType.class).stream().map(t -> t.getValueAsString()).collect(Collectors.toSet()); Set<String> targets = terser.getValues(theNextSp, "target", IPrimitiveType.class).stream().map(t -> t.getValueAsString()).collect(Collectors.toSet());
if (isBlank(name) || isBlank(path) || paramType == null) { if (isBlank(name) || isBlank(path) || paramType == null) {
if (paramType != RestSearchParameterTypeEnum.COMPOSITE) { if ("_text".equals(name) || "_content".equals(name)) {
// ok
} else if (paramType != RestSearchParameterTypeEnum.COMPOSITE) {
return null; return null;
} }
} }

View File

@ -63,7 +63,7 @@ import static org.mockito.Mockito.when;
@ExtendWith(SpringExtension.class) @ExtendWith(SpringExtension.class)
public class SearchParamRegistryImplTest { public class SearchParamRegistryImplTest {
private static final FhirContext ourFhirContext = FhirContext.forR4(); private static final FhirContext ourFhirContext = FhirContext.forR4();
private static final ReadOnlySearchParamCache ourBuiltInSearchParams = ReadOnlySearchParamCache.fromFhirContext(ourFhirContext); private static final ReadOnlySearchParamCache ourBuiltInSearchParams = ReadOnlySearchParamCache.fromFhirContext(ourFhirContext, new SearchParameterCanonicalizer(ourFhirContext));
public static final int TEST_SEARCH_PARAMS = 3; public static final int TEST_SEARCH_PARAMS = 3;
private static final List<ResourceTable> ourEntities; private static final List<ResourceTable> ourEntities;
@ -77,7 +77,7 @@ public class SearchParamRegistryImplTest {
ourEntities.add(createEntity(ourLastId, 1)); ourEntities.add(createEntity(ourLastId, 1));
} }
ourResourceVersionMap = ResourceVersionMap.fromResourceTableEntities(ourEntities); ourResourceVersionMap = ResourceVersionMap.fromResourceTableEntities(ourEntities);
ourBuiltinPatientSearchParamCount = ReadOnlySearchParamCache.fromFhirContext(ourFhirContext).getSearchParamMap("Patient").size(); ourBuiltinPatientSearchParamCount = ReadOnlySearchParamCache.fromFhirContext(ourFhirContext, new SearchParameterCanonicalizer(ourFhirContext)).getSearchParamMap("Patient").size();
} }
@Autowired @Autowired
@ -178,7 +178,7 @@ public class SearchParamRegistryImplTest {
@Test @Test
void handleInit() { void handleInit() {
assertEquals(25, mySearchParamRegistry.getActiveSearchParams("Patient").size()); assertEquals(31, mySearchParamRegistry.getActiveSearchParams("Patient").size());
IdDt idBad = new IdDt("SearchParameter/bad"); IdDt idBad = new IdDt("SearchParameter/bad");
when(mySearchParamProvider.read(idBad)).thenThrow(new ResourceNotFoundException("id bad")); when(mySearchParamProvider.read(idBad)).thenThrow(new ResourceNotFoundException("id bad"));
@ -191,7 +191,7 @@ public class SearchParamRegistryImplTest {
idList.add(idBad); idList.add(idBad);
idList.add(idGood); idList.add(idGood);
mySearchParamRegistry.handleInit(idList); mySearchParamRegistry.handleInit(idList);
assertEquals(26, mySearchParamRegistry.getActiveSearchParams("Patient").size()); assertEquals(32, mySearchParamRegistry.getActiveSearchParams("Patient").size());
} }
@Test @Test

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -59,7 +59,6 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
static { static {
HashSet<String> specialSearchParams = new HashSet<>(); HashSet<String> specialSearchParams = new HashSet<>();
specialSearchParams.add(IAnyResource.SP_RES_ID); specialSearchParams.add(IAnyResource.SP_RES_ID);
specialSearchParams.add(IAnyResource.SP_RES_LANGUAGE);
specialSearchParams.add(Constants.PARAM_INCLUDE); specialSearchParams.add(Constants.PARAM_INCLUDE);
specialSearchParams.add(Constants.PARAM_REVINCLUDE); specialSearchParams.add(Constants.PARAM_REVINCLUDE);
SPECIAL_SEARCH_PARAMS = Collections.unmodifiableSet(specialSearchParams); SPECIAL_SEARCH_PARAMS = Collections.unmodifiableSet(specialSearchParams);

View File

@ -411,15 +411,7 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
} }
String spUri = next.getUri(); String spUri = next.getUri();
if (isBlank(spUri) && servletRequest != null) {
String id;
if (next.getId() != null) {
id = next.getId().toUnqualifiedVersionless().getValue();
} else {
id = resourceName + "-" + next.getName();
}
spUri = configuration.getServerAddressStrategy().determineServerBase(servletRequest.getServletContext(), servletRequest) + "/" + id;
}
if (isNotBlank(spUri)) { if (isNotBlank(spUri)) {
terser.addElement(searchParam, "definition", spUri); terser.addElement(searchParam, "definition", spUri);
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId> <artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId> <artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId> <artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot</artifactId> <artifactId>hapi-fhir-spring-boot</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
</parent> </parent>
<artifactId>hapi-fhir-spring-boot-samples</artifactId> <artifactId>hapi-fhir-spring-boot-samples</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -72,18 +72,9 @@ public abstract class BaseResource extends BaseElement implements IResource {
@SearchParamDefinition(name="_id", path="", description="The ID of the resource", type="string" ) @SearchParamDefinition(name="_id", path="", description="The ID of the resource", type="string" )
public static final String SP_RES_ID = "_id"; public static final String SP_RES_ID = "_id";
/**
* Search parameter constant for <b>_language</b>
*/
@SearchParamDefinition(name="_language", path="", description="The language of the resource", type="string" )
public static final String SP_RES_LANGUAGE = "_language";
@Child(name = "contained", order = 2, min = 0, max = 1) @Child(name = "contained", order = 2, min = 0, max = 1)
private ContainedDt myContained; private ContainedDt myContained;
private IdDt myId; private IdDt myId;
@Child(name = "language", order = 0, min = 0, max = 1) @Child(name = "language", order = 0, min = 0, max = 1)

View File

@ -42,7 +42,7 @@ public class NameChanges {
} }
if (name.startsWith("_")) { if (name.startsWith("_")) {
continue; // _id and _language continue; // _id
} }
String path = nextParam.getPath(); String path = nextParam.getPath();

View File

@ -42,7 +42,7 @@ public class NameChanges {
} }
if (name.startsWith("_")) { if (name.startsWith("_")) {
continue; // _id and _language continue; // _id
} }
String path = nextParam.getPath(); String path = nextParam.getPath();

View File

@ -277,11 +277,6 @@
"type": "token", "type": "token",
"documentation": "The logical resource id associated with the resource (must be supported by all servers)" "documentation": "The logical resource id associated with the resource (must be supported by all servers)"
}, },
{
"name": "_language",
"type": "token",
"documentation": "The language of the resource"
},
{ {
"name": "subject", "name": "subject",
"type": "reference", "type": "reference",
@ -291,4 +286,4 @@
] ]
} }
] ]
} }

View File

@ -1021,11 +1021,6 @@
"type": "token", "type": "token",
"documentation": "The logical resource id associated with the resource (must be supported by all servers)" "documentation": "The logical resource id associated with the resource (must be supported by all servers)"
}, },
{
"name": "_language",
"type": "token",
"documentation": "The language of the resource"
},
{ {
"name": "active", "name": "active",
"type": "token", "type": "token",
@ -1118,4 +1113,4 @@
] ]
} }
] ]
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -69,13 +69,6 @@ public abstract class BaseResource extends BaseElement implements IResource {
@SearchParamDefinition(name="_id", path="", description="The ID of the resource", type="string" ) @SearchParamDefinition(name="_id", path="", description="The ID of the resource", type="string" )
public static final String SP_RES_ID = "_id"; public static final String SP_RES_ID = "_id";
/**
* Search parameter constant for <b>_language</b>
*/
@SearchParamDefinition(name="_language", path="", description="The language of the resource", type="string" )
public static final String SP_RES_LANGUAGE = "_language";
@Child(name = "contained", order = 2, min = 0, max = 1) @Child(name = "contained", order = 2, min = 0, max = 1)
private ContainedDt myContained; private ContainedDt myContained;
@ -127,7 +120,7 @@ public abstract class BaseResource extends BaseElement implements IResource {
@Override @Override
public IBaseMetaType addProfile(String theProfile) { public IBaseMetaType addProfile(String theProfile) {
ArrayList<IdDt> newTagList = new ArrayList<IdDt>(); ArrayList<IdDt> newTagList = new ArrayList<>();
List<IdDt> existingTagList = ResourceMetadataKeyEnum.PROFILES.get(BaseResource.this); List<IdDt> existingTagList = ResourceMetadataKeyEnum.PROFILES.get(BaseResource.this);
if (existingTagList != null) { if (existingTagList != null) {
newTagList.addAll(existingTagList); newTagList.addAll(existingTagList);

View File

@ -33,10 +33,6 @@ public class PatientResourceProvider implements IResourceProvider
@OptionalParam(name="_id") @OptionalParam(name="_id")
StringAndListParam theId, StringAndListParam theId,
@Description(shortDefinition="The resource language")
@OptionalParam(name="_language")
StringAndListParam theResourceLanguage,
@Description(shortDefinition="Search the contents of the resource's data using a fulltext search") @Description(shortDefinition="Search the contents of the resource's data using a fulltext search")
@OptionalParam(name=Constants.PARAM_CONTENT) @OptionalParam(name=Constants.PARAM_CONTENT)
StringAndListParam theFtContent, StringAndListParam theFtContent,

View File

@ -501,7 +501,7 @@ public class ServerConformanceProviderDstu2Test {
if (resourceBinding.getResourceName().equals("Patient")) { if (resourceBinding.getResourceName().equals("Patient")) {
List<BaseMethodBinding<?>> methodBindings = resourceBinding.getMethodBindings(); List<BaseMethodBinding<?>> methodBindings = resourceBinding.getMethodBindings();
SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0); SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0);
SearchParameter param = (SearchParameter) binding.getParameters().get(25); SearchParameter param = (SearchParameter) binding.getParameters().get(24);
assertEquals("The organization at which this person is a patient", param.getDescription()); assertEquals("The organization at which this person is a patient", param.getDescription());
found = true; found = true;
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -49,7 +49,7 @@ public class FhirContextDstu3Test {
@Test @Test
public void testRuntimeSearchParamToString() { public void testRuntimeSearchParamToString() {
String val = ourCtx.getResourceDefinition("Patient").getSearchParam("gender").toString(); String val = ourCtx.getResourceDefinition("Patient").getSearchParam("gender").toString();
assertEquals("RuntimeSearchParam[base=[Patient],name=gender,path=Patient.gender,id=<null>,uri=http://hl7.org/fhir/SearchParameter/patient-gender]", val); assertEquals("RuntimeSearchParam[base=[Patient],name=gender,path=Patient.gender,id=<null>,uri=http://hl7.org/fhir/SearchParameter/Patient-gender]", val);
} }
@Test @Test

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -35,10 +35,6 @@ public class PatientResourceProvider implements IResourceProvider
@OptionalParam(name="_id") @OptionalParam(name="_id")
StringAndListParam theId, StringAndListParam theId,
@Description(shortDefinition="The resource language")
@OptionalParam(name="_language")
StringAndListParam theResourceLanguage,
@Description(shortDefinition="Search the contents of the resource's data using a fulltext search") @Description(shortDefinition="Search the contents of the resource's data using a fulltext search")
@OptionalParam(name=Constants.PARAM_CONTENT) @OptionalParam(name=Constants.PARAM_CONTENT)
StringAndListParam theFtContent, StringAndListParam theFtContent,

View File

@ -479,7 +479,8 @@ public class ServerCapabilityStatementProviderR5Test {
List<BaseMethodBinding<?>> methodBindings = resourceBinding.getMethodBindings(); List<BaseMethodBinding<?>> methodBindings = resourceBinding.getMethodBindings();
SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0); SearchMethodBinding binding = (SearchMethodBinding) methodBindings.get(0);
SearchParameter param = (SearchParameter) binding.getParameters().get(25); SearchParameter param = (SearchParameter) binding.getParameters().get(25);
assertEquals("The organization at which this person is a patient", param.getDescription()); assertEquals("careprovider", param.getName());
assertEquals("Patient's nominated care provider, could be a care manager, not the organization that manages the record", param.getDescription());
found = true; found = true;
} }
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE4-SNAPSHOT</version> <version>5.6.0-PRE5-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

Some files were not shown because too many files have changed in this diff Show More