Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
e241b31905
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Reference in New Issue