Merge branch 'master' of github.com:jamesagnew/hapi-fhir

This commit is contained in:
James Agnew 2019-11-07 21:52:22 -05:00
commit c027ff27c3
6 changed files with 49 additions and 43 deletions

View File

@ -2071,6 +2071,7 @@ public class SearchBuilder implements ISearchBuilder {
outerQuery.multiselect(myBuilder.countDistinct(myResourceTableRoot)); outerQuery.multiselect(myBuilder.countDistinct(myResourceTableRoot));
} else { } else {
outerQuery.multiselect(myResourceTableRoot.get("myId").as(Long.class)); outerQuery.multiselect(myResourceTableRoot.get("myId").as(Long.class));
outerQuery.distinct(true);
} }
} }

View File

@ -1,31 +0,0 @@
package ca.uhn.fhir.jpa.provider;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2019 University Health Network
* %%
* 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%
*/
/**
* @deprecated Use ca.uhn.fhir.jpa.binstore.BinaryAccessProvider instead
*/
@Deprecated
public class BinaryAccessProvider extends ca.uhn.fhir.jpa.binstore.BinaryAccessProvider {
// FIXME: JA delete before 4.0.0
}

View File

@ -233,6 +233,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
ourLog.trace("Going to try to start next search"); ourLog.trace("Going to try to start next search");
Optional<Search> newSearch = mySearchCacheSvc.tryToMarkSearchAsInProgress(search); Optional<Search> newSearch = mySearchCacheSvc.tryToMarkSearchAsInProgress(search);
if (newSearch.isPresent()) { if (newSearch.isPresent()) {
ourLog.trace("Launching new search");
search = newSearch.get(); search = newSearch.get();
String resourceType = search.getResourceType(); String resourceType = search.getResourceType();
SearchParameterMap params = search.getSearchParameterMap().orElseThrow(() -> new IllegalStateException("No map in PASSCOMPLET search")); SearchParameterMap params = search.getSearchParameterMap().orElseThrow(() -> new IllegalStateException("No map in PASSCOMPLET search"));
@ -1113,7 +1114,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
throw newResourceGoneException(getSearch().getUuid()); throw newResourceGoneException(getSearch().getUuid());
} }
ourLog.debug("Have {} previously added IDs in search: {}", previouslyAddedResourcePids.size(), getSearch().getUuid()); ourLog.trace("Have {} previously added IDs in search: {}", previouslyAddedResourcePids.size(), getSearch().getUuid());
setPreviouslyAddedResourcePids(previouslyAddedResourcePids); setPreviouslyAddedResourcePids(previouslyAddedResourcePids);
return null; return null;
}); });

View File

@ -1,21 +1,19 @@
package ca.uhn.fhir.jpa.provider.r4; package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao; import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.entity.ResourceReindexJobEntity; import ca.uhn.fhir.jpa.entity.ResourceReindexJobEntity;
import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.SpringObjectCaster;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.gclient.ReferenceClientParam; import ca.uhn.fhir.rest.gclient.ReferenceClientParam;
import ca.uhn.fhir.rest.gclient.TokenClientParam; import ca.uhn.fhir.rest.gclient.TokenClientParam;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.BundleUtil;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
@ -33,9 +31,6 @@ import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.util.ProxyUtils;
import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
@ -48,7 +43,11 @@ import java.util.Map;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProviderR4Test { public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProviderR4Test {
@ -80,7 +79,7 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
} }
private Map<String, CapabilityStatementRestResourceSearchParamComponent> extractSearchParams(CapabilityStatement conformance, String resType) { private Map<String, CapabilityStatementRestResourceSearchParamComponent> extractSearchParams(CapabilityStatement conformance, String resType) {
Map<String, CapabilityStatementRestResourceSearchParamComponent> map = new HashMap<String, CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent>(); Map<String, CapabilityStatementRestResourceSearchParamComponent> map = new HashMap<>();
for (CapabilityStatementRestComponent nextRest : conformance.getRest()) { for (CapabilityStatementRestComponent nextRest : conformance.getRest()) {
for (CapabilityStatementRestResourceComponent nextResource : nextRest.getResource()) { for (CapabilityStatementRestResourceComponent nextResource : nextRest.getResource()) {
if (!resType.equals(nextResource.getType())) { if (!resType.equals(nextResource.getType())) {
@ -95,7 +94,7 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide
} }
@Test @Test
public void saveCreateSearchParamInvalidWithMissingStatus() throws IOException { public void saveCreateSearchParamInvalidWithMissingStatus() {
SearchParameter sp = new SearchParameter(); SearchParameter sp = new SearchParameter();
sp.setCode("foo"); sp.setCode("foo");
sp.setExpression("Patient.gender"); sp.setExpression("Patient.gender");

View File

@ -0,0 +1,29 @@
{
"resourceType": "SearchParameter",
"id": "54805",
"meta": {
"versionId": "1",
"lastUpdated": "2019-11-04T18:33:47.918+00:00",
"source": "#pt4ERkOO6LGm5ZoA"
},
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Search for a questionnaire by item.text nested field - up to 3 levels.</div>"
},
"url": "https://impact-fhir.mitre.org/r4/SearchParameter/QuestionnaireItemText",
"version": "0.0.1",
"name": "QuestionnaireItemText",
"status": "active",
"date": "2019-10-25T15:38:45-04:00",
"description": "Search for a questionnaire by item.text nested field - up to 3 levels.",
"code": "item-text",
"base": [
"Questionnaire"
],
"type": "string",
"expression": "Questionnaire.item.text | Questionnaire.item.item.text | Questionnaire.item.item.item.text",
"xpathUsage": "normal",
"modifier": [
"contains"
]
}

View File

@ -506,6 +506,13 @@
filter could bring in search results of the wrong type. Thanks to Anthony Sute for the Pull filter could bring in search results of the wrong type. Thanks to Anthony Sute for the Pull
Request and Jens Villadsen for reporting! Request and Jens Villadsen for reporting!
</action> </action>
<action type="fix" issue="1300">
In some cases where where a single search parameter matches the same resource many times with
different distinct values (e.g. a search by Patient:name where there are hundreds of patients having
hundreds of distinct names each) the Search Coordinator would end up in an infinite loop and never
return all of the possible results. Thanks to @imranmoezkhan for reporting, and to
Tim Shaffer for providing a reproducible test case!
</action>
</release> </release>
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)"> <release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
<action type="fix"> <action type="fix">