fix iBundleProvider.getResources(from,to) throwing a NPE (#2632)

* fix iBundleProvider.getResources(from,to) throwing a NPE

* change log

* review feedback

* rename test to IT that has concurrency failures
This commit is contained in:
Ken Stevens 2021-05-05 21:50:51 -04:00 committed by GitHub
parent 4031968357
commit a4856bba17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 133 additions and 101 deletions

View File

@ -0,0 +1,4 @@
---
type: fix
issue: 2632
title: "Certain calls to the $evaluate-measure operation could result in a NullPointerException. This is now corrected."

View File

@ -81,7 +81,7 @@ public class BaseJpaResourceProviderCompositionDstu3 extends JpaResourceProvider
startRequest(theServletRequest);
try {
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, theRequestDetails);
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
List<IBaseResource> resourceList = bundleProvider.getAllResources();
boolean foundCompositionResource = false;
Bundle bundle = new Bundle().setType(Bundle.BundleType.DOCUMENT);

View File

@ -78,7 +78,7 @@ public class BaseJpaResourceProviderCompositionR4 extends JpaResourceProviderR4<
startRequest(theServletRequest);
try {
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, theRequestDetails);
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
List<IBaseResource> resourceList = bundleProvider.getAllResources();
boolean foundCompositionResource = false;
Bundle bundle = new Bundle().setType(Bundle.BundleType.DOCUMENT);

View File

@ -77,8 +77,8 @@ public class BaseJpaResourceProviderCompositionR5 extends JpaResourceProviderR5<
startRequest(theServletRequest);
try {
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theOffset,theLastUpdated, theSortSpec, theRequestDetails);
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, theRequestDetails);
List<IBaseResource> resourceList = bundleProvider.getAllResources();
boolean foundCompositionResource = false;
Bundle bundle = new Bundle().setType(Bundle.BundleType.DOCUMENT);

View File

@ -95,10 +95,7 @@ public class JpaFhirRetrieveProvider extends SearchParamFhirRetrieveProvider {
if (bundleProvider.size() == null) {
return resolveResourceList(bundleProvider.getResources(0, 10000));
}
if (bundleProvider.size() == 0) {
return new ArrayList<>();
}
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
List<IBaseResource> resourceList = bundleProvider.getAllResources();
return resolveResourceList(resourceList);
}

View File

@ -33,10 +33,8 @@ import ca.uhn.fhir.cql.dstu3.provider.MeasureOperationsProvider;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.cache.IResourceChangeListenerRegistry;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
import org.cqframework.cql.cql2elm.CqlTranslatorOptions;
import org.cqframework.cql.cql2elm.model.Model;
import org.cqframework.cql.elm.execution.Library;
@ -99,7 +97,7 @@ public class CqlDstu3Config extends BaseCqlConfig {
@Bean
public ElmCacheResourceChangeListener elmCacheResourceChangeListener(IResourceChangeListenerRegistry resourceChangeListenerRegistry, IFhirResourceDao<org.hl7.fhir.dstu3.model.Library> libraryDao, Map<org.cqframework.cql.elm.execution.VersionedIdentifier, Library> globalLibraryCache) {
ElmCacheResourceChangeListener listener = new ElmCacheResourceChangeListener(libraryDao, globalLibraryCache);
resourceChangeListenerRegistry.registerResourceResourceChangeListener("Library", new SearchParameterMap(), listener, 1000);
resourceChangeListenerRegistry.registerResourceResourceChangeListener("Library", SearchParameterMap.newSynchronous(), listener, 1000);
return listener;
}
}

View File

@ -34,10 +34,8 @@ import ca.uhn.fhir.cql.r4.provider.MeasureOperationsProvider;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.cache.IResourceChangeListenerRegistry;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4;
import org.cqframework.cql.cql2elm.CqlTranslatorOptions;
import org.cqframework.cql.cql2elm.model.Model;
import org.cqframework.cql.elm.execution.Library;
@ -110,7 +108,7 @@ public class CqlR4Config extends BaseCqlConfig {
@Bean
public ElmCacheResourceChangeListener elmCacheResourceChangeListener(IResourceChangeListenerRegistry resourceChangeListenerRegistry, IFhirResourceDao<org.hl7.fhir.r4.model.Library> libraryDao, Map<org.cqframework.cql.elm.execution.VersionedIdentifier, Library> globalLibraryCache) {
ElmCacheResourceChangeListener listener = new ElmCacheResourceChangeListener(libraryDao, globalLibraryCache);
resourceChangeListenerRegistry.registerResourceResourceChangeListener("Library", new SearchParameterMap(), listener, 1000);
resourceChangeListenerRegistry.registerResourceResourceChangeListener("Library", SearchParameterMap.newSynchronous(), listener, 1000);
return listener;
}
}

View File

@ -33,7 +33,6 @@ import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.Extension;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.IntegerType;
import org.hl7.fhir.dstu3.model.ListResource;
import org.hl7.fhir.dstu3.model.Measure;
import org.hl7.fhir.dstu3.model.MeasureReport;
@ -65,20 +64,20 @@ import java.util.stream.Collectors;
public class MeasureEvaluation {
private static final Logger logger = LoggerFactory.getLogger(MeasureEvaluation.class);
private static final Logger logger = LoggerFactory.getLogger(MeasureEvaluation.class);
private Interval measurementPeriod;
private DaoRegistry registry;
private final Interval measurementPeriod;
private final DaoRegistry registry;
public MeasureEvaluation(DaoRegistry registry, Interval measurementPeriod) {
this.registry = registry;
this.measurementPeriod = measurementPeriod;
}
public MeasureEvaluation(DaoRegistry registry, Interval measurementPeriod) {
this.registry = registry;
this.measurementPeriod = measurementPeriod;
}
public MeasureReport evaluatePatientMeasure(Measure measure, Context context, String patientId) {
logger.info("Generating individual report");
public MeasureReport evaluatePatientMeasure(Measure measure, Context context, String patientId) {
logger.info("Generating individual report");
if (patientId == null) {
if (patientId == null) {
return evaluatePopulationMeasure(measure, context);
}
@ -107,24 +106,24 @@ public class MeasureEvaluation {
}
private List<Patient> getPractitionerPatients(String practitionerRef) {
SearchParameterMap map = new SearchParameterMap();
map.add("general-practitioner", new ReferenceParam(
practitionerRef.startsWith("Practitioner/") ? practitionerRef : "Practitioner/" + practitionerRef));
SearchParameterMap map = SearchParameterMap.newSynchronous();
map.add("general-practitioner", new ReferenceParam(
practitionerRef.startsWith("Practitioner/") ? practitionerRef : "Practitioner/" + practitionerRef));
List<Patient> patients = new ArrayList<>();
IBundleProvider patientProvider = registry.getResourceDao("Patient").search(map);
List<IBaseResource> patientList = patientProvider.getResources(0, patientProvider.size());
patientList.forEach(x -> patients.add((Patient) x));
return patients;
}
List<Patient> patients = new ArrayList<>();
IBundleProvider patientProvider = registry.getResourceDao("Patient").search(map);
List<IBaseResource> patientList = patientProvider.getAllResources();
patientList.forEach(x -> patients.add((Patient) x));
return patients;
}
private List<Patient> getAllPatients() {
List<Patient> patients = new ArrayList<>();
IBundleProvider patientProvider = registry.getResourceDao("Patient").search(new SearchParameterMap());
List<IBaseResource> patientList = patientProvider.getResources(0, patientProvider.size());
patientList.forEach(x -> patients.add((Patient) x));
return patients;
}
List<Patient> patients = new ArrayList<>();
IBundleProvider patientProvider = registry.getResourceDao("Patient").search(SearchParameterMap.newSynchronous());
List<IBaseResource> patientList = patientProvider.getAllResources();
patientList.forEach(x -> patients.add((Patient) x));
return patients;
}
public MeasureReport evaluatePopulationMeasure(Measure measure, Context context) {
logger.info("Generating summary report");
@ -567,8 +566,8 @@ public class MeasureEvaluation {
}
if (!list.isEmpty()) {
list.setId("List/" + UUID.randomUUID().toString());
list.setTitle(key);
list.setId("List/" + UUID.randomUUID());
list.setTitle(key);
resources.put(list.getId(), list);
list.getEntry().forEach(listResource -> evaluatedResourcesList.add(listResource.getItem().getReference()));
}
@ -713,17 +712,15 @@ public class MeasureEvaluation {
for (Object o : context.getEvaluatedResources()) {
if (o instanceof Resource) {
Resource r = (Resource) o;
String id = (r.getIdElement().getResourceType() != null ? (r.getIdElement().getResourceType() + "/")
: "") + r.getIdElement().getIdPart();
if (!codeHashSet.contains(id)) {
codeHashSet.add(id);
}
Resource r = (Resource) o;
String id = (r.getIdElement().getResourceType() != null ? (r.getIdElement().getResourceType() + "/")
: "") + r.getIdElement().getIdPart();
codeHashSet.add(id);
if (!resources.containsKey(id)) {
resources.put(id, r);
}
}
if (!resources.containsKey(id)) {
resources.put(id, r);
}
}
}
context.clearEvaluatedResources();

View File

@ -96,8 +96,8 @@ public class JpaTerminologyProvider implements TerminologyProvider {
}
IBundleProvider bundleProvider = myValueSetDao
.search(new SearchParameterMap().add(ValueSet.SP_URL, new UriParam(valueSet.getId())));
List<IBaseResource> valueSets = bundleProvider.getResources(0, bundleProvider.size());
.search(SearchParameterMap.newSynchronous().add(ValueSet.SP_URL, new UriParam(valueSet.getId())));
List<IBaseResource> valueSets = bundleProvider.getAllResources();
if (valueSets.isEmpty()) {
throw new IllegalArgumentException(String.format("Could not resolve value set %s.", valueSet.getId()));
} else if (valueSets.size() == 1) {

View File

@ -67,7 +67,7 @@ public class LibraryResolutionProviderImpl implements LibraryResolutionProvider<
version = parts[1];
}
SearchParameterMap map = new SearchParameterMap();
SearchParameterMap map = SearchParameterMap.newSynchronous();
map.add("url", new UriParam(resourceUrl));
if (version != null) {
map.add("version", new TokenParam(version));
@ -75,10 +75,10 @@ public class LibraryResolutionProviderImpl implements LibraryResolutionProvider<
ca.uhn.fhir.rest.api.server.IBundleProvider bundleProvider = myLibraryDao.search(map);
if (bundleProvider.size() == 0) {
if (bundleProvider.size() == null || bundleProvider.size() == 0) {
return null;
}
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
List<IBaseResource> resourceList = bundleProvider.getAllResources();
return LibraryResolutionProvider.selectFromList(resolveLibraries(resourceList), version, x -> x.getVersion());
}
@ -97,14 +97,14 @@ public class LibraryResolutionProviderImpl implements LibraryResolutionProvider<
private Iterable<org.hl7.fhir.dstu3.model.Library> getLibrariesByName(String name) {
// Search for libraries by name
SearchParameterMap map = new SearchParameterMap();
SearchParameterMap map = SearchParameterMap.newSynchronous();
map.add("name", new StringParam(name, true));
ca.uhn.fhir.rest.api.server.IBundleProvider bundleProvider = myLibraryDao.search(map);
if (bundleProvider.size() == 0) {
if (bundleProvider.size() == null || bundleProvider.size() == 0) {
return new ArrayList<>();
}
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
List<IBaseResource> resourceList = bundleProvider.getAllResources();
return resolveLibraries(resourceList);
}

View File

@ -35,7 +35,6 @@ import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.Extension;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.IntegerType;
import org.hl7.fhir.r4.model.ListResource;
import org.hl7.fhir.r4.model.Measure;
import org.hl7.fhir.r4.model.MeasureReport;
@ -68,9 +67,9 @@ public class MeasureEvaluation {
private static final Logger logger = LoggerFactory.getLogger(MeasureEvaluation.class);
private DataProvider provider;
private Interval measurementPeriod;
private DaoRegistry registry;
private final DataProvider provider;
private final Interval measurementPeriod;
private final DaoRegistry registry;
public MeasureEvaluation(DataProvider provider, DaoRegistry registry, Interval measurementPeriod) {
this.provider = provider;
@ -106,21 +105,21 @@ public class MeasureEvaluation {
}
private List<Patient> getPractitionerPatients(String practitionerRef) {
SearchParameterMap map = new SearchParameterMap();
SearchParameterMap map = SearchParameterMap.newSynchronous();
map.add("general-practitioner", new ReferenceParam(
practitionerRef.startsWith("Practitioner/") ? practitionerRef : "Practitioner/" + practitionerRef));
practitionerRef.startsWith("Practitioner/") ? practitionerRef : "Practitioner/" + practitionerRef));
List<Patient> patients = new ArrayList<>();
IBundleProvider patientProvider = registry.getResourceDao("Patient").search(map);
List<IBaseResource> patientList = patientProvider.getResources(0, patientProvider.size());
List<IBaseResource> patientList = patientProvider.getAllResources();
patientList.forEach(x -> patients.add((Patient) x));
return patients;
}
private List<Patient> getAllPatients() {
List<Patient> patients = new ArrayList<>();
IBundleProvider patientProvider = registry.getResourceDao("Patient").search(new SearchParameterMap());
List<IBaseResource> patientList = patientProvider.getResources(0, patientProvider.size());
IBundleProvider patientProvider = registry.getResourceDao("Patient").search(SearchParameterMap.newSynchronous());
List<IBaseResource> patientList = patientProvider.getAllResources();
patientList.forEach(x -> patients.add((Patient) x));
return patients;
}
@ -552,7 +551,7 @@ public class MeasureEvaluation {
}
if (!list.isEmpty()) {
list.setId("List/" + UUID.randomUUID().toString());
list.setId("List/" + UUID.randomUUID());
list.setTitle(key);
resources.put(list.getId(), list);
list.getEntry().forEach(listResource -> evaluatedResourcesList.add(listResource.getItem().getReference()));
@ -700,10 +699,8 @@ public class MeasureEvaluation {
if (o instanceof Resource) {
Resource r = (Resource) o;
String id = (r.getIdElement().getResourceType() != null ? (r.getIdElement().getResourceType() + "/") : "")
+ r.getIdElement().getIdPart();
if (!codeHashSet.contains(id)) {
codeHashSet.add(id);
}
+ r.getIdElement().getIdPart();
codeHashSet.add(id);
if (!resources.containsKey(id)) {
resources.put(id, r);

View File

@ -94,8 +94,8 @@ public class JpaTerminologyProvider implements TerminologyProvider {
}
IBundleProvider bundleProvider = myValueSetDao
.search(new SearchParameterMap().add(ValueSet.SP_URL, new UriParam(valueSet.getId())));
List<IBaseResource> valueSets = bundleProvider.getResources(0, bundleProvider.size());
.search(SearchParameterMap.newSynchronous().add(ValueSet.SP_URL, new UriParam(valueSet.getId())));
List<IBaseResource> valueSets = bundleProvider.getAllResources();
if (valueSets.isEmpty()) {
throw new IllegalArgumentException(String.format("Could not resolve value set %s.", valueSet.getId()));
} else if (valueSets.size() == 1) {

View File

@ -86,7 +86,7 @@ public class LibraryResolutionProviderImpl implements LibraryResolutionProvider<
version = parts[1];
}
SearchParameterMap map = new SearchParameterMap();
SearchParameterMap map = SearchParameterMap.newSynchronous();
map.add("url", new UriParam(resourceUrl));
if (version != null) {
map.add("version", new TokenParam(version));
@ -94,23 +94,23 @@ public class LibraryResolutionProviderImpl implements LibraryResolutionProvider<
ca.uhn.fhir.rest.api.server.IBundleProvider bundleProvider = myLibraryDao.search(map);
if (bundleProvider.size() == 0) {
if (bundleProvider.size() == null || bundleProvider.size() == 0) {
return null;
}
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
List<IBaseResource> resourceList = bundleProvider.getAllResources();
return LibraryResolutionProvider.selectFromList(resolveLibraries(resourceList), version, x -> x.getVersion());
}
private Iterable<org.hl7.fhir.r4.model.Library> getLibrariesByName(String name) {
// Search for libraries by name
SearchParameterMap map = new SearchParameterMap();
SearchParameterMap map = SearchParameterMap.newSynchronous();
map.add("name", new StringParam(name, true));
ca.uhn.fhir.rest.api.server.IBundleProvider bundleProvider = myLibraryDao.search(map);
if (bundleProvider.size() == 0) {
if (bundleProvider.size() == null || bundleProvider.size() == 0) {
return new ArrayList<>();
}
List<IBaseResource> resourceList = bundleProvider.getResources(0, bundleProvider.size());
List<IBaseResource> resourceList = bundleProvider.getAllResources();
return resolveLibraries(resourceList);
}

View File

@ -20,15 +20,15 @@ package ca.uhn.fhir.jpa.mdm.svc.candidate;
* #L%
*/
import ca.uhn.fhir.mdm.api.IMdmSettings;
import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.mdm.rules.json.MdmFilterSearchParamJson;
import ca.uhn.fhir.mdm.rules.json.MdmResourceSearchParamJson;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.mdm.svc.MdmSearchParamSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.mdm.api.IMdmSettings;
import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.mdm.rules.json.MdmFilterSearchParamJson;
import ca.uhn.fhir.mdm.rules.json.MdmResourceSearchParamJson;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -136,7 +136,7 @@ public class MdmCandidateSearchSvc {
//3.
IFhirResourceDao<?> resourceDao = myDaoRegistry.getResourceDao(theResourceType);
IBundleProvider search = resourceDao.search(searchParameterMap);
List<IBaseResource> resources = search.getResources(0, search.size());
List<IBaseResource> resources = search.getAllResources();
int initialSize = theMatchedPidsToResources.size();

View File

@ -1,9 +1,9 @@
package ca.uhn.fhir.jpa.mdm.svc;
import ca.uhn.fhir.mdm.api.IMdmSubmitSvc;
import ca.uhn.fhir.interceptor.api.IInterceptorService;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
import ca.uhn.fhir.mdm.api.IMdmSubmitSvc;
import ca.uhn.test.concurrency.PointcutLatch;
import org.apache.commons.lang3.time.DateUtils;
import org.junit.jupiter.api.AfterEach;
@ -14,7 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.util.Date;
class MdmBatchSvcImplTest extends BaseMdmR4Test {
class MdmBatchSvcImplIT extends BaseMdmR4Test {
@Autowired
IMdmSubmitSvc myMdmSubmitSvc;

View File

@ -66,7 +66,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
@Scope("prototype")
public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDeliverySubscriber {
private static Logger ourLog = LoggerFactory.getLogger(SubscriptionDeliveringRestHookSubscriber.class);
private static final Logger ourLog = LoggerFactory.getLogger(SubscriptionDeliveringRestHookSubscriber.class);
@Autowired
private DaoRegistry myDaoRegistry;
@ -155,7 +155,7 @@ public class SubscriptionDeliveringRestHookSubscriber extends BaseSubscriptionDe
IBundleProvider searchResults = dao.search(payloadSearchMap);
BundleBuilder builder = new BundleBuilder(myFhirContext);
for (IBaseResource next : searchResults.getResources(0, searchResults.size())) {
for (IBaseResource next : searchResults.getAllResources()) {
builder.addTransactionUpdateEntry(next);
}

View File

@ -1,11 +1,13 @@
package ca.uhn.fhir.rest.api.server;
import ca.uhn.fhir.context.ConfigurationException;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -113,6 +115,26 @@ public interface IBundleProvider {
@Nonnull
List<IBaseResource> getResources(int theFromIndex, int theToIndex);
/**
* Get all resources
*
* @return getResources(0, this.size ()). Return an empty list if size() is zero.
* @throws ConfigurationException if size() is null
*/
@Nonnull
default List<IBaseResource> getAllResources() {
List<IBaseResource> retval = new ArrayList<>();
Integer size = size();
if (size == null) {
throw new ConfigurationException("Attempt to request all resources from an asynchronous search result. The SearchParameterMap for this search probably should have been synchronous.");
}
if (size > 0) {
retval.addAll(getResources(0, size));
}
return retval;
}
/**
* Returns the UUID associated with this search. Note that this
* does not need to return a non-null value unless it a

View File

@ -19,12 +19,6 @@ package ca.uhn.fhir.rest.server.method;
* limitations under the License.
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.lang.reflect.Method;
import java.util.List;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
@ -34,13 +28,20 @@ import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.*;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.rest.server.method.TransactionParameter.ParamStyle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import javax.annotation.Nonnull;
import java.lang.reflect.Method;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class TransactionMethodBinding extends BaseResourceReturningMethodBinding {
@ -127,7 +128,7 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
* " entries, but server method response contained " + retVal.size() + " entries (must be the same)"); } }
*/
List<IBaseResource> retResources = retVal.getResources(0, retVal.size());
List<IBaseResource> retResources = retVal.getAllResources();
for (int i = 0; i < retResources.size(); i++) {
IBaseResource newRes = retResources.get(i);
if (newRes.getIdElement() == null || newRes.getIdElement().isEmpty()) {

View File

@ -1,12 +1,15 @@
package ca.uhn.fhir.rest.api.server;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
import com.google.common.collect.Lists;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.mock;
public class IBundleProviderTest {
@ -39,4 +42,19 @@ public class IBundleProviderTest {
assertFalse(provider.isEmpty());
}
@Test
void getResources() {
SimpleBundleProvider provider = new SimpleBundleProvider() {
@Override
public Integer size() {
return null;
}
};
try {
provider.getAllResources();
fail();
} catch (ConfigurationException e) {
assertEquals("Attempt to request all resources from an asynchronous search result. The SearchParameterMap for this search probably should have been synchronous.", e.getMessage());
}
}
}