Jd 20241126 fix versioned refs in transaction bundles (#6521)
* tests, fix, minor refactoring * spotless * changelog * changelog update --------- Co-authored-by: jdar <justin.dar@smiledigitalhealth.com>
This commit is contained in:
parent
e59e7fc29f
commit
6c4aa2c154
|
@ -23,12 +23,14 @@ import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.util.CollectionUtil;
|
import ca.uhn.fhir.util.CollectionUtil;
|
||||||
import jakarta.annotation.Nonnull;
|
import jakarta.annotation.Nonnull;
|
||||||
import jakarta.annotation.Nullable;
|
import jakarta.annotation.Nullable;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This object supplies default configuration to all {@link IParser parser} instances
|
* This object supplies default configuration to all {@link IParser parser} instances
|
||||||
|
@ -126,6 +128,17 @@ public class ParserOptions {
|
||||||
return myDontStripVersionsFromReferencesAtPaths;
|
return myDontStripVersionsFromReferencesAtPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a sub-collection of {@link #getDontStripVersionsFromReferencesAtPaths()} containing only paths
|
||||||
|
* for the given resource type.
|
||||||
|
*/
|
||||||
|
public Set<String> getDontStripVersionsFromReferencesAtPathsByResourceType(String theResourceType) {
|
||||||
|
Validate.notEmpty(theResourceType, "theResourceType must not be null or empty");
|
||||||
|
return myDontStripVersionsFromReferencesAtPaths.stream()
|
||||||
|
.filter(referencePath -> referencePath.startsWith(theResourceType + "."))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If supplied value(s), any resource references at the specified paths will have their
|
* If supplied value(s), any resource references at the specified paths will have their
|
||||||
* resource versions encoded instead of being automatically stripped during the encoding
|
* resource versions encoded instead of being automatically stripped during the encoding
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 6519
|
||||||
|
jira: SMILE-8776
|
||||||
|
title: "Previously, when posting a transaction bundle with versioned references, the server would strip versioned
|
||||||
|
references form the resource even when configured not to do so. This has now been fixed."
|
|
@ -26,6 +26,7 @@ import org.hl7.fhir.r4.model.MessageHeader;
|
||||||
import org.hl7.fhir.r4.model.Observation;
|
import org.hl7.fhir.r4.model.Observation;
|
||||||
import org.hl7.fhir.r4.model.Organization;
|
import org.hl7.fhir.r4.model.Organization;
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.hl7.fhir.r4.model.Provenance;
|
||||||
import org.hl7.fhir.r4.model.Reference;
|
import org.hl7.fhir.r4.model.Reference;
|
||||||
import org.hl7.fhir.r4.model.StringType;
|
import org.hl7.fhir.r4.model.StringType;
|
||||||
import org.hl7.fhir.r4.model.Task;
|
import org.hl7.fhir.r4.model.Task;
|
||||||
|
@ -42,6 +43,8 @@ import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -65,6 +68,8 @@ public class FhirResourceDaoR4VersionedReferenceTest extends BaseJpaR4Test {
|
||||||
myStorageSettings.setDeleteEnabled(new JpaStorageSettings().isDeleteEnabled());
|
myStorageSettings.setDeleteEnabled(new JpaStorageSettings().isDeleteEnabled());
|
||||||
myStorageSettings.setRespectVersionsForSearchIncludes(new JpaStorageSettings().isRespectVersionsForSearchIncludes());
|
myStorageSettings.setRespectVersionsForSearchIncludes(new JpaStorageSettings().isRespectVersionsForSearchIncludes());
|
||||||
myStorageSettings.setAutoVersionReferenceAtPaths(new JpaStorageSettings().getAutoVersionReferenceAtPaths());
|
myStorageSettings.setAutoVersionReferenceAtPaths(new JpaStorageSettings().getAutoVersionReferenceAtPaths());
|
||||||
|
myStorageSettings.setAutoCreatePlaceholderReferenceTargets(new JpaStorageSettings().isAutoCreatePlaceholderReferenceTargets());
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(new JpaStorageSettings().getResourceClientIdStrategy());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -667,6 +672,88 @@ public class FhirResourceDaoR4VersionedReferenceTest extends BaseJpaR4Test {
|
||||||
assertEquals(patientIdString, observation.getSubject().getReference());
|
assertEquals(patientIdString, observation.getSubject().getReference());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDontStripVersionsFromRefsAtPaths_inTransactionBundle_shouldPreserveVersion() {
|
||||||
|
Set<String> referencePaths = Set.of("AuditEvent.entity.what","MessageHeader.focus","Provenance.target","Provenance.entity.what");
|
||||||
|
|
||||||
|
myFhirContext.getParserOptions().setDontStripVersionsFromReferencesAtPaths(referencePaths);
|
||||||
|
myStorageSettings.setAutoVersionReferenceAtPaths("Encounter.subject");
|
||||||
|
myStorageSettings.setAutoCreatePlaceholderReferenceTargets(true);
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ANY);
|
||||||
|
|
||||||
|
postBundleAndAssertProvenanceRefsPreserved("/transaction-bundles/transaction-with-client-supplied-versioned-reference.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDontStripVersionsFromRefsAtAllPaths_inTransactionBundle_shouldPreserveVersion() {
|
||||||
|
myFhirContext.getParserOptions().setStripVersionsFromReferences(false);
|
||||||
|
myStorageSettings.setAutoVersionReferenceAtPaths("Encounter.subject");
|
||||||
|
myStorageSettings.setAutoCreatePlaceholderReferenceTargets(true);
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ANY);
|
||||||
|
|
||||||
|
postBundleAndAssertProvenanceRefsPreserved("/transaction-bundles/transaction-with-client-supplied-versioned-reference.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDontStripVersionsFromRefsAtPaths_withTransactionBundleAndAutoVersionSet_shouldPreserveVersion() {
|
||||||
|
Set<String> referencePaths = Set.of("AuditEvent.entity.what","MessageHeader.focus","Provenance.target","Provenance.entity.what");
|
||||||
|
|
||||||
|
myFhirContext.getParserOptions().setDontStripVersionsFromReferencesAtPaths(referencePaths);
|
||||||
|
myStorageSettings.setAutoVersionReferenceAtPaths("Provenance.entity.what");
|
||||||
|
myStorageSettings.setAutoCreatePlaceholderReferenceTargets(true);
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ANY);
|
||||||
|
|
||||||
|
Encounter encounter = new Encounter();
|
||||||
|
encounter.setId("242976");
|
||||||
|
myEncounterDao.update(encounter);
|
||||||
|
|
||||||
|
postBundleAndAssertProvenanceRefsPreserved("/transaction-bundles/transaction-with-client-supplied-versioned-reference.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Provenance postBundleAndAssertProvenanceRefsPreserved(String theBundlePath) {
|
||||||
|
Bundle bundle = myFhirContext.newJsonParser().parseResource(Bundle.class,
|
||||||
|
new InputStreamReader(
|
||||||
|
FhirResourceDaoR4VersionedReferenceTest.class.getResourceAsStream(theBundlePath)));
|
||||||
|
|
||||||
|
Bundle transaction = mySystemDao.transaction(new SystemRequestDetails(), bundle);
|
||||||
|
|
||||||
|
Optional<Bundle.BundleEntryComponent> provenanceEntry = transaction.getEntry().stream().filter(entry -> entry.getResponse().getLocation().contains("Provenance")).findFirst();
|
||||||
|
assertThat(provenanceEntry).isPresent();
|
||||||
|
String provenanceLocation = provenanceEntry.get().getResponse().getLocation();
|
||||||
|
Provenance provenance = myProvenanceDao.read(new IdDt(provenanceLocation));
|
||||||
|
assertThat(provenance.getEntity().get(0).getWhat().getReference()).isEqualTo("Encounter/242976/_history/1");
|
||||||
|
return provenance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDontStripVersionsFromRefsAtPathsAndAutoVersionSameTransaction_withTransactionBundle_shouldPreserveVersion() {
|
||||||
|
Set<String> referencePaths = Set.of("AuditEvent.entity.what","MessageHeader.focus","Provenance.target","Provenance.entity.what", "Provenance.agent.who");
|
||||||
|
|
||||||
|
myFhirContext.getParserOptions().setDontStripVersionsFromReferencesAtPaths(referencePaths);
|
||||||
|
myStorageSettings.setAutoVersionReferenceAtPaths("Provenance.agent.who");
|
||||||
|
myStorageSettings.setAutoCreatePlaceholderReferenceTargets(true);
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ANY);
|
||||||
|
|
||||||
|
Provenance provenance = postBundleAndAssertProvenanceRefsPreserved("/transaction-bundles/transaction-with-client-assigned-version-reference-and-auto-version-field.json");
|
||||||
|
assertThat(provenance.getAgent().get(0).getWho().getReference()).isEqualTo("Patient/237643/_history/1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDontStripVersionsFromRefsAtPaths_withTransactionBundleAndPreExistingReference_shouldPreserveVersion() {
|
||||||
|
Set<String> referencePaths = Set.of("AuditEvent.entity.what","MessageHeader.focus","Provenance.target","Provenance.entity.what");
|
||||||
|
|
||||||
|
myFhirContext.getParserOptions().setDontStripVersionsFromReferencesAtPaths(referencePaths);
|
||||||
|
myStorageSettings.setAutoVersionReferenceAtPaths("Provenance.entity.what");
|
||||||
|
myStorageSettings.setAutoCreatePlaceholderReferenceTargets(true);
|
||||||
|
myStorageSettings.setResourceClientIdStrategy(JpaStorageSettings.ClientIdStrategyEnum.ANY);
|
||||||
|
|
||||||
|
Encounter encounter = new Encounter();
|
||||||
|
encounter.setId("242976");
|
||||||
|
myEncounterDao.update(encounter);
|
||||||
|
|
||||||
|
postBundleAndAssertProvenanceRefsPreserved("/transaction-bundles/transaction-with-client-supplied-versioned-reference-and-pre-existing-ref.json");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDontOverwriteExistingVersion() {
|
public void testDontOverwriteExistingVersion() {
|
||||||
myFhirContext.getParserOptions().setStripVersionsFromReferences(false);
|
myFhirContext.getParserOptions().setStripVersionsFromReferences(false);
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
{
|
||||||
|
"resourceType": "Bundle",
|
||||||
|
"type": "transaction",
|
||||||
|
"entry": [
|
||||||
|
{
|
||||||
|
"fullUrl": "https://smilecdrmock.harrisarc.ca/fhir-system/Encounter/242976",
|
||||||
|
"resource": {
|
||||||
|
"resourceType": "Encounter",
|
||||||
|
"id": "242976",
|
||||||
|
"meta": {
|
||||||
|
"versionId": "4",
|
||||||
|
"lastUpdated": "2024-07-26T10:43:49.287-04:00",
|
||||||
|
"source": "#d9d63c433c828a4d"
|
||||||
|
},
|
||||||
|
"identifier": [
|
||||||
|
{
|
||||||
|
"use": "official",
|
||||||
|
"type": {
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
|
||||||
|
"code": "VN"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"system": "https://www.ciussscentreouest.ca/ids/visit-number/iclsc/dlm",
|
||||||
|
"value": "ICLSCRepair1-1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"status": "entered-in-error",
|
||||||
|
"class": {
|
||||||
|
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
|
||||||
|
"code": "AMB",
|
||||||
|
"display": "Ambulatory"
|
||||||
|
},
|
||||||
|
"type": [
|
||||||
|
{
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "https://www.ciussscentreouest.ca/codesystem/mode/iclsc",
|
||||||
|
"code": "1",
|
||||||
|
"display": "1 Rencontre présence usager"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subject": {
|
||||||
|
"reference": "Patient/237643"
|
||||||
|
},
|
||||||
|
"period": {
|
||||||
|
"start": "2020-07-26T13:36:00-04:00",
|
||||||
|
"end": "2020-07-26T14:06:00-04:00"
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"value": 30,
|
||||||
|
"unit": "min"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request": {
|
||||||
|
"method": "PUT",
|
||||||
|
"url": "Encounter/242976"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resource": {
|
||||||
|
"resourceType": "Provenance",
|
||||||
|
"target": [
|
||||||
|
{
|
||||||
|
"reference": "#"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"recorded": "2024-07-26T14:51:28.222+00:00",
|
||||||
|
"activity": {
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "http://terminology.hl7.org/CodeSystem/v3-DataOperation",
|
||||||
|
"code": "CREATE",
|
||||||
|
"display": "Create"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"agent": [
|
||||||
|
{
|
||||||
|
"role": [
|
||||||
|
{
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "http://terminology.hl7.org/CodeSystem/v3-RoleClass",
|
||||||
|
"code": "AGNT",
|
||||||
|
"display": "Agent"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"who": {
|
||||||
|
"display": "ICLSC Encounter Repair loop",
|
||||||
|
"reference": "Patient/237643"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"entity": [
|
||||||
|
{
|
||||||
|
"role": "source",
|
||||||
|
"what": {
|
||||||
|
"reference": "Encounter/242976/_history/1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"url": "Provenance"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resource": {
|
||||||
|
"resourceType": "Patient",
|
||||||
|
"id": "237643",
|
||||||
|
"identifier" : [{
|
||||||
|
"system" : "urn:oid:1.2.36.146.595.217.0.1",
|
||||||
|
"value" : "abc"
|
||||||
|
}],
|
||||||
|
"name": [ {
|
||||||
|
"family": "smith",
|
||||||
|
"given": [ "John" ]
|
||||||
|
} ],
|
||||||
|
"gender": "male",
|
||||||
|
"birthDate": "1988-08-10"
|
||||||
|
},
|
||||||
|
"request": {
|
||||||
|
"method": "PUT",
|
||||||
|
"url": "Patient/237643"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
{
|
||||||
|
"resourceType": "Bundle",
|
||||||
|
"type": "transaction",
|
||||||
|
"entry": [
|
||||||
|
{
|
||||||
|
"resource": {
|
||||||
|
"resourceType": "Provenance",
|
||||||
|
"target": [
|
||||||
|
{
|
||||||
|
"reference": "#"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"recorded": "2024-07-26T14:51:28.222+00:00",
|
||||||
|
"activity": {
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "http://terminology.hl7.org/CodeSystem/v3-DataOperation",
|
||||||
|
"code": "CREATE",
|
||||||
|
"display": "Create"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"agent": [
|
||||||
|
{
|
||||||
|
"role": [
|
||||||
|
{
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "http://terminology.hl7.org/CodeSystem/v3-RoleClass",
|
||||||
|
"code": "AGNT",
|
||||||
|
"display": "Agent"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"who": {
|
||||||
|
"display": "ICLSC Encounter Repair loop"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"entity": [
|
||||||
|
{
|
||||||
|
"role": "source",
|
||||||
|
"what": {
|
||||||
|
"reference": "Encounter/242976/_history/1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"url": "Provenance"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
{
|
||||||
|
"resourceType": "Bundle",
|
||||||
|
"type": "transaction",
|
||||||
|
"entry": [
|
||||||
|
{
|
||||||
|
"fullUrl": "https://smilecdrmock.harrisarc.ca/fhir-system/Encounter/242976",
|
||||||
|
"resource": {
|
||||||
|
"resourceType": "Encounter",
|
||||||
|
"id": "242976",
|
||||||
|
"meta": {
|
||||||
|
"versionId": "4",
|
||||||
|
"lastUpdated": "2024-07-26T10:43:49.287-04:00",
|
||||||
|
"source": "#d9d63c433c828a4d"
|
||||||
|
},
|
||||||
|
"identifier": [
|
||||||
|
{
|
||||||
|
"use": "official",
|
||||||
|
"type": {
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
|
||||||
|
"code": "VN"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"system": "https://www.ciussscentreouest.ca/ids/visit-number/iclsc/dlm",
|
||||||
|
"value": "ICLSCRepair1-1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"status": "entered-in-error",
|
||||||
|
"class": {
|
||||||
|
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
|
||||||
|
"code": "AMB",
|
||||||
|
"display": "Ambulatory"
|
||||||
|
},
|
||||||
|
"type": [
|
||||||
|
{
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "https://www.ciussscentreouest.ca/codesystem/mode/iclsc",
|
||||||
|
"code": "1",
|
||||||
|
"display": "1 Rencontre présence usager"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subject": {
|
||||||
|
"reference": "Patient/237643"
|
||||||
|
},
|
||||||
|
"period": {
|
||||||
|
"start": "2020-07-26T13:36:00-04:00",
|
||||||
|
"end": "2020-07-26T14:06:00-04:00"
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"value": 30,
|
||||||
|
"unit": "min"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"request": {
|
||||||
|
"method": "PUT",
|
||||||
|
"url": "Encounter/242976"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resource": {
|
||||||
|
"resourceType": "Provenance",
|
||||||
|
"target": [
|
||||||
|
{
|
||||||
|
"reference": "#"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"recorded": "2024-07-26T14:51:28.222+00:00",
|
||||||
|
"activity": {
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "http://terminology.hl7.org/CodeSystem/v3-DataOperation",
|
||||||
|
"code": "CREATE",
|
||||||
|
"display": "Create"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"agent": [
|
||||||
|
{
|
||||||
|
"role": [
|
||||||
|
{
|
||||||
|
"coding": [
|
||||||
|
{
|
||||||
|
"system": "http://terminology.hl7.org/CodeSystem/v3-RoleClass",
|
||||||
|
"code": "AGNT",
|
||||||
|
"display": "Agent"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"who": {
|
||||||
|
"display": "ICLSC Encounter Repair loop"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"entity": [
|
||||||
|
{
|
||||||
|
"role": "source",
|
||||||
|
"what": {
|
||||||
|
"reference": "Encounter/242976/_history/1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"url": "Provenance"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -727,6 +727,27 @@ public abstract class BaseStorageDao {
|
||||||
ourLog.debug(msg);
|
ourLog.debug(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts a list of references that have versions in their ID whose versions should not be stripped
|
||||||
|
*
|
||||||
|
* @return A set of references that should not have their client-given versions stripped according to the
|
||||||
|
* versioned references settings.
|
||||||
|
*/
|
||||||
|
public static Set<IBaseReference> extractReferencesToAvoidReplacement(
|
||||||
|
FhirContext theFhirContext, IBaseResource theResource) {
|
||||||
|
if (!theFhirContext
|
||||||
|
.getParserOptions()
|
||||||
|
.getDontStripVersionsFromReferencesAtPaths()
|
||||||
|
.isEmpty()) {
|
||||||
|
String theResourceType = theFhirContext.getResourceType(theResource);
|
||||||
|
Set<String> versionReferencesPaths = theFhirContext
|
||||||
|
.getParserOptions()
|
||||||
|
.getDontStripVersionsFromReferencesAtPathsByResourceType(theResourceType);
|
||||||
|
return getReferencesWithOrWithoutVersionId(versionReferencesPaths, theFhirContext, theResource, false);
|
||||||
|
}
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts a list of references that should be auto-versioned.
|
* Extracts a list of references that should be auto-versioned.
|
||||||
*
|
*
|
||||||
|
@ -760,7 +781,7 @@ public abstract class BaseStorageDao {
|
||||||
MetaUtil.getAutoVersionReferencesAtPath(theResource.getMeta(), resourceType);
|
MetaUtil.getAutoVersionReferencesAtPath(theResource.getMeta(), resourceType);
|
||||||
|
|
||||||
if (!autoVersionReferencesAtPaths.isEmpty()) {
|
if (!autoVersionReferencesAtPaths.isEmpty()) {
|
||||||
return getReferencesWithoutVersionId(autoVersionReferencesAtPaths, theFhirContext, theResource);
|
return getReferencesWithOrWithoutVersionId(autoVersionReferencesAtPaths, theFhirContext, theResource, true);
|
||||||
}
|
}
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
@ -776,17 +797,30 @@ public abstract class BaseStorageDao {
|
||||||
String resourceName = theFhirContext.getResourceType(theResource);
|
String resourceName = theFhirContext.getResourceType(theResource);
|
||||||
Set<String> autoVersionReferencesPaths =
|
Set<String> autoVersionReferencesPaths =
|
||||||
theStorageSettings.getAutoVersionReferenceAtPathsByResourceType(resourceName);
|
theStorageSettings.getAutoVersionReferenceAtPathsByResourceType(resourceName);
|
||||||
return getReferencesWithoutVersionId(autoVersionReferencesPaths, theFhirContext, theResource);
|
return getReferencesWithOrWithoutVersionId(autoVersionReferencesPaths, theFhirContext, theResource, true);
|
||||||
}
|
}
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<IBaseReference> getReferencesWithoutVersionId(
|
/**
|
||||||
Set<String> autoVersionReferencesPaths, FhirContext theFhirContext, IBaseResource theResource) {
|
* Extracts references from given resource and filters references by those with versions, or those without versions.
|
||||||
return autoVersionReferencesPaths.stream()
|
*
|
||||||
|
* @param theVersionReferencesPaths the paths from which to extract references from
|
||||||
|
* @param theFhirContext the FHIR context
|
||||||
|
* @param theResource the resource from which to extract references from
|
||||||
|
* @param theShouldFilterByRefsWithoutVersionId If true, this method will return only references without a version. If false, this method will return only references with a version.
|
||||||
|
* @return Set of references contained in the resource with or without versions
|
||||||
|
*/
|
||||||
|
private static Set<IBaseReference> getReferencesWithOrWithoutVersionId(
|
||||||
|
Set<String> theVersionReferencesPaths,
|
||||||
|
FhirContext theFhirContext,
|
||||||
|
IBaseResource theResource,
|
||||||
|
boolean theShouldFilterByRefsWithoutVersionId) {
|
||||||
|
return theVersionReferencesPaths.stream()
|
||||||
.map(fullPath -> theFhirContext.newTerser().getValues(theResource, fullPath, IBaseReference.class))
|
.map(fullPath -> theFhirContext.newTerser().getValues(theResource, fullPath, IBaseReference.class))
|
||||||
.flatMap(Collection::stream)
|
.flatMap(Collection::stream)
|
||||||
.filter(reference -> !reference.getReferenceElement().hasVersionIdPart())
|
.filter(reference ->
|
||||||
|
reference.getReferenceElement().hasVersionIdPart() ^ theShouldFilterByRefsWithoutVersionId)
|
||||||
.collect(Collectors.toMap(ref -> ref, ref -> ref, (oldRef, newRef) -> oldRef, IdentityHashMap::new))
|
.collect(Collectors.toMap(ref -> ref, ref -> ref, (oldRef, newRef) -> oldRef, IdentityHashMap::new))
|
||||||
.keySet();
|
.keySet();
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,19 +274,20 @@ public abstract class BaseTransactionProcessor {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void handleTransactionCreateOrUpdateOutcome(
|
private void handleTransactionCreateOrUpdateOutcome(
|
||||||
IdSubstitutionMap idSubstitutions,
|
IdSubstitutionMap theIdSubstitutions,
|
||||||
Map<IIdType, DaoMethodOutcome> idToPersistedOutcome,
|
Map<IIdType, DaoMethodOutcome> theIdToPersistedOutcome,
|
||||||
IIdType nextResourceId,
|
IIdType theNextResourceId,
|
||||||
DaoMethodOutcome outcome,
|
DaoMethodOutcome theOutcome,
|
||||||
IBase newEntry,
|
IBase theNewEntry,
|
||||||
String theResourceType,
|
String theResourceType,
|
||||||
IBaseResource theRes,
|
IBaseResource theRes,
|
||||||
RequestDetails theRequestDetails) {
|
RequestDetails theRequestDetails) {
|
||||||
IIdType newId = outcome.getId().toUnqualified();
|
IIdType newId = theOutcome.getId().toUnqualified();
|
||||||
IIdType resourceId = isPlaceholder(nextResourceId) ? nextResourceId : nextResourceId.toUnqualifiedVersionless();
|
IIdType resourceId =
|
||||||
if (newId.equals(resourceId) == false) {
|
isPlaceholder(theNextResourceId) ? theNextResourceId : theNextResourceId.toUnqualifiedVersionless();
|
||||||
if (!nextResourceId.isEmpty()) {
|
if (!newId.equals(resourceId)) {
|
||||||
idSubstitutions.put(resourceId, newId);
|
if (!theNextResourceId.isEmpty()) {
|
||||||
|
theIdSubstitutions.put(resourceId, newId);
|
||||||
}
|
}
|
||||||
if (isPlaceholder(resourceId)) {
|
if (isPlaceholder(resourceId)) {
|
||||||
/*
|
/*
|
||||||
|
@ -294,27 +295,27 @@ public abstract class BaseTransactionProcessor {
|
||||||
*/
|
*/
|
||||||
IIdType id = myContext.getVersion().newIdType();
|
IIdType id = myContext.getVersion().newIdType();
|
||||||
id.setValue(theResourceType + '/' + resourceId.getValue());
|
id.setValue(theResourceType + '/' + resourceId.getValue());
|
||||||
idSubstitutions.put(id, newId);
|
theIdSubstitutions.put(id, newId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
populateIdToPersistedOutcomeMap(idToPersistedOutcome, newId, outcome);
|
populateIdToPersistedOutcomeMap(theIdToPersistedOutcome, newId, theOutcome);
|
||||||
|
|
||||||
if (shouldSwapBinaryToActualResource(theRes, theResourceType, nextResourceId)) {
|
if (shouldSwapBinaryToActualResource(theRes, theResourceType, theNextResourceId)) {
|
||||||
theRes = idToPersistedOutcome.get(newId).getResource();
|
theRes = theIdToPersistedOutcome.get(newId).getResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outcome.getCreated()) {
|
if (theOutcome.getCreated()) {
|
||||||
myVersionAdapter.setResponseStatus(newEntry, toStatusString(Constants.STATUS_HTTP_201_CREATED));
|
myVersionAdapter.setResponseStatus(theNewEntry, toStatusString(Constants.STATUS_HTTP_201_CREATED));
|
||||||
} else {
|
} else {
|
||||||
myVersionAdapter.setResponseStatus(newEntry, toStatusString(Constants.STATUS_HTTP_200_OK));
|
myVersionAdapter.setResponseStatus(theNewEntry, toStatusString(Constants.STATUS_HTTP_200_OK));
|
||||||
}
|
}
|
||||||
|
|
||||||
Date lastModified = getLastModified(theRes);
|
Date lastModified = getLastModified(theRes);
|
||||||
myVersionAdapter.setResponseLastModified(newEntry, lastModified);
|
myVersionAdapter.setResponseLastModified(theNewEntry, lastModified);
|
||||||
|
|
||||||
if (outcome.getOperationOutcome() != null) {
|
if (theOutcome.getOperationOutcome() != null) {
|
||||||
myVersionAdapter.setResponseOutcome(newEntry, outcome.getOperationOutcome());
|
myVersionAdapter.setResponseOutcome(theNewEntry, theOutcome.getOperationOutcome());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theRequestDetails != null) {
|
if (theRequestDetails != null) {
|
||||||
|
@ -323,9 +324,9 @@ public abstract class BaseTransactionProcessor {
|
||||||
RestfulServerUtils.parsePreferHeader(null, prefer).getReturn();
|
RestfulServerUtils.parsePreferHeader(null, prefer).getReturn();
|
||||||
if (preferReturn != null) {
|
if (preferReturn != null) {
|
||||||
if (preferReturn == PreferReturnEnum.REPRESENTATION) {
|
if (preferReturn == PreferReturnEnum.REPRESENTATION) {
|
||||||
if (outcome.getResource() != null) {
|
if (theOutcome.getResource() != null) {
|
||||||
outcome.fireResourceViewCallbacks();
|
theOutcome.fireResourceViewCallbacks();
|
||||||
myVersionAdapter.setResource(newEntry, outcome.getResource());
|
myVersionAdapter.setResource(theNewEntry, theOutcome.getResource());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1685,9 +1686,9 @@ public abstract class BaseTransactionProcessor {
|
||||||
IdSubstitutionMap theIdSubstitutions,
|
IdSubstitutionMap theIdSubstitutions,
|
||||||
Map<IIdType, DaoMethodOutcome> theIdToPersistedOutcome,
|
Map<IIdType, DaoMethodOutcome> theIdToPersistedOutcome,
|
||||||
StopWatch theTransactionStopWatch,
|
StopWatch theTransactionStopWatch,
|
||||||
EntriesToProcessMap entriesToProcess,
|
EntriesToProcessMap theEntriesToProcess,
|
||||||
Set<IIdType> nonUpdatedEntities,
|
Set<IIdType> theNonUpdatedEntities,
|
||||||
Set<IBasePersistedResource> updatedEntities) {
|
Set<IBasePersistedResource> theUpdatedEntities) {
|
||||||
FhirTerser terser = myContext.newTerser();
|
FhirTerser terser = myContext.newTerser();
|
||||||
theTransactionStopWatch.startTask("Index " + theIdToPersistedOutcome.size() + " resources");
|
theTransactionStopWatch.startTask("Index " + theIdToPersistedOutcome.size() + " resources");
|
||||||
IdentityHashMap<DaoMethodOutcome, Set<IBaseReference>> deferredIndexesForAutoVersioning = null;
|
IdentityHashMap<DaoMethodOutcome, Set<IBaseReference>> deferredIndexesForAutoVersioning = null;
|
||||||
|
@ -1712,6 +1713,9 @@ public abstract class BaseTransactionProcessor {
|
||||||
|
|
||||||
Set<IBaseReference> referencesToAutoVersion =
|
Set<IBaseReference> referencesToAutoVersion =
|
||||||
BaseStorageDao.extractReferencesToAutoVersion(myContext, myStorageSettings, nextResource);
|
BaseStorageDao.extractReferencesToAutoVersion(myContext, myStorageSettings, nextResource);
|
||||||
|
Set<IBaseReference> referencesToKeepClientSuppliedVersion =
|
||||||
|
BaseStorageDao.extractReferencesToAvoidReplacement(myContext, nextResource);
|
||||||
|
|
||||||
if (referencesToAutoVersion.isEmpty()) {
|
if (referencesToAutoVersion.isEmpty()) {
|
||||||
// no references to autoversion - we can do the resolve and save now
|
// no references to autoversion - we can do the resolve and save now
|
||||||
resolveReferencesThenSaveAndIndexResource(
|
resolveReferencesThenSaveAndIndexResource(
|
||||||
|
@ -1719,13 +1723,14 @@ public abstract class BaseTransactionProcessor {
|
||||||
theTransactionDetails,
|
theTransactionDetails,
|
||||||
theIdSubstitutions,
|
theIdSubstitutions,
|
||||||
theIdToPersistedOutcome,
|
theIdToPersistedOutcome,
|
||||||
entriesToProcess,
|
theEntriesToProcess,
|
||||||
nonUpdatedEntities,
|
theNonUpdatedEntities,
|
||||||
updatedEntities,
|
theUpdatedEntities,
|
||||||
terser,
|
terser,
|
||||||
nextOutcome,
|
nextOutcome,
|
||||||
nextResource,
|
nextResource,
|
||||||
referencesToAutoVersion); // this is empty
|
referencesToAutoVersion, // this is empty
|
||||||
|
referencesToKeepClientSuppliedVersion);
|
||||||
} else {
|
} else {
|
||||||
// we have autoversioned things to defer until later
|
// we have autoversioned things to defer until later
|
||||||
if (deferredIndexesForAutoVersioning == null) {
|
if (deferredIndexesForAutoVersioning == null) {
|
||||||
|
@ -1742,19 +1747,22 @@ public abstract class BaseTransactionProcessor {
|
||||||
DaoMethodOutcome nextOutcome = nextEntry.getKey();
|
DaoMethodOutcome nextOutcome = nextEntry.getKey();
|
||||||
Set<IBaseReference> referencesToAutoVersion = nextEntry.getValue();
|
Set<IBaseReference> referencesToAutoVersion = nextEntry.getValue();
|
||||||
IBaseResource nextResource = nextOutcome.getResource();
|
IBaseResource nextResource = nextOutcome.getResource();
|
||||||
|
Set<IBaseReference> referencesToKeepClientSuppliedVersion =
|
||||||
|
BaseStorageDao.extractReferencesToAvoidReplacement(myContext, nextResource);
|
||||||
|
|
||||||
resolveReferencesThenSaveAndIndexResource(
|
resolveReferencesThenSaveAndIndexResource(
|
||||||
theRequest,
|
theRequest,
|
||||||
theTransactionDetails,
|
theTransactionDetails,
|
||||||
theIdSubstitutions,
|
theIdSubstitutions,
|
||||||
theIdToPersistedOutcome,
|
theIdToPersistedOutcome,
|
||||||
entriesToProcess,
|
theEntriesToProcess,
|
||||||
nonUpdatedEntities,
|
theNonUpdatedEntities,
|
||||||
updatedEntities,
|
theUpdatedEntities,
|
||||||
terser,
|
terser,
|
||||||
nextOutcome,
|
nextOutcome,
|
||||||
nextResource,
|
nextResource,
|
||||||
referencesToAutoVersion);
|
referencesToAutoVersion,
|
||||||
|
referencesToKeepClientSuppliedVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1764,15 +1772,16 @@ public abstract class BaseTransactionProcessor {
|
||||||
TransactionDetails theTransactionDetails,
|
TransactionDetails theTransactionDetails,
|
||||||
IdSubstitutionMap theIdSubstitutions,
|
IdSubstitutionMap theIdSubstitutions,
|
||||||
Map<IIdType, DaoMethodOutcome> theIdToPersistedOutcome,
|
Map<IIdType, DaoMethodOutcome> theIdToPersistedOutcome,
|
||||||
EntriesToProcessMap entriesToProcess,
|
EntriesToProcessMap theEntriesToProcess,
|
||||||
Set<IIdType> nonUpdatedEntities,
|
Set<IIdType> theNonUpdatedEntities,
|
||||||
Set<IBasePersistedResource> updatedEntities,
|
Set<IBasePersistedResource> theUpdatedEntities,
|
||||||
FhirTerser terser,
|
FhirTerser theTerser,
|
||||||
DaoMethodOutcome theDaoMethodOutcome,
|
DaoMethodOutcome theDaoMethodOutcome,
|
||||||
IBaseResource theResource,
|
IBaseResource theResource,
|
||||||
Set<IBaseReference> theReferencesToAutoVersion) {
|
Set<IBaseReference> theReferencesToAutoVersion,
|
||||||
|
Set<IBaseReference> theReferencesToKeepClientSuppliedVersion) {
|
||||||
// References
|
// References
|
||||||
List<ResourceReferenceInfo> allRefs = terser.getAllResourceReferences(theResource);
|
List<ResourceReferenceInfo> allRefs = theTerser.getAllResourceReferences(theResource);
|
||||||
for (ResourceReferenceInfo nextRef : allRefs) {
|
for (ResourceReferenceInfo nextRef : allRefs) {
|
||||||
IBaseReference resourceReference = nextRef.getResourceReference();
|
IBaseReference resourceReference = nextRef.getResourceReference();
|
||||||
IIdType nextId = resourceReference.getReferenceElement();
|
IIdType nextId = resourceReference.getReferenceElement();
|
||||||
|
@ -1794,18 +1803,20 @@ public abstract class BaseTransactionProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newId != null || theIdSubstitutions.containsSource(nextId)) {
|
if (newId != null || theIdSubstitutions.containsSource(nextId)) {
|
||||||
|
if (shouldReplaceResourceReference(
|
||||||
|
theReferencesToAutoVersion, theReferencesToKeepClientSuppliedVersion, resourceReference)) {
|
||||||
if (newId == null) {
|
if (newId == null) {
|
||||||
newId = theIdSubstitutions.getForSource(nextId);
|
newId = theIdSubstitutions.getForSource(nextId);
|
||||||
}
|
}
|
||||||
if (newId != null) {
|
if (newId != null) {
|
||||||
ourLog.debug(" * Replacing resource ref {} with {}", nextId, newId);
|
ourLog.debug(" * Replacing resource ref {} with {}", nextId, newId);
|
||||||
|
|
||||||
if (theReferencesToAutoVersion.contains(resourceReference)) {
|
if (theReferencesToAutoVersion.contains(resourceReference)) {
|
||||||
replaceResourceReference(newId, resourceReference, theTransactionDetails);
|
replaceResourceReference(newId, resourceReference, theTransactionDetails);
|
||||||
} else {
|
} else {
|
||||||
replaceResourceReference(newId.toVersionless(), resourceReference, theTransactionDetails);
|
replaceResourceReference(newId.toVersionless(), resourceReference, theTransactionDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (nextId.getValue().startsWith("urn:")) {
|
} else if (nextId.getValue().startsWith("urn:")) {
|
||||||
throw new InvalidRequestException(
|
throw new InvalidRequestException(
|
||||||
Msg.code(541) + "Unable to satisfy placeholder ID " + nextId.getValue()
|
Msg.code(541) + "Unable to satisfy placeholder ID " + nextId.getValue()
|
||||||
|
@ -1858,7 +1869,7 @@ public abstract class BaseTransactionProcessor {
|
||||||
// URIs
|
// URIs
|
||||||
Class<? extends IPrimitiveType<?>> uriType = (Class<? extends IPrimitiveType<?>>)
|
Class<? extends IPrimitiveType<?>> uriType = (Class<? extends IPrimitiveType<?>>)
|
||||||
myContext.getElementDefinition("uri").getImplementingClass();
|
myContext.getElementDefinition("uri").getImplementingClass();
|
||||||
List<? extends IPrimitiveType<?>> allUris = terser.getAllPopulatedChildElementsOfType(theResource, uriType);
|
List<? extends IPrimitiveType<?>> allUris = theTerser.getAllPopulatedChildElementsOfType(theResource, uriType);
|
||||||
for (IPrimitiveType<?> nextRef : allUris) {
|
for (IPrimitiveType<?> nextRef : allUris) {
|
||||||
if (nextRef instanceof IIdType) {
|
if (nextRef instanceof IIdType) {
|
||||||
continue; // No substitution on the resource ID itself!
|
continue; // No substitution on the resource ID itself!
|
||||||
|
@ -1886,7 +1897,7 @@ public abstract class BaseTransactionProcessor {
|
||||||
IJpaDao jpaDao = (IJpaDao) dao;
|
IJpaDao jpaDao = (IJpaDao) dao;
|
||||||
|
|
||||||
IBasePersistedResource updateOutcome = null;
|
IBasePersistedResource updateOutcome = null;
|
||||||
if (updatedEntities.contains(theDaoMethodOutcome.getEntity())) {
|
if (theUpdatedEntities.contains(theDaoMethodOutcome.getEntity())) {
|
||||||
boolean forceUpdateVersion = !theReferencesToAutoVersion.isEmpty();
|
boolean forceUpdateVersion = !theReferencesToAutoVersion.isEmpty();
|
||||||
String matchUrl = theDaoMethodOutcome.getMatchUrl();
|
String matchUrl = theDaoMethodOutcome.getMatchUrl();
|
||||||
RestOperationTypeEnum operationType = theDaoMethodOutcome.getOperationType();
|
RestOperationTypeEnum operationType = theDaoMethodOutcome.getOperationType();
|
||||||
|
@ -1903,7 +1914,7 @@ public abstract class BaseTransactionProcessor {
|
||||||
theTransactionDetails);
|
theTransactionDetails);
|
||||||
updateOutcome = daoMethodOutcome.getEntity();
|
updateOutcome = daoMethodOutcome.getEntity();
|
||||||
theDaoMethodOutcome = daoMethodOutcome;
|
theDaoMethodOutcome = daoMethodOutcome;
|
||||||
} else if (!nonUpdatedEntities.contains(theDaoMethodOutcome.getId())) {
|
} else if (!theNonUpdatedEntities.contains(theDaoMethodOutcome.getId())) {
|
||||||
updateOutcome = jpaDao.updateEntity(
|
updateOutcome = jpaDao.updateEntity(
|
||||||
theRequest,
|
theRequest,
|
||||||
theResource,
|
theResource,
|
||||||
|
@ -1920,7 +1931,7 @@ public abstract class BaseTransactionProcessor {
|
||||||
if (updateOutcome != null) {
|
if (updateOutcome != null) {
|
||||||
IIdType newId = updateOutcome.getIdDt();
|
IIdType newId = updateOutcome.getIdDt();
|
||||||
|
|
||||||
IIdType entryId = entriesToProcess.getIdWithVersionlessComparison(newId);
|
IIdType entryId = theEntriesToProcess.getIdWithVersionlessComparison(newId);
|
||||||
if (entryId != null && !StringUtils.equals(entryId.getValue(), newId.getValue())) {
|
if (entryId != null && !StringUtils.equals(entryId.getValue(), newId.getValue())) {
|
||||||
entryId.setValue(newId.getValue());
|
entryId.setValue(newId.getValue());
|
||||||
}
|
}
|
||||||
|
@ -1930,12 +1941,32 @@ public abstract class BaseTransactionProcessor {
|
||||||
theIdSubstitutions.updateTargets(newId);
|
theIdSubstitutions.updateTargets(newId);
|
||||||
|
|
||||||
if (theDaoMethodOutcome.getOperationOutcome() != null) {
|
if (theDaoMethodOutcome.getOperationOutcome() != null) {
|
||||||
IBase responseEntry = entriesToProcess.getResponseBundleEntryWithVersionlessComparison(newId);
|
IBase responseEntry = theEntriesToProcess.getResponseBundleEntryWithVersionlessComparison(newId);
|
||||||
myVersionAdapter.setResponseOutcome(responseEntry, theDaoMethodOutcome.getOperationOutcome());
|
myVersionAdapter.setResponseOutcome(responseEntry, theDaoMethodOutcome.getOperationOutcome());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We should replace the references when
|
||||||
|
* 1. It is not a reference we should keep the client-supplied version for as configured by `DontStripVersionsFromReferences` or
|
||||||
|
* 2. It is a reference that has been identified for auto versioning or
|
||||||
|
* 3. Is a placeholder reference
|
||||||
|
* @param theReferencesToAutoVersion list of references identified for auto versioning
|
||||||
|
* @param theReferencesToKeepClientSuppliedVersion list of references that we should not strip the version for
|
||||||
|
* @param theResourceReference the resource reference
|
||||||
|
* @return true if we should replace the resource reference, false if we should keep the client provided reference
|
||||||
|
*/
|
||||||
|
private boolean shouldReplaceResourceReference(
|
||||||
|
Set<IBaseReference> theReferencesToAutoVersion,
|
||||||
|
Set<IBaseReference> theReferencesToKeepClientSuppliedVersion,
|
||||||
|
IBaseReference theResourceReference) {
|
||||||
|
return (!theReferencesToKeepClientSuppliedVersion.contains(theResourceReference)
|
||||||
|
&& myContext.getParserOptions().isStripVersionsFromReferences())
|
||||||
|
|| theReferencesToAutoVersion.contains(theResourceReference)
|
||||||
|
|| isPlaceholder(theResourceReference.getReferenceElement());
|
||||||
|
}
|
||||||
|
|
||||||
private void replaceResourceReference(
|
private void replaceResourceReference(
|
||||||
IIdType theReferenceId, IBaseReference theResourceReference, TransactionDetails theTransactionDetails) {
|
IIdType theReferenceId, IBaseReference theResourceReference, TransactionDetails theTransactionDetails) {
|
||||||
addRollbackReferenceRestore(theTransactionDetails, theResourceReference);
|
addRollbackReferenceRestore(theTransactionDetails, theResourceReference);
|
||||||
|
|
Loading…
Reference in New Issue