Add changelog
This commit is contained in:
parent
71ed25b77c
commit
fe98162616
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
type: fix
|
||||
issue: 2876
|
||||
jira: SMILE-1153
|
||||
title: "Fixed a bug in transaction bundle processing, specifically for bundles which contained both a conditional create, and a resource which relied on this conditional create as a reference.
|
||||
This would cause the referring resource to generate a contained resource instead of appropriately referencing the existing patient."
|
|
@ -94,6 +94,7 @@ import com.google.common.collect.Sets;
|
|||
import com.google.common.hash.HashFunction;
|
||||
import com.google.common.hash.Hashing;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
|
@ -1162,10 +1163,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
|||
validateResourceForStorage((T) theResource, entity);
|
||||
}
|
||||
}
|
||||
String resourceType = myContext.getResourceType(theResource);
|
||||
if (isNotBlank(entity.getResourceType()) && !entity.getResourceType().equals(resourceType)) {
|
||||
throw new UnprocessableEntityException(
|
||||
"Existing resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + entity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
|
||||
if (!StringUtils.isBlank(entity.getResourceType())) {
|
||||
validateIncomingResourceTypeMatchesExisting(theResource, entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1206,6 +1205,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
|||
if (thePerformIndexing || ((ResourceTable) theEntity).getVersion() == 1) {
|
||||
|
||||
newParams = new ResourceIndexedSearchParams();
|
||||
|
||||
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, theTransactionDetails, entity, theResource, existingParams, theRequest, thePerformIndexing);
|
||||
|
||||
changed = populateResourceIntoEntity(theTransactionDetails, theRequest, theResource, entity, true);
|
||||
|
@ -1415,6 +1415,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
|||
return entity;
|
||||
}
|
||||
|
||||
private void validateIncomingResourceTypeMatchesExisting(IBaseResource theResource, ResourceTable entity) {
|
||||
String resourceType = myContext.getResourceType(theResource);
|
||||
if (!resourceType.equals(entity.getResourceType())) {
|
||||
throw new UnprocessableEntityException(
|
||||
"Existing resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + entity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceTable updateInternal(RequestDetails theRequestDetails, T theResource, boolean thePerformIndexing, boolean theForceUpdateVersion,
|
||||
IBasePersistedResource theEntity, IIdType theResourceId, IBaseResource theOldResource, TransactionDetails theTransactionDetails) {
|
||||
|
|
|
@ -262,7 +262,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
entity.setCreatedByMatchUrl(theIfNoneExist);
|
||||
entity.setVersion(1);
|
||||
|
||||
//FIXME GGG is this possibly where we are fetching the thing?
|
||||
if (isNotBlank(theIfNoneExist)) {
|
||||
Set<ResourcePersistentId> match = myMatchResourceUrlService.processMatchUrl(theIfNoneExist, myResourceType, theTransactionDetails, theRequest);
|
||||
if (match.size() > 1) {
|
||||
|
@ -279,7 +278,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
};
|
||||
|
||||
Supplier<IIdType> idSupplier = () -> {
|
||||
return myTxTemplate.execute(tx -> {
|
||||
myTxTemplate.execute(tx -> {
|
||||
IIdType retVal = myIdHelperService.translatePidIdToForcedId(myFhirContext, myResourceName, pid);
|
||||
if (!retVal.hasVersionIdPart()) {
|
||||
IIdType idWithVersion = myMemoryCacheService.getIfPresent(MemoryCacheService.CacheEnum.RESOURCE_CONDITIONAL_CREATE_VERSION, pid.getIdAsLong());
|
||||
|
|
|
@ -791,6 +791,8 @@ public abstract class BaseTransactionProcessor {
|
|||
String matchUrl = myVersionAdapter.getEntryRequestIfNoneExist(nextReqEntry);
|
||||
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
|
||||
outcome = resourceDao.create(res, matchUrl, false, theTransactionDetails, theRequest);
|
||||
// IS THIS THE MAGIC SAUCE?
|
||||
res.setId(outcome.getId());
|
||||
if (nextResourceId != null) {
|
||||
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequest);
|
||||
}
|
||||
|
@ -865,7 +867,6 @@ public abstract class BaseTransactionProcessor {
|
|||
matchUrl = parts.getResourceType();
|
||||
}
|
||||
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
|
||||
//TODO FIXME GGG This update call comes back with a contained resource.
|
||||
outcome = resourceDao.update(res, matchUrl, false, false, theRequest, theTransactionDetails);
|
||||
if (Boolean.TRUE.equals(outcome.getCreated())) {
|
||||
conditionalRequestUrls.put(matchUrl, res.getClass());
|
||||
|
|
|
@ -129,6 +129,7 @@ public class SearchParamWithInlineReferencesExtractor {
|
|||
partitionId = RequestPartitionId.allPartitions();
|
||||
}
|
||||
|
||||
//THIS IS THE NEW SPOT
|
||||
mySearchParamExtractorService.extractFromResource(partitionId, theRequest, theParams, theEntity, theResource, theTransactionDetails, theFailOnInvalidReference);
|
||||
|
||||
Set<Map.Entry<String, RuntimeSearchParam>> activeSearchParams = mySearchParamRegistry.getActiveSearchParams(theEntity.getResourceType()).entrySet();
|
||||
|
|
|
@ -78,6 +78,7 @@ import java.util.Collections;
|
|||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
@ -964,6 +965,17 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to determine if a set of SPs for a resource uses a resolve as part of its fhir path.
|
||||
*/
|
||||
private boolean anySearchParameterUsesResolve(Collection<RuntimeSearchParam> searchParams, RestSearchParameterTypeEnum theSearchParamType) {
|
||||
return searchParams.stream()
|
||||
.filter(param -> param.getParamType() != theSearchParamType)
|
||||
.filter(Objects::nonNull)
|
||||
.anyMatch(param -> param.getPath().contains("resolve"));
|
||||
}
|
||||
|
||||
/**
|
||||
* HAPI FHIR Reference objects (e.g. {@link org.hl7.fhir.r4.model.Reference}) can hold references either by text
|
||||
* (e.g. "#3") or by resource (e.g. "new Reference(patientInstance)"). The FHIRPath evaluator only understands the
|
||||
|
@ -974,17 +986,12 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
|||
* if we think there's actually a chance
|
||||
*/
|
||||
private void cleanUpContainedResourceReferences(IBaseResource theResource, RestSearchParameterTypeEnum theSearchParamType, Collection<RuntimeSearchParam> searchParams) {
|
||||
boolean havePathWithResolveExpression = myModelConfig.isIndexOnContainedResources();
|
||||
for (RuntimeSearchParam nextSpDef : searchParams) {
|
||||
if (nextSpDef.getParamType() != theSearchParamType) {
|
||||
continue;
|
||||
}
|
||||
if (defaultString(nextSpDef.getPath()).contains("resolve")) {
|
||||
havePathWithResolveExpression = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
boolean havePathWithResolveExpression =
|
||||
myModelConfig.isIndexOnContainedResources()
|
||||
|| anySearchParameterUsesResolve(searchParams, theSearchParamType);
|
||||
|
||||
if (havePathWithResolveExpression) {
|
||||
//FIXME GGG/JA: At this point, if the Task.basedOn.reference.resource does _not_ have an ID, we will attempt to contain it internally.
|
||||
myContext.newTerser().containResources(theResource, FhirTerser.OptionsEnum.MODIFY_RESOURCE, FhirTerser.OptionsEnum.STORE_AND_REUSE_RESULTS);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue