Propagate RequestDetails to everything in JPA server (#1358)

This commit is contained in:
James Agnew 2019-06-22 15:18:06 -05:00 committed by GitHub
parent 58e6b7f6aa
commit 4ad1808da3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
85 changed files with 728 additions and 718 deletions

View File

@ -904,7 +904,7 @@ public enum Pointcut {
* Hooks should return <code>void</code>.
* </p>
*/
STORAGE_PROCESSING_MESSAGE(void.class,
JPA_PERFTRACE_WARNING(void.class,
"ca.uhn.fhir.jpa.model.search.StorageProcessingMessage"
),

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.config;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.HapiLocalizer;
import ca.uhn.fhir.interceptor.api.IInterceptorService;
import ca.uhn.fhir.interceptor.executor.InterceptorService;
import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.provider.SubscriptionTriggeringProvider;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
@ -16,7 +17,6 @@ import ca.uhn.fhir.jpa.subscription.module.cache.ISubscribableChannelFactory;
import ca.uhn.fhir.jpa.subscription.module.cache.LinkedBlockingQueueSubscribableChannelFactory;
import ca.uhn.fhir.jpa.subscription.module.matcher.ISubscriptionMatcher;
import ca.uhn.fhir.jpa.subscription.module.matcher.InMemorySubscriptionMatcher;
import ca.uhn.fhir.jpa.util.JpaInterceptorService;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
@ -45,9 +45,9 @@ import javax.annotation.Nonnull;
* 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.
@ -179,7 +179,7 @@ public abstract class BaseConfig implements SchedulingConfigurer {
@Bean
public IInterceptorService jpaInterceptorService() {
return new JpaInterceptorService();
return new InterceptorService();
}
/**

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
import ca.uhn.fhir.jpa.util.JpaConstants;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag;
@ -281,7 +282,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
}
}
private void findMatchingTagIds(String theResourceName, IIdType theResourceId, Set<Long> tagIds, Class<? extends BaseTag> entityClass) {
private void findMatchingTagIds(RequestDetails theRequest, String theResourceName, IIdType theResourceId, Set<Long> tagIds, Class<? extends BaseTag> entityClass) {
{
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = builder.createTupleQuery();
@ -291,7 +292,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
if (theResourceName != null) {
Predicate typePredicate = builder.equal(from.get("myResourceType"), theResourceName);
if (theResourceId != null) {
cq.where(typePredicate, builder.equal(from.get("myResourceId"), myIdHelperService.translateForcedIdToPid(theResourceName, theResourceId.getIdPart())));
cq.where(typePredicate, builder.equal(from.get("myResourceId"), myIdHelperService.translateForcedIdToPid(theResourceName, theResourceId.getIdPart(), theRequest)));
} else {
cq.where(typePredicate);
}
@ -387,13 +388,13 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
}
}
protected TagList getTags(Class<? extends IBaseResource> theResourceType, IIdType theResourceId) {
protected TagList getTags(RequestDetails theRequest, Class<? extends IBaseResource> theResourceType, IIdType theResourceId) {
String resourceName = null;
if (theResourceType != null) {
resourceName = toResourceName(theResourceType);
if (theResourceId != null && theResourceId.hasVersionIdPart()) {
IFhirResourceDao<? extends IBaseResource> dao = getDao(theResourceType);
BaseHasResource entity = dao.readEntity(theResourceId);
BaseHasResource entity = dao.readEntity(theResourceId, theRequest);
TagList retVal = new TagList();
for (BaseTag next : entity.getTags()) {
retVal.add(next.getTag().toTag());
@ -403,8 +404,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
}
Set<Long> tagIds = new HashSet<>();
findMatchingTagIds(resourceName, theResourceId, tagIds, ResourceTag.class);
findMatchingTagIds(resourceName, theResourceId, tagIds, ResourceHistoryTag.class);
findMatchingTagIds(theRequest, resourceName, theResourceId, tagIds, ResourceTag.class);
findMatchingTagIds(theRequest, resourceName, theResourceId, tagIds, ResourceHistoryTag.class);
if (tagIds.isEmpty()) {
return new TagList();
}
@ -426,7 +427,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
}
}
protected IBundleProvider history(String theResourceName, Long theId, Date theSince, Date theUntil) {
protected IBundleProvider history(RequestDetails theRequest, String theResourceName, Long theId, Date theSince, Date theUntil) {
String resourceName = defaultIfBlank(theResourceName, null);
@ -461,7 +462,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
search = mySearchDao.save(search);
return new PersistedJpaBundleProvider(search.getUuid(), this);
return new PersistedJpaBundleProvider(theRequest, search.getUuid(), this);
}
void incrementId(T theResource, ResourceTable theSavedEntity, IIdType theResourceId) {
@ -781,7 +782,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
}
@CoverageIgnore
public BaseHasResource readEntity(IIdType theValueId) {
public BaseHasResource readEntity(IIdType theValueId, RequestDetails theRequest) {
throw new NotImplementedException("");
}
@ -1021,7 +1022,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
if (thePerformIndexing) {
newParams = new ResourceIndexedSearchParams();
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, this, theUpdateTime, theEntity, theResource, existingParams);
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, this, theUpdateTime, theEntity, theResource, existingParams, theRequest);
changed = populateResourceIntoEntity(theRequest, theResource, theEntity, true);
if (changed.isChanged()) {
@ -1161,7 +1162,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
.add(IBaseResource.class, theResource)
.add(RequestDetails.class, theRequestDetails)
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRESTORAGE_RESOURCE_UPDATED, hookParams);
doCallHooks(theRequestDetails, Pointcut.STORAGE_PRESTORAGE_RESOURCE_UPDATED, hookParams);
// Perform update
ResourceTable savedEntity = updateEntity(theRequestDetails, theResource, theEntity, null, thePerformIndexing, thePerformIndexing, new Date(), theForceUpdateVersion, thePerformIndexing);
@ -1191,7 +1192,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
.add(IBaseResource.class, theResource)
.add(RequestDetails.class, theRequestDetails)
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED, hookParams);
doCallHooks(theRequestDetails, Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED, hookParams);
}
});
}
@ -1199,6 +1200,10 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
return savedEntity;
}
protected void doCallHooks(RequestDetails theRequestDetails, Pointcut thePointcut, HookParams theParams) {
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, thePointcut, theParams);
}
protected void updateResourceMetadata(IBaseResourceEntity theEntity, IBaseResource theResource) {
IIdType id = theEntity.getIdDt();
if (getContext().getVersion().getVersion().isRi()) {

View File

@ -75,7 +75,6 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import static ca.uhn.fhir.util.UrlUtil.sanitizeUrlPart;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
@Transactional(propagation = Propagation.REQUIRED)
@ -99,9 +98,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
private String mySecondaryPrimaryKeyParamName;
@Override
public void addTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel) {
public void addTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel, RequestDetails theRequest) {
StopWatch w = new StopWatch();
BaseHasResource entity = readEntity(theId);
BaseHasResource entity = readEntity(theId, theRequest);
if (entity == null) {
throw new ResourceNotFoundException(theId);
}
@ -192,7 +191,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
if (theId == null || !theId.hasIdPart()) {
throw new InvalidRequestException("Can not perform delete, no ID provided");
}
final ResourceTable entity = readEntityLatestVersion(theId);
final ResourceTable entity = readEntityLatestVersion(theId, theRequest);
if (theId.hasVersionIdPart() && Long.parseLong(theId.getVersionIdPart()) != entity.getVersion()) {
throw new ResourceVersionConflictException("Trying to delete " + theId + " but this is not the current version");
}
@ -225,9 +224,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
.add(IBaseResource.class, resourceToDelete)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRESTORAGE_RESOURCE_DELETED, hook);
doCallHooks(theRequest, Pointcut.STORAGE_PRESTORAGE_RESOURCE_DELETED, hook);
myDeleteConflictService.validateOkToDelete(theDeleteConflicts, entity, false);
myDeleteConflictService.validateOkToDelete(theDeleteConflicts, entity, false, theRequest);
preDelete(resourceToDelete, entity);
@ -248,7 +247,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
.add(IBaseResource.class, resourceToDelete)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED, hookParams);
doCallHooks(theRequest, Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED, hookParams);
}
});
@ -278,14 +277,14 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
/**
* This method gets called by {@link #deleteByUrl(String, List, RequestDetails)} as well as by
* This method gets called by {@link #deleteByUrl(String, DeleteConflictList, RequestDetails)} as well as by
* transaction processors
*/
@Override
public DeleteMethodOutcome deleteByUrl(String theUrl, DeleteConflictList deleteConflicts, RequestDetails theRequest) {
StopWatch w = new StopWatch();
Set<Long> resourceIds = myMatchResourceUrlService.processMatchUrl(theUrl, myResourceType);
Set<Long> resourceIds = myMatchResourceUrlService.processMatchUrl(theUrl, myResourceType, theRequest);
if (resourceIds.size() > 1) {
if (myDaoConfig.isAllowMultipleDelete() == false) {
throw new PreconditionFailedException(getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "DELETE", theUrl, resourceIds.size()));
@ -304,9 +303,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
.add(IBaseResource.class, resourceToDelete)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRESTORAGE_RESOURCE_DELETED, hooks);
doCallHooks(theRequest, Pointcut.STORAGE_PRESTORAGE_RESOURCE_DELETED, hooks);
myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, false);
myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, false, theRequest);
// Notify interceptors
IdDt idToDelete = entity.getIdDt();
@ -328,7 +327,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
.add(IBaseResource.class, resourceToDelete)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED, hookParams);
doCallHooks(theRequest, Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED, hookParams);
}
});
}
@ -383,7 +382,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
entity.setResourceType(toResourceName(theResource));
if (isNotBlank(theIfNoneExist)) {
Set<Long> match = myMatchResourceUrlService.processMatchUrl(theIfNoneExist, myResourceType);
Set<Long> match = myMatchResourceUrlService.processMatchUrl(theIfNoneExist, myResourceType, theRequest);
if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "CREATE", theIfNoneExist, match.size());
throw new PreconditionFailedException(msg);
@ -429,7 +428,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
.add(IBaseResource.class, theResource)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRESTORAGE_RESOURCE_CREATED, hookParams);
doCallHooks(theRequest, Pointcut.STORAGE_PRESTORAGE_RESOURCE_CREATED, hookParams);
// Perform actual DB update
ResourceTable updatedEntity = updateEntity(theRequest, theResource, entity, null, thePerformIndexing, thePerformIndexing, theUpdateTime, false, thePerformIndexing);
@ -471,7 +470,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
.add(IBaseResource.class, theResource)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED, hookParams);
doCallHooks(theRequest, Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED, hookParams);
}
});
}
@ -546,14 +545,14 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Override
@Transactional(propagation = Propagation.NEVER)
public ExpungeOutcome expunge(IIdType theId, ExpungeOptions theExpungeOptions) {
public ExpungeOutcome expunge(IIdType theId, ExpungeOptions theExpungeOptions, RequestDetails theRequest) {
TransactionTemplate txTemplate = new TransactionTemplate(myPlatformTransactionManager);
BaseHasResource entity = txTemplate.execute(t -> readEntity(theId));
BaseHasResource entity = txTemplate.execute(t -> readEntity(theId, theRequest));
if (theId.hasVersionIdPart()) {
BaseHasResource currentVersion;
currentVersion = txTemplate.execute(t -> readEntity(theId.toVersionless()));
currentVersion = txTemplate.execute(t -> readEntity(theId.toVersionless(), theRequest));
if (entity.getVersion() == currentVersion.getVersion()) {
throw new PreconditionFailedException("Can not perform version-specific expunge of resource " + theId.toUnqualified().getValue() + " as this is the current version");
}
@ -579,7 +578,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
notifyInterceptors(RestOperationTypeEnum.GET_TAGS, requestDetails);
StopWatch w = new StopWatch();
TagList tags = super.getTags(myResourceType, null);
TagList tags = super.getTags(theRequestDetails, myResourceType, null);
ourLog.debug("Processed getTags on {} in {}ms", myResourceName, w.getMillisAndRestart());
return tags;
}
@ -606,7 +605,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
notifyInterceptors(RestOperationTypeEnum.GET_TAGS, requestDetails);
StopWatch w = new StopWatch();
TagList retVal = super.getTags(myResourceType, theResourceId);
TagList retVal = super.getTags(theRequestDetails, myResourceType, theResourceId);
ourLog.debug("Processed getTags on {} in {}ms", theResourceId, w.getMillisAndRestart());
return retVal;
}
@ -618,23 +617,23 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
notifyInterceptors(RestOperationTypeEnum.HISTORY_TYPE, requestDetails);
StopWatch w = new StopWatch();
IBundleProvider retVal = super.history(myResourceName, null, theSince, theUntil);
IBundleProvider retVal = super.history(theRequestDetails, myResourceName, null, theSince, theUntil);
ourLog.debug("Processed history on {} in {}ms", myResourceName, w.getMillisAndRestart());
return retVal;
}
@Override
public IBundleProvider history(final IIdType theId, final Date theSince, Date theUntil, RequestDetails theRequestDetails) {
public IBundleProvider history(final IIdType theId, final Date theSince, Date theUntil, RequestDetails theRequest) {
// Notify interceptors
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), theId);
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequest, getResourceName(), theId);
notifyInterceptors(RestOperationTypeEnum.HISTORY_INSTANCE, requestDetails);
StopWatch w = new StopWatch();
IIdType id = theId.withResourceType(myResourceName).toUnqualifiedVersionless();
BaseHasResource entity = readEntity(id);
BaseHasResource entity = readEntity(id, theRequest);
IBundleProvider retVal = super.history(myResourceName, entity.getId(), theSince, theUntil);
IBundleProvider retVal = super.history(theRequest, myResourceName, entity.getId(), theSince, theUntil);
ourLog.debug("Processed history on {} in {}ms", id, w.getMillisAndRestart());
return retVal;
@ -673,20 +672,20 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
@Override
public <MT extends IBaseMetaType> MT metaAddOperation(IIdType theResourceId, MT theMetaAdd, RequestDetails theRequestDetails) {
public <MT extends IBaseMetaType> MT metaAddOperation(IIdType theResourceId, MT theMetaAdd, RequestDetails theRequest) {
// Notify interceptors
if (theRequestDetails != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), theResourceId);
if (theRequest != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequest, getResourceName(), theResourceId);
notifyInterceptors(RestOperationTypeEnum.META_ADD, requestDetails);
}
StopWatch w = new StopWatch();
BaseHasResource entity = readEntity(theResourceId);
BaseHasResource entity = readEntity(theResourceId, theRequest);
if (entity == null) {
throw new ResourceNotFoundException(theResourceId);
}
ResourceTable latestVersion = readEntityLatestVersion(theResourceId);
ResourceTable latestVersion = readEntityLatestVersion(theResourceId, theRequest);
if (latestVersion.getVersion() != entity.getVersion()) {
doMetaAdd(theMetaAdd, entity);
} else {
@ -700,25 +699,25 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
ourLog.debug("Processed metaAddOperation on {} in {}ms", new Object[]{theResourceId, w.getMillisAndRestart()});
@SuppressWarnings("unchecked")
MT retVal = (MT) metaGetOperation(theMetaAdd.getClass(), theResourceId, theRequestDetails);
MT retVal = (MT) metaGetOperation(theMetaAdd.getClass(), theResourceId, theRequest);
return retVal;
}
@Override
public <MT extends IBaseMetaType> MT metaDeleteOperation(IIdType theResourceId, MT theMetaDel, RequestDetails theRequestDetails) {
public <MT extends IBaseMetaType> MT metaDeleteOperation(IIdType theResourceId, MT theMetaDel, RequestDetails theRequest) {
// Notify interceptors
if (theRequestDetails != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), theResourceId);
if (theRequest != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequest, getResourceName(), theResourceId);
notifyInterceptors(RestOperationTypeEnum.META_DELETE, requestDetails);
}
StopWatch w = new StopWatch();
BaseHasResource entity = readEntity(theResourceId);
BaseHasResource entity = readEntity(theResourceId, theRequest);
if (entity == null) {
throw new ResourceNotFoundException(theResourceId);
}
ResourceTable latestVersion = readEntityLatestVersion(theResourceId);
ResourceTable latestVersion = readEntityLatestVersion(theResourceId, theRequest);
if (latestVersion.getVersion() != entity.getVersion()) {
doMetaDelete(theMetaDel, entity);
} else {
@ -734,20 +733,20 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
ourLog.debug("Processed metaDeleteOperation on {} in {}ms", new Object[]{theResourceId.getValue(), w.getMillisAndRestart()});
@SuppressWarnings("unchecked")
MT retVal = (MT) metaGetOperation(theMetaDel.getClass(), theResourceId, theRequestDetails);
MT retVal = (MT) metaGetOperation(theMetaDel.getClass(), theResourceId, theRequest);
return retVal;
}
@Override
public <MT extends IBaseMetaType> MT metaGetOperation(Class<MT> theType, IIdType theId, RequestDetails theRequestDetails) {
public <MT extends IBaseMetaType> MT metaGetOperation(Class<MT> theType, IIdType theId, RequestDetails theRequest) {
// Notify interceptors
if (theRequestDetails != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), theId);
if (theRequest != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequest, getResourceName(), theId);
notifyInterceptors(RestOperationTypeEnum.META, requestDetails);
}
Set<TagDefinition> tagDefs = new HashSet<>();
BaseHasResource entity = readEntity(theId);
BaseHasResource entity = readEntity(theId, theRequest);
for (BaseTag next : entity.getTags()) {
tagDefs.add(next.getTag());
}
@ -776,12 +775,12 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
@Override
public DaoMethodOutcome patch(IIdType theId, String theConditionalUrl, PatchTypeEnum thePatchType, String thePatchBody, RequestDetails theRequestDetails) {
public DaoMethodOutcome patch(IIdType theId, String theConditionalUrl, PatchTypeEnum thePatchType, String thePatchBody, RequestDetails theRequest) {
ResourceTable entityToUpdate;
if (isNotBlank(theConditionalUrl)) {
Set<Long> match = myMatchResourceUrlService.processMatchUrl(theConditionalUrl, myResourceType);
Set<Long> match = myMatchResourceUrlService.processMatchUrl(theConditionalUrl, myResourceType, theRequest);
if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "PATCH", theConditionalUrl, match.size());
throw new PreconditionFailedException(msg);
@ -794,7 +793,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
} else {
entityToUpdate = readEntityLatestVersion(theId);
entityToUpdate = readEntityLatestVersion(theId, theRequest);
if (theId.hasVersionIdPart()) {
if (theId.getVersionIdPartAsLong() != entityToUpdate.getVersion()) {
throw new ResourceVersionConflictException("Version " + theId.getVersionIdPart() + " is not the most recent version of this resource, unable to apply patch");
@ -814,7 +813,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@SuppressWarnings("unchecked")
T destinationCasted = (T) destination;
return update(destinationCasted, null, true, theRequestDetails);
return update(destinationCasted, null, true, theRequest);
}
@PostConstruct
@ -878,8 +877,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
@Override
public Set<Long> processMatchUrl(String theMatchUrl) {
return myMatchResourceUrlService.processMatchUrl(theMatchUrl, getResourceType());
public Set<Long> processMatchUrl(String theMatchUrl, RequestDetails theRequest) {
return myMatchResourceUrlService.processMatchUrl(theMatchUrl, getResourceType(), theRequest);
}
@Override
@ -912,18 +911,18 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
@Override
public T read(IIdType theId, RequestDetails theRequestDetails, boolean theDeletedOk) {
public T read(IIdType theId, RequestDetails theRequest, boolean theDeletedOk) {
validateResourceTypeAndThrowInvalidRequestException(theId);
// Notify interceptors
if (theRequestDetails != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), theId);
if (theRequest != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequest, getResourceName(), theId);
RestOperationTypeEnum operationType = theId.hasVersionIdPart() ? RestOperationTypeEnum.VREAD : RestOperationTypeEnum.READ;
notifyInterceptors(operationType, requestDetails);
}
StopWatch w = new StopWatch();
BaseHasResource entity = readEntity(theId);
BaseHasResource entity = readEntity(theId, theRequest);
validateResourceType(entity);
T retVal = toResource(myResourceType, entity, null, false);
@ -937,25 +936,25 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
// Interceptor broadcast: RESOURCE_MAY_BE_RETURNED
HookParams params = new HookParams()
.add(IBaseResource.class, retVal)
.add(RequestDetails.class, theRequestDetails)
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PREACCESS_RESOURCE, params);
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
doCallHooks(theRequest, Pointcut.STORAGE_PREACCESS_RESOURCE, params);
ourLog.debug("Processed read on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
return retVal;
}
@Override
public BaseHasResource readEntity(IIdType theId) {
public BaseHasResource readEntity(IIdType theId, RequestDetails theRequest) {
return readEntity(theId, true);
return readEntity(theId, true, theRequest);
}
@Override
public BaseHasResource readEntity(IIdType theId, boolean theCheckForForcedId) {
public BaseHasResource readEntity(IIdType theId, boolean theCheckForForcedId, RequestDetails theRequest) {
validateResourceTypeAndThrowInvalidRequestException(theId);
Long pid = myIdHelperService.translateForcedIdToPid(getResourceName(), theId.getIdPart());
Long pid = myIdHelperService.translateForcedIdToPid(getResourceName(), theId.getIdPart(), theRequest);
BaseHasResource entity = myEntityManager.find(ResourceTable.class, pid);
if (entity == null) {
@ -993,8 +992,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
return entity;
}
protected ResourceTable readEntityLatestVersion(IIdType theId) {
ResourceTable entity = myEntityManager.find(ResourceTable.class, myIdHelperService.translateForcedIdToPid(getResourceName(), theId.getIdPart()));
protected ResourceTable readEntityLatestVersion(IIdType theId, RequestDetails theRequest) {
ResourceTable entity = myEntityManager.find(ResourceTable.class, myIdHelperService.translateForcedIdToPid(getResourceName(), theId.getIdPart(), theRequest));
if (entity == null) {
throw new ResourceNotFoundException(theId);
}
@ -1021,15 +1020,15 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
@Override
public void removeTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, RequestDetails theRequestDetails) {
public void removeTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, RequestDetails theRequest) {
// Notify interceptors
if (theRequestDetails != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), theId);
if (theRequest != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequest, getResourceName(), theId);
notifyInterceptors(RestOperationTypeEnum.DELETE_TAGS, requestDetails);
}
StopWatch w = new StopWatch();
BaseHasResource entity = readEntity(theId);
BaseHasResource entity = readEntity(theId, theRequest);
if (entity == null) {
throw new ResourceNotFoundException(theId);
}
@ -1060,13 +1059,13 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public IBundleProvider search(final SearchParameterMap theParams, RequestDetails theRequestDetails) {
return search(theParams, theRequestDetails, null);
public IBundleProvider search(final SearchParameterMap theParams, RequestDetails theRequest) {
return search(theParams, theRequest, null);
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public IBundleProvider search(final SearchParameterMap theParams, RequestDetails theRequestDetails, HttpServletResponse theServletResponse) {
public IBundleProvider search(final SearchParameterMap theParams, RequestDetails theRequest, HttpServletResponse theServletResponse) {
if (myDaoConfig.getIndexMissingFields() == DaoConfig.IndexEnabledEnum.DISABLED) {
for (List<List<IQueryParameterType>> nextAnds : theParams.values()) {
@ -1081,11 +1080,11 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
// Notify interceptors
if (theRequestDetails != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getContext(), getResourceName(), null);
if (theRequest != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequest, getContext(), getResourceName(), null);
notifyInterceptors(RestOperationTypeEnum.SEARCH_TYPE, requestDetails);
if (theRequestDetails.isSubRequest()) {
if (theRequest.isSubRequest()) {
Integer max = myDaoConfig.getMaximumSearchResultCountInTransaction();
if (max != null) {
Validate.inclusiveBetween(1, Integer.MAX_VALUE, max.intValue(), "Maximum search result count in transaction ust be a positive integer");
@ -1093,23 +1092,23 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
}
if (!isPagingProviderDatabaseBacked(theRequestDetails)) {
if (!isPagingProviderDatabaseBacked(theRequest)) {
theParams.setLoadSynchronous(true);
}
}
CacheControlDirective cacheControlDirective = new CacheControlDirective();
if (theRequestDetails != null) {
cacheControlDirective.parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL));
if (theRequest != null) {
cacheControlDirective.parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL));
}
IBundleProvider retVal = mySearchCoordinatorSvc.registerSearch(this, theParams, getResourceName(), cacheControlDirective);
IBundleProvider retVal = mySearchCoordinatorSvc.registerSearch(this, theParams, getResourceName(), cacheControlDirective, theRequest);
if (retVal instanceof PersistedJpaBundleProvider) {
PersistedJpaBundleProvider provider = (PersistedJpaBundleProvider) retVal;
if (provider.isCacheHit()) {
if (theServletResponse != null && theRequestDetails != null) {
String value = "HIT from " + theRequestDetails.getFhirServerBase();
if (theServletResponse != null && theRequest != null) {
String value = "HIT from " + theRequest.getFhirServerBase();
theServletResponse.addHeader(Constants.HEADER_X_CACHE, value);
}
}
@ -1119,7 +1118,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
@Override
public Set<Long> searchForIds(SearchParameterMap theParams) {
public Set<Long> searchForIds(SearchParameterMap theParams, RequestDetails theRequest) {
SearchBuilder builder = newSearchBuilder();
builder.setType(getResourceType(), getResourceName());
@ -1131,7 +1130,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
String uuid = UUID.randomUUID().toString();
SearchRuntimeDetails searchRuntimeDetails = new SearchRuntimeDetails(uuid);
try (IResultIterator iter = builder.createQuery(theParams, searchRuntimeDetails)) {
try (IResultIterator iter = builder.createQuery(theParams, searchRuntimeDetails, theRequest)) {
while (iter.hasNext()) {
retVal.add(iter.next());
}
@ -1200,7 +1199,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
.add(IBaseResource.class, theResource)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PREACCESS_RESOURCE, params);
doCallHooks(theRequest, Pointcut.STORAGE_PREACCESS_RESOURCE, params);
return outcome;
}
@ -1271,7 +1270,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
}
@Override
public DaoMethodOutcome update(T theResource, String theMatchUrl, boolean thePerformIndexing, boolean theForceUpdateVersion, RequestDetails theRequestDetails) {
public DaoMethodOutcome update(T theResource, String theMatchUrl, boolean thePerformIndexing, boolean theForceUpdateVersion, RequestDetails theRequest) {
if (theResource == null) {
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "missingBody");
throw new InvalidRequestException(msg);
@ -1285,7 +1284,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
IIdType resourceId;
if (isNotBlank(theMatchUrl)) {
Set<Long> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType);
Set<Long> match = myMatchResourceUrlService.processMatchUrl(theMatchUrl, myResourceType, theRequest);
if (match.size() > 1) {
String msg = getContext().getLocalizer().getMessageSanitized(BaseHapiFhirDao.class, "transactionOperationWithMultipleMatchFailure", "UPDATE", theMatchUrl, match.size());
throw new PreconditionFailedException(msg);
@ -1294,7 +1293,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
entity = myEntityManager.find(ResourceTable.class, pid);
resourceId = entity.getIdDt();
} else {
return create(theResource, null, thePerformIndexing, new Date(), theRequestDetails);
return create(theResource, null, thePerformIndexing, new Date(), theRequest);
}
} else {
/*
@ -1305,9 +1304,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
resourceId = theResource.getIdElement();
try {
entity = readEntityLatestVersion(resourceId);
entity = readEntityLatestVersion(resourceId, theRequest);
} catch (ResourceNotFoundException e) {
return doCreate(theResource, null, thePerformIndexing, new Date(), theRequestDetails);
return doCreate(theResource, null, thePerformIndexing, new Date(), theRequest);
}
}
@ -1344,7 +1343,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
*/
if (!thePerformIndexing) {
theResource.setId(entity.getIdDt().getValue());
DaoMethodOutcome outcome = toMethodOutcome(theRequestDetails, entity, theResource).setCreated(wasDeleted);
DaoMethodOutcome outcome = toMethodOutcome(theRequest, entity, theResource).setCreated(wasDeleted);
outcome.setPreviousResource(oldResource);
return outcome;
}
@ -1352,8 +1351,8 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
/*
* Otherwise, we're not in a transaction
*/
ResourceTable savedEntity = updateInternal(theRequestDetails, theResource, thePerformIndexing, theForceUpdateVersion, entity, resourceId, oldResource);
DaoMethodOutcome outcome = toMethodOutcome(theRequestDetails, savedEntity, theResource).setCreated(wasDeleted);
ResourceTable savedEntity = updateInternal(theRequest, theResource, thePerformIndexing, theForceUpdateVersion, entity, resourceId, oldResource);
DaoMethodOutcome outcome = toMethodOutcome(theRequest, savedEntity, theResource).setCreated(wasDeleted);
if (!thePerformIndexing) {
outcome.setId(theResource.getIdElement());

View File

@ -82,7 +82,7 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
}
StopWatch w = new StopWatch();
IBundleProvider retVal = super.history(null, null, theSince, theUntil);
IBundleProvider retVal = super.history(theRequestDetails, null, null, theSince, theUntil);
ourLog.info("Processed global history in {}ms", w.getMillisAndRestart());
return retVal;
}

View File

@ -69,21 +69,21 @@ public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResou
}
@Override
public MethodOutcome validate(T theResource, IIdType theId, String theRawResource, EncodingEnum theEncoding, ValidationModeEnum theMode, String theProfile, RequestDetails theRequestDetails) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, theResource, null, theId);
public MethodOutcome validate(T theResource, IIdType theId, String theRawResource, EncodingEnum theEncoding, ValidationModeEnum theMode, String theProfile, RequestDetails theRequest) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequest, theResource, null, theId);
notifyInterceptors(RestOperationTypeEnum.VALIDATE, requestDetails);
if (theMode == ValidationModeEnum.DELETE) {
if (theId == null || theId.hasIdPart() == false) {
throw new InvalidRequestException("No ID supplied. ID is required when validating with mode=DELETE");
}
final ResourceTable entity = readEntityLatestVersion(theId);
final ResourceTable entity = readEntityLatestVersion(theId, theRequest);
// Validate that there are no resources pointing to the candidate that
// would prevent deletion
DeleteConflictList deleteConflicts = new DeleteConflictList();
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete()) {
myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, true);
myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, true, theRequest);
}
myDeleteConflictService.validateDeleteConflictsEmptyOrThrowException(deleteConflicts);

View File

@ -43,7 +43,7 @@ public class FhirResourceDaoPatientDstu2 extends FhirResourceDaoDstu2<Patient>im
super();
}
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequest) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
@ -62,11 +62,11 @@ public class FhirResourceDaoPatientDstu2 extends FhirResourceDaoDstu2<Patient>im
paramMap.add("_id", new StringParam(theId.getIdPart()));
}
if (!isPagingProviderDatabaseBacked(theRequestDetails)) {
if (!isPagingProviderDatabaseBacked(theRequest)) {
paramMap.setLoadSynchronous(true);
}
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)));
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequest);
}
@Override

View File

@ -54,8 +54,8 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subsc
}
@Override
public Long getSubscriptionTablePidForSubscriptionResource(IIdType theId) {
ResourceTable entity = readEntityLatestVersion(theId);
public Long getSubscriptionTablePidForSubscriptionResource(IIdType theId, RequestDetails theRequest) {
ResourceTable entity = readEntityLatestVersion(theId, theRequest);
SubscriptionTable table = mySubscriptionTableDao.findOneByResourcePid(entity.getId());
if (table == null) {
return null;

View File

@ -91,8 +91,8 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
}
@Override
public ValueSet expand(IIdType theId, String theFilter, RequestDetails theRequestDetails) {
ValueSet source = loadValueSetForExpansion(theId);
public ValueSet expand(IIdType theId, String theFilter, RequestDetails theRequest) {
ValueSet source = loadValueSetForExpansion(theId, theRequest);
return expand(source, theFilter);
}
@ -156,13 +156,13 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
}
@Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem) {
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) {
if (theSystem != null && theSystem.startsWith("http://hl7.org/fhir/")) {
return Collections.singletonList((IIdType) new IdDt(theSystem));
}
List<IIdType> valueSetIds;
Set<Long> ids = searchForIds(new SearchParameterMap(ValueSet.SP_CODE, new TokenParam(theSystem, theCode)));
Set<Long> ids = searchForIds(new SearchParameterMap(ValueSet.SP_CODE, new TokenParam(theSystem, theCode)), theRequest);
valueSetIds = new ArrayList<IIdType>();
for (Long next : ids) {
valueSetIds.add(new IdDt("ValueSet", next));
@ -170,14 +170,14 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
return valueSetIds;
}
private ValueSet loadValueSetForExpansion(IIdType theId) {
private ValueSet loadValueSetForExpansion(IIdType theId, RequestDetails theRequest) {
if (theId.getValue().startsWith("http://hl7.org/fhir/")) {
org.hl7.fhir.instance.model.ValueSet valueSet = myValidationSupport.fetchResource(myRiCtx, org.hl7.fhir.instance.model.ValueSet.class, theId.getValue());
if (valueSet != null) {
return getContext().newJsonParser().parseResource(ValueSet.class, myRiCtx.newJsonParser().encodeResourceToString(valueSet));
}
}
BaseHasResource sourceEntity = readEntity(theId);
BaseHasResource sourceEntity = readEntity(theId, theRequest);
if (sourceEntity == null) {
throw new ResourceNotFoundException(theId);
}
@ -210,7 +210,7 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
}
@Override
public LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CodingDt theCoding, RequestDetails theRequestDetails) {
public LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CodingDt theCoding, RequestDetails theRequest) {
boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode());
boolean haveCode = theCode != null && theCode.isEmpty() == false;
boolean haveSystem = theSystem != null && theSystem.isEmpty() == false;
@ -232,9 +232,9 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
system = theSystem.getValue();
}
List<IIdType> valueSetIds = findCodeSystemIdsContainingSystemAndCode(code, system);
List<IIdType> valueSetIds = findCodeSystemIdsContainingSystemAndCode(code, system, theRequest);
for (IIdType nextId : valueSetIds) {
ValueSet expansion = expand(nextId, null, theRequestDetails);
ValueSet expansion = expand(nextId, null, theRequest);
List<ExpansionContains> contains = expansion.getExpansion().getContains();
LookupCodeResult result = lookup(contains, system, code);
if (result != null) {
@ -273,7 +273,7 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
@Override
public ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult validateCode(IPrimitiveType<String> theValueSetIdentifier, IIdType theId, IPrimitiveType<String> theCode,
IPrimitiveType<String> theSystem, IPrimitiveType<String> theDisplay, CodingDt theCoding, CodeableConceptDt theCodeableConcept, RequestDetails theRequestDetails) {
IPrimitiveType<String> theSystem, IPrimitiveType<String> theDisplay, CodingDt theCoding, CodeableConceptDt theCodeableConcept, RequestDetails theRequest) {
List<IIdType> valueSetIds;
boolean haveCodeableConcept = theCodeableConcept != null && theCodeableConcept.getCoding().size() > 0;
@ -291,8 +291,8 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
if (theId != null) {
valueSetIds = Collections.singletonList(theId);
} else if (haveIdentifierParam) {
Set<Long> ids = searchForIds(new SearchParameterMap(ValueSet.SP_IDENTIFIER, new TokenParam(null, theValueSetIdentifier.getValue())));
valueSetIds = new ArrayList<IIdType>();
Set<Long> ids = searchForIds(new SearchParameterMap(ValueSet.SP_IDENTIFIER, new TokenParam(null, theValueSetIdentifier.getValue())), theRequest);
valueSetIds = new ArrayList<>();
for (Long next : ids) {
valueSetIds.add(new IdDt("ValueSet", next));
}
@ -302,11 +302,11 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
}
String code = theCode.getValue();
String system = toStringOrNull(theSystem);
valueSetIds = findCodeSystemIdsContainingSystemAndCode(code, system);
valueSetIds = findCodeSystemIdsContainingSystemAndCode(code, system, theRequest);
}
for (IIdType nextId : valueSetIds) {
ValueSet expansion = expand(nextId, null, theRequestDetails);
ValueSet expansion = expand(nextId, null, theRequest);
List<ExpansionContains> contains = expansion.getExpansion().getContains();
ValidateCodeResult result = validateCodeIsInContains(contains, toStringOrNull(theSystem), toStringOrNull(theCode), theCoding, theCodeableConcept);
if (result != null) {

View File

@ -509,7 +509,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
String matchUrl = nextEntry.getRequest().getIfNoneExist();
if (isNotBlank(matchUrl)) {
IFhirResourceDao<?> resourceDao = getDao(nextEntry.getResource().getClass());
Set<Long> val = resourceDao.processMatchUrl(matchUrl);
Set<Long> val = resourceDao.processMatchUrl(matchUrl, theRequestDetails);
if (val.size() > 1) {
throw new InvalidRequestException(
"Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@ -214,7 +215,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
}
@Override
public List<Long> everything(String theResourceName, SearchParameterMap theParams) {
public List<Long> everything(String theResourceName, SearchParameterMap theParams, RequestDetails theRequest) {
Long pid = null;
if (theParams.get(IAnyResource.SP_RES_ID) != null) {
@ -227,7 +228,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
StringParam idParm = (StringParam) idParam;
idParamValue = idParm.getValue();
}
pid = myIdHelperService.translateForcedIdToPid(theResourceName, idParamValue);
pid = myIdHelperService.translateForcedIdToPid(theResourceName, idParamValue, theRequest);
}
Long referencingPid = pid;
@ -269,7 +270,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
@Transactional()
@Override
public List<Suggestion> suggestKeywords(String theContext, String theSearchParam, String theText) {
public List<Suggestion> suggestKeywords(String theContext, String theSearchParam, String theText, RequestDetails theRequest) {
Validate.notBlank(theContext, "theContext must be provided");
Validate.notBlank(theSearchParam, "theSearchParam must be provided");
Validate.notBlank(theText, "theSearchParam must be provided");
@ -280,7 +281,7 @@ public class FulltextSearchSvcImpl implements IFulltextSearchSvc {
if (contextParts.length != 3 || "Patient".equals(contextParts[0]) == false || "$everything".equals(contextParts[2]) == false) {
throw new InvalidRequestException("Invalid context: " + theContext);
}
Long pid = myIdHelperService.translateForcedIdToPid(contextParts[0], contextParts[1]);
Long pid = myIdHelperService.translateForcedIdToPid(contextParts[0], contextParts[1], theRequest);
FullTextEntityManager em = org.hibernate.search.jpa.Search.getFullTextEntityManager(myEntityManager);

View File

@ -52,7 +52,7 @@ import java.util.Set;
public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
void addTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel);
void addTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel, RequestDetails theRequest);
/**
* Create a resource - Note that this variant of the method does not take in a {@link RequestDetails} and
@ -110,7 +110,7 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
ExpungeOutcome expunge(ExpungeOptions theExpungeOptions);
ExpungeOutcome expunge(IIdType theIIdType, ExpungeOptions theExpungeOptions);
ExpungeOutcome expunge(IIdType theIIdType, ExpungeOptions theExpungeOptions, RequestDetails theRequest);
TagList getAllResourceTags(RequestDetails theRequestDetails);
@ -152,7 +152,7 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
DaoMethodOutcome patch(IIdType theId, String theConditionalUrl, PatchTypeEnum thePatchType, String thePatchBody, RequestDetails theRequestDetails);
Set<Long> processMatchUrl(String theMatchUrl);
Set<Long> processMatchUrl(String theMatchUrl, RequestDetails theRequest);
/**
* Read a resource - Note that this variant of the method does not take in a {@link RequestDetails} and
@ -178,13 +178,13 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
*/
T read(IIdType theId, RequestDetails theRequestDetails, boolean theDeletedOk);
BaseHasResource readEntity(IIdType theId);
BaseHasResource readEntity(IIdType theId, RequestDetails theRequest);
/**
* @param theCheckForForcedId If true, this method should fail if the requested ID contains a numeric PID which exists, but is
* obscured by a "forced ID" so should not exist as far as the outside world is concerned.
*/
BaseHasResource readEntity(IIdType theId, boolean theCheckForForcedId);
BaseHasResource readEntity(IIdType theId, boolean theCheckForForcedId, RequestDetails theRequest);
/**
* Updates index tables associated with the given resource. Does not create a new
@ -203,7 +203,7 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
@Transactional(propagation = Propagation.SUPPORTS)
IBundleProvider search(SearchParameterMap theParams, RequestDetails theRequestDetails, HttpServletResponse theServletResponse);
Set<Long> searchForIds(SearchParameterMap theParams);
Set<Long> searchForIds(SearchParameterMap theParams, RequestDetails theRequest);
/**
* Takes a map of incoming raw search parameters and translates/parses them into

View File

@ -41,7 +41,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
public interface IFhirResourceDaoCodeSystem<T extends IBaseResource, CD, CC> extends IFhirResourceDao<T> {
List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem);
List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest);
LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CD theCoding, RequestDetails theRequestDetails);

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
@ -25,6 +26,6 @@ import org.hl7.fhir.instance.model.api.IIdType;
public interface IFhirResourceDaoSubscription<T extends IBaseResource> extends IFhirResourceDao<T> {
Long getSubscriptionTablePidForSubscriptionResource(IIdType theId);
Long getSubscriptionTablePidForSubscriptionResource(IIdType theId, RequestDetails theRequest);
}

View File

@ -24,14 +24,15 @@ import java.util.List;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.RequestDetails;
public interface IFulltextSearchSvc {
List<Suggestion> suggestKeywords(String theContext, String theSearchParam, String theText);
List<Suggestion> suggestKeywords(String theContext, String theSearchParam, String theText, RequestDetails theRequest);
List<Long> search(String theResourceName, SearchParameterMap theParams);
List<Long> everything(String theResourceName, SearchParameterMap theParams);
List<Long> everything(String theResourceName, SearchParameterMap theParams, RequestDetails theRequest);
boolean isDisabled();

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -35,14 +36,14 @@ import java.util.Set;
public interface ISearchBuilder {
IResultIterator createQuery(SearchParameterMap theParams, SearchRuntimeDetails theSearchRuntime);
IResultIterator createQuery(SearchParameterMap theParams, SearchRuntimeDetails theSearchRuntime, RequestDetails theRequest);
void setMaxResultsToFetch(Integer theMaxResultsToFetch);
Iterator<Long> createCountQuery(SearchParameterMap theParams, String theSearchUuid);
Iterator<Long> createCountQuery(SearchParameterMap theParams, String theSearchUuid, RequestDetails theRequest);
void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theRevIncludedPids, boolean theForHistoryOperation, EntityManager theEntityManager,
FhirContext theContext, IDao theDao);
FhirContext theContext, IDao theDao, RequestDetails theRequest);
Set<Long> loadIncludes(FhirContext theContext, EntityManager theEntityManager, Collection<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode,
DateRangeParam theLastUpdated, String theSearchIdOrDescription);

View File

@ -42,6 +42,7 @@ import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
import ca.uhn.fhir.jpa.util.BaseIterator;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.jpa.util.ScrollableResultsIterator;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
@ -109,7 +110,7 @@ public class SearchBuilder implements ISearchBuilder {
private static final List<Long> EMPTY_LONG_LIST = Collections.unmodifiableList(new ArrayList<>());
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchBuilder.class);
/**
* @see #loadResourcesByPid(Collection, List, Set, boolean, EntityManager, FhirContext, IDao)
* @see ISearchBuilder#loadResourcesByPid(Collection, List, Set, boolean, EntityManager, FhirContext, IDao, RequestDetails)
* for an explanation of why we use the constant 800
*/
private static final int MAXIMUM_PAGE_SIZE = 800;
@ -216,7 +217,7 @@ public class SearchBuilder implements ISearchBuilder {
}
private void addPredicateHas(List<List<IQueryParameterType>> theHasParameters) {
private void addPredicateHas(List<List<IQueryParameterType>> theHasParameters, RequestDetails theRequest) {
for (List<? extends IQueryParameterType> nextOrList : theHasParameters) {
@ -267,7 +268,7 @@ public class SearchBuilder implements ISearchBuilder {
orValues.addAll(next.getValuesAsQueryTokens());
}
Subquery<Long> subQ = createLinkSubquery(true, parameterName, targetResourceType, orValues);
Subquery<Long> subQ = createLinkSubquery(true, parameterName, targetResourceType, orValues, theRequest);
Join<ResourceTable, ResourceLink> join = myResourceTableRoot.join("myResourceLinksAsTarget", JoinType.LEFT);
Predicate pathPredicate = createResourceLinkPathPredicate(targetResourceType, paramReference, join);
@ -385,7 +386,7 @@ public class SearchBuilder implements ISearchBuilder {
/**
* Add reference predicate to the current search
*/
private void addPredicateReference(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList) {
private void addPredicateReference(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList, RequestDetails theRequest) {
assert theParamName.contains(".") == false;
if (theList.get(0).getMissing() != null) {
@ -429,7 +430,7 @@ public class SearchBuilder implements ISearchBuilder {
* Handle chained search, e.g. Patient?organization.name=Kwik-e-mart
*/
addPredicateReferenceWithChain(theResourceName, theParamName, theList, join, new ArrayList<>(), ref);
addPredicateReferenceWithChain(theResourceName, theParamName, theList, join, new ArrayList<>(), ref, theRequest);
return;
}
@ -443,7 +444,7 @@ public class SearchBuilder implements ISearchBuilder {
List<Predicate> codePredicates = new ArrayList<>();
// Resources by ID
List<Long> targetPids = myIdHelperService.translateForcedIdToPids(targetIds);
List<Long> targetPids = myIdHelperService.translateForcedIdToPids(targetIds, theRequest);
if (!targetPids.isEmpty()) {
ourLog.debug("Searching for resource link with target PIDs: {}", targetPids);
Predicate pathPredicate = createResourceLinkPathPredicate(theResourceName, theParamName, join);
@ -469,7 +470,7 @@ public class SearchBuilder implements ISearchBuilder {
}
}
private void addPredicateReferenceWithChain(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList, Join<ResourceTable, ResourceLink> theJoin, List<Predicate> theCodePredicates, ReferenceParam theRef) {
private void addPredicateReferenceWithChain(String theResourceName, String theParamName, List<? extends IQueryParameterType> theList, Join<ResourceTable, ResourceLink> theJoin, List<Predicate> theCodePredicates, ReferenceParam theRef, RequestDetails theRequest) {
final List<Class<? extends IBaseResource>> resourceTypes;
String resourceId;
if (!theRef.getValue().matches("[a-zA-Z]+/.*")) {
@ -593,7 +594,7 @@ public class SearchBuilder implements ISearchBuilder {
orValues.add(chainValue);
}
Subquery<Long> subQ = createLinkSubquery(foundChainMatch, chain, subResourceName, orValues);
Subquery<Long> subQ = createLinkSubquery(foundChainMatch, chain, subResourceName, orValues, theRequest);
Predicate pathPredicate = createResourceLinkPathPredicate(theResourceName, theParamName, theJoin);
Predicate pidPredicate = theJoin.get("myTargetResourcePid").in(subQ);
@ -609,7 +610,7 @@ public class SearchBuilder implements ISearchBuilder {
myPredicates.add(myBuilder.or(toArray(theCodePredicates)));
}
private Subquery<Long> createLinkSubquery(boolean theFoundChainMatch, String theChain, String theSubResourceName, List<IQueryParameterType> theOrValues) {
private Subquery<Long> createLinkSubquery(boolean theFoundChainMatch, String theChain, String theSubResourceName, List<IQueryParameterType> theOrValues, RequestDetails theRequest) {
Subquery<Long> subQ = myResourceTableQuery.subquery(Long.class);
Root<ResourceTable> subQfrom = subQ.from(ResourceTable.class);
subQ.select(subQfrom.get("myId").as(Long.class));
@ -634,7 +635,7 @@ public class SearchBuilder implements ISearchBuilder {
myPredicates.add(myBuilder.isNull(myResourceTableRoot.get("myDeleted")));
if (theFoundChainMatch) {
searchForIdsWithAndOr(theSubResourceName, theChain, andOrParams);
searchForIdsWithAndOr(theSubResourceName, theChain, andOrParams, theRequest);
subQ.where(toArray(myPredicates));
}
@ -669,7 +670,7 @@ public class SearchBuilder implements ISearchBuilder {
return chainValue;
}
private void addPredicateResourceId(List<List<IQueryParameterType>> theValues) {
private void addPredicateResourceId(List<List<IQueryParameterType>> theValues, RequestDetails theRequest) {
for (List<? extends IQueryParameterType> nextValue : theValues) {
Set<Long> orPids = new HashSet<>();
for (IQueryParameterType next : nextValue) {
@ -681,7 +682,7 @@ public class SearchBuilder implements ISearchBuilder {
IdType valueAsId = new IdType(value);
if (isNotBlank(value)) {
try {
Long pid = myIdHelperService.translateForcedIdToPid(myResourceName, valueAsId.getIdPart());
Long pid = myIdHelperService.translateForcedIdToPid(myResourceName, valueAsId.getIdPart(), theRequest);
orPids.add(pid);
} catch (ResourceNotFoundException e) {
// This is not an error in a search, it just results in no matchesFhirResourceDaoR4InterceptorTest
@ -1527,12 +1528,12 @@ public class SearchBuilder implements ISearchBuilder {
}
@Override
public Iterator<Long> createCountQuery(SearchParameterMap theParams, String theSearchUuid) {
public Iterator<Long> createCountQuery(SearchParameterMap theParams, String theSearchUuid, RequestDetails theRequest) {
myParams = theParams;
myBuilder = myEntityManager.getCriteriaBuilder();
mySearchUuid = theSearchUuid;
TypedQuery<Long> query = createQuery(null, null, true);
TypedQuery<Long> query = createQuery(null, null, true, theRequest);
return new CountQueryIterator(query);
}
@ -1545,7 +1546,7 @@ public class SearchBuilder implements ISearchBuilder {
}
@Override
public IResultIterator createQuery(SearchParameterMap theParams, SearchRuntimeDetails theSearchRuntimeDetails) {
public IResultIterator createQuery(SearchParameterMap theParams, SearchRuntimeDetails theSearchRuntimeDetails, RequestDetails theRequest) {
myParams = theParams;
myBuilder = myEntityManager.getCriteriaBuilder();
mySearchUuid = theSearchRuntimeDetails.getSearchUuid();
@ -1560,10 +1561,10 @@ public class SearchBuilder implements ISearchBuilder {
myPidSet = new HashSet<>();
}
return new QueryIterator(theSearchRuntimeDetails);
return new QueryIterator(theSearchRuntimeDetails, theRequest);
}
private TypedQuery<Long> createQuery(SortSpec sort, Integer theMaximumResults, boolean theCount) {
private TypedQuery<Long> createQuery(SortSpec sort, Integer theMaximumResults, boolean theCount, RequestDetails theRequest) {
myPredicates = new ArrayList<>();
CriteriaQuery<Long> outerQuery;
@ -1611,7 +1612,7 @@ public class SearchBuilder implements ISearchBuilder {
if (myParams.get(IAnyResource.SP_RES_ID) != null) {
StringParam idParm = (StringParam) myParams.get(IAnyResource.SP_RES_ID).get(0).get(0);
Long pid = myIdHelperService.translateForcedIdToPid(myResourceName, idParm.getValue());
Long pid = myIdHelperService.translateForcedIdToPid(myResourceName, idParm.getValue(), theRequest);
if (myAlsoIncludePids == null) {
myAlsoIncludePids = new ArrayList<>(1);
}
@ -1625,7 +1626,7 @@ public class SearchBuilder implements ISearchBuilder {
} else {
// Normal search
searchForIdsWithAndOr(myParams);
searchForIdsWithAndOr(myParams, theRequest);
}
/*
@ -1642,7 +1643,7 @@ public class SearchBuilder implements ISearchBuilder {
List<Long> pids;
if (myParams.getEverythingMode() != null) {
pids = myFulltextSearchSvc.everything(myResourceName, myParams);
pids = myFulltextSearchSvc.everything(myResourceName, myParams, theRequest);
} else {
pids = myFulltextSearchSvc.search(myResourceName, myParams);
}
@ -1846,7 +1847,7 @@ public class SearchBuilder implements ISearchBuilder {
}
private void doLoadPids(List<IBaseResource> theResourceListToPopulate, Set<Long> theIncludedPids, boolean theForHistoryOperation, EntityManager theEntityManager, FhirContext theContext, IDao theDao,
Map<Long, Integer> thePosition, Collection<Long> thePids) {
Map<Long, Integer> thePosition, Collection<Long> thePids, RequestDetails theRequest) {
// -- get the resource from the searchView
Collection<ResourceSearchView> resourceSearchViewList = myResourceSearchViewDao.findByResourceIds(thePids);
@ -1886,12 +1887,12 @@ public class SearchBuilder implements ISearchBuilder {
}
}
// Interceptor broadcast: RESOURCE_MAY_BE_RETURNED
// Interceptor broadcast: STORAGE_PREACCESS_RESOURCE
HookParams params = new HookParams()
.add(IBaseResource.class, resource)
.add(RequestDetails.class, null)
.add(ServletRequestDetails.class, null);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PREACCESS_RESOURCE, params);
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PREACCESS_RESOURCE, params);
theResourceListToPopulate.set(index, resource);
}
@ -1937,7 +1938,7 @@ public class SearchBuilder implements ISearchBuilder {
@Override
public void loadResourcesByPid(Collection<Long> theIncludePids, List<IBaseResource> theResourceListToPopulate, Set<Long> theIncludedPids, boolean theForHistoryOperation,
EntityManager entityManager, FhirContext context, IDao theDao) {
EntityManager entityManager, FhirContext context, IDao theDao, RequestDetails theRequest) {
if (theIncludePids.isEmpty()) {
ourLog.debug("The include pids are empty");
// return;
@ -1964,7 +1965,7 @@ public class SearchBuilder implements ISearchBuilder {
int to = i + MAXIMUM_PAGE_SIZE;
to = Math.min(to, pids.size());
List<Long> pidsSubList = pids.subList(i, to);
doLoadPids(theResourceListToPopulate, theIncludedPids, theForHistoryOperation, entityManager, context, theDao, position, pidsSubList);
doLoadPids(theResourceListToPopulate, theIncludedPids, theForHistoryOperation, entityManager, context, theDao, position, pidsSubList, theRequest);
}
}
@ -2134,7 +2135,7 @@ public class SearchBuilder implements ISearchBuilder {
}
}
private void searchForIdsWithAndOr(@Nonnull SearchParameterMap theParams) {
private void searchForIdsWithAndOr(@Nonnull SearchParameterMap theParams, RequestDetails theRequest) {
myParams = theParams;
// Remove any empty parameters
@ -2214,7 +2215,7 @@ public class SearchBuilder implements ISearchBuilder {
for (Entry<String, List<List<IQueryParameterType>>> nextParamEntry : myParams.entrySet()) {
String nextParamName = nextParamEntry.getKey();
List<List<IQueryParameterType>> andOrParams = nextParamEntry.getValue();
searchForIdsWithAndOr(myResourceName, nextParamName, andOrParams);
searchForIdsWithAndOr(myResourceName, nextParamName, andOrParams, theRequest);
}
}
@ -2241,7 +2242,7 @@ public class SearchBuilder implements ISearchBuilder {
theParams.clean();
}
private void searchForIdsWithAndOr(String theResourceName, String theParamName, List<List<IQueryParameterType>> theAndOrParams) {
private void searchForIdsWithAndOr(String theResourceName, String theParamName, List<List<IQueryParameterType>> theAndOrParams, RequestDetails theRequest) {
if (theAndOrParams.isEmpty()) {
return;
@ -2249,7 +2250,7 @@ public class SearchBuilder implements ISearchBuilder {
if (theParamName.equals(IAnyResource.SP_RES_ID)) {
addPredicateResourceId(theAndOrParams);
addPredicateResourceId(theAndOrParams, theRequest);
} else if (theParamName.equals(IAnyResource.SP_RES_LANGUAGE)) {
@ -2257,7 +2258,7 @@ public class SearchBuilder implements ISearchBuilder {
} else if (theParamName.equals(Constants.PARAM_HAS)) {
addPredicateHas(theAndOrParams);
addPredicateHas(theAndOrParams, theRequest);
} else if (theParamName.equals(Constants.PARAM_TAG) || theParamName.equals(Constants.PARAM_PROFILE) || theParamName.equals(Constants.PARAM_SECURITY)) {
@ -2280,7 +2281,7 @@ public class SearchBuilder implements ISearchBuilder {
break;
case REFERENCE:
for (List<? extends IQueryParameterType> nextAnd : theAndOrParams) {
addPredicateReference(theResourceName, theParamName, nextAnd);
addPredicateReference(theResourceName, theParamName, nextAnd, theRequest);
}
break;
case STRING:
@ -2491,10 +2492,12 @@ public class SearchBuilder implements ISearchBuilder {
private SortSpec mySort;
private boolean myStillNeedToFetchIncludes;
private int mySkipCount = 0;
private final RequestDetails myRequest;
private QueryIterator(SearchRuntimeDetails theSearchRuntimeDetails) {
private QueryIterator(SearchRuntimeDetails theSearchRuntimeDetails, RequestDetails theRequest) {
mySearchRuntimeDetails = theSearchRuntimeDetails;
mySort = myParams.getSort();
myRequest = theRequest;
// Includes are processed inline for $everything query
if (myParams.getEverythingMode() != null) {
@ -2510,7 +2513,7 @@ public class SearchBuilder implements ISearchBuilder {
myMaxResultsToFetch = myDaoConfig.getFetchSizeDefaultMaximum();
}
final TypedQuery<Long> query = createQuery(mySort, myMaxResultsToFetch, false);
final TypedQuery<Long> query = createQuery(mySort, myMaxResultsToFetch, false, myRequest);
mySearchRuntimeDetails.setQueryStopwatch(new StopWatch());
@ -2581,14 +2584,14 @@ public class SearchBuilder implements ISearchBuilder {
if (myFirst) {
HookParams params = new HookParams();
params.add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
myInterceptorBroadcaster.callHooks(Pointcut.JPA_PERFTRACE_SEARCH_FIRST_RESULT_LOADED, params);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FIRST_RESULT_LOADED, params);
myFirst = false;
}
if (NO_MORE.equals(myNext)) {
HookParams params = new HookParams();
params.add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
myInterceptorBroadcaster.callHooks(Pointcut.JPA_PERFTRACE_SEARCH_SELECT_COMPLETE, params);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_SELECT_COMPLETE, params);
}
}

View File

@ -494,11 +494,11 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
}
private Map<BUNDLEENTRY, ResourceTable> doTransactionWriteOperations(final ServletRequestDetails theRequestDetails, String theActionName, Date theUpdateTime, Set<IIdType> theAllIds,
private Map<BUNDLEENTRY, ResourceTable> doTransactionWriteOperations(final ServletRequestDetails theRequest, String theActionName, Date theUpdateTime, Set<IIdType> theAllIds,
Map<IIdType, IIdType> theIdSubstitutions, Map<IIdType, DaoMethodOutcome> theIdToPersistedOutcome, BUNDLE theResponse, IdentityHashMap<BUNDLEENTRY, Integer> theOriginalRequestOrder, List<BUNDLEENTRY> theEntries, StopWatch theTransactionStopWatch) {
if (theRequestDetails != null) {
theRequestDetails.startDeferredOperationCallback();
if (theRequest != null) {
theRequest.startDeferredOperationCallback();
}
try {
@ -640,9 +640,9 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
DaoMethodOutcome outcome;
String matchUrl = myVersionAdapter.getEntryRequestIfNoneExist(nextReqEntry);
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
outcome = resourceDao.create(res, matchUrl, false, theUpdateTime, theRequestDetails);
outcome = resourceDao.create(res, matchUrl, false, theUpdateTime, theRequest);
if (nextResourceId != null) {
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequestDetails);
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequest);
}
entriesToProcess.put(nextRespEntry, outcome.getEntity());
if (outcome.getCreated() == false) {
@ -664,7 +664,7 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
if (parts.getResourceId() != null) {
IIdType deleteId = newIdType(parts.getResourceType(), parts.getResourceId());
if (!deletedResources.contains(deleteId.getValueAsString())) {
DaoMethodOutcome outcome = dao.delete(deleteId, deleteConflicts, theRequestDetails);
DaoMethodOutcome outcome = dao.delete(deleteId, deleteConflicts, theRequest);
if (outcome.getEntity() != null) {
deletedResources.add(deleteId.getValueAsString());
entriesToProcess.put(nextRespEntry, outcome.getEntity());
@ -673,7 +673,7 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
} else {
String matchUrl = parts.getResourceType() + '?' + parts.getParams();
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
DeleteMethodOutcome deleteOutcome = dao.deleteByUrl(matchUrl, deleteConflicts, theRequestDetails);
DeleteMethodOutcome deleteOutcome = dao.deleteByUrl(matchUrl, deleteConflicts, theRequest);
List<ResourceTable> allDeleted = deleteOutcome.getDeletedEntities();
for (ResourceTable deleted : allDeleted) {
deletedResources.add(deleted.getIdDt().toUnqualifiedVersionless().getValueAsString());
@ -705,7 +705,7 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
version = ParameterUtil.parseETagValue(myVersionAdapter.getEntryRequestIfMatch(nextReqEntry));
}
res.setId(newIdType(parts.getResourceType(), parts.getResourceId(), version));
outcome = resourceDao.update(res, null, false, false, theRequestDetails);
outcome = resourceDao.update(res, null, false, false, theRequest);
} else {
res.setId((String) null);
String matchUrl;
@ -715,7 +715,7 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
matchUrl = parts.getResourceType();
}
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
outcome = resourceDao.update(res, matchUrl, false, false, theRequestDetails);
outcome = resourceDao.update(res, matchUrl, false, false, theRequest);
if (Boolean.TRUE.equals(outcome.getCreated())) {
conditionalRequestUrls.put(matchUrl, res.getClass());
}
@ -729,7 +729,7 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
}
}
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequestDetails);
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequest);
entriesToProcess.put(nextRespEntry, outcome.getEntity());
break;
}
@ -843,9 +843,9 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null;
if (updatedEntities.contains(nextOutcome.getEntity())) {
myDao.updateInternal(theRequestDetails, nextResource, true, false, nextOutcome.getEntity(), nextResource.getIdElement(), nextOutcome.getPreviousResource());
myDao.updateInternal(theRequest, nextResource, true, false, nextOutcome.getEntity(), nextResource.getIdElement(), nextOutcome.getPreviousResource());
} else if (!nonUpdatedEntities.contains(nextOutcome.getEntity())) {
myDao.updateEntity(theRequestDetails, nextResource, nextOutcome.getEntity(), deletedTimestampOrNull, true, false, theUpdateTime, false, true);
myDao.updateEntity(theRequest, nextResource, nextOutcome.getEntity(), deletedTimestampOrNull, true, false, theUpdateTime, false, true);
}
}
@ -876,7 +876,7 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
Class<? extends IBaseResource> resType = nextEntry.getValue();
if (isNotBlank(matchUrl)) {
IFhirResourceDao<?> resourceDao = myDao.getDao(resType);
Set<Long> val = resourceDao.processMatchUrl(matchUrl);
Set<Long> val = resourceDao.processMatchUrl(matchUrl, theRequest);
if (val.size() > 1) {
throw new InvalidRequestException(
"Unable to process " + theActionName + " - Request would cause multiple resources to match URL: \"" + matchUrl + "\". Does transaction request contain duplicates?");
@ -899,8 +899,8 @@ public class TransactionProcessor<BUNDLE extends IBaseBundle, BUNDLEENTRY> {
return entriesToProcess;
} finally {
if (theRequestDetails != null) {
theRequestDetails.stopDeferredRequestOperationCallbackAndRunDeferredItems();
if (theRequest != null) {
theRequest.stopDeferredRequestOperationCallbackAndRunDeferredItems();
}
}
}

View File

@ -92,9 +92,9 @@ public class FhirResourceDaoCodeSystemDstu3 extends FhirResourceDaoDstu3<CodeSys
// }
@Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem) {
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) {
List<IIdType> valueSetIds;
Set<Long> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)));
Set<Long> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest );
valueSetIds = new ArrayList<>();
for (Long next : ids) {
valueSetIds.add(new IdType("CodeSystem", next));

View File

@ -75,9 +75,9 @@ public class FhirResourceDaoDstu3<T extends IAnyResource> extends BaseHapiFhirRe
@Override
public MethodOutcome validate(T theResource, IIdType theId, String theRawResource, EncodingEnum theEncoding, ValidationModeEnum theMode, String theProfile, RequestDetails theRequestDetails) {
if (theRequestDetails != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, theResource, null, theId);
public MethodOutcome validate(T theResource, IIdType theId, String theRawResource, EncodingEnum theEncoding, ValidationModeEnum theMode, String theProfile, RequestDetails theRequest) {
if (theRequest != null) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequest, theResource, null, theId);
notifyInterceptors(RestOperationTypeEnum.VALIDATE, requestDetails);
}
@ -85,13 +85,13 @@ public class FhirResourceDaoDstu3<T extends IAnyResource> extends BaseHapiFhirRe
if (theId == null || theId.hasIdPart() == false) {
throw new InvalidRequestException("No ID supplied. ID is required when validating with mode=DELETE");
}
final ResourceTable entity = readEntityLatestVersion(theId);
final ResourceTable entity = readEntityLatestVersion(theId, theRequest);
// Validate that there are no resources pointing to the candidate that
// would prevent deletion
DeleteConflictList deleteConflicts = new DeleteConflictList();
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete()) {
myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, true);
myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, true, theRequest);
}
myDeleteConflictService.validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
@ -110,7 +110,7 @@ public class FhirResourceDaoDstu3<T extends IAnyResource> extends BaseHapiFhirRe
if (theId != null && theId.hasResourceType() && theId.hasIdPart()) {
Class<? extends IBaseResource> type = getContext().getResourceDefinition(theId.getResourceType()).getImplementingClass();
IFhirResourceDao<? extends IBaseResource> dao = getDao(type);
resourceToValidateById = dao.read(theId, theRequestDetails);
resourceToValidateById = dao.read(theId, theRequest);
}
ValidationResult result;

View File

@ -41,7 +41,7 @@ import ca.uhn.fhir.rest.param.*;
public class FhirResourceDaoPatientDstu3 extends FhirResourceDaoDstu3<Patient>implements IFhirResourceDaoPatient<Patient> {
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequest) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
@ -60,11 +60,11 @@ public class FhirResourceDaoPatientDstu3 extends FhirResourceDaoDstu3<Patient>im
paramMap.add("_id", new StringParam(theId.getIdPart()));
}
if (!isPagingProviderDatabaseBacked(theRequestDetails)) {
if (!isPagingProviderDatabaseBacked(theRequest)) {
paramMap.setLoadSynchronous(true);
}
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)));
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequest);
}
@Override

View File

@ -61,8 +61,8 @@ public class FhirResourceDaoSubscriptionDstu3 extends FhirResourceDaoDstu3<Subsc
}
@Override
public Long getSubscriptionTablePidForSubscriptionResource(IIdType theId) {
ResourceTable entity = readEntityLatestVersion(theId);
public Long getSubscriptionTablePidForSubscriptionResource(IIdType theId, RequestDetails theRequest) {
ResourceTable entity = readEntityLatestVersion(theId, theRequest);
SubscriptionTable table = mySubscriptionTableDao.findOneByResourcePid(entity.getId());
if (table == null) {
return null;

View File

@ -28,6 +28,7 @@ import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.IResourceLinkResolver;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
@ -57,11 +58,11 @@ public class DaoResourceLinkResolver implements IResourceLinkResolver {
protected EntityManager myEntityManager;
@Override
public ResourceTable findTargetResource(RuntimeSearchParam theNextSpDef, String theNextPathsUnsplit, IIdType theNextId, String theTypeString, Class<? extends IBaseResource> theType, String theId) {
public ResourceTable findTargetResource(RuntimeSearchParam theNextSpDef, String theNextPathsUnsplit, IIdType theNextId, String theTypeString, Class<? extends IBaseResource> theType, String theId, RequestDetails theRequest) {
ResourceTable target;
Long valueOf;
try {
valueOf = myIdHelperService.translateForcedIdToPid(theTypeString, theId);
valueOf = myIdHelperService.translateForcedIdToPid(theTypeString, theId, theRequest);
ourLog.trace("Translated {}/{} to resource PID {}", theType, theId, valueOf);
} catch (ResourceNotFoundException e) {
if (myDaoConfig.isEnforceReferentialIntegrityOnWrite() == false) {

View File

@ -27,7 +27,9 @@ import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.MultimapBuilder;
@ -58,10 +60,10 @@ public class IdHelperService {
* @throws ResourceNotFoundException If the ID can not be found
*/
@Nonnull
public Long translateForcedIdToPid(String theResourceName, String theResourceId) throws ResourceNotFoundException {
public Long translateForcedIdToPid(String theResourceName, String theResourceId, RequestDetails theRequestDetails) throws ResourceNotFoundException {
// We only pass 1 input in so only 0..1 will come back
IdDt id = new IdDt(theResourceName, theResourceId);
List<Long> matches = translateForcedIdToPids(myDaoConfig, myInterceptorBroadcaster, myForcedIdDao, Collections.singletonList(id));
List<Long> matches = translateForcedIdToPids(myDaoConfig, myInterceptorBroadcaster, theRequestDetails, myForcedIdDao, Collections.singletonList(id));
assert matches.size() <= 1;
if (matches.isEmpty()) {
throw new ResourceNotFoundException(id);
@ -69,11 +71,11 @@ public class IdHelperService {
return matches.get(0);
}
public List<Long> translateForcedIdToPids(Collection<IIdType> theId) {
return IdHelperService.translateForcedIdToPids(myDaoConfig, myInterceptorBroadcaster, myForcedIdDao, theId);
public List<Long> translateForcedIdToPids(Collection<IIdType> theId, RequestDetails theRequestDetails) {
return IdHelperService.translateForcedIdToPids(myDaoConfig, myInterceptorBroadcaster, theRequestDetails, myForcedIdDao, theId);
}
static List<Long> translateForcedIdToPids(DaoConfig theDaoConfig, IInterceptorBroadcaster theInterceptorBroadcaster, IForcedIdDao theForcedIdDao, Collection<IIdType> theId) {
private static List<Long> translateForcedIdToPids(DaoConfig theDaoConfig, IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequest, IForcedIdDao theForcedIdDao, Collection<IIdType> theId) {
theId.forEach(id -> Validate.isTrue(id.hasIdPart()));
if (theId.isEmpty()) {
@ -104,7 +106,7 @@ public class IdHelperService {
.setMessage("This search uses unqualified resource IDs (an ID without a resource type). This is less efficient than using a qualified type.");
HookParams params = new HookParams()
.add(StorageProcessingMessage.class, msg);
theInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PROCESSING_MESSAGE, params);
JpaInterceptorBroadcaster.doCallHooks(theInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
retVal.addAll(theForcedIdDao.findByForcedId(nextIds));
@ -116,7 +118,7 @@ public class IdHelperService {
return retVal;
}
public String translatePidIdToForcedId(String theResourceType, Long theId) {
String translatePidIdToForcedId(String theResourceType, Long theId) {
ForcedId forcedId = myForcedIdDao.findByResourcePid(theId);
if (forcedId != null) {
return forcedId.getResourceType() + '/' + forcedId.getForcedId();

View File

@ -38,6 +38,7 @@ import ca.uhn.fhir.jpa.searchparam.extractor.ResourceLinkExtractor;
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorService;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@ -87,7 +88,7 @@ public class SearchParamWithInlineReferencesExtractor {
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager myEntityManager;
public void populateFromResource(ResourceIndexedSearchParams theParams, IDao theCallingDao, Date theUpdateTime, ResourceTable theEntity, IBaseResource theResource, ResourceIndexedSearchParams theExistingParams) {
public void populateFromResource(ResourceIndexedSearchParams theParams, IDao theCallingDao, Date theUpdateTime, ResourceTable theEntity, IBaseResource theResource, ResourceIndexedSearchParams theExistingParams, RequestDetails theRequest) {
mySearchParamExtractorService.extractFromResource(theParams, theEntity, theResource);
Set<Map.Entry<String, RuntimeSearchParam>> activeSearchParams = mySearchParamRegistry.getActiveSearchParams(theEntity.getResourceType()).entrySet();
@ -97,9 +98,9 @@ public class SearchParamWithInlineReferencesExtractor {
theParams.setUpdatedTime(theUpdateTime);
extractInlineReferences(theResource);
extractInlineReferences(theResource, theRequest);
myResourceLinkExtractor.extractResourceLinks(theParams, theEntity, theResource, theUpdateTime, myDaoResourceLinkResolver, true);
myResourceLinkExtractor.extractResourceLinks(theParams, theEntity, theResource, theUpdateTime, myDaoResourceLinkResolver, true, theRequest);
/*
* If the existing resource already has links and those match links we still want, use them instead of removing them and re adding them
@ -206,7 +207,7 @@ public class SearchParamWithInlineReferencesExtractor {
* Handle references within the resource that are match URLs, for example references like "Patient?identifier=foo". These match URLs are resolved and replaced with the ID of the
* matching resource.
*/
public void extractInlineReferences(IBaseResource theResource) {
public void extractInlineReferences(IBaseResource theResource, RequestDetails theRequest) {
if (!myDaoConfig.isAllowInlineMatchUrlReferences()) {
return;
}
@ -237,7 +238,7 @@ public class SearchParamWithInlineReferencesExtractor {
throw new InvalidRequestException(msg);
}
Class<? extends IBaseResource> matchResourceType = matchResourceDef.getImplementingClass();
Set<Long> matches = myMatchResourceUrlService.processMatchUrl(nextIdText, matchResourceType);
Set<Long> matches = myMatchResourceUrlService.processMatchUrl(nextIdText, matchResourceType, theRequest);
if (matches.isEmpty()) {
String msg = myContext.getLocalizer().getMessage(BaseHapiFhirDao.class, "invalidMatchUrlNoMatches", nextId.getValue());
throw new ResourceNotFoundException(msg);

View File

@ -27,6 +27,7 @@ import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.LogicUtil;
@ -50,7 +51,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
@ -67,9 +67,9 @@ public class FhirResourceDaoCodeSystemR4 extends FhirResourceDaoR4<CodeSystem> i
private ValidationSupportChain myValidationSupport;
@Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem) {
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) {
List<IIdType> valueSetIds;
Set<Long> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)));
Set<Long> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest);
valueSetIds = new ArrayList<>();
for (Long next : ids) {
valueSetIds.add(new IdType("CodeSystem", next));

View File

@ -41,7 +41,7 @@ import ca.uhn.fhir.rest.param.*;
public class FhirResourceDaoPatientR4 extends FhirResourceDaoR4<Patient>implements IFhirResourceDaoPatient<Patient> {
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequestDetails) {
private IBundleProvider doEverythingOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, RequestDetails theRequest) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
@ -60,11 +60,11 @@ public class FhirResourceDaoPatientR4 extends FhirResourceDaoR4<Patient>implemen
paramMap.add("_id", new StringParam(theId.getIdPart()));
}
if (!isPagingProviderDatabaseBacked(theRequestDetails)) {
if (!isPagingProviderDatabaseBacked(theRequest)) {
paramMap.setLoadSynchronous(true);
}
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)));
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequest);
}
@Override

View File

@ -75,21 +75,21 @@ public class FhirResourceDaoR4<T extends IAnyResource> extends BaseHapiFhirResou
@Override
public MethodOutcome validate(T theResource, IIdType theId, String theRawResource, EncodingEnum theEncoding, ValidationModeEnum theMode, String theProfile, RequestDetails theRequestDetails) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, theResource, null, theId);
public MethodOutcome validate(T theResource, IIdType theId, String theRawResource, EncodingEnum theEncoding, ValidationModeEnum theMode, String theProfile, RequestDetails theRequest) {
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequest, theResource, null, theId);
notifyInterceptors(RestOperationTypeEnum.VALIDATE, requestDetails);
if (theMode == ValidationModeEnum.DELETE) {
if (theId == null || theId.hasIdPart() == false) {
throw new InvalidRequestException("No ID supplied. ID is required when validating with mode=DELETE");
}
final ResourceTable entity = readEntityLatestVersion(theId);
final ResourceTable entity = readEntityLatestVersion(theId, theRequest);
// Validate that there are no resources pointing to the candidate that
// would prevent deletion
DeleteConflictList deleteConflicts = new DeleteConflictList();
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete()) {
myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, true);
myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, true, theRequest);
}
myDeleteConflictService.validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
@ -108,7 +108,7 @@ public class FhirResourceDaoR4<T extends IAnyResource> extends BaseHapiFhirResou
if (theId != null && theId.hasResourceType() && theId.hasIdPart()) {
Class<? extends IBaseResource> type = getContext().getResourceDefinition(theId.getResourceType()).getImplementingClass();
IFhirResourceDao<? extends IBaseResource> dao = getDao(type);
resourceToValidateById = dao.read(theId, theRequestDetails);
resourceToValidateById = dao.read(theId, theRequest);
}
ValidationResult result;

View File

@ -56,8 +56,8 @@ public class FhirResourceDaoSubscriptionR4 extends FhirResourceDaoR4<Subscriptio
}
@Override
public Long getSubscriptionTablePidForSubscriptionResource(IIdType theId) {
ResourceTable entity = readEntityLatestVersion(theId);
public Long getSubscriptionTablePidForSubscriptionResource(IIdType theId, RequestDetails theRequest) {
ResourceTable entity = readEntityLatestVersion(theId, theRequest);
SubscriptionTable table = mySubscriptionTableDao.findOneByResourcePid(entity.getId());
if (table == null) {
return null;
@ -80,7 +80,7 @@ public class FhirResourceDaoSubscriptionR4 extends FhirResourceDaoR4<Subscriptio
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
if (theDeletedTimestampOrNull != null) {
Long subscriptionId = getSubscriptionTablePidForSubscriptionResource(theEntity.getIdDt());
Long subscriptionId = getSubscriptionTablePidForSubscriptionResource(theEntity.getIdDt(), theRequest);
if (subscriptionId != null) {
mySubscriptionTableDao.deleteAllForSubscription(retVal);
}

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
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 org.hl7.fhir.instance.model.api.IBaseResource;
@ -43,7 +44,7 @@ public class MatchResourceUrlService {
@Autowired
private MatchUrlService myMatchUrlService;
public <R extends IBaseResource> Set<Long> processMatchUrl(String theMatchUrl, Class<R> theResourceType) {
public <R extends IBaseResource> Set<Long> processMatchUrl(String theMatchUrl, Class<R> theResourceType, RequestDetails theRequest) {
RuntimeResourceDefinition resourceDef = myContext.getResourceDefinition(theResourceType);
SearchParameterMap paramMap = myMatchUrlService.translateMatchUrl(theMatchUrl, resourceDef);
@ -58,7 +59,7 @@ public class MatchResourceUrlService {
throw new InternalErrorException("No DAO for resource type: " + theResourceType.getName());
}
return dao.searchForIds(paramMap);
return dao.searchForIds(paramMap, theRequest);
}

View File

@ -30,7 +30,9 @@ import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao;
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.util.DeleteConflict;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.util.OperationOutcomeUtil;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
@ -60,33 +62,33 @@ public class DeleteConflictService {
@Autowired
protected IInterceptorBroadcaster myInterceptorBroadcaster;
public int validateOkToDelete(DeleteConflictList theDeleteConflicts, ResourceTable theEntity, boolean theForValidate) {
public int validateOkToDelete(DeleteConflictList theDeleteConflicts, ResourceTable theEntity, boolean theForValidate, RequestDetails theRequest) {
DeleteConflictList newConflicts = new DeleteConflictList();
// In most cases, there will be no hooks, and so we only need to check if there is at least FIRST_QUERY_RESULT_COUNT conflict and populate that.
// Only in the case where there is a hook do we need to go back and collect larger batches of conflicts for processing.
boolean tryAgain = findAndHandleConflicts(newConflicts, theEntity, theForValidate, FIRST_QUERY_RESULT_COUNT);
boolean tryAgain = findAndHandleConflicts(theRequest, newConflicts, theEntity, theForValidate, FIRST_QUERY_RESULT_COUNT);
int retryCount = 0;
while (tryAgain && retryCount < MAX_RETRY_ATTEMPTS) {
newConflicts = new DeleteConflictList();
tryAgain = findAndHandleConflicts(newConflicts, theEntity, theForValidate, RETRY_QUERY_RESULT_COUNT);
tryAgain = findAndHandleConflicts(theRequest, newConflicts, theEntity, theForValidate, RETRY_QUERY_RESULT_COUNT);
++retryCount;
}
theDeleteConflicts.addAll(newConflicts);
return retryCount;
}
private boolean findAndHandleConflicts(DeleteConflictList theDeleteConflicts, ResourceTable theEntity, boolean theForValidate, int theMinQueryResultCount) {
private boolean findAndHandleConflicts(RequestDetails theRequest, DeleteConflictList theDeleteConflicts, ResourceTable theEntity, boolean theForValidate, int theMinQueryResultCount) {
List<ResourceLink> resultList = myDeleteConflictFinderService.findConflicts(theEntity, theMinQueryResultCount);
if (resultList.isEmpty()) {
return false;
}
return handleConflicts(theDeleteConflicts, theEntity, theForValidate, resultList);
return handleConflicts(theRequest, theDeleteConflicts, theEntity, theForValidate, resultList);
}
private boolean handleConflicts(DeleteConflictList theDeleteConflicts, ResourceTable theEntity, boolean theForValidate, List<ResourceLink> theResultList) {
private boolean handleConflicts(RequestDetails theRequest, DeleteConflictList theDeleteConflicts, ResourceTable theEntity, boolean theForValidate, List<ResourceLink> theResultList) {
if (!myDaoConfig.isEnforceReferentialIntegrityOnDelete() && !theForValidate) {
ourLog.debug("Deleting {} resource dependencies which can no longer be satisfied", theResultList.size());
myResourceLinkDao.deleteAll(theResultList);
@ -98,7 +100,7 @@ public class DeleteConflictService {
// Notify Interceptors about pre-action call
HookParams hooks = new HookParams()
.add(DeleteConflictList.class, theDeleteConflicts);
return myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRESTORAGE_DELETE_CONFLICTS, hooks);
return JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESTORAGE_DELETE_CONFLICTS, hooks);
}
private void addConflictsToList(DeleteConflictList theDeleteConflicts, ResourceTable theEntity, List<ResourceLink> theResultList) {

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.graphql;
* 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.
@ -24,10 +24,11 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
@ -92,6 +93,9 @@ public class JpaStorageServices extends BaseHapiFhirDao<IBaseResource> implement
case QUANTITY:
param = new QuantityParam(value);
break;
case SPECIAL:
param = new SpecialParam().setValue(value);
break;
case URI:
break;
case HAS:
@ -117,10 +121,13 @@ public class JpaStorageServices extends BaseHapiFhirDao<IBaseResource> implement
@Transactional(propagation = Propagation.REQUIRED)
@Override
public Resource lookup(Object theAppInfo, String theType, String theId) throws FHIRException {
RequestDetails requestDetails = (RequestDetails) theAppInfo;
assert requestDetails != null;
IIdType refId = getContext().getVersion().newIdType();
refId.setValue(theType + "/" + theId);
IFhirResourceDao<? extends IBaseResource> dao = getDao(theType);
BaseHasResource id = dao.readEntity(refId);
BaseHasResource id = dao.readEntity(refId, requestDetails);
return (Resource) toResource(id, false);
}

View File

@ -54,13 +54,13 @@ public abstract class BaseJpaResourceProvider<T extends IBaseResource> extends B
}
protected Parameters doExpunge(IIdType theIdParam, IPrimitiveType<? extends Integer> theLimit, IPrimitiveType<? extends Boolean> theExpungeDeletedResources, IPrimitiveType<? extends Boolean> theExpungeOldVersions, IPrimitiveType<? extends Boolean> theExpungeEverything) {
protected Parameters doExpunge(IIdType theIdParam, IPrimitiveType<? extends Integer> theLimit, IPrimitiveType<? extends Boolean> theExpungeDeletedResources, IPrimitiveType<? extends Boolean> theExpungeOldVersions, IPrimitiveType<? extends Boolean> theExpungeEverything, RequestDetails theRequest) {
ExpungeOptions options = createExpungeOptions(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
ExpungeOutcome outcome;
if (theIdParam != null) {
outcome = getDao().expunge(theIdParam, options);
outcome = getDao().expunge(theIdParam, options, theRequest);
} else {
outcome = getDao().expunge(options);
}

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.provider;
* 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.
@ -83,11 +83,11 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
})
public Parameters expunge(
@IdParam IIdType theIdParam,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerDt theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanDt theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanDt theExpungeOldVersions
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
@OperationParam(name = OPERATION_EXPUNGE_PARAM_LIMIT) IntegerDt theLimit,
@OperationParam(name = OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanDt theExpungeDeletedResources,
@OperationParam(name = OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanDt theExpungeOldVersions,
RequestDetails theRequest) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null, theRequest);
return JpaSystemProviderDstu2.toExpungeResponse(retVal);
}
@ -95,11 +95,11 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_OUT_PARAM_EXPUNGE_COUNT, type = IntegerDt.class)
})
public Parameters expunge(
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerDt theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanDt theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanDt theExpungeOldVersions
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
@OperationParam(name = OPERATION_EXPUNGE_PARAM_LIMIT) IntegerDt theLimit,
@OperationParam(name = OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanDt theExpungeDeletedResources,
@OperationParam(name = OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanDt theExpungeOldVersions,
RequestDetails theRequest) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null, theRequest);
return JpaSystemProviderDstu2.toExpungeResponse(retVal);
}

View File

@ -214,8 +214,8 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
public Parameters suggestKeywords(
@OperationParam(name = "context", min = 1, max = 1) String theContext,
@OperationParam(name = "searchParam", min = 1, max = 1) String theSearchParam,
@OperationParam(name = "text", min = 1, max = 1) String theText
) {
@OperationParam(name = "text", min = 1, max = 1) String theText,
RequestDetails theRequest) {
JpaSystemProviderDstu3.validateFulltextSearchEnabled(mySearchDao);
if (isBlank(theContext)) {
@ -228,7 +228,7 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
throw new InvalidRequestException("Parameter 'text' must be provided");
}
List<Suggestion> keywords = mySearchDao.suggestKeywords(theContext, theSearchParam, theText);
List<Suggestion> keywords = mySearchDao.suggestKeywords(theContext, theSearchParam, theText, theRequest);
Parameters retVal = new Parameters();
for (Suggestion next : keywords) {

View File

@ -65,5 +65,32 @@ public class BaseJpaResourceProviderCodeSystemDstu3 extends JpaResourceProviderD
endRequest(theServletRequest);
}
}
/**
* $subsumes operation
*/
@Operation(name = JpaConstants.OPERATION_SUBSUMES, idempotent = true, returnParameters= {
@OperationParam(name="outcome", type= CodeType.class, min=1),
})
public Parameters subsumes(
HttpServletRequest theServletRequest,
@OperationParam(name="codeA", min=0, max=1) CodeType theCodeA,
@OperationParam(name="codeB", min=0, max=1) CodeType theCodeB,
@OperationParam(name="system", min=0, max=1) UriType theSystem,
@OperationParam(name="codingA", min=0, max=1) Coding theCodingA,
@OperationParam(name="codingB", min=0, max=1) Coding theCodingB,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
IFhirResourceDaoCodeSystem.SubsumesResult result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theRequestDetails);
return (Parameters) result.toParameters(theRequestDetails.getFhirContext());
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -87,9 +87,9 @@ public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaRes
@IdParam IIdType theIdParam,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions,
RequestDetails theRequest) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null, theRequest);
try {
return VersionConvertor_30_40.convertParameters(retVal);
} catch (FHIRException e) {
@ -103,9 +103,9 @@ public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaRes
public Parameters expunge(
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions,
RequestDetails theRequest) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null, theRequest);
try {
return VersionConvertor_30_40.convertParameters(retVal);
} catch (FHIRException e) {

View File

@ -216,8 +216,8 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
public Parameters suggestKeywords(
@OperationParam(name = "context", min = 1, max = 1) String theContext,
@OperationParam(name = "searchParam", min = 1, max = 1) String theSearchParam,
@OperationParam(name = "text", min = 1, max = 1) String theText
) {
@OperationParam(name = "text", min = 1, max = 1) String theText,
RequestDetails theRequest) {
if (isBlank(theContext)) {
@ -230,7 +230,7 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
throw new InvalidRequestException("Parameter 'text' must be provided");
}
List<Suggestion> keywords = mySearchDao.suggestKeywords(theContext, theSearchParam, theText);
List<Suggestion> keywords = mySearchDao.suggestKeywords(theContext, theSearchParam, theText, theRequest);
Parameters retVal = new Parameters();
for (Suggestion next : keywords) {

View File

@ -84,9 +84,9 @@ public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResour
@IdParam IIdType theIdParam,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions
) {
return super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions,
RequestDetails theRequest) {
return super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null, theRequest);
}
@Operation(name = JpaConstants.OPERATION_EXPUNGE, idempotent = false, returnParameters = {
@ -95,9 +95,9 @@ public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResour
public Parameters expunge(
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions
) {
return super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions,
RequestDetails theRequest) {
return super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null, theRequest);
}
@Operation(name = OPERATION_META, idempotent = true, returnParameters = {

View File

@ -203,8 +203,8 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle,
public Parameters suggestKeywords(
@OperationParam(name = "context", min = 1, max = 1) String theContext,
@OperationParam(name = "searchParam", min = 1, max = 1) String theSearchParam,
@OperationParam(name = "text", min = 1, max = 1) String theText
) {
@OperationParam(name = "text", min = 1, max = 1) String theText,
RequestDetails theRequest) {
ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3.validateFulltextSearchEnabled(mySearchDao);
if (isBlank(theContext)) {
@ -217,7 +217,7 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle,
throw new InvalidRequestException("Parameter 'text' must be provided");
}
List<Suggestion> keywords = mySearchDao.suggestKeywords(theContext, theSearchParam, theText);
List<Suggestion> keywords = mySearchDao.suggestKeywords(theContext, theSearchParam, theText, theRequest);
Parameters retVal = new Parameters();
for (Suggestion next : keywords) {

View File

@ -23,10 +23,10 @@ package ca.uhn.fhir.jpa.search;
import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.BasePagingProvider;
import ca.uhn.fhir.rest.server.IPagingProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
// Note: this class is not annotated with @Service because we want to
// explicitly define it in BaseConfig.java. This is done so that
@ -53,9 +53,9 @@ public class DatabaseBackedPagingProvider extends BasePagingProvider implements
}
@Override
public synchronized IBundleProvider retrieveResultList(String theId) {
public synchronized IBundleProvider retrieveResultList(String theId, RequestDetails theRequest) {
IFhirSystemDao<?, ?> systemDao = myDaoRegistry.getSystemDao();
PersistedJpaBundleProvider provider = new PersistedJpaBundleProvider(theId, systemDao);
PersistedJpaBundleProvider provider = new PersistedJpaBundleProvider(theRequest, theId, systemDao);
if (!provider.ensureSearchEntityLoaded()) {
return null;
}

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import java.util.List;
@ -31,8 +32,8 @@ public interface ISearchCoordinatorSvc {
void cancelAllActiveSearches();
List<Long> getResources(String theUuid, int theFrom, int theTo);
List<Long> getResources(String theUuid, int theFrom, int theTo, RequestDetails theRequest);
IBundleProvider registerSearch(IDao theCallingDao, SearchParameterMap theParams, String theResourceType, CacheControlDirective theCacheControlDirective);
IBundleProvider registerSearch(IDao theCallingDao, SearchParameterMap theParams, String theResourceType, CacheControlDirective theCacheControlDirective, RequestDetails theRequest);
}

View File

@ -30,13 +30,13 @@ import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
@ -52,6 +52,7 @@ import java.util.*;
public class PersistedJpaBundleProvider implements IBundleProvider {
private static final Logger ourLog = LoggerFactory.getLogger(PersistedJpaBundleProvider.class);
private final RequestDetails myRequest;
private FhirContext myContext;
private IDao myDao;
private EntityManager myEntityManager;
@ -62,7 +63,8 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
private String myUuid;
private boolean myCacheHit;
public PersistedJpaBundleProvider(String theSearchUuid, IDao theDao) {
public PersistedJpaBundleProvider(RequestDetails theRequest, String theSearchUuid, IDao theDao) {
myRequest = theRequest;
myUuid = theSearchUuid;
myDao = theDao;
}
@ -135,7 +137,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
Class<? extends IBaseResource> resourceType = myContext.getResourceDefinition(resourceName).getImplementingClass();
sb.setType(resourceType, resourceName);
final List<Long> pidsSubList = mySearchCoordinatorSvc.getResources(myUuid, theFromIndex, theToIndex);
final List<Long> pidsSubList = mySearchCoordinatorSvc.getResources(myUuid, theFromIndex, theToIndex, myRequest);
TransactionTemplate template = new TransactionTemplate(myPlatformTransactionManager);
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
@ -287,7 +289,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
// Execute the query and make sure we return distinct results
List<IBaseResource> resources = new ArrayList<>();
sb.loadResourcesByPid(pidsSubList, resources, includedPids, false, myEntityManager, myContext, myDao);
sb.loadResourcesByPid(pidsSubList, resources, includedPids, false, myEntityManager, myContext, myDao, myRequest);
return resources;
}

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.search;
import java.util.List;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -41,8 +42,8 @@ public class PersistedJpaSearchFirstPageBundleProvider extends PersistedJpaBundl
private Search mySearch;
private PlatformTransactionManager myTxManager;
public PersistedJpaSearchFirstPageBundleProvider(Search theSearch, IDao theDao, SearchTask theSearchTask, ISearchBuilder theSearchBuilder, PlatformTransactionManager theTxManager) {
super(theSearch.getUuid(), theDao);
public PersistedJpaSearchFirstPageBundleProvider(Search theSearch, IDao theDao, SearchTask theSearchTask, ISearchBuilder theSearchBuilder, PlatformTransactionManager theTxManager, RequestDetails theRequest) {
super(theRequest, theSearch.getUuid(), theDao);
setSearchEntity(theSearch);
mySearchTask = theSearchTask;
mySearchBuilder = theSearchBuilder;

View File

@ -32,12 +32,14 @@ import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
import ca.uhn.fhir.rest.api.SummaryEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
@ -52,6 +54,7 @@ import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.AbstractPageRequest;
import org.springframework.data.domain.Page;
@ -156,7 +159,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
*/
@Override
@Transactional(propagation = Propagation.NEVER)
public List<Long> getResources(final String theUuid, int theFrom, int theTo) {
public List<Long> getResources(final String theUuid, int theFrom, int theTo, RequestDetails theRequest) {
TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
@ -207,7 +210,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
String resourceType = search.getResourceType();
SearchParameterMap params = search.getSearchParameterMap();
IFhirResourceDao<?> resourceDao = myDaoRegistry.getResourceDao(resourceType);
SearchContinuationTask task = new SearchContinuationTask(search, resourceDao, params, resourceType);
SearchContinuationTask task = new SearchContinuationTask(search, resourceDao, params, resourceType, theRequest);
myIdToSearchTask.put(search.getUuid(), task);
myExecutor.submit(task);
}
@ -271,7 +274,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
}
@Override
public IBundleProvider registerSearch(final IDao theCallingDao, final SearchParameterMap theParams, String theResourceType, CacheControlDirective theCacheControlDirective) {
public IBundleProvider registerSearch(final IDao theCallingDao, final SearchParameterMap theParams, String theResourceType, CacheControlDirective theCacheControlDirective, RequestDetails theRequest) {
StopWatch w = new StopWatch();
final String searchUuid = UUID.randomUUID().toString();
@ -310,7 +313,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
// Load the results synchronously
final List<Long> pids = new ArrayList<>();
try (IResultIterator resultIter = sb.createQuery(theParams, searchRuntimeDetails)) {
try (IResultIterator resultIter = sb.createQuery(theParams, searchRuntimeDetails, theRequest)) {
while (resultIter.hasNext()) {
pids.add(resultIter.next());
if (loadSynchronousUpTo != null && pids.size() >= loadSynchronousUpTo) {
@ -339,7 +342,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
includedPids.addAll(sb.loadIncludes(myContext, myEntityManager, pids, theParams.getIncludes(), false, theParams.getLastUpdated(), "(synchronous)"));
List<IBaseResource> resources = new ArrayList<>();
sb.loadResourcesByPid(pids, resources, includedPids, false, myEntityManager, myContext, theCallingDao);
sb.loadResourcesByPid(pids, resources, includedPids, false, myEntityManager, myContext, theCallingDao, theRequest);
return new SimpleBundleProvider(resources);
});
}
@ -377,7 +380,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
searchToUse.setSearchLastReturned(new Date());
mySearchDao.updateSearchLastReturned(searchToUse.getId(), new Date());
retVal = new PersistedJpaBundleProvider(searchToUse.getUuid(), theCallingDao);
retVal = new PersistedJpaBundleProvider(theRequest, searchToUse.getUuid(), theCallingDao);
retVal.setCacheHit(true);
populateBundleProvider(retVal);
@ -396,11 +399,11 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
Search search = new Search();
populateSearchEntity(theParams, theResourceType, searchUuid, queryString, search);
SearchTask task = new SearchTask(search, theCallingDao, theParams, theResourceType);
SearchTask task = new SearchTask(search, theCallingDao, theParams, theResourceType, theRequest);
myIdToSearchTask.put(search.getUuid(), task);
myExecutor.submit(task);
PersistedJpaSearchFirstPageBundleProvider retVal = new PersistedJpaSearchFirstPageBundleProvider(search, theCallingDao, task, sb, myManagedTxManager);
PersistedJpaSearchFirstPageBundleProvider retVal = new PersistedJpaSearchFirstPageBundleProvider(search, theCallingDao, task, sb, myManagedTxManager, theRequest);
populateBundleProvider(retVal);
ourLog.debug("Search initial phase completed in {}ms", w.getMillis());
@ -428,11 +431,6 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
myLoadingThrottleForUnitTests = theLoadingThrottleForUnitTests;
}
@VisibleForTesting
void setMaxMillisToWaitForRemoteResultsForUnitTest(long theMaxMillisToWaitForRemoteResults) {
myMaxMillisToWaitForRemoteResults = theMaxMillisToWaitForRemoteResults;
}
@VisibleForTesting
public void setNeverUseLocalSearchForUnitTests(boolean theNeverUseLocalSearchForUnitTests) {
myNeverUseLocalSearchForUnitTests = theNeverUseLocalSearchForUnitTests;
@ -481,6 +479,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
private final CountDownLatch myInitialCollectionLatch = new CountDownLatch(1);
private final CountDownLatch myCompletionLatch;
private final ArrayList<Long> myUnsyncedPids = new ArrayList<>();
private final RequestDetails myRequest;
private Search mySearch;
private boolean myAbortRequested;
private int myCountSavedTotal = 0;
@ -493,7 +492,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
/**
* Constructor
*/
protected BaseTask(Search theSearch, IDao theCallingDao, SearchParameterMap theParams, String theResourceType) {
protected BaseTask(Search theSearch, IDao theCallingDao, SearchParameterMap theParams, String theResourceType, RequestDetails theRequest) {
mySearch = theSearch;
myCallingDao = theCallingDao;
myParams = theParams;
@ -501,21 +500,18 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
myCompletionLatch = new CountDownLatch(1);
mySearchRuntimeDetails = new SearchRuntimeDetails(mySearch.getUuid());
mySearchRuntimeDetails.setQueryString(theParams.toNormalizedQueryString(theCallingDao.getContext()));
}
public SearchRuntimeDetails getSearchRuntimeDetails() {
return mySearchRuntimeDetails;
myRequest = theRequest;
}
protected Search getSearch() {
return mySearch;
}
protected CountDownLatch getInitialCollectionLatch() {
CountDownLatch getInitialCollectionLatch() {
return myInitialCollectionLatch;
}
protected void setPreviouslyAddedResourcePids(List<Long> thePreviouslyAddedResourcePids) {
void setPreviouslyAddedResourcePids(List<Long> thePreviouslyAddedResourcePids) {
myPreviouslyAddedResourcePids = thePreviouslyAddedResourcePids;
myCountSavedTotal = myPreviouslyAddedResourcePids.size();
}
@ -591,12 +587,12 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
return retVal;
}
protected void saveSearch() {
void saveSearch() {
TransactionTemplate txTemplate = new TransactionTemplate(myManagedTxManager);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
protected void doInTransactionWithoutResult(@NotNull TransactionStatus theArg0) {
doSaveSearch();
}
@ -608,7 +604,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
txTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
protected void doInTransactionWithoutResult(@NotNull TransactionStatus theArg0) {
if (mySearch.getId() == null) {
doSaveSearch();
}
@ -676,22 +672,22 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
}
public boolean isNotAborted() {
boolean isNotAborted() {
return myAbortRequested == false;
}
protected void markComplete() {
void markComplete() {
myCompletionLatch.countDown();
}
public CountDownLatch getCompletionLatch() {
CountDownLatch getCompletionLatch() {
return myCompletionLatch;
}
/**
* Request that the task abort as soon as possible
*/
public void requestImmediateAbort() {
void requestImmediateAbort() {
myAbortRequested = true;
}
@ -724,10 +720,10 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
mySearchRuntimeDetails.setSearchStatus(mySearch.getStatus());
if (mySearch.getStatus() == SearchStatusEnum.FINISHED) {
HookParams params = new HookParams().add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
myInterceptorBroadcaster.callHooks(Pointcut.JPA_PERFTRACE_SEARCH_COMPLETE, params);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_COMPLETE, params);
} else {
HookParams params = new HookParams().add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
myInterceptorBroadcaster.callHooks(Pointcut.JPA_PERFTRACE_SEARCH_PASS_COMPLETE, params);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_PASS_COMPLETE, params);
}
ourLog.info("Have completed search for [{}{}] and found {} resources in {}ms - Status is {}", mySearch.getResourceType(), mySearch.getSearchQueryString(), mySyncedPids.size(), sw.getMillis(), mySearch.getStatus());
@ -769,7 +765,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
mySearchRuntimeDetails.setSearchStatus(mySearch.getStatus());
HookParams params = new HookParams().add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
myInterceptorBroadcaster.callHooks(Pointcut.JPA_PERFTRACE_SEARCH_FAILED, params);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FAILED, params);
saveSearch();
@ -823,7 +819,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
if (wantCount) {
ourLog.trace("Performing count");
ISearchBuilder sb = newSearchBuilder();
Iterator<Long> countIterator = sb.createCountQuery(myParams, mySearch.getUuid());
Iterator<Long> countIterator = sb.createCountQuery(myParams, mySearch.getUuid(), myRequest);
Long count = countIterator.next();
ourLog.trace("Got count {}", count);
@ -900,7 +896,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
/*
* Construct the SQL query we'll be sending to the database
*/
try (IResultIterator resultIterator = sb.createQuery(myParams, mySearchRuntimeDetails)) {
try (IResultIterator resultIterator = sb.createQuery(myParams, mySearchRuntimeDetails, myRequest)) {
assert (resultIterator != null);
/*
@ -956,8 +952,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
public class SearchContinuationTask extends BaseTask {
public SearchContinuationTask(Search theSearch, IDao theCallingDao, SearchParameterMap theParams, String theResourceType) {
super(theSearch, theCallingDao, theParams, theResourceType);
public SearchContinuationTask(Search theSearch, IDao theCallingDao, SearchParameterMap theParams, String theResourceType, RequestDetails theRequest) {
super(theSearch, theCallingDao, theParams, theResourceType, theRequest);
}
@Override
@ -1007,8 +1003,8 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
/**
* Constructor
*/
public SearchTask(Search theSearch, IDao theCallingDao, SearchParameterMap theParams, String theResourceType) {
super(theSearch, theCallingDao, theParams, theResourceType);
public SearchTask(Search theSearch, IDao theCallingDao, SearchParameterMap theParams, String theResourceType, RequestDetails theRequest) {
super(theSearch, theCallingDao, theParams, theResourceType, theRequest);
}
/**

View File

@ -7,6 +7,8 @@ import ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage;
import ca.uhn.fhir.jpa.subscription.module.cache.SubscriptionChannelFactory;
import ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceModifiedJsonMessage;
import ca.uhn.fhir.jpa.subscription.module.subscriber.SubscriptionMatchingSubscriber;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -83,26 +85,27 @@ public class SubscriptionMatcherInterceptor implements IResourceModifiedConsumer
}
@Hook(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED)
public void resourceCreated(IBaseResource theResource) {
submitResourceModified(theResource, ResourceModifiedMessage.OperationTypeEnum.CREATE);
public void resourceCreated(IBaseResource theResource, RequestDetails theRequest) {
submitResourceModified(theResource, ResourceModifiedMessage.OperationTypeEnum.CREATE, theRequest);
}
@Hook(Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED)
public void resourceDeleted(IBaseResource theResource) {
submitResourceModified(theResource, ResourceModifiedMessage.OperationTypeEnum.DELETE);
public void resourceDeleted(IBaseResource theResource, RequestDetails theRequest) {
submitResourceModified(theResource, ResourceModifiedMessage.OperationTypeEnum.DELETE, theRequest);
}
@Hook(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED)
public void resourceUpdated(IBaseResource theOldResource, IBaseResource theNewResource) {
submitResourceModified(theNewResource, ResourceModifiedMessage.OperationTypeEnum.UPDATE);
public void resourceUpdated(IBaseResource theOldResource, IBaseResource theNewResource, RequestDetails theRequest) {
submitResourceModified(theNewResource, ResourceModifiedMessage.OperationTypeEnum.UPDATE, theRequest);
}
private void submitResourceModified(IBaseResource theNewResource, ResourceModifiedMessage.OperationTypeEnum theOperationType) {
private void submitResourceModified(IBaseResource theNewResource, ResourceModifiedMessage.OperationTypeEnum theOperationType, RequestDetails theRequest) {
ResourceModifiedMessage msg = new ResourceModifiedMessage(myFhirContext, theNewResource, theOperationType);
// Interceptor call: SUBSCRIPTION_RESOURCE_MODIFIED
HookParams params = new HookParams()
.add(ResourceModifiedMessage.class, msg);
if (!myInterceptorBroadcaster.callHooks(Pointcut.SUBSCRIPTION_RESOURCE_MODIFIED, params)) {
boolean outcome = JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.SUBSCRIPTION_RESOURCE_MODIFIED, params);
if (!outcome) {
return;
}

View File

@ -218,7 +218,7 @@ public class SubscriptionTriggeringSvcImpl implements ISubscriptionTriggeringSvc
ourLog.info("Triggering job[{}] is starting a search for {}", theJobDetails.getJobId(), nextSearchUrl);
IBundleProvider search = mySearchCoordinatorSvc.registerSearch(callingDao, params, resourceType, new CacheControlDirective());
IBundleProvider search = mySearchCoordinatorSvc.registerSearch(callingDao, params, resourceType, new CacheControlDirective(), null);
theJobDetails.setCurrentSearchUuid(search.getUuid());
theJobDetails.setCurrentSearchResourceType(resourceType);
theJobDetails.setCurrentSearchCount(params.getCount());
@ -237,7 +237,7 @@ public class SubscriptionTriggeringSvcImpl implements ISubscriptionTriggeringSvc
toIndex = Math.min(toIndex, theJobDetails.getCurrentSearchCount());
}
ourLog.info("Triggering job[{}] search {} requesting resources {} - {}", theJobDetails.getJobId(), theJobDetails.getCurrentSearchUuid(), fromIndex, toIndex);
List<Long> resourceIds = mySearchCoordinatorSvc.getResources(theJobDetails.getCurrentSearchUuid(), fromIndex, toIndex);
List<Long> resourceIds = mySearchCoordinatorSvc.getResources(theJobDetails.getCurrentSearchUuid(), fromIndex, toIndex, null);
ourLog.info("Triggering job[{}] delivering {} resources", theJobDetails.getJobId(), resourceIds.size());
int highestIndexSubmitted = theJobDetails.getCurrentSearchLastUploadedIndex();

View File

@ -1197,12 +1197,12 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
@Override
@Transactional(propagation = Propagation.REQUIRED)
public IIdType storeNewCodeSystemVersion(CodeSystem theCodeSystemResource, TermCodeSystemVersion theCodeSystemVersion, RequestDetails theRequestDetails, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
public IIdType storeNewCodeSystemVersion(CodeSystem theCodeSystemResource, TermCodeSystemVersion theCodeSystemVersion, RequestDetails theRequest, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
Validate.notBlank(theCodeSystemResource.getUrl(), "theCodeSystemResource must have a URL");
IIdType csId = createOrUpdateCodeSystem(theCodeSystemResource);
ResourceTable resource = (ResourceTable) myCodeSystemResourceDao.readEntity(csId);
ResourceTable resource = (ResourceTable) myCodeSystemResourceDao.readEntity(csId, theRequest);
Long codeSystemResourcePid = resource.getId();
ourLog.info("CodeSystem resource has ID: {}", csId.getValue());

View File

@ -0,0 +1,24 @@
package ca.uhn.fhir.jpa.util;
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.api.server.RequestDetails;
public class JpaInterceptorBroadcaster {
/**
* Broadcast hooks to both the interceptor service associated with the request, as well
* as the one associated with the JPA module.
*/
public static boolean doCallHooks(IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequestDetails, Pointcut thePointcut, HookParams theParams) {
boolean retVal = true;
if (theInterceptorBroadcaster != null) {
retVal = theInterceptorBroadcaster.callHooks(thePointcut, theParams);
}
if (theRequestDetails != null && retVal) {
theRequestDetails.getInterceptorBroadcaster().callHooks(thePointcut, theParams);
}
return retVal;
}
}

View File

@ -1,119 +0,0 @@
package ca.uhn.fhir.jpa.util;
/*-
* #%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%
*/
import ca.uhn.fhir.interceptor.api.*;
import ca.uhn.fhir.interceptor.executor.InterceptorService;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
/**
* The JPA server has two interceptor services (aka two registries of interceptors). One that lives
* in the JPA module and is created via Spring, and one that lives in the RestfulServer. We do this
* so that interceptors can be registered at the JPA level via Spring (which is convenient for
* lots of reasons) and also via the RestfulServer (which is how other interceptors work outside the
* JPA context)
* <p>
* This class is basically a composite broadcaster that broadcasts events to the internal registry but
* also to
* </p>
*/
public class JpaInterceptorService implements IInterceptorService {
private IInterceptorService myInterceptorBroadcaster = new InterceptorService("hapi-fhir-jpa");
@Override
public boolean callHooks(Pointcut thePointcut, HookParams theParams) {
if (!myInterceptorBroadcaster.callHooks(thePointcut, theParams)) {
return false;
}
RequestDetails requestDetails = theParams.get(RequestDetails.class);
if (requestDetails != null) {
requestDetails.getInterceptorBroadcaster().callHooks(thePointcut, theParams);
}
return true;
}
@Override
public Object callHooksAndReturnObject(Pointcut thePointcut, HookParams theParams) {
Object retVal = myInterceptorBroadcaster.callHooksAndReturnObject(thePointcut, theParams);
if (retVal == null) {
RequestDetails requestDetails = theParams.get(RequestDetails.class);
if (requestDetails != null) {
retVal = requestDetails.getInterceptorBroadcaster().callHooksAndReturnObject(thePointcut, theParams);
}
}
return retVal;
}
@Override
public boolean registerThreadLocalInterceptor(Object theInterceptor) {
return myInterceptorBroadcaster.registerThreadLocalInterceptor(theInterceptor);
}
@Override
public void unregisterThreadLocalInterceptor(Object theInterceptor) {
myInterceptorBroadcaster.unregisterThreadLocalInterceptor(theInterceptor);
}
@Override
public boolean registerInterceptor(Object theInterceptor) {
return myInterceptorBroadcaster.registerInterceptor(theInterceptor);
}
@Override
public void unregisterInterceptor(Object theInterceptor) {
myInterceptorBroadcaster.unregisterInterceptor(theInterceptor);
}
@Override
public void registerAnonymousInterceptor(Pointcut thePointcut, IAnonymousInterceptor theInterceptor) {
myInterceptorBroadcaster.registerAnonymousInterceptor(thePointcut, theInterceptor);
}
@Override
public void registerAnonymousInterceptor(Pointcut thePointcut, int theOrder, IAnonymousInterceptor theInterceptor) {
myInterceptorBroadcaster.registerAnonymousInterceptor(thePointcut, theOrder, theInterceptor);
}
@Override
public List<Object> getAllRegisteredInterceptors() {
return myInterceptorBroadcaster.getAllRegisteredInterceptors();
}
@Override
public void unregisterAllInterceptors() {
myInterceptorBroadcaster.unregisterAllInterceptors();
}
@Override
public void unregisterInterceptors(@Nullable Collection<?> theInterceptors) {
myInterceptorBroadcaster.unregisterInterceptors(theInterceptors);
}
@Override
public void registerInterceptors(@Nullable Collection<?> theInterceptors) {
myInterceptorBroadcaster.registerInterceptors(theInterceptors);
}
}

View File

@ -256,7 +256,7 @@ public abstract class BaseJpaTest {
if (theFirstCall) {
bundleProvider = theFound;
} else {
bundleProvider = myDatabaseBackedPagingProvider.retrieveResultList(theFound.getUuid());
bundleProvider = myDatabaseBackedPagingProvider.retrieveResultList(theFound.getUuid(), null);
}
List<IBaseResource> resources = bundleProvider.getResources(theFromIndex, theToIndex);
@ -267,7 +267,7 @@ public abstract class BaseJpaTest {
}
protected List<IIdType> toUnqualifiedVersionlessIds(Bundle theFound) {
List<IIdType> retVal = new ArrayList<IIdType>();
List<IIdType> retVal = new ArrayList<>();
for (Entry next : theFound.getEntry()) {
// if (next.getResource()!= null) {
retVal.add(next.getResource().getId().toUnqualifiedVersionless());
@ -310,7 +310,7 @@ public abstract class BaseJpaTest {
}
protected List<IIdType> toUnqualifiedVersionlessIds(List<? extends IBaseResource> theFound) {
List<IIdType> retVal = new ArrayList<IIdType>();
List<IIdType> retVal = new ArrayList<>();
for (IBaseResource next : theFound) {
retVal.add(next.getIdElement().toUnqualifiedVersionless());
}
@ -326,7 +326,7 @@ public abstract class BaseJpaTest {
}
protected List<IIdType> toUnqualifiedVersionlessIds(org.hl7.fhir.dstu3.model.Bundle theFound) {
List<IIdType> retVal = new ArrayList<IIdType>();
List<IIdType> retVal = new ArrayList<>();
for (BundleEntryComponent next : theFound.getEntry()) {
// if (next.getResource()!= null) {
retVal.add(next.getResource().getIdElement().toUnqualifiedVersionless());
@ -336,7 +336,7 @@ public abstract class BaseJpaTest {
}
protected List<IIdType> toUnqualifiedVersionlessIds(org.hl7.fhir.r4.model.Bundle theFound) {
List<IIdType> retVal = new ArrayList<IIdType>();
List<IIdType> retVal = new ArrayList<>();
for (org.hl7.fhir.r4.model.Bundle.BundleEntryComponent next : theFound.getEntry()) {
// if (next.getResource()!= null) {
retVal.add(next.getResource().getIdElement().toUnqualifiedVersionless());
@ -346,11 +346,11 @@ public abstract class BaseJpaTest {
}
protected String[] toValues(IIdType... theValues) {
ArrayList<String> retVal = new ArrayList<String>();
ArrayList<String> retVal = new ArrayList<>();
for (IIdType next : theValues) {
retVal.add(next.getValue());
}
return retVal.toArray(new String[retVal.size()]);
return retVal.toArray(new String[0]);
}
@BeforeClass
@ -379,8 +379,7 @@ public abstract class BaseJpaTest {
if (bundleRes == null) {
throw new NullPointerException("Can not load " + resource);
}
String bundleStr = IOUtils.toString(bundleRes);
return bundleStr;
return IOUtils.toString(bundleRes, Constants.CHARSET_UTF8);
}
public static void purgeDatabase(DaoConfig theDaoConfig, IFhirSystemDao<?, ?> theSystemDao, IResourceReindexingSvc theResourceReindexingSvc, ISearchCoordinatorSvc theSearchCoordinatorSvc, ISearchParamRegistry theSearchParamRegistry) {

View File

@ -14,7 +14,6 @@ import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
@ -55,19 +54,19 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
myMediaDao.create(med, mySrd);
ourLog.info(myFhirCtx.newJsonParser().encodeResourceToString(med));
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "press");
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "press", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("Pressure", output.get(0).getTerm());
assertEquals("Systolic Blood Pressure", output.get(1).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "prezure");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "prezure", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("Pressure", output.get(0).getTerm());
assertEquals("Systolic Blood Pressure", output.get(1).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "syst");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "syst", null);
ourLog.info("Found: " + output);
assertEquals(4, output.size());
assertEquals("syst", output.get(0).getTerm());
@ -75,7 +74,7 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
assertEquals("Systolic", output.get(2).getTerm());
assertEquals("Systolic Blood Pressure", output.get(3).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "LCws");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "LCws", null);
ourLog.info("Found: " + output);
assertEquals(0, output.size());
}
@ -114,7 +113,7 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
obs2.getCode().setText("ZXCVBNMZZ");
myObservationDao.create(obs2, mySrd);
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXCVBNM");
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXCVBNM", null);
ourLog.info("Found: " + output);
assertEquals(4, output.size());
assertEquals("ZXCVBNM", output.get(0).getTerm());
@ -122,7 +121,7 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
assertEquals("ZXC", output.get(2).getTerm());
assertEquals("ZXC HELLO", output.get(3).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXC");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXC", null);
ourLog.info("Found: " + output);
assertEquals(4, output.size());
assertEquals("ZXC", output.get(0).getTerm());
@ -130,17 +129,17 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
assertEquals("ZXCVBNM", output.get(2).getTerm());
assertEquals("ZXCVBNM ASDFGHJKL QWERTYUIOPASDFGHJKL", output.get(3).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "HELO");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "HELO", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("HELLO", output.get(0).getTerm());
assertEquals("ZXC HELLO", output.get(1).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "Z");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "Z", null);
ourLog.info("Found: " + output);
assertEquals(0, output.size());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZX");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZX", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("ZXC", output.get(0).getTerm());

View File

@ -1,6 +1,5 @@
package ca.uhn.fhir.jpa.dao.dstu2;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.dao.data.ISearchParamPresentDao;
@ -1542,7 +1541,7 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
QuantityParam param;
Set<Long> found;
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param));
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param), null);
int initialSize = found.size();
Observation o = new Observation();
@ -1553,19 +1552,19 @@ public class FhirResourceDaoDstu2SearchNoFtTest extends BaseJpaDstu2Test {
myObservationDao.create(o, mySrd);
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, null);
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param));
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param), null);
assertEquals(1 + initialSize, found.size());
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), null, methodName + "units");
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param));
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param), null);
assertEquals(1, found.size());
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), "urn:bar:" + methodName, null);
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param));
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param), null);
assertEquals(1, found.size());
param = new QuantityParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, new BigDecimal("10"), "urn:bar:" + methodName, methodName + "units");
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param));
found = myObservationDao.searchForIds(new SearchParameterMap("value-quantity", param), null);
assertEquals(1, found.size());
}

View File

@ -4,7 +4,6 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@ -20,7 +19,6 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.*;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoDstu3Test;
@ -39,7 +37,6 @@ import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.TestUtil;
@SuppressWarnings("unchecked")
@ -82,7 +79,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
}
private List<String> extractNames(IBundleProvider theSearch) {
ArrayList<String> retVal = new ArrayList<String>();
ArrayList<String> retVal = new ArrayList<>();
for (IBaseResource next : theSearch.getResources(0, theSearch.size())) {
Patient nextPt = (Patient) next;
retVal.add(nextPt.getNameFirstRep().getNameAsSingleString());
@ -99,7 +96,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
}
private void sort(TagList thePublished) {
ArrayList<Tag> tags = new ArrayList<Tag>(thePublished);
ArrayList<Tag> tags = new ArrayList<>(thePublished);
Collections.sort(tags, new Comparator<Tag>() {
@Override
public int compare(Tag theO1, Tag theO2) {
@ -225,7 +222,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertThat(toUnqualifiedVersionlessIdValues(found), hasItem(id2.getValue()));
}
{
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")));
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")), null);
assertThat(found, not(hasItem(id2.getIdPartAsLong())));
}
}
@ -1583,13 +1580,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
"}\n";
//@formatter:on
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
Organization org = myFhirCtx.newJsonParser().parseResource(Organization.class, inputStr);
myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
assertEquals(initial + 1, val.size());
}
@ -2716,19 +2713,19 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertThat(str.length(), greaterThan(ResourceIndexedSearchParamString.MAX_LENGTH));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
assertEquals(initial + 0, val.size());
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH))));
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH))), null);
assertEquals(initial + 1, val.size());
try {
myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH + 1))));
myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH + 1))), null);
fail();
} catch (InvalidRequestException e) {
// ok
@ -2747,12 +2744,12 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
tagList.addTag("http://foo", "Cat", "Kittens");
ResourceMetadataKeyEnum.TAG_LIST.put(patient, tagList);
List<BaseCodingDt> securityLabels = new ArrayList<BaseCodingDt>();
List<BaseCodingDt> securityLabels = new ArrayList<>();
securityLabels.add(new CodingDt().setSystem("seclabel:sys:1").setCode("seclabel:code:1").setDisplay("seclabel:dis:1"));
securityLabels.add(new CodingDt().setSystem("seclabel:sys:2").setCode("seclabel:code:2").setDisplay("seclabel:dis:2"));
ResourceMetadataKeyEnum.SECURITY_LABELS.put(patient, securityLabels);
List<IdDt> profiles = new ArrayList<IdDt>();
List<IdDt> profiles = new ArrayList<>();
profiles.add(new IdDt("http://profile/1"));
profiles.add(new IdDt("http://profile/2"));
ResourceMetadataKeyEnum.PROFILES.put(patient, profiles);
@ -2817,8 +2814,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
assertEquals("http://profile/1", profiles.get(0).getValue());
assertEquals("http://profile/2", profiles.get(1).getValue());
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cat", "Kittens");
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cow", "Calves");
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cat", "Kittens", null);
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cow", "Calves", null);
retrieved = myPatientDao.read(patientId, mySrd);
published = (TagList) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
@ -2864,23 +2861,23 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
String subStr1 = longStr1.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
String subStr2 = longStr2.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, subStr2)));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, subStr2)), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, subStr2)));
val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, subStr2)), null);
assertEquals(initial + 1, val.size());
try {
myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(longStr1, subStr2)));
myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(longStr1, subStr2)), null);
fail();
} catch (InvalidRequestException e) {
// ok
}
try {
myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, longStr2)));
myOrganizationDao.searchForIds(new SearchParameterMap("type", new IdentifierDt(subStr1, longStr2)), null);
fail();
} catch (InvalidRequestException e) {
// ok

View File

@ -1,33 +1,30 @@
package ca.uhn.fhir.jpa.dao.dstu2;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import java.util.*;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
import ca.uhn.fhir.model.dstu2.resource.Organization;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.primitive.*;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class FhirResourceDaoDstu2UpdateTest extends BaseJpaDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2UpdateTest.class);
@ -155,7 +152,7 @@ public class FhirResourceDaoDstu2UpdateTest extends BaseJpaDstu2Test {
p2.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB");
myPatientDao.create(p2, mySrd);
Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA")));
Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA")), null);
assertEquals(1, ids.size());
assertThat(ids, contains(p1id.getIdPartAsLong()));
@ -164,10 +161,10 @@ public class FhirResourceDaoDstu2UpdateTest extends BaseJpaDstu2Test {
MethodOutcome update2 = myPatientDao.update(p1, mySrd);
IIdType p1id2 = update2.getId();
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA")));
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA")), null);
assertEquals(0, ids.size());
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2BBB")));
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2BBB")), null);
assertEquals(2, ids.size());
// Make sure vreads work

View File

@ -147,19 +147,19 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
myMediaDao.create(med, mockSrd());
ourLog.info(myFhirCtx.newJsonParser().encodeResourceToString(med));
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "press");
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "press", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("Pressure", output.get(0).getTerm());
assertEquals("Systolic Blood Pressure", output.get(1).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "prezure");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "prezure", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("Pressure", output.get(0).getTerm());
assertEquals("Systolic Blood Pressure", output.get(1).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "syst");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "syst", null);
ourLog.info("Found: " + output);
assertEquals(4, output.size());
assertEquals("syst", output.get(0).getTerm());
@ -167,7 +167,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
assertEquals("Systolic", output.get(2).getTerm());
assertEquals("Systolic Blood Pressure", output.get(3).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "LCws");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "LCws", null);
ourLog.info("Found: " + output);
assertEquals(0, output.size());
}
@ -206,7 +206,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
obs2.getCode().setText("ZXCVBNMZZ");
myObservationDao.create(obs2, mockSrd());
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXCVBNM");
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXCVBNM", null);
ourLog.info("Found: " + output);
assertEquals(4, output.size());
assertEquals("ZXCVBNM", output.get(0).getTerm());
@ -214,7 +214,7 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
assertEquals("ZXC", output.get(2).getTerm());
assertEquals("ZXC HELLO", output.get(3).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXC");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXC", null);
ourLog.info("Found: " + output);
assertEquals(4, output.size());
assertEquals("ZXC", output.get(0).getTerm());
@ -222,17 +222,17 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
assertEquals("ZXCVBNM", output.get(2).getTerm());
assertEquals("ZXCVBNM ASDFGHJKL QWERTYUIOPASDFGHJKL", output.get(3).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "HELO");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "HELO", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("HELLO", output.get(0).getTerm());
assertEquals("ZXC HELLO", output.get(1).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "Z");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "Z", null);
ourLog.info("Found: " + output);
assertEquals(0, output.size());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZX");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZX", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("ZXC", output.get(0).getTerm());

View File

@ -14,7 +14,6 @@ import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.TestUtil;
import com.google.common.collect.Lists;
import org.apache.commons.io.IOUtils;
@ -35,7 +34,6 @@ import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.*;
import org.mockito.ArgumentCaptor;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
@ -47,7 +45,6 @@ import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@SuppressWarnings({"unchecked", "deprecation"})
public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
@ -214,11 +211,11 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
IIdType id2 = myObservationDao.create(o2, mySrd).getId();
{
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2001-01-02")));
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2001-01-02")), null);
assertThat(found, hasItem(id2.getIdPartAsLong()));
}
{
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")));
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")), null);
assertThat(found, not(hasItem(id2.getIdPartAsLong())));
}
}
@ -2030,13 +2027,13 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
"}\n";
//@formatter:on
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
Organization org = myFhirCtx.newJsonParser().parseResource(Organization.class, inputStr);
myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
assertEquals(initial + 1, val.size());
}
@ -3227,19 +3224,19 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
assertThat(str.length(), greaterThan(ResourceIndexedSearchParamString.MAX_LENGTH));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
assertEquals(initial + 0, val.size());
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH))));
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH))), null);
assertEquals(initial + 1, val.size());
try {
myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH + 1))));
myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH + 1))), null);
fail();
} catch (InvalidRequestException e) {
// ok
@ -3328,8 +3325,8 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
assertEquals("http://profile/1", profiles.get(0).getValue());
assertEquals("http://profile/2", profiles.get(1).getValue());
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cat", "Kittens");
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cow", "Calves");
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cat", "Kittens", null);
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cow", "Calves", null);
retrieved = myPatientDao.read(patientId, mySrd);
published = (ArrayList<Coding>) retrieved.getMeta().getTag();
@ -3406,23 +3403,23 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
String subStr1 = longStr1.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
String subStr2 = longStr2.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)));
val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)), null);
assertEquals(initial + 1, val.size());
try {
myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(longStr1, subStr2)));
myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(longStr1, subStr2)), null);
fail();
} catch (InvalidRequestException e) {
// ok
}
try {
myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, longStr2)));
myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, longStr2)), null);
fail();
} catch (InvalidRequestException e) {
// ok

View File

@ -1,29 +1,26 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import java.util.*;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.*;
import org.mockito.ArgumentCaptor;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Ignore;
import org.junit.Test;
import java.util.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3UpdateTest.class);
@ -450,7 +447,7 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
p2.addName().setFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB");
myPatientDao.create(p2, mySrd).getId();
Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")));
Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")), null);
assertEquals(1, ids.size());
assertThat(ids, contains(p1id.getIdPartAsLong()));
@ -459,10 +456,10 @@ public class FhirResourceDaoDstu3UpdateTest extends BaseJpaDstu3Test {
MethodOutcome update2 = myPatientDao.update(p1, mySrd);
IIdType p1id2 = update2.getId();
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")));
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")), null);
assertEquals(0, ids.size());
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2BBB")));
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2BBB")), null);
assertEquals(2, ids.size());
// Make sure vreads work

View File

@ -9,8 +9,6 @@ import java.util.List;
import javax.servlet.http.HttpServletRequest;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Observation.ObservationStatus;
import org.hl7.fhir.instance.model.api.IIdType;
@ -160,19 +158,19 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
myMediaDao.create(med, mockSrd());
ourLog.info(myFhirCtx.newJsonParser().encodeResourceToString(med));
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "press");
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "press", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("Pressure", output.get(0).getTerm());
assertEquals("Systolic Blood Pressure", output.get(1).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "prezure");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "prezure", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("Pressure", output.get(0).getTerm());
assertEquals("Systolic Blood Pressure", output.get(1).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "syst");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "syst", null);
ourLog.info("Found: " + output);
assertEquals(4, output.size());
assertEquals("syst", output.get(0).getTerm());
@ -180,7 +178,7 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
assertEquals("Systolic", output.get(2).getTerm());
assertEquals("Systolic Blood Pressure", output.get(3).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "LCws");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "LCws", null);
ourLog.info("Found: " + output);
assertEquals(0, output.size());
}
@ -219,7 +217,7 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
obs2.getCode().setText("ZXCVBNMZZ");
myObservationDao.create(obs2, mockSrd());
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXCVBNM");
List<Suggestion> output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXCVBNM", null);
ourLog.info("Found: " + output);
assertEquals(4, output.size());
assertEquals("ZXCVBNM", output.get(0).getTerm());
@ -227,7 +225,7 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
assertEquals("ZXC", output.get(2).getTerm());
assertEquals("ZXC HELLO", output.get(3).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXC");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZXC", null);
ourLog.info("Found: " + output);
assertEquals(4, output.size());
assertEquals("ZXC", output.get(0).getTerm());
@ -235,17 +233,17 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
assertEquals("ZXCVBNM", output.get(2).getTerm());
assertEquals("ZXCVBNM ASDFGHJKL QWERTYUIOPASDFGHJKL", output.get(3).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "HELO");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "HELO", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("HELLO", output.get(0).getTerm());
assertEquals("ZXC HELLO", output.get(1).getTerm());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "Z");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "Z", null);
ourLog.info("Found: " + output);
assertEquals(0, output.size());
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZX");
output = mySearchDao.suggestKeywords("Patient/" + ptId.getIdPart() + "/$everything", "_content", "ZX", null);
ourLog.info("Found: " + output);
assertEquals(2, output.size());
assertEquals("ZXC", output.get(0).getTerm());

View File

@ -89,7 +89,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
assertEquals(200, results.size().intValue());
List<String> ids = toUnqualifiedVersionlessIdValues(results, 0, 10, true);
assertThat(ids, empty());
assertEquals(200, myDatabaseBackedPagingProvider.retrieveResultList(uuid).size().intValue());
assertEquals(200, myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size().intValue());
}
@Test
@ -119,7 +119,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
assertEquals(201, results.size().intValue());
List<String> ids = toUnqualifiedVersionlessIdValues(results, 0, 10, true);
assertThat(ids, empty());
assertEquals(201, myDatabaseBackedPagingProvider.retrieveResultList(uuid).size().intValue());
assertEquals(201, myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size().intValue());
// Seach with total expicitly requested
params = new SearchParameterMap();
@ -131,7 +131,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
assertEquals(201, results.size().intValue());
ids = toUnqualifiedVersionlessIdValues(results, 0, 10, true);
assertThat(ids, hasSize(10));
assertEquals(201, myDatabaseBackedPagingProvider.retrieveResultList(uuid).size().intValue());
assertEquals(201, myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size().intValue());
// Seach with count only
params = new SearchParameterMap();
@ -143,7 +143,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
assertEquals(201, results.size().intValue());
ids = toUnqualifiedVersionlessIdValues(results, 0, 10, true);
assertThat(ids, empty());
assertEquals(201, myDatabaseBackedPagingProvider.retrieveResultList(uuid).size().intValue());
assertEquals(201, myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size().intValue());
}
@ -172,7 +172,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
assertEquals("Patient/PT00004", ids.get(4));
ourLog.info("** About to make new query for search with UUID: {}", uuid);
IBundleProvider search2 = myDatabaseBackedPagingProvider.retrieveResultList(uuid);
IBundleProvider search2 = myDatabaseBackedPagingProvider.retrieveResultList(uuid, null);
Integer search2Size = search2.size();
assertEquals(200, search2Size.intValue());
}
@ -194,7 +194,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
List<String> ids = toUnqualifiedVersionlessIdValues(results, 0, 10, true);
assertEquals("Patient/PT00000", ids.get(0));
assertEquals("Patient/PT00009", ids.get(9));
assertEquals(200, myDatabaseBackedPagingProvider.retrieveResultList(uuid).size().intValue());
assertEquals(200, myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size().intValue());
// Try the same query again. This time the same thing should come back, but
// from the cache...
@ -210,7 +210,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
ids = toUnqualifiedVersionlessIdValues(results, 0, 10, true);
assertEquals("Patient/PT00000", ids.get(0));
assertEquals("Patient/PT00009", ids.get(9));
assertEquals(200, myDatabaseBackedPagingProvider.retrieveResultList(uuid).size().intValue());
assertEquals(200, myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size().intValue());
}
@ -229,7 +229,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
List<String> ids = toUnqualifiedVersionlessIdValues(results, 0, 10, true);
assertEquals("Patient/PT00000", ids.get(0));
assertEquals("Patient/PT00009", ids.get(9));
assertEquals(null, myDatabaseBackedPagingProvider.retrieveResultList(uuid).size());
assertEquals(null, myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size());
// Try the same query again. This time we'll request _total=accurate as well
// which means the total should be calculated no matter what.
@ -244,7 +244,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
ids = toUnqualifiedVersionlessIdValues(results, 0, 10, true);
assertEquals("Patient/PT00000", ids.get(0));
assertEquals("Patient/PT00009", ids.get(9));
assertEquals(200, myDatabaseBackedPagingProvider.retrieveResultList(uuid2).size().intValue());
assertEquals(200, myDatabaseBackedPagingProvider.retrieveResultList(uuid2, null).size().intValue());
assertNotEquals(uuid, uuid2);
}
@ -267,7 +267,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
List<String> ids = toUnqualifiedVersionlessIdValues(results, 0, 200, true);
assertEquals("Patient/PT00000", ids.get(0));
assertEquals("Patient/PT00199", ids.get(199));
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid).size());
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size());
/*
* 20 should be prefetched since that's the initial page size
@ -322,7 +322,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
List<String> ids = toUnqualifiedVersionlessIdValues(results, 0, 10, true);
assertEquals("Patient/PT00000", ids.get(0));
assertEquals("Patient/PT00009", ids.get(9));
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid).size());
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size());
/*
* 20 should be prefetched since that's the initial page size
@ -347,7 +347,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
ids = toUnqualifiedVersionlessIdValues(results, 10, 15, false);
assertEquals("Patient/PT00010", ids.get(0));
assertEquals("Patient/PT00014", ids.get(4));
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid).size());
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size());
/*
* Search should be untouched
@ -387,7 +387,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
ids = toUnqualifiedVersionlessIdValues(results, 25, 30, false);
assertEquals("Patient/PT00025", ids.get(0));
assertEquals("Patient/PT00029", ids.get(4));
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid).size());
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size());
/*
* Search should be untouched
@ -425,7 +425,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
assertEquals(10, ids.size());
assertEquals("Patient/PT00180", ids.get(0));
assertEquals("Patient/PT00189", ids.get(9));
assertEquals(190, myDatabaseBackedPagingProvider.retrieveResultList(uuid).size().intValue());
assertEquals(190, myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size().intValue());
}
@ -449,7 +449,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
List<String> ids = toUnqualifiedVersionlessIdValues(results, 0, 50, true);
assertEquals("Patient/PT00000", ids.get(0));
assertEquals("Patient/PT00049", ids.get(49));
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid).size());
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size());
/*
* 20 should be prefetched since that's the initial page size
@ -484,7 +484,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
List<String> ids = toUnqualifiedVersionlessIdValues(results, 0, 10, true);
assertEquals("Patient/PT00000", ids.get(0));
assertEquals("Patient/PT00009", ids.get(9));
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid).size());
assertNull(myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size());
/*
* 20 should be prefetched since that's the initial page size
@ -509,7 +509,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
ids = toUnqualifiedVersionlessIdValues(results, 15, 25, false);
assertEquals("Patient/PT00015", ids.get(0));
assertEquals("Patient/PT00024", ids.get(9));
assertEquals(200, myDatabaseBackedPagingProvider.retrieveResultList(uuid).size().intValue());
assertEquals(200, myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size().intValue());
/*
* Search should be untouched
@ -619,7 +619,7 @@ public class FhirResourceDaoR4SearchOptimizedTest extends BaseJpaR4Test {
assertEquals(1, search.getVersion().intValue());
});
assertEquals(1, myDatabaseBackedPagingProvider.retrieveResultList(uuid).size().intValue());
assertEquals(1, myDatabaseBackedPagingProvider.retrieveResultList(uuid, null).size().intValue());
}

View File

@ -320,11 +320,11 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
IIdType id2 = myObservationDao.create(o2, mySrd).getId();
{
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2001-01-02")));
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2001-01-02")), null);
assertThat(found, hasItem(id2.getIdPartAsLong()));
}
{
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")));
Set<Long> found = myObservationDao.searchForIds(new SearchParameterMap(Observation.SP_DATE, new DateParam(">2016-01-02")), null);
assertThat(found, not(hasItem(id2.getIdPartAsLong())));
}
}
@ -2298,13 +2298,13 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
"}\n";
//@formatter:on
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
Organization org = myFhirCtx.newJsonParser().parseResource(Organization.class, inputStr);
myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
assertEquals(initial + 1, val.size());
}
@ -3593,19 +3593,19 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertThat(str.length(), greaterThan(ResourceIndexedSearchParamString.MAX_LENGTH));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")));
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam("P")), null);
assertEquals(initial + 0, val.size());
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH))));
val = myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH))), null);
assertEquals(initial + 1, val.size());
try {
myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH + 1))));
myOrganizationDao.searchForIds(new SearchParameterMap("name", new StringParam(str.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH + 1))), null);
fail();
} catch (InvalidRequestException e) {
// ok
@ -3694,8 +3694,8 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertEquals("http://profile/1", profiles.get(0).getValue());
assertEquals("http://profile/2", profiles.get(1).getValue());
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cat", "Kittens");
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cow", "Calves");
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cat", "Kittens", null);
myPatientDao.addTag(patientId, TagTypeEnum.TAG, "http://foo", "Cow", "Calves", null);
retrieved = myPatientDao.read(patientId, mySrd);
published = (ArrayList<Coding>) retrieved.getMeta().getTag();
@ -3772,23 +3772,23 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
String subStr1 = longStr1.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
String subStr2 = longStr2.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)));
Set<Long> val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)), null);
int initial = val.size();
myOrganizationDao.create(org, mySrd);
val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)));
val = myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, subStr2)), null);
assertEquals(initial + 1, val.size());
try {
myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(longStr1, subStr2)));
myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(longStr1, subStr2)), null);
fail();
} catch (InvalidRequestException e) {
// ok
}
try {
myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, longStr2)));
myOrganizationDao.searchForIds(new SearchParameterMap("type", new TokenParam(subStr1, longStr2)), null);
fail();
} catch (InvalidRequestException e) {
// ok

View File

@ -7,19 +7,16 @@ import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.TestUtil;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*;
import org.junit.*;
import org.mockito.ArgumentCaptor;
import org.springframework.test.context.TestPropertySource;
import java.util.*;
@ -577,7 +574,7 @@ public class FhirResourceDaoR4UpdateTest extends BaseJpaR4Test {
p2.addName().setFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB");
myPatientDao.create(p2, mySrd).getId();
Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")));
Set<Long> ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")), null);
assertEquals(1, ids.size());
assertThat(ids, contains(p1id.getIdPartAsLong()));
@ -586,10 +583,10 @@ public class FhirResourceDaoR4UpdateTest extends BaseJpaR4Test {
MethodOutcome update2 = myPatientDao.update(p1, mySrd);
IIdType p1id2 = update2.getId();
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")));
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2AAA")), null);
assertEquals(0, ids.size());
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2BBB")));
ids = myPatientDao.searchForIds(new SearchParameterMap(Patient.SP_GIVEN, new StringParam("testUpdateMaintainsSearchParamsDstu2BBB")), null);
assertEquals(2, ids.size());
// Make sure vreads work
@ -633,7 +630,7 @@ public class FhirResourceDaoR4UpdateTest extends BaseJpaR4Test {
{
Patient p1 = myPatientDao.read(p1id, mySrd);
List<Coding> tagList = p1.getMeta().getTag();
Set<String> secListValues = new HashSet<String>();
Set<String> secListValues = new HashSet<>();
for (Coding next : tagList) {
secListValues.add(next.getSystemElement().getValue() + "|" + next.getCodeElement().getValue());
}

View File

@ -58,7 +58,7 @@ public class DeleteConflictServiceTest {
link.setSourceResource(entity);
list.add(link);
when(myDeleteConflictFinderService.findConflicts(any(), anyInt())).thenReturn(list);
int retryCount = myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, false);
int retryCount = myDeleteConflictService.validateOkToDelete(deleteConflicts, entity, false, null);
assertEquals(0, retryCount);
}
}

View File

@ -135,7 +135,7 @@ public class ResourceProviderExpungeDstu2Test extends BaseResourceProviderDstu2T
myPatientDao.expunge(myTwoVersionPatientId.toUnqualifiedVersionless(), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Patients
assertStillThere(myOneVersionPatientId);
@ -157,7 +157,7 @@ public class ResourceProviderExpungeDstu2Test extends BaseResourceProviderDstu2T
try {
myPatientDao.expunge(myTwoVersionPatientId.withVersion("2"), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
fail();
} catch (PreconditionFailedException e) {
assertEquals("Can not perform version-specific expunge of resource Patient/PT-TWOVERSION/_history/2 as this is the current version", e.getMessage());
@ -175,7 +175,7 @@ public class ResourceProviderExpungeDstu2Test extends BaseResourceProviderDstu2T
myPatientDao.expunge(myTwoVersionPatientId.withVersion("2"), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Patients
assertStillThere(myOneVersionPatientId);

View File

@ -140,7 +140,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
myPatientDao.expunge(myTwoVersionPatientId.toUnqualifiedVersionless(), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Patients
assertStillThere(myOneVersionPatientId);
@ -162,7 +162,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
try {
myPatientDao.expunge(myTwoVersionPatientId.withVersion("2"), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
fail();
} catch (PreconditionFailedException e) {
assertEquals("Can not perform version-specific expunge of resource Patient/PT-TWOVERSION/_history/2 as this is the current version", e.getMessage());
@ -180,7 +180,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
myPatientDao.expunge(myTwoVersionPatientId.withVersion("2"), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Patients
assertStillThere(myOneVersionPatientId);
@ -312,7 +312,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
myPatientDao.expunge(myTwoVersionPatientId.toUnqualifiedVersionless(), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true)
.setLimit(2));
.setLimit(2), null);
// Patients
assertStillThere(myOneVersionPatientId);
@ -332,7 +332,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
myPatientDao.expunge(myOneVersionPatientId.toUnqualifiedVersionless(), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Patients
assertStillThere(myOneVersionPatientId);

View File

@ -144,7 +144,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
myPatientDao.expunge(myTwoVersionPatientId.toUnqualifiedVersionless(), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Patients
assertStillThere(myOneVersionPatientId);
@ -192,7 +192,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
try {
myPatientDao.expunge(myTwoVersionPatientId.withVersion("2"), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
fail();
} catch (PreconditionFailedException e) {
assertEquals("Can not perform version-specific expunge of resource Patient/PT-TWOVERSION/_history/2 as this is the current version", e.getMessage());
@ -212,7 +212,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
myPatientDao.expunge(myTwoVersionPatientId.withVersion("2"), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Patients
assertStillThere(myOneVersionPatientId);

View File

@ -15,6 +15,7 @@ import ca.uhn.fhir.jpa.util.BaseIterator;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.TestUtil;
@ -151,9 +152,9 @@ public class SearchCoordinatorSvcImplTest {
List<Long> pids = createPidSequence(10, 800);
IResultIterator iter = new FailAfterNIterator(new SlowIterator(pids.iterator(), 2), 300);
when(mySearchBuider.createQuery(Mockito.same(params), any())).thenReturn(iter);
when(mySearchBuider.createQuery(Mockito.same(params), any(), any())).thenReturn(iter);
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective());
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null);
assertNotNull(result.getUuid());
assertEquals(null, result.size());
@ -172,8 +173,8 @@ public class SearchCoordinatorSvcImplTest {
List<Long> pids = createPidSequence(10, 800);
SlowIterator iter = new SlowIterator(pids.iterator(), 1);
when(mySearchBuider.createQuery(any(), any())).thenReturn(iter);
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(any(List.class), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao));
when(mySearchBuider.createQuery(any(), any(), nullable(RequestDetails.class))).thenReturn(iter);
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(any(List.class), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao), nullable(RequestDetails.class));
when(mySearchResultDao.findWithSearchUuid(any(), any())).thenAnswer(t -> {
List<Long> returnedValues = iter.getReturnedValues();
@ -186,7 +187,7 @@ public class SearchCoordinatorSvcImplTest {
return new PageImpl<>(returnedValues.subList(offset, end));
});
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective());
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null);
assertNotNull(result.getUuid());
assertEquals(null, result.size());
@ -229,11 +230,11 @@ public class SearchCoordinatorSvcImplTest {
List<Long> pids = createPidSequence(10, 800);
SlowIterator iter = new SlowIterator(pids.iterator(), 2);
when(mySearchBuider.createQuery(Mockito.same(params), any())).thenReturn(iter);
when(mySearchBuider.createQuery(Mockito.same(params), any(), nullable(RequestDetails.class))).thenReturn(iter);
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(any(List.class), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao));
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(any(List.class), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao), nullable(RequestDetails.class));
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective());
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null);
assertNotNull(result.getUuid());
assertEquals(null, result.size());
@ -257,11 +258,11 @@ public class SearchCoordinatorSvcImplTest {
List<Long> pids = createPidSequence(10, 800);
IResultIterator iter = new SlowIterator(pids.iterator(), 2);
when(mySearchBuider.createQuery(Mockito.same(params), any())).thenReturn(iter);
when(mySearchBuider.createQuery(Mockito.same(params), any(), nullable(RequestDetails.class))).thenReturn(iter);
when(mySearchDao.save(any())).thenAnswer(t -> t.getArguments()[0]);
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(any(List.class), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao));
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(any(List.class), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao), nullable(RequestDetails.class));
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective());
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null);
assertNotNull(result.getUuid());
assertEquals(null, result.size());
@ -285,7 +286,7 @@ public class SearchCoordinatorSvcImplTest {
* Now call from a new bundle provider. This simulates a separate HTTP
* client request coming in.
*/
provider = new PersistedJpaBundleProvider(result.getUuid(), myCallingDao);
provider = new PersistedJpaBundleProvider(null, result.getUuid(), myCallingDao);
resources = provider.getResources(10, 20);
assertEquals(10, resources.size());
assertEquals("20", resources.get(0).getIdElement().getValueAsString());
@ -301,11 +302,11 @@ public class SearchCoordinatorSvcImplTest {
List<Long> pids = createPidSequence(10, 100);
SlowIterator iter = new SlowIterator(pids.iterator(), 2);
when(mySearchBuider.createQuery(Mockito.same(params), any())).thenReturn(iter);
when(mySearchBuider.createQuery(Mockito.same(params), any(), nullable(RequestDetails.class))).thenReturn(iter);
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(any(List.class), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao));
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(any(List.class), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao), nullable(RequestDetails.class));
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective());
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null);
assertNotNull(result.getUuid());
assertEquals(90, result.size().intValue());
@ -332,7 +333,7 @@ public class SearchCoordinatorSvcImplTest {
search.setResourceType("Patient");
when(mySearchDao.findByUuid(eq(uuid))).thenReturn(search);
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(any(List.class), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao));
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(any(List.class), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao), nullable(RequestDetails.class));
PersistedJpaBundleProvider provider;
List<IBaseResource> resources;
@ -368,13 +369,13 @@ public class SearchCoordinatorSvcImplTest {
* Now call from a new bundle provider. This simulates a separate HTTP
* client request coming in.
*/
provider = new PersistedJpaBundleProvider(uuid, myCallingDao);
provider = new PersistedJpaBundleProvider(null, uuid, myCallingDao);
resources = provider.getResources(10, 20);
assertEquals(10, resources.size());
assertEquals("20", resources.get(0).getIdElement().getValueAsString());
assertEquals("29", resources.get(9).getIdElement().getValueAsString());
provider = new PersistedJpaBundleProvider(uuid, myCallingDao);
provider = new PersistedJpaBundleProvider(null, uuid, myCallingDao);
resources = provider.getResources(20, 40);
assertEquals(20, resources.size());
assertEquals("30", resources.get(0).getIdElement().getValueAsString());
@ -390,11 +391,11 @@ public class SearchCoordinatorSvcImplTest {
params.add("name", new StringParam("ANAME"));
List<Long> pids = createPidSequence(10, 800);
when(mySearchBuider.createQuery(Mockito.same(params), any())).thenReturn(new ResultIterator(pids.iterator()));
when(mySearchBuider.createQuery(Mockito.same(params), any(), nullable(RequestDetails.class))).thenReturn(new ResultIterator(pids.iterator()));
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(eq(pids), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao));
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(eq(pids), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao), nullable(RequestDetails.class));
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective());
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null);
assertNull(result.getUuid());
assertEquals(790, result.size().intValue());
@ -411,12 +412,12 @@ public class SearchCoordinatorSvcImplTest {
params.add("name", new StringParam("ANAME"));
List<Long> pids = createPidSequence(10, 800);
when(mySearchBuider.createQuery(Mockito.same(params), any())).thenReturn(new ResultIterator(pids.iterator()));
when(mySearchBuider.createQuery(Mockito.same(params), any(), nullable(RequestDetails.class))).thenReturn(new ResultIterator(pids.iterator()));
pids = createPidSequence(10, 110);
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(eq(pids), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao));
doAnswer(loadPids()).when(mySearchBuider).loadResourcesByPid(eq(pids), any(List.class), any(Set.class), anyBoolean(), any(EntityManager.class), any(FhirContext.class), same(myCallingDao), nullable(RequestDetails.class));
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective());
IBundleProvider result = mySvc.registerSearch(myCallingDao, params, "Patient", new CacheControlDirective(), null);
assertNull(result.getUuid());
assertEquals(100, result.size().intValue());

View File

@ -139,7 +139,7 @@ public class StressTestR4Test extends BaseResourceProviderR4Test {
for (int i = 0; i <= count; i += 100) {
List<IBaseResource> resultsAndIncludes = results.getResources(i, i + 100);
ids.addAll(toUnqualifiedVersionlessIdValues(resultsAndIncludes));
results = myPagingProvider.retrieveResultList(results.getUuid());
results = myPagingProvider.retrieveResultList(results.getUuid(), null);
}
assertEquals(count, ids.size());
assertEquals(count, Sets.newHashSet(ids).size());
@ -152,7 +152,7 @@ public class StressTestR4Test extends BaseResourceProviderR4Test {
for (int i = 1000; i <= count; i += 100) {
List<IBaseResource> resultsAndIncludes = results.getResources(i, i + 100);
ids.addAll(toUnqualifiedVersionlessIdValues(resultsAndIncludes));
results = myPagingProvider.retrieveResultList(results.getUuid());
results = myPagingProvider.retrieveResultList(results.getUuid(), null);
}
assertEquals(count - 1000, ids.size());
assertEquals(count - 1000, Sets.newHashSet(ids).size());

View File

@ -66,7 +66,7 @@ public class InMemorySubscriptionMatcherR4Test {
private InMemoryMatchResult match(String criteria, Resource theResource) {
ourLog.info("Criteria: <{}>", criteria);
return mySearchParamMatcher.match(criteria, theResource);
return mySearchParamMatcher.match(criteria, theResource, null);
}
private void assertUnsupported(Resource resource, SearchParameterMap theParams) {

View File

@ -22,11 +22,12 @@ package ca.uhn.fhir.jpa.searchparam.extractor;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
public interface IResourceLinkResolver {
ResourceTable findTargetResource(RuntimeSearchParam theNextSpDef, String theNextPathsUnsplit, IIdType theNextId, String theTypeString, Class<? extends IBaseResource> theType, String theId);
ResourceTable findTargetResource(RuntimeSearchParam theNextSpDef, String theNextPathsUnsplit, IIdType theNextId, String theTypeString, Class<? extends IBaseResource> theType, String theId, RequestDetails theRequest);
void validateTypeOrThrowException(Class<? extends IBaseResource> theType);
}

View File

@ -30,6 +30,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.*;
@ -58,7 +59,7 @@ public class ResourceLinkExtractor {
@Autowired
private ISearchParamExtractor mySearchParamExtractor;
public void extractResourceLinks(ResourceIndexedSearchParams theParams, ResourceTable theEntity, IBaseResource theResource, Date theUpdateTime, IResourceLinkResolver theResourceLinkResolver, boolean theFailOnInvalidReference) {
public void extractResourceLinks(ResourceIndexedSearchParams theParams, ResourceTable theEntity, IBaseResource theResource, Date theUpdateTime, IResourceLinkResolver theResourceLinkResolver, boolean theFailOnInvalidReference, RequestDetails theRequest) {
String resourceType = theEntity.getResourceType();
/*
@ -71,13 +72,13 @@ public class ResourceLinkExtractor {
Map<String, RuntimeSearchParam> searchParams = mySearchParamRegistry.getActiveSearchParams(toResourceName(theResource.getClass()));
for (RuntimeSearchParam nextSpDef : searchParams.values()) {
extractResourceLinks(theParams, theEntity, theResource, theUpdateTime, theResourceLinkResolver, resourceType, nextSpDef, theFailOnInvalidReference);
extractResourceLinks(theParams, theEntity, theResource, theUpdateTime, theResourceLinkResolver, resourceType, nextSpDef, theFailOnInvalidReference, theRequest);
}
theEntity.setHasLinks(theParams.myLinks.size() > 0);
}
private void extractResourceLinks(ResourceIndexedSearchParams theParams, ResourceTable theEntity, IBaseResource theResource, Date theUpdateTime, IResourceLinkResolver theResourceLinkResolver, String theResourceType, RuntimeSearchParam nextSpDef, boolean theFailOnInvalidReference) {
private void extractResourceLinks(ResourceIndexedSearchParams theParams, ResourceTable theEntity, IBaseResource theResource, Date theUpdateTime, IResourceLinkResolver theResourceLinkResolver, String theResourceType, RuntimeSearchParam nextSpDef, boolean theFailOnInvalidReference, RequestDetails theRequest) {
if (nextSpDef.getParamType() != RestSearchParameterTypeEnum.REFERENCE) {
return;
}
@ -94,11 +95,11 @@ public class ResourceLinkExtractor {
List<PathAndRef> refs = mySearchParamExtractor.extractResourceLinks(theResource, nextSpDef);
for (PathAndRef nextPathAndRef : refs) {
extractResourceLinks(theParams, theEntity, theUpdateTime, theResourceLinkResolver, theResourceType, nextSpDef, nextPathsUnsplit, multiType, nextPathAndRef, theFailOnInvalidReference);
extractResourceLinks(theParams, theEntity, theUpdateTime, theResourceLinkResolver, theResourceType, nextSpDef, nextPathsUnsplit, multiType, nextPathAndRef, theFailOnInvalidReference, theRequest);
}
}
private void extractResourceLinks(ResourceIndexedSearchParams theParams, ResourceTable theEntity, Date theUpdateTime, IResourceLinkResolver theResourceLinkResolver, String theResourceType, RuntimeSearchParam nextSpDef, String theNextPathsUnsplit, boolean theMultiType, PathAndRef nextPathAndRef, boolean theFailOnInvalidReference) {
private void extractResourceLinks(ResourceIndexedSearchParams theParams, ResourceTable theEntity, Date theUpdateTime, IResourceLinkResolver theResourceLinkResolver, String theResourceType, RuntimeSearchParam nextSpDef, String theNextPathsUnsplit, boolean theMultiType, PathAndRef nextPathAndRef, boolean theFailOnInvalidReference, RequestDetails theRequest) {
Object nextObject = nextPathAndRef.getRef();
/*
@ -215,13 +216,13 @@ public class ResourceLinkExtractor {
}
theResourceLinkResolver.validateTypeOrThrowException(type);
ResourceLink resourceLink = createResourceLink(theEntity, theUpdateTime, theResourceLinkResolver, nextSpDef, theNextPathsUnsplit, nextPathAndRef, nextId, typeString, type, id);
ResourceLink resourceLink = createResourceLink(theEntity, theUpdateTime, theResourceLinkResolver, nextSpDef, theNextPathsUnsplit, nextPathAndRef, nextId, typeString, type, id, theRequest);
if (resourceLink == null) return;
theParams.myLinks.add(resourceLink);
}
private ResourceLink createResourceLink(ResourceTable theEntity, Date theUpdateTime, IResourceLinkResolver theResourceLinkResolver, RuntimeSearchParam nextSpDef, String theNextPathsUnsplit, PathAndRef nextPathAndRef, IIdType theNextId, String theTypeString, Class<? extends IBaseResource> theType, String theId) {
ResourceTable targetResource = theResourceLinkResolver.findTargetResource(nextSpDef, theNextPathsUnsplit, theNextId, theTypeString, theType, theId);
private ResourceLink createResourceLink(ResourceTable theEntity, Date theUpdateTime, IResourceLinkResolver theResourceLinkResolver, RuntimeSearchParam nextSpDef, String theNextPathsUnsplit, PathAndRef nextPathAndRef, IIdType theNextId, String theTypeString, Class<? extends IBaseResource> theType, String theId, RequestDetails theRequest) {
ResourceTable targetResource = theResourceLinkResolver.findTargetResource(nextSpDef, theNextPathsUnsplit, theNextId, theTypeString, theType, theId, theRequest);
if (targetResource == null) return null;
ResourceLink resourceLink = new ResourceLink(nextPathAndRef.getPath(), theEntity, targetResource, theUpdateTime);

View File

@ -25,6 +25,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams;
import ca.uhn.fhir.jpa.searchparam.extractor.ResourceLinkExtractor;
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorService;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -40,13 +41,13 @@ public class IndexedSearchParamExtractor {
@Autowired
private InlineResourceLinkResolver myInlineResourceLinkResolver;
public ResourceIndexedSearchParams extractIndexedSearchParams(IBaseResource theResource) {
public ResourceIndexedSearchParams extractIndexedSearchParams(IBaseResource theResource, RequestDetails theRequest) {
ResourceTable entity = new ResourceTable();
String resourceType = myContext.getResourceDefinition(theResource).getName();
entity.setResourceType(resourceType);
ResourceIndexedSearchParams resourceIndexedSearchParams = new ResourceIndexedSearchParams();
mySearchParamExtractorService.extractFromResource(resourceIndexedSearchParams, entity, theResource);
myResourceLinkExtractor.extractResourceLinks(resourceIndexedSearchParams, entity, theResource, theResource.getMeta().getLastUpdated(), myInlineResourceLinkResolver, false);
myResourceLinkExtractor.extractResourceLinks(resourceIndexedSearchParams, entity, theResource, theResource.getMeta().getLastUpdated(), myInlineResourceLinkResolver, false, theRequest);
return resourceIndexedSearchParams;
}
}

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.model.entity.ForcedId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.IResourceLinkResolver;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.stereotype.Service;
@ -32,7 +33,7 @@ import org.springframework.stereotype.Service;
public class InlineResourceLinkResolver implements IResourceLinkResolver {
@Override
public ResourceTable findTargetResource(RuntimeSearchParam theNextSpDef, String theNextPathsUnsplit, IIdType theNextId, String theTypeString, Class<? extends IBaseResource> theType, String theId) {
public ResourceTable findTargetResource(RuntimeSearchParam theNextSpDef, String theNextPathsUnsplit, IIdType theNextId, String theTypeString, Class<? extends IBaseResource> theType, String theId, RequestDetails theRequest) {
ResourceTable target;
target = new ResourceTable();
target.setResourceType(theTypeString);

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.searchparam.matcher;
*/
import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -32,8 +33,8 @@ public class SearchParamMatcher {
@Autowired
private InMemoryResourceMatcher myInMemoryResourceMatcher;
public InMemoryMatchResult match(String theCriteria, IBaseResource theResource) {
ResourceIndexedSearchParams resourceIndexedSearchParams = myIndexedSearchParamExtractor.extractIndexedSearchParams(theResource);
public InMemoryMatchResult match(String theCriteria, IBaseResource theResource, RequestDetails theRequest) {
ResourceIndexedSearchParams resourceIndexedSearchParams = myIndexedSearchParamExtractor.extractIndexedSearchParams(theResource, theRequest);
return myInMemoryResourceMatcher.match(theCriteria, theResource, resourceIndexedSearchParams);
}
}

View File

@ -24,6 +24,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryMatchResult;
import ca.uhn.fhir.jpa.searchparam.matcher.SearchParamMatcher;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -46,13 +47,13 @@ public class SearchableHashMapResourceProvider<T extends IBaseResource> extends
mySearchParamMatcher = theSearchParamMatcher;
}
public List<T> searchByCriteria(String theCriteria) {
return searchBy(resource -> mySearchParamMatcher.match(theCriteria, resource));
public List<T> searchByCriteria(String theCriteria, RequestDetails theRequest) {
return searchBy(resource -> mySearchParamMatcher.match(theCriteria, resource, theRequest));
}
public List<T> searchByParams(SearchParameterMap theSearchParams) {
return searchBy(resource -> mySearchParamMatcher.match(theSearchParams.toNormalizedQueryString(getFhirContext()), resource));
public List<T> searchByParams(SearchParameterMap theSearchParams, RequestDetails theRequest) {
return searchBy(resource -> mySearchParamMatcher.match(theSearchParams.toNormalizedQueryString(getFhirContext()), resource, theRequest));
}
private List<T> searchBy(Function<IBaseResource, InMemoryMatchResult> theMatcher) {

View File

@ -187,9 +187,11 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
.collect(Collectors.joining(", "));
String message = "Search parameter " + next.getId().toUnqualifiedVersionless().getValue() + " refers to unknown component " + nextRef + ", ignoring this parameter (valid values: " + existingParams + ")";
ourLog.warn(message);
StorageProcessingMessage msg = new StorageProcessingMessage().setMessage(message);
HookParams params = new HookParams(msg);
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PROCESSING_MESSAGE, params);
// Interceptor broadcast: JPA_PERFTRACE_WARNING
HookParams params = new HookParams();
params.add(StorageProcessingMessage.class, new StorageProcessingMessage().setMessage(message));
myInterceptorBroadcaster.callHooks(Pointcut.JPA_PERFTRACE_WARNING, params);
}
}

View File

@ -41,7 +41,7 @@ public class InMemorySubscriptionMatcher implements ISubscriptionMatcher {
@Override
public InMemoryMatchResult match(CanonicalSubscription theSubscription, ResourceModifiedMessage theMsg) {
try {
return mySearchParamMatcher.match(theSubscription.getCriteriaString(), theMsg.getNewPayload(myContext));
return mySearchParamMatcher.match(theSubscription.getCriteriaString(), theMsg.getNewPayload(myContext), null);
} catch (Exception e) {
ourLog.error("Failure in in-memory matcher", e);
throw new InternalErrorException("Failure performing memory-match for resource ID[" + theMsg.getId(myContext) + "] for subscription ID[" + theSubscription.getIdElementString() + "]: " + e.getMessage(), e);

View File

@ -23,12 +23,12 @@ public class InMemorySubscriptionMatcherR3Test extends BaseSubscriptionDstu3Test
SearchParamMatcher mySearchParamMatcher;
private void assertUnsupported(IBaseResource resource, String criteria) {
assertFalse(mySearchParamMatcher.match(criteria, resource).supported());
assertFalse(mySearchParamMatcher.match(criteria, resource, null).supported());
assertEquals(SubscriptionMatchingStrategy.DATABASE, mySubscriptionStrategyEvaluator.determineStrategy(criteria));
}
private void assertMatched(IBaseResource resource, String criteria) {
InMemoryMatchResult result = mySearchParamMatcher.match(criteria, resource);
InMemoryMatchResult result = mySearchParamMatcher.match(criteria, resource, null);
assertTrue(result.supported());
assertTrue(result.matched());
@ -40,7 +40,7 @@ public class InMemorySubscriptionMatcherR3Test extends BaseSubscriptionDstu3Test
}
private void assertNotMatched(IBaseResource resource, String criteria, SubscriptionMatchingStrategy theSubscriptionMatchingStrategy) {
InMemoryMatchResult result = mySearchParamMatcher.match(criteria, resource);
InMemoryMatchResult result = mySearchParamMatcher.match(criteria, resource, null);
assertTrue(result.supported());
assertFalse(result.matched());

View File

@ -23,6 +23,7 @@ package ca.uhn.fhir.rest.server;
import java.util.LinkedHashMap;
import java.util.UUID;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.apache.commons.lang3.Validate;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
@ -40,7 +41,7 @@ public class FifoMemoryPagingProvider extends BasePagingProvider implements IPag
}
@Override
public synchronized IBundleProvider retrieveResultList(String theId) {
public synchronized IBundleProvider retrieveResultList(String theId, RequestDetails theRequest) {
return myBundleProviders.get(theId);
}

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.rest.server;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
/*
* #%L
@ -11,9 +12,9 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider;
* 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.
@ -30,13 +31,23 @@ public interface IPagingProvider {
/**
* Retrieve a result list by ID
* <p>
* Note that the <code>theRequest</code> parameter was added to this
* method in HAPI FHIR 4.0.0. Existing implementations may choose to
* add this parameter and not use it if needed.
* </p>
*/
IBundleProvider retrieveResultList(String theSearchId);
IBundleProvider retrieveResultList(String theSearchId, RequestDetails theRequest);
/**
* Retrieve a result list by ID
* <p>
* Note that the <code>theRequest</code> parameter was added to this
* method in HAPI FHIR 4.0.0. Existing implementations may choose to
* add this parameter and not use it if needed.
* </p>
*/
default IBundleProvider retrieveResultList(String theSearchId, String thePageId) {
default IBundleProvider retrieveResultList(String theSearchId, String thePageId, RequestDetails theRequest) {
return null;
}

View File

@ -101,13 +101,13 @@ public class PageMethodBinding extends BaseResourceReturningMethodBinding {
if (pageId != null) {
// This is a page request by Search ID and Page ID
resultList = pagingProvider.retrieveResultList(thePagingAction, pageId);
resultList = pagingProvider.retrieveResultList(thePagingAction, pageId, theRequest);
validateHaveBundleProvider(thePagingAction, resultList);
} else {
// This is a page request by Search ID and Offset
resultList = pagingProvider.retrieveResultList(thePagingAction);
resultList = pagingProvider.retrieveResultList(thePagingAction, theRequest);
validateHaveBundleProvider(thePagingAction, resultList);
offsetI = RestfulServerUtils.tryToExtractNamedParameter(theRequest, Constants.PARAM_PAGINGOFFSET);

View File

@ -73,7 +73,7 @@ public class ClientServerValidationDstu3Test {
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML_NEW + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
public InputStream answer(InvocationOnMock theInvocation) {
if (myFirstResponse) {
myFirstResponse=false;
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));

View File

@ -67,6 +67,7 @@ public class OperationServerR4Test {
ourLastParamMoney1 = null;
ourLastId = null;
ourLastMethod = "";
ourNextResponse = null;
myFhirClient = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort);
}
@ -136,19 +137,45 @@ public class OperationServerR4Test {
return retVal;
}
@Test
public void testElementsFilterOnOperationResponse() throws Exception {
Bundle bundle = new Bundle();
bundle.setType(Bundle.BundleType.COLLECTION);
ourNextResponse = bundle;
Patient patient = new Patient();
patient.addName().setFamily("FAMILY").addGiven("GIVEN");
patient.addIdentifier().setSystem("SYSTEM").setValue("VALUE");
bundle.addEntry().setResource(patient);
HttpGet httpPost = new HttpGet("http://localhost:" + ourPort + "/Patient/$OP_TYPE_RETURNING_BUNDLE"
+ "?_pretty=true&_elements=identifier");
try (CloseableHttpResponse status = ourClient.execute(httpPost)) {
assertEquals(200, status.getStatusLine().getStatusCode());
String response = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info("Response: {}", response);
Bundle resp = ourCtx.newXmlParser().parseResource(Bundle.class, response);
Patient pt = (Patient) resp.getEntry().get(0).getResource();
assertEquals(0, pt.getName().size());
assertEquals(1, pt.getIdentifier().size());
}
}
@Test
public void testInstanceEverythingGet() throws Exception {
// Try with a GET
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$everything");
CloseableHttpResponse status = ourClient.execute(httpGet);
assertEquals(200, status.getStatusLine().getStatusCode());
String response = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
IOUtils.closeQuietly(status.getEntity().getContent());
try (CloseableHttpResponse status = ourClient.execute(httpGet)) {
assertEquals(200, status.getStatusLine().getStatusCode());
String response = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
assertThat(response, startsWith("<Bundle"));
}
assertEquals("instance $everything", ourLastMethod);
assertThat(response, startsWith("<Bundle"));
assertEquals("Patient/123", ourLastId.toUnqualifiedVersionless().getValue());
}
@ -590,21 +617,21 @@ public class OperationServerR4Test {
}
}
private static IBaseResource ourNextResponse;
public static class PatientProvider implements IResourceProvider {
@Override
public Class<Patient> getResourceType() {
return Patient.class;
}
//@formatter:off
@Operation(name = "$OP_INSTANCE")
public Parameters opInstance(
@IdParam IdType theId,
@OperationParam(name = "PARAM1") StringType theParam1,
@OperationParam(name = "PARAM2") Patient theParam2
) {
//@formatter:on
ourLastMethod = "$OP_INSTANCE";
ourLastId = theId;
@ -635,6 +662,14 @@ public class OperationServerR4Test {
return retVal;
}
@Operation(name = "$OP_TYPE_RETURNING_BUNDLE", idempotent = true)
public IBaseResource opTypeReturningBundle(
) {
ourLastMethod = "$OP_TYPE_RETURNING_BUNDLE";
return ourNextResponse;
}
@Operation(name = "$OP_PROFILE_DT2", idempotent = true)
public Bundle opProfileType(
@OperationParam(name = "PARAM1") MoneyQuantity theParam1

View File

@ -35,8 +35,7 @@ import java.util.concurrent.TimeUnit;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ -93,18 +92,18 @@ public class PagingUsingNamedPagesR4Test {
List<IBaseResource> patients0 = createPatients(0, 9);
BundleProviderWithNamedPages provider0 = new BundleProviderWithNamedPages(patients0, "SEARCHID0", "PAGEID0", 1000);
provider0.setNextPageId("PAGEID1");
when(myPagingProvider.retrieveResultList(eq("SEARCHID0"), eq("PAGEID0"))).thenReturn(provider0);
when(myPagingProvider.retrieveResultList(eq("SEARCHID0"), eq("PAGEID0"), any())).thenReturn(provider0);
List<IBaseResource> patients1 = createPatients(10, 19);
BundleProviderWithNamedPages provider1 = new BundleProviderWithNamedPages(patients1, "SEARCHID0", "PAGEID1", 1000);
provider1.setPreviousPageId("PAGEID0");
provider1.setNextPageId("PAGEID2");
when(myPagingProvider.retrieveResultList(eq("SEARCHID0"), eq("PAGEID1"))).thenReturn(provider1);
when(myPagingProvider.retrieveResultList(eq("SEARCHID0"), eq("PAGEID1"), any())).thenReturn(provider1);
List<IBaseResource> patients2 = createPatients(20, 29);
BundleProviderWithNamedPages provider2 = new BundleProviderWithNamedPages(patients2, "SEARCHID0", "PAGEID2", 1000);
provider2.setPreviousPageId("PAGEID1");
when(myPagingProvider.retrieveResultList(eq("SEARCHID0"), eq("PAGEID2"))).thenReturn(provider2);
when(myPagingProvider.retrieveResultList(eq("SEARCHID0"), eq("PAGEID2"), any())).thenReturn(provider2);
ourNextBundleProvider = provider0;
@ -146,8 +145,8 @@ public class PagingUsingNamedPagesR4Test {
@Test
public void testPagingLinkUnknownPage() throws Exception {
when(myPagingProvider.retrieveResultList(nullable(String.class))).thenReturn(null);
when(myPagingProvider.retrieveResultList(nullable(String.class), nullable(String.class))).thenReturn(null);
when(myPagingProvider.retrieveResultList(nullable(String.class), any(), any())).thenReturn(null);
when(myPagingProvider.retrieveResultList(nullable(String.class), nullable(String.class), any())).thenReturn(null);
// With ID
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "?_getpages=SEARCHID0&_pageId=PAGEID0&_format=xml&_bundletype=FOO" + UrlUtil.escapeUrlParam("\""));
@ -175,7 +174,7 @@ public class PagingUsingNamedPagesR4Test {
List<IBaseResource> patients0 = createPatients(0, 9);
BundleProviderWithNamedPages provider0 = new BundleProviderWithNamedPages(patients0, "SEARCHID0", "PAGEID0", 1000);
provider0.setNextPageId("PAGEID1");
when(myPagingProvider.retrieveResultList(eq("SEARCHID0"), eq("PAGEID0"))).thenReturn(provider0);
when(myPagingProvider.retrieveResultList(eq("SEARCHID0"), eq("PAGEID0"), any())).thenReturn(provider0);
// Initial search
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "?_getpages=SEARCHID0&_pageId=PAGEID0&_format=xml&_bundletype=FOO" + UrlUtil.escapeUrlParam("\""));

View File

@ -23,6 +23,21 @@
</ul>
]]>
</action>
<action type="change">
<![CDATA[
<b>Breaking Change</b>:
The
<code>IPagingProvider</code>
interface has been
modified so that the
<code>retrieveResultList</code>
method now takes one additional parameter of type
<code>RequestDetails</code>. If you have created a custom
implementation of this interface, you can add this parameter and
ignore it if needed. The use of the method has not changed, so this
should be an easy fix to existing code.
]]>
</action>
<action type="add">
The $expunge global everything operation has been refactored to do deletes
in small batches. This change will likely reduce performance, but does allow