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

This commit is contained in:
James Agnew 2018-02-21 17:16:08 -05:00
commit e241b31905
10 changed files with 669 additions and 469 deletions

View File

@ -25,6 +25,7 @@ import java.util.*;
import javax.persistence.TypedQuery;
import ca.uhn.fhir.model.primitive.UriDt;
import org.apache.http.NameValuePair;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
@ -453,6 +454,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
continue;
}
// References
List<BaseResourceReferenceDt> allRefs = terser.getAllPopulatedChildElementsOfType(nextResource, BaseResourceReferenceDt.class);
for (BaseResourceReferenceDt nextRef : allRefs) {
IdDt nextId = nextRef.getReference();
@ -468,6 +470,23 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao<Bundle, MetaDt> {
}
}
// URIs
List<UriDt> allUris = terser.getAllPopulatedChildElementsOfType(nextResource, UriDt.class);
for (UriDt nextRef : allUris) {
if (nextRef instanceof IIdType) {
continue; // No substitution on the resource ID itself!
}
IdDt nextUriString = new IdDt(nextRef.getValueAsString());
if (idSubstitutions.containsKey(nextUriString)) {
IdDt newId = idSubstitutions.get(nextUriString);
ourLog.info(" * Replacing resource ref {} with {}", nextUriString, newId);
nextRef.setValue(newId.getValue());
} else {
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
}
}
InstantDt deletedInstantOrNull = ResourceMetadataKeyEnum.DELETED_AT.get(nextResource);
Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null;
boolean shouldUpdate = !nonUpdatedEntities.contains(nextOutcome.getEntity());

View File

@ -311,7 +311,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
@SuppressWarnings("unchecked")
private Map<BundleEntryComponent, ResourceTable> doTransactionWriteOperations(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName, Date updateTime, Set<IdType> allIds,
Map<IdType, IdType> idSubstitutions, Map<IdType, DaoMethodOutcome> idToPersistedOutcome, Bundle response, IdentityHashMap<BundleEntryComponent, Integer> originalRequestOrder, List<BundleEntryComponent> theEntries) {
Map<IdType, IdType> theIdSubstitutions, Map<IdType, DaoMethodOutcome> idToPersistedOutcome, Bundle response, IdentityHashMap<BundleEntryComponent, Integer> originalRequestOrder, List<BundleEntryComponent> theEntries) {
Set<String> deletedResources = new HashSet<String>();
List<DeleteConflict> deleteConflicts = new ArrayList<DeleteConflict>();
Map<BundleEntryComponent, ResourceTable> entriesToProcess = new IdentityHashMap<BundleEntryComponent, ResourceTable>();
@ -379,10 +379,10 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
res.setId((String) null);
DaoMethodOutcome outcome;
String matchUrl = nextReqEntry.getRequest().getIfNoneExist();
matchUrl = performIdSubstitutionsInMatchUrl(idSubstitutions, matchUrl);
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
outcome = resourceDao.create(res, matchUrl, false, theRequestDetails);
if (nextResourceId != null) {
handleTransactionCreateOrUpdateOutcome(idSubstitutions, idToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequestDetails);
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, idToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequestDetails);
}
entriesToProcess.put(nextRespEntry, outcome.getEntity());
if (outcome.getCreated() == false) {
@ -412,7 +412,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
}
} else {
String matchUrl = parts.getResourceType() + '?' + parts.getParams();
matchUrl = performIdSubstitutionsInMatchUrl(idSubstitutions, matchUrl);
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
DeleteMethodOutcome deleteOutcome = dao.deleteByUrl(matchUrl, deleteConflicts, theRequestDetails);
List<ResourceTable> allDeleted = deleteOutcome.getDeletedEntities();
for (ResourceTable deleted : allDeleted) {
@ -453,14 +453,14 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
} else {
matchUrl = parts.getResourceType();
}
matchUrl = performIdSubstitutionsInMatchUrl(idSubstitutions, matchUrl);
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
outcome = resourceDao.update(res, matchUrl, false, theRequestDetails);
if (Boolean.TRUE.equals(outcome.getCreated())) {
conditionalRequestUrls.put(matchUrl, res.getClass());
}
}
handleTransactionCreateOrUpdateOutcome(idSubstitutions, idToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequestDetails);
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, idToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequestDetails);
entriesToProcess.put(nextRespEntry, outcome.getEntity());
break;
}
@ -496,14 +496,15 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
continue;
}
// Refererences
List<IBaseReference> allRefs = terser.getAllPopulatedChildElementsOfType(nextResource, IBaseReference.class);
for (IBaseReference nextRef : allRefs) {
IIdType nextId = nextRef.getReferenceElement();
if (!nextId.hasIdPart()) {
continue;
}
if (idSubstitutions.containsKey(nextId)) {
IdType newId = idSubstitutions.get(nextId);
if (theIdSubstitutions.containsKey(nextId)) {
IdType newId = theIdSubstitutions.get(nextId);
ourLog.info(" * Replacing resource ref {} with {}", nextId, newId);
nextRef.setReference(newId.getValue());
} else if (nextId.getValue().startsWith("urn:")) {
@ -513,6 +514,22 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
}
}
// URIs
List<UriType> allUris = terser.getAllPopulatedChildElementsOfType(nextResource, UriType.class);
for (UriType nextRef : allUris) {
if (nextRef instanceof IIdType) {
continue; // No substitution on the resource ID itself!
}
IdType nextUriString = new IdType(nextRef.getValueAsString());
if (theIdSubstitutions.containsKey(nextUriString)) {
IdType newId = theIdSubstitutions.get(nextUriString);
ourLog.info(" * Replacing resource ref {} with {}", nextUriString, newId);
nextRef.setValue(newId.getValue());
} else {
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
}
}
IPrimitiveType<Date> deletedInstantOrNull = ResourceMetadataKeyEnum.DELETED_AT.get((IAnyResource) nextResource);
Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null;
boolean shouldUpdate = !nonUpdatedEntities.contains(nextOutcome.getEntity());
@ -546,7 +563,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
}
for (IdType next : allIds) {
IdType replacement = idSubstitutions.get(next);
IdType replacement = theIdSubstitutions.get(next);
if (replacement == null) {
continue;
}
@ -603,6 +620,23 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
return retVal;
}
private String performIdSubstitutionsInMatchUrl(Map<IdType, IdType> theIdSubstitutions, String theMatchUrl) {
String matchUrl = theMatchUrl;
if (isNotBlank(matchUrl)) {
for (Entry<IdType, IdType> nextSubstitutionEntry : theIdSubstitutions.entrySet()) {
IdType nextTemporaryId = nextSubstitutionEntry.getKey();
IdType nextReplacementId = nextSubstitutionEntry.getValue();
String nextTemporaryIdPart = nextTemporaryId.getIdPart();
String nextReplacementIdPart = nextReplacementId.getValueAsString();
if (nextTemporaryId.isUrn() && nextTemporaryIdPart.length() > IdType.URN_PREFIX.length()) {
matchUrl = matchUrl.replace(nextTemporaryIdPart, nextReplacementIdPart);
matchUrl = matchUrl.replace(UrlUtil.escapeUrlParam(nextTemporaryIdPart), nextReplacementIdPart);
}
}
}
return matchUrl;
}
private void populateEntryWithOperationOutcome(BaseServerResponseException caughtEx, BundleEntryComponent nextEntry) {
OperationOutcome oo = new OperationOutcome();
oo.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics(caughtEx.getMessage());
@ -664,27 +698,6 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
return transaction((ServletRequestDetails) theRequestDetails, theRequest, actionName);
}
private String performIdSubstitutionsInMatchUrl(Map<IdType, IdType> theIdSubstitutions, String theMatchUrl) {
String matchUrl = theMatchUrl;
if (isNotBlank(matchUrl)) {
for (Entry<IdType, IdType> nextSubstitutionEntry : theIdSubstitutions.entrySet()) {
IdType nextTemporaryId = nextSubstitutionEntry.getKey();
IdType nextReplacementId = nextSubstitutionEntry.getValue();
String nextTemporaryIdPart = nextTemporaryId.getIdPart();
String nextReplacementIdPart = nextReplacementId.getValueAsString();
if (nextTemporaryId.isUrn() && nextTemporaryIdPart.length() > IdType.URN_PREFIX.length()) {
matchUrl = matchUrl.replace(nextTemporaryIdPart, nextReplacementIdPart);
matchUrl = matchUrl.replace(UrlUtil.escapeUrlParam(nextTemporaryIdPart), nextReplacementIdPart);
}
}
}
return matchUrl;
}
private Bundle transaction(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName) {
super.markRequestAsProcessingSubRequest(theRequestDetails);
try {
@ -742,23 +755,9 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
return Integer.toString(theStatusCode) + " " + defaultString(Constants.HTTP_STATUS_NAMES.get(theStatusCode));
}
private static class BaseServerResponseExceptionHolder
{
private BaseServerResponseException myException;
public BaseServerResponseException getException() {
return myException;
}
public void setException(BaseServerResponseException myException) {
this.myException = myException;
}
}
//@formatter:off
/**
* Transaction Order, per the spec:
*
*
* Process any DELETE interactions
* Process any POST interactions
* Process any PUT interactions
@ -859,4 +858,19 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
}
//@formatter:off
private static class BaseServerResponseExceptionHolder
{
private BaseServerResponseException myException;
public BaseServerResponseException getException() {
return myException;
}
public void setException(BaseServerResponseException myException) {
this.myException = myException;
}
}
}

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao.r4;
* 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.
@ -144,7 +144,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
}
long delay = System.currentTimeMillis() - start;
ourLog.info("Batch completed in {}ms", new Object[]{delay});
ourLog.info("Batch completed in {}ms", new Object[] {delay});
return resp;
}
@ -169,9 +169,9 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
long start = System.currentTimeMillis();
final Date updateTime = new Date();
final Set<IdType> allIds = new LinkedHashSet<IdType>();
final Map<IdType, IdType> idSubstitutions = new HashMap<IdType, IdType>();
final Map<IdType, DaoMethodOutcome> idToPersistedOutcome = new HashMap<IdType, DaoMethodOutcome>();
final Set<IdType> allIds = new LinkedHashSet<>();
final Map<IdType, IdType> idSubstitutions = new HashMap<>();
final Map<IdType, DaoMethodOutcome> idToPersistedOutcome = new HashMap<>();
// Do all entries have a verb?
for (int i = 0; i < theRequest.getEntry().size(); i++) {
@ -193,8 +193,8 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
* we want the GET processing to use the final indexing state
*/
final Bundle response = new Bundle();
List<BundleEntryComponent> getEntries = new ArrayList<BundleEntryComponent>();
final IdentityHashMap<BundleEntryComponent, Integer> originalRequestOrder = new IdentityHashMap<Bundle.BundleEntryComponent, Integer>();
List<BundleEntryComponent> getEntries = new ArrayList<>();
final IdentityHashMap<BundleEntryComponent, Integer> originalRequestOrder = new IdentityHashMap<>();
for (int i = 0; i < theRequest.getEntry().size(); i++) {
originalRequestOrder.put(theRequest.getEntry().get(i), i);
response.addEntry();
@ -265,7 +265,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
paramValues.put(next.getName(), next.getValue());
}
for (java.util.Map.Entry<String, Collection<String>> nextParamEntry : paramValues.asMap().entrySet()) {
String[] nextValue = nextParamEntry.getValue().toArray(new String[nextParamEntry.getValue().size()]);
String[] nextValue = nextParamEntry.getValue().toArray(new String[ nextParamEntry.getValue().size() ]);
requestDetails.addParameter(nextParamEntry.getKey(), nextValue);
}
url = url.substring(0, qIndex);
@ -309,20 +309,20 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
}
long delay = System.currentTimeMillis() - start;
ourLog.info(theActionName + " completed in {}ms", new Object[]{delay});
ourLog.info(theActionName + " completed in {}ms", new Object[] {delay});
response.setType(BundleType.TRANSACTIONRESPONSE);
return response;
}
@SuppressWarnings("unchecked")
private Map<BundleEntryComponent, ResourceTable> doTransactionWriteOperations(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName, Date updateTime, Set<IdType> allIds,
Map<IdType, IdType> idSubstitutions, Map<IdType, DaoMethodOutcome> idToPersistedOutcome, Bundle response, IdentityHashMap<BundleEntryComponent, Integer> originalRequestOrder, List<BundleEntryComponent> theEntries) {
Set<String> deletedResources = new HashSet<String>();
List<DeleteConflict> deleteConflicts = new ArrayList<DeleteConflict>();
Map<BundleEntryComponent, ResourceTable> entriesToProcess = new IdentityHashMap<BundleEntryComponent, ResourceTable>();
Set<ResourceTable> nonUpdatedEntities = new HashSet<ResourceTable>();
Map<String, Class<? extends IBaseResource>> conditionalRequestUrls = new HashMap<String, Class<? extends IBaseResource>>();
private Map<BundleEntryComponent, ResourceTable> doTransactionWriteOperations(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName, Date theUpdateTime, Set<IdType> theAllIds,
Map<IdType, IdType> theIdSubstitutions, Map<IdType, DaoMethodOutcome> theIdToPersistedOutcome, Bundle theResponse, IdentityHashMap<BundleEntryComponent, Integer> theOriginalRequestOrder, List<BundleEntryComponent> theEntries) {
Set<String> deletedResources = new HashSet<>();
List<DeleteConflict> deleteConflicts = new ArrayList<>();
Map<BundleEntryComponent, ResourceTable> entriesToProcess = new IdentityHashMap<>();
Set<ResourceTable> nonUpdatedEntities = new HashSet<>();
Map<String, Class<? extends IBaseResource>> conditionalRequestUrls = new HashMap<>();
/*
* Loop through the request and process any entries of type
@ -341,7 +341,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
nextResourceId = res.getIdElement();
if (nextResourceId.hasIdPart() == false) {
if (!nextResourceId.hasIdPart()) {
if (isNotBlank(nextReqEntry.getFullUrl())) {
nextResourceId = new IdType(nextReqEntry.getFullUrl());
}
@ -360,12 +360,12 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
* Ensure that the bundle doesn't have any duplicates, since this causes all kinds of weirdness
*/
if (isPlaceholder(nextResourceId)) {
if (!allIds.add(nextResourceId)) {
if (!theAllIds.add(nextResourceId)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionContainsMultipleWithDuplicateId", nextResourceId));
}
} else if (nextResourceId.hasResourceType() && nextResourceId.hasIdPart()) {
IdType nextId = nextResourceId.toUnqualifiedVersionless();
if (!allIds.add(nextId)) {
if (!theAllIds.add(nextId)) {
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirSystemDao.class, "transactionContainsMultipleWithDuplicateId", nextId));
}
}
@ -375,7 +375,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
HTTPVerb verb = nextReqEntry.getRequest().getMethodElement().getValue();
String resourceType = res != null ? getContext().getResourceDefinition(res).getName() : null;
BundleEntryComponent nextRespEntry = response.getEntry().get(originalRequestOrder.get(nextReqEntry));
BundleEntryComponent nextRespEntry = theResponse.getEntry().get(theOriginalRequestOrder.get(nextReqEntry));
switch (verb) {
case POST: {
@ -385,10 +385,10 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
res.setId((String) null);
DaoMethodOutcome outcome;
String matchUrl = nextReqEntry.getRequest().getIfNoneExist();
matchUrl = performIdSubstitutionsInMatchUrl(idSubstitutions, matchUrl);
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
outcome = resourceDao.create(res, matchUrl, false, theRequestDetails);
if (nextResourceId != null) {
handleTransactionCreateOrUpdateOutcome(idSubstitutions, idToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequestDetails);
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequestDetails);
}
entriesToProcess.put(nextRespEntry, outcome.getEntity());
if (outcome.getCreated() == false) {
@ -418,7 +418,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
}
} else {
String matchUrl = parts.getResourceType() + '?' + parts.getParams();
matchUrl = performIdSubstitutionsInMatchUrl(idSubstitutions, matchUrl);
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
DeleteMethodOutcome deleteOutcome = dao.deleteByUrl(matchUrl, deleteConflicts, theRequestDetails);
List<ResourceTable> allDeleted = deleteOutcome.getDeletedEntities();
for (ResourceTable deleted : allDeleted) {
@ -459,14 +459,14 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
} else {
matchUrl = parts.getResourceType();
}
matchUrl = performIdSubstitutionsInMatchUrl(idSubstitutions, matchUrl);
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
outcome = resourceDao.update(res, matchUrl, false, theRequestDetails);
if (Boolean.TRUE.equals(outcome.getCreated())) {
conditionalRequestUrls.put(matchUrl, res.getClass());
}
}
handleTransactionCreateOrUpdateOutcome(idSubstitutions, idToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequestDetails);
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequestDetails);
entriesToProcess.put(nextRespEntry, outcome.getEntity());
break;
}
@ -499,20 +499,21 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
*/
FhirTerser terser = getContext().newTerser();
for (DaoMethodOutcome nextOutcome : idToPersistedOutcome.values()) {
for (DaoMethodOutcome nextOutcome : theIdToPersistedOutcome.values()) {
IBaseResource nextResource = nextOutcome.getResource();
if (nextResource == null) {
continue;
}
// References
List<IBaseReference> allRefs = terser.getAllPopulatedChildElementsOfType(nextResource, IBaseReference.class);
for (IBaseReference nextRef : allRefs) {
IIdType nextId = nextRef.getReferenceElement();
if (!nextId.hasIdPart()) {
continue;
}
if (idSubstitutions.containsKey(nextId)) {
IdType newId = idSubstitutions.get(nextId);
if (theIdSubstitutions.containsKey(nextId)) {
IdType newId = theIdSubstitutions.get(nextId);
ourLog.info(" * Replacing resource ref {} with {}", nextId, newId);
nextRef.setReference(newId.getValue());
} else if (nextId.getValue().startsWith("urn:")) {
@ -522,11 +523,27 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
}
}
// URIs
List<UriType> allUris = terser.getAllPopulatedChildElementsOfType(nextResource, UriType.class);
for (UriType nextRef : allUris) {
if (nextRef instanceof IIdType) {
continue; // No substitution on the resource ID itself!
}
IdType nextUriString = new IdType(nextRef.getValueAsString());
if (theIdSubstitutions.containsKey(nextUriString)) {
IdType newId = theIdSubstitutions.get(nextUriString);
ourLog.info(" * Replacing resource ref {} with {}", nextUriString, newId);
nextRef.setValue(newId.getValue());
} else {
ourLog.debug(" * Reference [{}] does not exist in bundle", nextUriString);
}
}
IPrimitiveType<Date> deletedInstantOrNull = ResourceMetadataKeyEnum.DELETED_AT.get((IAnyResource) nextResource);
Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null;
boolean shouldUpdate = !nonUpdatedEntities.contains(nextOutcome.getEntity());
if (shouldUpdate) {
updateEntity(nextResource, nextOutcome.getEntity(), deletedTimestampOrNull, shouldUpdate, false, updateTime, false, true);
updateEntity(nextResource, nextOutcome.getEntity(), deletedTimestampOrNull, shouldUpdate, false, theUpdateTime, false, true);
}
}
@ -548,8 +565,8 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
}
}
for (IdType next : allIds) {
IdType replacement = idSubstitutions.get(next);
for (IdType next : theAllIds) {
IdType replacement = theIdSubstitutions.get(next);
if (replacement == null) {
continue;
}

View File

@ -75,6 +75,9 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
@Qualifier("myDiagnosticReportDaoDstu2")
protected IFhirResourceDao<DiagnosticReport> myDiagnosticReportDao;
@Autowired
@Qualifier("myBinaryDaoDstu2")
protected IFhirResourceDao<Binary> myBinaryDao;
@Autowired
@Qualifier("myEncounterDaoDstu2")
protected IFhirResourceDao<Encounter> myEncounterDao;
// @PersistenceContext()

View File

@ -1,37 +1,23 @@
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.times;
import static org.mockito.Mockito.verify;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.dstu2.composite.*;
import ca.uhn.fhir.model.dstu2.composite.AttachmentDt;
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu2.resource.*;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.*;
import ca.uhn.fhir.model.dstu2.valueset.*;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.model.dstu2.resource.Bundle.EntryRequest;
import ca.uhn.fhir.model.dstu2.resource.Bundle.EntryResponse;
import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.rest.api.Constants;
@ -40,101 +26,28 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoDstu2Test.class);
/**
* See #638
*/
@Test
public void testTransactionBug638() throws Exception {
String input = loadClasspath("/bug638.xml");
Bundle request = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
Bundle resp = mySystemDao.transaction(mySrd, request);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
assertEquals(18, resp.getEntry().size());
}
@Test
public void testTransactionWhichFailsPersistsNothing() {
// Run a transaction which points to that practitioner
// in a field that isn't allowed to refer to a practitioner
Bundle input = new Bundle();
input.setType(BundleTypeEnum.TRANSACTION);
Patient pt = new Patient();
pt.setId("PT");
pt.setActive(true);
pt.addName().addFamily("FAMILY");
input.addEntry()
.setResource(pt)
.getRequest().setMethod(HTTPVerbEnum.PUT).setUrl("Patient/PT");
Observation obs = new Observation();
obs.setId("OBS");
obs.getCode().addCoding().setSystem("foo").setCode("bar");
obs.addPerformer().setReference("Practicioner/AAAAA");
input.addEntry()
.setResource(obs)
.getRequest().setMethod(HTTPVerbEnum.PUT).setUrl("Observation/OBS");
try {
mySystemDao.transaction(mySrd, input);
fail();
} catch (UnprocessableEntityException e) {
assertThat(e.getMessage(), containsString("Resource type 'Practicioner' is not valid for this path"));
}
assertThat(myResourceTableDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty());
}
/**
* Per a message on the mailing list
*/
@Test
public void testTransactionWithPostDoesntUpdate() throws Exception {
// First bundle (name is Joshua)
String input = IOUtils.toString(getClass().getResource("/dstu3-post1.xml"), StandardCharsets.UTF_8);
Bundle request = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
Bundle response = mySystemDao.transaction(mySrd, request);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
assertEquals(1, response.getEntry().size());
assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
assertEquals("1", response.getEntry().get(0).getResponse().getEtag());
String id = response.getEntry().get(0).getResponse().getLocation();
// Now the second (name is Adam, shouldn't get used)
input = IOUtils.toString(getClass().getResource("/dstu3-post2.xml"), StandardCharsets.UTF_8);
request = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
response = mySystemDao.transaction(mySrd, request);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
assertEquals(1, response.getEntry().size());
assertEquals("200 OK", response.getEntry().get(0).getResponse().getStatus());
assertEquals("1", response.getEntry().get(0).getResponse().getEtag());
String id2 = response.getEntry().get(0).getResponse().getLocation();
assertEquals(id, id2);
Patient patient = myPatientDao.read(new IdType(id), mySrd);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient));
assertEquals("Joshua", patient.getNameFirstRep().getGivenAsSingleString());
}
@Test
public void testSystemMetaOperation() {
@ -223,7 +136,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
assertEquals("http://profile/2", profiles.get(0).getValue());
}
@Test
public void testTransactionBatchWithFailingRead() {
String methodName = "testTransactionBatchWithFailingRead";
@ -265,7 +178,21 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
assertThat(respEntry.getStatus(), startsWith("404"));
}
/**
* See #638
*/
@Test
public void testTransactionBug638() throws Exception {
String input = loadClasspath("/bug638.xml");
Bundle request = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
Bundle resp = mySystemDao.transaction(mySrd, request);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
assertEquals(18, resp.getEntry().size());
}
@Test
public void testTransactionCreateMatchUrlWithOneMatch() {
@ -308,7 +235,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
assertEquals("1", o.getId().getVersionIdPart());
}
/**
* ?identifier=
*/
@ -871,7 +798,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
Bundle resp = mySystemDao.transaction(mySrd, request);
assertEquals(1, resp.getEntry().size());
assertEquals("404 Not Found", resp.getEntry().get(0).getResponse().getStatus());
// fail();
// } catch (ResourceNotFoundException e) {
// assertThat(e.getMessage(), containsString("resource matching URL \"Patient?"));
@ -966,32 +893,32 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
@Test
public void testTransactionOrdering() {
String methodName = "testTransactionOrdering";
//@formatter:off
/*
* Transaction Order, per the spec:
*
*
* Process any DELETE interactions
* Process any POST interactions
* Process any PUT interactions
* Process any GET interactions
*
* This test creates a transaction bundle that includes
*
* This test creates a transaction bundle that includes
* these four operations in the reverse order and verifies
* that they are invoked correctly.
*/
//@formatter:off
int pass = 0;
IdDt patientPlaceholderId = IdDt.newRandomUuid();
Bundle req = testTransactionOrderingCreateBundle(methodName, pass, patientPlaceholderId);
Bundle resp = mySystemDao.transaction(mySrd, req);
testTransactionOrderingValidateResponse(pass, resp);
pass = 1;
patientPlaceholderId = IdDt.newRandomUuid();
req = testTransactionOrderingCreateBundle(methodName, pass, patientPlaceholderId);
resp = mySystemDao.transaction(mySrd, req);
testTransactionOrderingValidateResponse(pass, resp);
@ -1001,18 +928,18 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
private Bundle testTransactionOrderingCreateBundle(String methodName, int pass, IdDt patientPlaceholderId) {
Bundle req = new Bundle();
req.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?identifier=" + methodName);
Observation obs = new Observation();
obs.getSubject().setReference(patientPlaceholderId);
obs.addIdentifier().setValue(methodName);
obs.getCode().setText(methodName + pass);
req.addEntry().setResource(obs).getRequest().setMethod(HTTPVerbEnum.PUT).setUrl("Observation?identifier=" + methodName);
Patient pat = new Patient();
pat.addIdentifier().setValue(methodName);
pat.addName().addFamily(methodName + pass);
req.addEntry().setResource(pat).setFullUrl(patientPlaceholderId.getValue()).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Patient");
req.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=" + methodName);
return req;
}
@ -1037,11 +964,11 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
} else {
assertEquals("204 No Content", resp.getEntry().get(3).getResponse().getStatus());
}
Bundle respGetBundle = (Bundle) resp.getEntry().get(0).getResource();
assertEquals(1, respGetBundle.getEntry().size());
assertEquals("testTransactionOrdering" + pass, ((Patient)respGetBundle.getEntry().get(0).getResource()).getNameFirstRep().getFamilyFirstRep().getValue());
assertEquals("testTransactionOrdering" + pass, ((Patient) respGetBundle.getEntry().get(0).getResource()).getNameFirstRep().getFamilyFirstRep().getValue());
assertThat(respGetBundle.getLink("self").getUrl(), endsWith("/Patient?identifier=testTransactionOrdering"));
}
@ -1112,7 +1039,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
details = detailsCapt.getValue();
assertEquals("Patient", details.getResourceType());
}
@Test
@ -1246,7 +1173,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
Bundle resp = mySystemDao.transaction(mySrd, request);
assertEquals(2, resp.getEntry().size());
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
Entry nextEntry = resp.getEntry().get(0);
@ -1379,6 +1306,42 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
}
@Test
public void testTransactionWhichFailsPersistsNothing() {
// Run a transaction which points to that practitioner
// in a field that isn't allowed to refer to a practitioner
Bundle input = new Bundle();
input.setType(BundleTypeEnum.TRANSACTION);
Patient pt = new Patient();
pt.setId("PT");
pt.setActive(true);
pt.addName().addFamily("FAMILY");
input.addEntry()
.setResource(pt)
.getRequest().setMethod(HTTPVerbEnum.PUT).setUrl("Patient/PT");
Observation obs = new Observation();
obs.setId("OBS");
obs.getCode().addCoding().setSystem("foo").setCode("bar");
obs.addPerformer().setReference("Practicioner/AAAAA");
input.addEntry()
.setResource(obs)
.getRequest().setMethod(HTTPVerbEnum.PUT).setUrl("Observation/OBS");
try {
mySystemDao.transaction(mySrd, input);
fail();
} catch (UnprocessableEntityException e) {
assertThat(e.getMessage(), containsString("Resource type 'Practicioner' is not valid for this path"));
}
assertThat(myResourceTableDao.findAll(), empty());
assertThat(myResourceIndexedSearchParamStringDao.findAll(), empty());
}
/**
* From a message from David Hay
*/
@ -1389,72 +1352,72 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
final IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
//@formatter:on
String input = "{\n" +
" \"resourceType\": \"Bundle\",\n" +
" \"type\": \"transaction\",\n" +
" \"entry\": [\n" +
" {\n" +
" \"resource\": {\n" +
" \"resourceType\": \"Appointment\",\n" +
" \"status\": \"pending\",\n" +
" \"type\": {\"text\": \"Cardiology\"},\n" +
" \"description\": \"Investigate Angina\",\n" +
" \"start\": \"2016-04-30T18:48:29+12:00\",\n" +
" \"end\": \"2016-04-30T19:03:29+12:00\",\n" +
" \"minutesDuration\": 15,\n" +
" \"participant\": [\n" +
" {\n" +
" \"actor\": {\"display\": \"Clarence cardiology clinic\"},\n" +
" \"status\": \"accepted\"\n" +
" },\n" +
" {\n" +
" \"actor\": {\"reference\": \"Patient/" + id.getIdPart() + "\"},\n" +
" \"status\": \"accepted\"\n" +
" }\n" +
" ],\n" +
" \"text\": {\n" +
" \"status\": \"generated\",\n" +
" \"div\": \"<div><div>Investigate Angina<\\/div><div>Clarence cardiology clinic<\\/div><\\/div>\"\n" +
" }\n" +
" },\n" +
" \"request\": {\n" +
" \"method\": \"POST\",\n" +
" \"url\": \"Appointment\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"resource\": {\n" +
" \"resourceType\": \"Appointment\",\n" +
" \"status\": \"pending\",\n" +
" \"type\": {\"text\": \"GP Visit\"},\n" +
" \"description\": \"Routine checkup\",\n" +
" \"start\": \"2016-05-03T18:48:29+12:00\",\n" +
" \"end\": \"2016-05-03T19:03:29+12:00\",\n" +
" \"minutesDuration\": 15,\n" +
" \"participant\": [\n" +
" {\n" +
" \"actor\": {\"display\": \"Dr Dave\"},\n" +
" \"status\": \"accepted\"\n" +
" },\n" +
" {\n" +
" \"actor\": {\"reference\": \"Patient/" + id.getIdPart() + "\"},\n" +
" \"status\": \"accepted\"\n" +
" }\n" +
" ],\n" +
" \"text\": {\n" +
" \"status\": \"generated\",\n" +
" \"div\": \"<div><div>Routine checkup<\\/div><div>Dr Dave<\\/div><\\/div>\"\n" +
" }\n" +
" },\n" +
" \"request\": {\n" +
" \"method\": \"POST\",\n" +
" \"url\": \"Appointment\"\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
String input = "{\n" +
" \"resourceType\": \"Bundle\",\n" +
" \"type\": \"transaction\",\n" +
" \"entry\": [\n" +
" {\n" +
" \"resource\": {\n" +
" \"resourceType\": \"Appointment\",\n" +
" \"status\": \"pending\",\n" +
" \"type\": {\"text\": \"Cardiology\"},\n" +
" \"description\": \"Investigate Angina\",\n" +
" \"start\": \"2016-04-30T18:48:29+12:00\",\n" +
" \"end\": \"2016-04-30T19:03:29+12:00\",\n" +
" \"minutesDuration\": 15,\n" +
" \"participant\": [\n" +
" {\n" +
" \"actor\": {\"display\": \"Clarence cardiology clinic\"},\n" +
" \"status\": \"accepted\"\n" +
" },\n" +
" {\n" +
" \"actor\": {\"reference\": \"Patient/" + id.getIdPart() + "\"},\n" +
" \"status\": \"accepted\"\n" +
" }\n" +
" ],\n" +
" \"text\": {\n" +
" \"status\": \"generated\",\n" +
" \"div\": \"<div><div>Investigate Angina<\\/div><div>Clarence cardiology clinic<\\/div><\\/div>\"\n" +
" }\n" +
" },\n" +
" \"request\": {\n" +
" \"method\": \"POST\",\n" +
" \"url\": \"Appointment\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"resource\": {\n" +
" \"resourceType\": \"Appointment\",\n" +
" \"status\": \"pending\",\n" +
" \"type\": {\"text\": \"GP Visit\"},\n" +
" \"description\": \"Routine checkup\",\n" +
" \"start\": \"2016-05-03T18:48:29+12:00\",\n" +
" \"end\": \"2016-05-03T19:03:29+12:00\",\n" +
" \"minutesDuration\": 15,\n" +
" \"participant\": [\n" +
" {\n" +
" \"actor\": {\"display\": \"Dr Dave\"},\n" +
" \"status\": \"accepted\"\n" +
" },\n" +
" {\n" +
" \"actor\": {\"reference\": \"Patient/" + id.getIdPart() + "\"},\n" +
" \"status\": \"accepted\"\n" +
" }\n" +
" ],\n" +
" \"text\": {\n" +
" \"status\": \"generated\",\n" +
" \"div\": \"<div><div>Routine checkup<\\/div><div>Dr Dave<\\/div><\\/div>\"\n" +
" }\n" +
" },\n" +
" \"request\": {\n" +
" \"method\": \"POST\",\n" +
" \"url\": \"Appointment\"\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
//@formatter:on
Bundle inputBundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, input);
Bundle outputBundle = mySystemDao.transaction(mySrd, inputBundle);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outputBundle));
@ -1481,7 +1444,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
Patient p = new Patient();
p.addName().addFamily("family");
final IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
Bundle inputBundle = new Bundle();
//@formatter:off
@ -1490,22 +1453,22 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
String placeholderId0 = IdDt.newRandomUuid().getValue();
inputBundle
.addEntry()
.setResource(app0)
.setFullUrl(placeholderId0)
.getRequest()
.setMethod(HTTPVerbEnum.POST)
.setUrl("Patient");
.setResource(app0)
.setFullUrl(placeholderId0)
.getRequest()
.setMethod(HTTPVerbEnum.POST)
.setUrl("Patient");
//@formatter:on
//@formatter:off
Appointment app1 = new Appointment();
app1.addParticipant().getActor().setReference(id);
inputBundle
.addEntry()
.setResource(app1)
.getRequest()
.setMethod(HTTPVerbEnum.POST)
.setUrl("Appointment");
.setResource(app1)
.getRequest()
.setMethod(HTTPVerbEnum.POST)
.setUrl("Appointment");
//@formatter:on
//@formatter:off
@ -1514,20 +1477,20 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
app2.addParticipant().getActor().setDisplay("YES REF").setReference(placeholderId0);
inputBundle
.addEntry()
.setResource(app2)
.getRequest()
.setMethod(HTTPVerbEnum.POST)
.setUrl("Appointment");
.setResource(app2)
.getRequest()
.setMethod(HTTPVerbEnum.POST)
.setUrl("Appointment");
//@formatter:on
Bundle outputBundle = mySystemDao.transaction(mySrd, inputBundle);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outputBundle));
assertEquals(3, outputBundle.getEntry().size());
IdDt id0 = new IdDt(outputBundle.getEntry().get(0).getResponse().getLocation());
IdDt id1 = new IdDt(outputBundle.getEntry().get(1).getResponse().getLocation());
IdDt id2 = new IdDt(outputBundle.getEntry().get(2).getResponse().getLocation());
app2 = myAppointmentDao.read(id2, mySrd);
assertEquals("NO REF", app2.getParticipant().get(0).getActor().getDisplay().getValue());
assertEquals(null, app2.getParticipant().get(0).getActor().getReference().getValue());
@ -1535,6 +1498,42 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
assertEquals(id0.toUnqualifiedVersionless().getValue(), app2.getParticipant().get(1).getActor().getReference().getValue());
}
/**
* Per a message on the mailing list
*/
@Test
public void testTransactionWithPostDoesntUpdate() throws Exception {
// First bundle (name is Joshua)
String input = IOUtils.toString(getClass().getResource("/dstu3-post1.xml"), StandardCharsets.UTF_8);
Bundle request = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
Bundle response = mySystemDao.transaction(mySrd, request);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
assertEquals(1, response.getEntry().size());
assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
assertEquals("1", response.getEntry().get(0).getResponse().getEtag());
String id = response.getEntry().get(0).getResponse().getLocation();
// Now the second (name is Adam, shouldn't get used)
input = IOUtils.toString(getClass().getResource("/dstu3-post2.xml"), StandardCharsets.UTF_8);
request = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
response = mySystemDao.transaction(mySrd, request);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
assertEquals(1, response.getEntry().size());
assertEquals("200 OK", response.getEntry().get(0).getResponse().getStatus());
assertEquals("1", response.getEntry().get(0).getResponse().getEtag());
String id2 = response.getEntry().get(0).getResponse().getLocation();
assertEquals(id, id2);
Patient patient = myPatientDao.read(new IdType(id), mySrd);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient));
assertEquals("Joshua", patient.getNameFirstRep().getGivenAsSingleString());
}
@Test
public void testTransactionWithReferenceToCreateIfNoneExist() {
Bundle bundle = new Bundle();
@ -1626,6 +1625,47 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
}
/**
* This is not the correct way to do it, but we'll allow it to be lenient
*/
@Test
public void testTransactionWithRelativeOidIdsQualified() throws Exception {
Bundle res = new Bundle();
res.setType(BundleTypeEnum.TRANSACTION);
Patient p1 = new Patient();
p1.setId("urn:oid:0.1.2.3");
p1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds01");
res.addEntry().setResource(p1).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Patient");
Observation o1 = new Observation();
o1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds02");
o1.setSubject(new ResourceReferenceDt("Patient/urn:oid:0.1.2.3"));
res.addEntry().setResource(o1).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
Observation o2 = new Observation();
o2.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds03");
o2.setSubject(new ResourceReferenceDt("Patient/urn:oid:0.1.2.3"));
res.addEntry().setResource(o2).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
Bundle resp = mySystemDao.transaction(mySrd, res);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
assertEquals(BundleTypeEnum.TRANSACTION_RESPONSE, resp.getTypeElement().getValueAsEnum());
assertEquals(3, resp.getEntry().size());
assertTrue(resp.getEntry().get(0).getResponse().getLocation(), new IdDt(resp.getEntry().get(0).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(1).getResponse().getLocation(), new IdDt(resp.getEntry().get(1).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(2).getResponse().getLocation(), new IdDt(resp.getEntry().get(2).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
o1 = myObservationDao.read(new IdDt(resp.getEntry().get(1).getResponse().getLocation()), mySrd);
o2 = myObservationDao.read(new IdDt(resp.getEntry().get(2).getResponse().getLocation()), mySrd);
assertThat(o1.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
assertThat(o2.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
}
//
//
// /**
@ -1728,45 +1768,52 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
//
// }
/**
* This is not the correct way to do it, but we'll allow it to be lenient
*/
@Test
public void testTransactionWithRelativeOidIdsQualified() throws Exception {
Bundle res = new Bundle();
res.setType(BundleTypeEnum.TRANSACTION);
public void testTransactionWithReplacement() {
byte[] bytes = new byte[] {0, 1, 2, 3, 4};
Patient p1 = new Patient();
p1.setId("urn:oid:0.1.2.3");
p1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds01");
res.addEntry().setResource(p1).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Patient");
Binary binary = new Binary();
binary.setId(IdDt.newRandomUuid());
binary.setContent(bytes);
binary.setContentType("application/pdf");
Observation o1 = new Observation();
o1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds02");
o1.setSubject(new ResourceReferenceDt("Patient/urn:oid:0.1.2.3"));
res.addEntry().setResource(o1).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
DiagnosticReport dr = new DiagnosticReport();
dr.setId(IdDt.newRandomUuid());
Observation o2 = new Observation();
o2.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds03");
o2.setSubject(new ResourceReferenceDt("Patient/urn:oid:0.1.2.3"));
res.addEntry().setResource(o2).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
AttachmentDt attachment = new AttachmentDt();
attachment.setContentType("application/pdf");
attachment.getUrlElement().setValueAsString(binary.getId().getValueAsString()); // this one has substitution
dr.addPresentedForm(attachment);
Bundle resp = mySystemDao.transaction(mySrd, res);
AttachmentDt attachment2 = new AttachmentDt();
attachment2.getUrlElement().setValueAsString(IdDt.newRandomUuid().getValue()); // this one has no subscitution
dr.addPresentedForm(attachment2);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
Bundle transactionBundle = new Bundle();
transactionBundle.setType(BundleTypeEnum.TRANSACTION);
assertEquals(BundleTypeEnum.TRANSACTION_RESPONSE, resp.getTypeElement().getValueAsEnum());
assertEquals(3, resp.getEntry().size());
Entry binaryEntry = new Bundle.Entry();
binaryEntry.setResource(binary).setFullUrl(binary.getId()).getRequest().setUrl("Binary").setMethod(HTTPVerbEnum.POST);
transactionBundle.addEntry(binaryEntry);
assertTrue(resp.getEntry().get(0).getResponse().getLocation(), new IdDt(resp.getEntry().get(0).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(1).getResponse().getLocation(), new IdDt(resp.getEntry().get(1).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(2).getResponse().getLocation(), new IdDt(resp.getEntry().get(2).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
Entry drEntry = new Entry();
drEntry.setResource(dr).setFullUrl(dr.getId()).getRequest().setUrl("DiagnosticReport").setMethod(HTTPVerbEnum.POST);
transactionBundle.addEntry(drEntry);
o1 = myObservationDao.read(new IdDt(resp.getEntry().get(1).getResponse().getLocation()), mySrd);
o2 = myObservationDao.read(new IdDt(resp.getEntry().get(2).getResponse().getLocation()), mySrd);
assertThat(o1.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
assertThat(o2.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(transactionBundle));
Bundle transactionResp = mySystemDao.transaction(mySrd, transactionBundle);
assertEquals(2, transactionResp.getEntry().size());
// Validate Binary
binary = myBinaryDao.read(new IdType(transactionResp.getEntry().get(0).getResponse().getLocation()));
assertArrayEquals(bytes, binary.getContent());
// Validate DiagnosticReport
dr = myDiagnosticReportDao.read(new IdType(transactionResp.getEntry().get(1).getResponse().getLocation()));
assertEquals(binary.getIdElement().toUnqualifiedVersionless().getValue(), dr.getPresentedForm().get(0).getUrl());
assertEquals(attachment2.getUrl(), dr.getPresentedForm().get(1).getUrl());
}
@AfterClass

View File

@ -99,6 +99,9 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
@Qualifier("myDiagnosticReportDaoDstu3")
protected IFhirResourceDao<DiagnosticReport> myDiagnosticReportDao;
@Autowired
@Qualifier("myBinaryDaoDstu3")
protected IFhirResourceDao<Binary> myBinaryDao;
@Autowired
@Qualifier("myEncounterDaoDstu3")
protected IFhirResourceDao<Encounter> myEncounterDao;
// @PersistenceContext()

View File

@ -2520,7 +2520,6 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
assertEquals("Joshua", patient.getNameFirstRep().getGivenAsSingleString());
}
@Test
public void testTransactionWithReferenceResource() {
Bundle request = new Bundle();
@ -2548,7 +2547,6 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
assertEquals(1, found.size().intValue());
}
@Test
public void testTransactionWithReferenceToCreateIfNoneExist() {
Bundle bundle = new Bundle();
@ -2602,6 +2600,33 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
assertNotEquals(medOrderId1, medOrderId2);
}
@Test
public void testTransactionWithReferenceUuid() {
Bundle request = new Bundle();
Patient p = new Patient();
p.setActive(true);
p.setId(IdType.newRandomUuid());
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.POST).setUrl(p.getId());
Observation o = new Observation();
o.getCode().setText("Some Observation");
o.getSubject().setReference(p.getId());
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerb.POST);
Bundle resp = mySystemDao.transaction(mySrd, request);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
String patientId = new IdType(resp.getEntry().get(0).getResponse().getLocation()).toUnqualifiedVersionless().getValue();
assertThat(patientId, startsWith("Patient/"));
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("subject", new ReferenceParam(patientId));
IBundleProvider found = myObservationDao.search(params);
assertEquals(1, found.size().intValue());
}
//
//
// /**
@ -2704,34 +2729,6 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
//
// }
@Test
public void testTransactionWithReferenceUuid() {
Bundle request = new Bundle();
Patient p = new Patient();
p.setActive(true);
p.setId(IdType.newRandomUuid());
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerb.POST).setUrl(p.getId());
Observation o = new Observation();
o.getCode().setText("Some Observation");
o.getSubject().setReference(p.getId());
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerb.POST);
Bundle resp = mySystemDao.transaction(mySrd, request);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
String patientId = new IdType(resp.getEntry().get(0).getResponse().getLocation()).toUnqualifiedVersionless().getValue();
assertThat(patientId, startsWith("Patient/"));
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronous(true);
params.add("subject", new ReferenceParam(patientId));
IBundleProvider found = myObservationDao.search(params);
assertEquals(1, found.size().intValue());
}
@Test
public void testTransactionWithRelativeOidIds() throws Exception {
Bundle res = new Bundle();
@ -2811,6 +2808,52 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
}
@Test
public void testTransactionWithReplacement() {
byte[] bytes = new byte[] {0, 1, 2, 3, 4};
Binary binary = new Binary();
binary.setId(IdType.newRandomUuid());
binary.setContent(bytes);
binary.setContentType("application/pdf");
DiagnosticReport dr = new DiagnosticReport();
dr.setId(IdDt.newRandomUuid());
Attachment attachment = new Attachment();
attachment.setContentType("application/pdf");
attachment.setUrl(binary.getId()); // this one has substitution
dr.addPresentedForm(attachment);
Attachment attachment2 = new Attachment();
attachment2.setUrl(IdType.newRandomUuid().getValue()); // this one has no subscitution
dr.addPresentedForm(attachment2);
Bundle transactionBundle = new Bundle();
transactionBundle.setType(BundleType.TRANSACTION);
Bundle.BundleEntryComponent binaryEntry = new Bundle.BundleEntryComponent();
binaryEntry.setResource(binary).setFullUrl(binary.getId()).getRequest().setUrl("Binary").setMethod(Bundle.HTTPVerb.POST);
transactionBundle.addEntry(binaryEntry);
Bundle.BundleEntryComponent drEntry = new Bundle.BundleEntryComponent();
drEntry.setResource(dr).setFullUrl(dr.getId()).getRequest().setUrl("DiagnosticReport").setMethod(Bundle.HTTPVerb.POST);
transactionBundle.addEntry(drEntry);
Bundle transactionResp = mySystemDao.transaction(mySrd, transactionBundle);
assertEquals(2, transactionResp.getEntry().size());
// Validate Binary
binary = myBinaryDao.read(new IdType(transactionResp.getEntry().get(0).getResponse().getLocation()));
assertArrayEquals(bytes, binary.getContent());
// Validate DiagnosticReport
dr = myDiagnosticReportDao.read(new IdType(transactionResp.getEntry().get(1).getResponse().getLocation()));
assertEquals(binary.getIdElement().toUnqualifiedVersionless().getValue(), dr.getPresentedForm().get(0).getUrl());
assertEquals(attachment2.getUrl(), dr.getPresentedForm().get(1).getUrl());
}
/**
* See #467
*/

View File

@ -157,6 +157,9 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
@Autowired
protected DatabaseBackedPagingProvider myPagingProvider;
@Autowired
@Qualifier("myBinaryDaoR4")
protected IFhirResourceDao<Binary> myBinaryDao;
@Autowired
@Qualifier("myPatientDaoR4")
protected IFhirResourceDaoPatient<Patient> myPatientDao;
@Autowired
@ -315,7 +318,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
linkNext = linkNext.substring(linkNext.indexOf('?'));
Map<String, String[]> params = UrlUtil.parseQueryString(linkNext);
String[] uuidParams = params.get(Constants.PARAM_PAGINGACTION);
String uuid = uuidParams[0];
String uuid = uuidParams[ 0 ];
return uuid;
}

View File

@ -159,8 +159,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
for (BundleEntryComponent nextEntry : theBundle.getEntry()) {
if (nextEntry.getResource() != null && theType.isAssignableFrom(nextEntry.getResource().getClass())) {
if (count == theIndex) {
T t = (T) nextEntry.getResource();
return t;
return (T) nextEntry.getResource();
}
count++;
}
@ -729,78 +728,6 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
}
@Test
public void testTransactionWithCircularReferences() {
Bundle request = new Bundle();
request.setType(BundleType.TRANSACTION);
Encounter enc = new Encounter();
enc.addIdentifier().setSystem("A").setValue("1");
enc.setId(IdType.newRandomUuid());
Condition cond = new Condition();
cond.addIdentifier().setSystem("A").setValue("2");
cond.setId(IdType.newRandomUuid());
enc.addDiagnosis().getCondition().setReference(cond.getId());
cond.getContext().setReference(enc.getId());
request
.addEntry()
.setFullUrl(enc.getId())
.setResource(enc)
.getRequest()
.setMethod(HTTPVerb.PUT)
.setUrl("Encounter?identifier=A|1");
request
.addEntry()
.setFullUrl(cond.getId())
.setResource(cond)
.getRequest()
.setMethod(HTTPVerb.PUT)
.setUrl("Condition?identifier=A|2");
Bundle resp = mySystemDao.transaction(mySrd, request);
assertEquals(2, resp.getEntry().size());
BundleEntryComponent respEntry = resp.getEntry().get(0);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
respEntry = resp.getEntry().get(1);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
}
@Test
public void testTransactionWithCircularReferences2() throws IOException {
Bundle request = loadResourceFromClasspath(Bundle.class, "/dstu3_transaction.xml");
Bundle resp = mySystemDao.transaction(mySrd, request);
assertEquals(3, resp.getEntry().size());
BundleEntryComponent respEntry = resp.getEntry().get(0);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
respEntry = resp.getEntry().get(1);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
}
@Test
public void testTransactionWithCircularReferences3() throws IOException {
Bundle request = loadResourceFromClasspath(Bundle.class, "/dstu3_transaction2.xml");
Bundle resp = mySystemDao.transaction(mySrd, request);
assertEquals(3, resp.getEntry().size());
BundleEntryComponent respEntry = resp.getEntry().get(0);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
respEntry = resp.getEntry().get(1);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
}
@Test
public void testTransactionCreateInlineMatchUrlWithOneMatchLastUpdated() {
Bundle request = new Bundle();
@ -2260,6 +2187,78 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
}
@Test
public void testTransactionWithCircularReferences() {
Bundle request = new Bundle();
request.setType(BundleType.TRANSACTION);
Encounter enc = new Encounter();
enc.addIdentifier().setSystem("A").setValue("1");
enc.setId(IdType.newRandomUuid());
Condition cond = new Condition();
cond.addIdentifier().setSystem("A").setValue("2");
cond.setId(IdType.newRandomUuid());
enc.addDiagnosis().getCondition().setReference(cond.getId());
cond.getContext().setReference(enc.getId());
request
.addEntry()
.setFullUrl(enc.getId())
.setResource(enc)
.getRequest()
.setMethod(HTTPVerb.PUT)
.setUrl("Encounter?identifier=A|1");
request
.addEntry()
.setFullUrl(cond.getId())
.setResource(cond)
.getRequest()
.setMethod(HTTPVerb.PUT)
.setUrl("Condition?identifier=A|2");
Bundle resp = mySystemDao.transaction(mySrd, request);
assertEquals(2, resp.getEntry().size());
BundleEntryComponent respEntry = resp.getEntry().get(0);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
respEntry = resp.getEntry().get(1);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
}
@Test
public void testTransactionWithCircularReferences2() throws IOException {
Bundle request = loadResourceFromClasspath(Bundle.class, "/dstu3_transaction.xml");
Bundle resp = mySystemDao.transaction(mySrd, request);
assertEquals(3, resp.getEntry().size());
BundleEntryComponent respEntry = resp.getEntry().get(0);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
respEntry = resp.getEntry().get(1);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
}
@Test
public void testTransactionWithCircularReferences3() throws IOException {
Bundle request = loadResourceFromClasspath(Bundle.class, "/dstu3_transaction2.xml");
Bundle resp = mySystemDao.transaction(mySrd, request);
assertEquals(3, resp.getEntry().size());
BundleEntryComponent respEntry = resp.getEntry().get(0);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
respEntry = resp.getEntry().get(1);
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", respEntry.getResponse().getStatus());
}
@Test
public void testTransactionWithIfMatch() {
Patient p = new Patient();
@ -2719,6 +2718,44 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
assertEquals(1, found.size().intValue());
}
@Test
public void testTransactionWithRelativeOidIds() throws Exception {
Bundle res = new Bundle();
res.setType(BundleType.TRANSACTION);
Patient p1 = new Patient();
p1.setId("urn:oid:0.1.2.3");
p1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds01");
res.addEntry().setResource(p1).getRequest().setMethod(HTTPVerb.POST).setUrl("Patient");
Observation o1 = new Observation();
o1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds02");
o1.setSubject(new Reference("urn:oid:0.1.2.3"));
res.addEntry().setResource(o1).getRequest().setMethod(HTTPVerb.POST).setUrl("Observation");
Observation o2 = new Observation();
o2.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds03");
o2.setSubject(new Reference("urn:oid:0.1.2.3"));
res.addEntry().setResource(o2).getRequest().setMethod(HTTPVerb.POST).setUrl("Observation");
Bundle resp = mySystemDao.transaction(mySrd, res);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
assertEquals(BundleType.TRANSACTIONRESPONSE, resp.getTypeElement().getValue());
assertEquals(3, resp.getEntry().size());
assertTrue(resp.getEntry().get(0).getResponse().getLocation(), new IdType(resp.getEntry().get(0).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(1).getResponse().getLocation(), new IdType(resp.getEntry().get(1).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(2).getResponse().getLocation(), new IdType(resp.getEntry().get(2).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
o1 = myObservationDao.read(new IdType(resp.getEntry().get(1).getResponse().getLocation()), mySrd);
o2 = myObservationDao.read(new IdType(resp.getEntry().get(2).getResponse().getLocation()), mySrd);
assertThat(o1.getSubject().getReferenceElement().getValue(), endsWith("Patient/" + p1.getIdElement().getIdPart()));
assertThat(o2.getSubject().getReferenceElement().getValue(), endsWith("Patient/" + p1.getIdElement().getIdPart()));
}
//
//
// /**
@ -2821,44 +2858,6 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
//
// }
@Test
public void testTransactionWithRelativeOidIds() throws Exception {
Bundle res = new Bundle();
res.setType(BundleType.TRANSACTION);
Patient p1 = new Patient();
p1.setId("urn:oid:0.1.2.3");
p1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds01");
res.addEntry().setResource(p1).getRequest().setMethod(HTTPVerb.POST).setUrl("Patient");
Observation o1 = new Observation();
o1.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds02");
o1.setSubject(new Reference("urn:oid:0.1.2.3"));
res.addEntry().setResource(o1).getRequest().setMethod(HTTPVerb.POST).setUrl("Observation");
Observation o2 = new Observation();
o2.addIdentifier().setSystem("system").setValue("testTransactionWithRelativeOidIds03");
o2.setSubject(new Reference("urn:oid:0.1.2.3"));
res.addEntry().setResource(o2).getRequest().setMethod(HTTPVerb.POST).setUrl("Observation");
Bundle resp = mySystemDao.transaction(mySrd, res);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
assertEquals(BundleType.TRANSACTIONRESPONSE, resp.getTypeElement().getValue());
assertEquals(3, resp.getEntry().size());
assertTrue(resp.getEntry().get(0).getResponse().getLocation(), new IdType(resp.getEntry().get(0).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(1).getResponse().getLocation(), new IdType(resp.getEntry().get(1).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
assertTrue(resp.getEntry().get(2).getResponse().getLocation(), new IdType(resp.getEntry().get(2).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
o1 = myObservationDao.read(new IdType(resp.getEntry().get(1).getResponse().getLocation()), mySrd);
o2 = myObservationDao.read(new IdType(resp.getEntry().get(2).getResponse().getLocation()), mySrd);
assertThat(o1.getSubject().getReferenceElement().getValue(), endsWith("Patient/" + p1.getIdElement().getIdPart()));
assertThat(o2.getSubject().getReferenceElement().getValue(), endsWith("Patient/" + p1.getIdElement().getIdPart()));
}
/**
* This is not the correct way to do it, but we'll allow it to be lenient
*/
@ -2900,6 +2899,52 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
}
@Test
public void testTransactionWithReplacement() {
byte[] bytes = new byte[] {0, 1, 2, 3, 4};
Binary binary = new Binary();
binary.setId(IdType.newRandomUuid());
binary.setContent(bytes);
binary.setContentType("application/pdf");
DiagnosticReport dr = new DiagnosticReport();
dr.setId(IdDt.newRandomUuid());
Attachment attachment = new Attachment();
attachment.setContentType("application/pdf");
attachment.setUrl(binary.getId()); // this one has substitution
dr.addPresentedForm(attachment);
Attachment attachment2 = new Attachment();
attachment2.setUrl(IdType.newRandomUuid().getValue()); // this one has no subscitution
dr.addPresentedForm(attachment2);
Bundle transactionBundle = new Bundle();
transactionBundle.setType(BundleType.TRANSACTION);
Bundle.BundleEntryComponent binaryEntry = new Bundle.BundleEntryComponent();
binaryEntry.setResource(binary).setFullUrl(binary.getId()).getRequest().setUrl("Binary").setMethod(Bundle.HTTPVerb.POST);
transactionBundle.addEntry(binaryEntry);
Bundle.BundleEntryComponent drEntry = new Bundle.BundleEntryComponent();
drEntry.setResource(dr).setFullUrl(dr.getId()).getRequest().setUrl("DiagnosticReport").setMethod(Bundle.HTTPVerb.POST);
transactionBundle.addEntry(drEntry);
Bundle transactionResp = mySystemDao.transaction(mySrd, transactionBundle);
assertEquals(2, transactionResp.getEntry().size());
// Validate Binary
binary = myBinaryDao.read(new IdType(transactionResp.getEntry().get(0).getResponse().getLocation()));
assertArrayEquals(bytes, binary.getContent());
// Validate DiagnosticReport
dr = myDiagnosticReportDao.read(new IdType(transactionResp.getEntry().get(1).getResponse().getLocation()));
assertEquals(binary.getIdElement().toUnqualifiedVersionless().getValue(), dr.getPresentedForm().get(0).getUrl());
assertEquals(attachment2.getUrl(), dr.getPresentedForm().get(1).getUrl());
}
/**
* See #467
*/

View File

@ -144,6 +144,12 @@
Avoid an endless loop of reindexing in JPA if a SearchParameter is
created which indexed the SearchParameter resource itself
</action>
<action type="add" issue="854">
JPA server now performs temporary/placeholder ID substitution processing on elements in
resources which are of type "URI" in addition to the current substitution for
elements of type "Reference". Thanks to GitHub user @t4deon for supplying
a testcase!
</action>
</release>
<release version="3.2.0" date="2018-01-13">
<action type="add">