Remove duplicate resource body creation (Merge branch 'optimize_jpa')
This commit is contained in:
commit
4fd3e20d06
|
@ -913,9 +913,12 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
/**
|
/**
|
||||||
* Returns true if the resource has changed (either the contents or the tags)
|
* Returns true if the resource has changed (either the contents or the tags)
|
||||||
*/
|
*/
|
||||||
protected boolean populateResourceIntoEntity(IBaseResource theResource, ResourceTable theEntity, boolean theUpdateHash) {
|
protected EncodedResource populateResourceIntoEntity(IBaseResource theResource, ResourceTable theEntity, boolean theUpdateHash) {
|
||||||
|
if (theEntity.getResourceType() == null) {
|
||||||
theEntity.setResourceType(toResourceName(theResource));
|
theEntity.setResourceType(toResourceName(theResource));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theResource != null) {
|
||||||
List<BaseResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, BaseResourceReferenceDt.class);
|
List<BaseResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(theResource, BaseResourceReferenceDt.class);
|
||||||
for (BaseResourceReferenceDt nextRef : refs) {
|
for (BaseResourceReferenceDt nextRef : refs) {
|
||||||
if (nextRef.getReference().isEmpty() == false) {
|
if (nextRef.getReference().isEmpty() == false) {
|
||||||
|
@ -924,16 +927,20 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ResourceEncodingEnum encoding = myConfig.getResourceEncoding();
|
byte[] bytes;
|
||||||
|
ResourceEncodingEnum encoding;
|
||||||
|
boolean changed = false;
|
||||||
|
|
||||||
|
if (theEntity.getDeleted() == null) {
|
||||||
|
|
||||||
|
encoding = myConfig.getResourceEncoding();
|
||||||
IParser parser = encoding.newParser(myContext);
|
IParser parser = encoding.newParser(myContext);
|
||||||
parser.setDontEncodeElements(EXCLUDE_ELEMENTS_IN_ENCODED);
|
parser.setDontEncodeElements(EXCLUDE_ELEMENTS_IN_ENCODED);
|
||||||
String encoded = parser.encodeResourceToString(theResource);
|
String encoded = parser.encodeResourceToString(theResource);
|
||||||
|
|
||||||
theEntity.setEncoding(encoding);
|
|
||||||
theEntity.setFhirVersion(myContext.getVersion().getVersion());
|
theEntity.setFhirVersion(myContext.getVersion().getVersion());
|
||||||
byte[] bytes;
|
|
||||||
switch (encoding) {
|
switch (encoding) {
|
||||||
case JSON:
|
case JSON:
|
||||||
bytes = encoded.getBytes(Charsets.UTF_8);
|
bytes = encoded.getBytes(Charsets.UTF_8);
|
||||||
|
@ -946,8 +953,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
|
|
||||||
ourLog.debug("Encoded {} chars of resource body as {} bytes", encoded.length(), bytes.length);
|
ourLog.debug("Encoded {} chars of resource body as {} bytes", encoded.length(), bytes.length);
|
||||||
|
|
||||||
boolean changed = false;
|
|
||||||
|
|
||||||
if (theUpdateHash) {
|
if (theUpdateHash) {
|
||||||
HashFunction sha256 = Hashing.sha256();
|
HashFunction sha256 = Hashing.sha256();
|
||||||
String hashSha256 = sha256.hashBytes(bytes).toString();
|
String hashSha256 = sha256.hashBytes(bytes).toString();
|
||||||
|
@ -957,16 +962,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
theEntity.setHashSha256(hashSha256);
|
theEntity.setHashSha256(hashSha256);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed == false) {
|
|
||||||
if (theEntity.getResource() == null) {
|
|
||||||
changed = true;
|
|
||||||
} else {
|
|
||||||
changed = !Arrays.equals(theEntity.getResource(), bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
theEntity.setResource(bytes);
|
|
||||||
|
|
||||||
Set<TagDefinition> allDefs = new HashSet<>();
|
Set<TagDefinition> allDefs = new HashSet<>();
|
||||||
|
|
||||||
theEntity.setHasTags(false);
|
theEntity.setHasTags(false);
|
||||||
|
@ -1010,7 +1005,31 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return changed;
|
} else {
|
||||||
|
theEntity.setHashSha256(null);
|
||||||
|
bytes = null;
|
||||||
|
encoding = ResourceEncodingEnum.DEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed == false) {
|
||||||
|
if (theEntity.getId() == null) {
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
ResourceHistoryTable currentHistoryVersion = myResourceHistoryTableDao.findForIdAndVersion(theEntity.getId(), theEntity.getVersion());
|
||||||
|
if (currentHistoryVersion == null || currentHistoryVersion.getResource() == null) {
|
||||||
|
changed = true;
|
||||||
|
} else {
|
||||||
|
changed = !Arrays.equals(currentHistoryVersion.getResource(), bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EncodedResource retVal = new EncodedResource();
|
||||||
|
retVal.setEncoding(encoding);
|
||||||
|
retVal.setResource(bytes);
|
||||||
|
retVal.setChanged(changed);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -1183,6 +1202,17 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
throw new NotImplementedException("");
|
throw new NotImplementedException("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> Collection<T> removeCommon(Collection<T> theInput, Collection<T> theToRemove) {
|
||||||
|
assert theInput != theToRemove;
|
||||||
|
|
||||||
|
if (theInput.isEmpty()) {
|
||||||
|
return theInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<T> retVal = new ArrayList<>(theInput);
|
||||||
|
retVal.removeAll(theToRemove);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
private void setUpdatedTime(Collection<? extends BaseResourceIndexedSearchParam> theParams, Date theUpdateTime) {
|
private void setUpdatedTime(Collection<? extends BaseResourceIndexedSearchParam> theParams, Date theUpdateTime) {
|
||||||
for (BaseResourceIndexedSearchParam nextSearchParam : theParams) {
|
for (BaseResourceIndexedSearchParam nextSearchParam : theParams) {
|
||||||
nextSearchParam.setUpdated(theUpdateTime);
|
nextSearchParam.setUpdated(theUpdateTime);
|
||||||
|
@ -1219,17 +1249,34 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public <R extends IBaseResource> R toResource(Class<R> theResourceType, BaseHasResource theEntity, boolean theForHistoryOperation) {
|
public <R extends IBaseResource> R toResource(Class<R> theResourceType, BaseHasResource theEntity, boolean theForHistoryOperation) {
|
||||||
|
|
||||||
|
ResourceHistoryTable history;
|
||||||
|
if (theEntity instanceof ResourceHistoryTable) {
|
||||||
|
history = (ResourceHistoryTable) theEntity;
|
||||||
|
} else {
|
||||||
|
history = myResourceHistoryTableDao.findForIdAndVersion(theEntity.getId(), theEntity.getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (history == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] resourceBytes = history.getResource();
|
||||||
|
ResourceEncodingEnum resourceEncoding = history.getEncoding();
|
||||||
|
|
||||||
String resourceText = null;
|
String resourceText = null;
|
||||||
switch (theEntity.getEncoding()) {
|
switch (resourceEncoding) {
|
||||||
case JSON:
|
case JSON:
|
||||||
try {
|
try {
|
||||||
resourceText = new String(theEntity.getResource(), "UTF-8");
|
resourceText = new String(resourceBytes, "UTF-8");
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new Error("Should not happen", e);
|
throw new Error("Should not happen", e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case JSONC:
|
case JSONC:
|
||||||
resourceText = GZipUtil.decompress(theEntity.getResource());
|
resourceText = GZipUtil.decompress(resourceBytes);
|
||||||
|
break;
|
||||||
|
case DEL:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1253,10 +1300,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IParser parser = theEntity.getEncoding().newParser(getContext(theEntity.getFhirVersion()));
|
R retVal;
|
||||||
|
if (resourceEncoding != ResourceEncodingEnum.DEL) {
|
||||||
|
IParser parser = resourceEncoding.newParser(getContext(theEntity.getFhirVersion()));
|
||||||
parser.setParserErrorHandler(new LenientErrorHandler(false).setErrorOnInvalidValue(false));
|
parser.setParserErrorHandler(new LenientErrorHandler(false).setErrorOnInvalidValue(false));
|
||||||
|
|
||||||
R retVal;
|
|
||||||
try {
|
try {
|
||||||
retVal = parser.parseResource(resourceType, resourceText);
|
retVal = parser.parseResource(resourceType, resourceText);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -1276,6 +1324,12 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
throw new DataFormatException(msg, e);
|
throw new DataFormatException(msg, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
retVal = (R) myContext.getResourceDefinition(theEntity.getResourceType()).newInstance();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (retVal instanceof IResource) {
|
if (retVal instanceof IResource) {
|
||||||
IResource res = (IResource) retVal;
|
IResource res = (IResource) retVal;
|
||||||
retVal = populateResourceMetadataHapi(resourceType, theEntity, theForHistoryOperation, res);
|
retVal = populateResourceMetadataHapi(resourceType, theEntity, theForHistoryOperation, res);
|
||||||
|
@ -1283,6 +1337,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
IAnyResource res = (IAnyResource) retVal;
|
IAnyResource res = (IAnyResource) retVal;
|
||||||
retVal = populateResourceMetadataRi(resourceType, theEntity, theForHistoryOperation, res);
|
retVal = populateResourceMetadataRi(resourceType, theEntity, theForHistoryOperation, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1290,11 +1346,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
return myContext.getResourceDefinition(theResourceType).getName();
|
return myContext.getResourceDefinition(theResourceType).getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String toResourceName(IBaseResource theResource) {
|
String toResourceName(IBaseResource theResource) {
|
||||||
return myContext.getResourceDefinition(theResource).getName();
|
return myContext.getResourceDefinition(theResource).getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Long translateForcedIdToPid(String theResourceName, String theResourceId) {
|
Long translateForcedIdToPid(String theResourceName, String theResourceId) {
|
||||||
return translateForcedIdToPids(new IdDt(theResourceName, theResourceId), myForcedIdDao).get(0);
|
return translateForcedIdToPids(new IdDt(theResourceName, theResourceId), myForcedIdDao).get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1302,7 +1358,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
return translateForcedIdToPids(theId, myForcedIdDao);
|
return translateForcedIdToPids(theId, myForcedIdDao);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String translatePidIdToForcedId(String theResourceType, Long theId) {
|
private String translatePidIdToForcedId(String theResourceType, Long theId) {
|
||||||
ForcedId forcedId = myForcedIdDao.findByResourcePid(theId);
|
ForcedId forcedId = myForcedIdDao.findByResourcePid(theId);
|
||||||
if (forcedId != null) {
|
if (forcedId != null) {
|
||||||
return forcedId.getResourceType() + '/' + forcedId.getForcedId();
|
return forcedId.getResourceType() + '/' + forcedId.getForcedId();
|
||||||
|
@ -1385,7 +1441,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
Set<ResourceLink> links = null;
|
Set<ResourceLink> links = null;
|
||||||
|
|
||||||
Set<String> populatedResourceLinkParameters = Collections.emptySet();
|
Set<String> populatedResourceLinkParameters = Collections.emptySet();
|
||||||
boolean changed;
|
EncodedResource changed;
|
||||||
if (theDeletedTimestampOrNull != null) {
|
if (theDeletedTimestampOrNull != null) {
|
||||||
|
|
||||||
stringParams = Collections.emptySet();
|
stringParams = Collections.emptySet();
|
||||||
|
@ -1403,7 +1459,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
theEntity.setNarrativeTextParsedIntoWords(null);
|
theEntity.setNarrativeTextParsedIntoWords(null);
|
||||||
theEntity.setContentTextParsedIntoWords(null);
|
theEntity.setContentTextParsedIntoWords(null);
|
||||||
theEntity.setHashSha256(null);
|
theEntity.setHashSha256(null);
|
||||||
changed = true;
|
changed = populateResourceIntoEntity(theResource, theEntity, true);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -1555,7 +1611,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!changed && !theForceUpdate && myConfig.isSuppressUpdatesWithNoChange()) {
|
if (!changed.isChanged() && !theForceUpdate && myConfig.isSuppressUpdatesWithNoChange()) {
|
||||||
ourLog.info("Resource {} has not changed", theEntity.getIdDt().toUnqualified().getValue());
|
ourLog.info("Resource {} has not changed", theEntity.getIdDt().toUnqualified().getValue());
|
||||||
if (theResource != null) {
|
if (theResource != null) {
|
||||||
populateResourceIdFromEntity(theEntity, theResource);
|
populateResourceIdFromEntity(theEntity, theResource);
|
||||||
|
@ -1586,6 +1642,22 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
postUpdate(theEntity, (T) theResource);
|
postUpdate(theEntity, (T) theResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create history entry
|
||||||
|
*/
|
||||||
|
if (theCreateNewHistoryEntry) {
|
||||||
|
final ResourceHistoryTable historyEntry = theEntity.toHistory();
|
||||||
|
// if (theEntity.getVersion() > 1) {
|
||||||
|
// existing = myResourceHistoryTableDao.findForIdAndVersion(theEntity.getId(), theEntity.getVersion());
|
||||||
|
// ourLog.warn("Reusing existing history entry entity {}", theEntity.getIdDt().getValue());
|
||||||
|
// }
|
||||||
|
historyEntry.setEncoding(changed.getEncoding());
|
||||||
|
historyEntry.setResource(changed.getResource());
|
||||||
|
|
||||||
|
ourLog.info("Saving history entry {}", historyEntry.getIdDt());
|
||||||
|
myResourceHistoryTableDao.save(historyEntry);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update the "search param present" table which is used for the
|
* Update the "search param present" table which is used for the
|
||||||
* ?foo:missing=true queries
|
* ?foo:missing=true queries
|
||||||
|
@ -1612,22 +1684,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
mySearchParamPresenceSvc.updatePresence(theEntity, presentSearchParams);
|
mySearchParamPresenceSvc.updatePresence(theEntity, presentSearchParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Create history entry
|
|
||||||
*/
|
|
||||||
if (theCreateNewHistoryEntry) {
|
|
||||||
|
|
||||||
ResourceHistoryTable existing = null;
|
|
||||||
// if (theEntity.getVersion() > 1) {
|
|
||||||
// existing = myResourceHistoryTableDao.findForIdAndVersion(theEntity.getId(), theEntity.getVersion());
|
|
||||||
// ourLog.warn("Reusing existing history entry entity {}", theEntity.getIdDt().getValue());
|
|
||||||
// }
|
|
||||||
final ResourceHistoryTable historyEntry = theEntity.toHistory(existing);
|
|
||||||
|
|
||||||
ourLog.info("Saving history entry {}", historyEntry.getIdDt());
|
|
||||||
myResourceHistoryTableDao.save(historyEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Indexing
|
* Indexing
|
||||||
*/
|
*/
|
||||||
|
@ -1728,19 +1784,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
return theEntity;
|
return theEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Collection<T> removeCommon(Collection<T> theInput, Collection<T> theToRemove) {
|
|
||||||
assert theInput != theToRemove;
|
|
||||||
|
|
||||||
if (theInput.isEmpty()) {
|
|
||||||
return theInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<T> retVal = new ArrayList<>(theInput);
|
|
||||||
retVal.removeAll(theToRemove);
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected ResourceTable updateEntity(IBaseResource theResource, ResourceTable entity, Date theDeletedTimestampOrNull, Date theUpdateTime) {
|
protected ResourceTable updateEntity(IBaseResource theResource, ResourceTable entity, Date theDeletedTimestampOrNull, Date theUpdateTime) {
|
||||||
return updateEntity(theResource, entity, theDeletedTimestampOrNull, true, true, theUpdateTime, false, true);
|
return updateEntity(theResource, entity, theDeletedTimestampOrNull, true, true, theUpdateTime, false, true);
|
||||||
}
|
}
|
||||||
|
@ -1921,8 +1964,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
Collections.sort(thePartsChoices, new Comparator<List<String>>() {
|
Collections.sort(thePartsChoices, new Comparator<List<String>>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(List<String> o1, List<String> o2) {
|
public int compare(List<String> o1, List<String> o2) {
|
||||||
String str1=null;
|
String str1 = null;
|
||||||
String str2=null;
|
String str2 = null;
|
||||||
if (o1.size() > 0) {
|
if (o1.size() > 0) {
|
||||||
str1 = o1.get(0);
|
str1 = o1.get(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ import ca.uhn.fhir.util.FhirTerser;
|
||||||
import ca.uhn.fhir.util.ObjectUtil;
|
import ca.uhn.fhir.util.ObjectUtil;
|
||||||
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||||
import ca.uhn.fhir.util.ResourceReferenceInfo;
|
import ca.uhn.fhir.util.ResourceReferenceInfo;
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.instance.model.api.*;
|
import org.hl7.fhir.instance.model.api.*;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -75,6 +76,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends BaseHapiFhirDao<T> implements IFhirResourceDao<T> {
|
public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends BaseHapiFhirDao<T> implements IFhirResourceDao<T> {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirResourceDao.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirResourceDao.class);
|
||||||
|
private static boolean ourDisableIncrementOnUpdateForUnitTest = false;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected PlatformTransactionManager myPlatformTransactionManager;
|
protected PlatformTransactionManager myPlatformTransactionManager;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -84,7 +86,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
@Autowired()
|
@Autowired()
|
||||||
protected ISearchResultDao mySearchResultDao;
|
protected ISearchResultDao mySearchResultDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
private DaoConfig myDaoConfig;
|
protected DaoConfig myDaoConfig;
|
||||||
@Autowired
|
@Autowired
|
||||||
private IResourceHistoryTableDao myResourceHistoryTableDao;
|
private IResourceHistoryTableDao myResourceHistoryTableDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -92,7 +94,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
private String myResourceName;
|
private String myResourceName;
|
||||||
private Class<T> myResourceType;
|
private Class<T> myResourceType;
|
||||||
private String mySecondaryPrimaryKeyParamName;
|
private String mySecondaryPrimaryKeyParamName;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISearchParamRegistry mySearchParamRegistry;
|
private ISearchParamRegistry mySearchParamRegistry;
|
||||||
|
|
||||||
|
@ -192,6 +193,25 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
throw new ResourceVersionConflictException("Trying to delete " + theId + " but this is not the current version");
|
throw new ResourceVersionConflictException("Trying to delete " + theId + " but this is not the current version");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't delete again if it's already deleted
|
||||||
|
if (entity.getDeleted() != null) {
|
||||||
|
DaoMethodOutcome outcome = new DaoMethodOutcome();
|
||||||
|
outcome.setEntity(entity);
|
||||||
|
|
||||||
|
IIdType id = getContext().getVersion().newIdType();
|
||||||
|
id.setValue(entity.getIdDt().getValue());
|
||||||
|
outcome.setId(id);
|
||||||
|
|
||||||
|
IBaseOperationOutcome oo = OperationOutcomeUtil.newInstance(getContext());
|
||||||
|
String message = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "successfulDeletes", 1, 0);
|
||||||
|
String severity = "information";
|
||||||
|
String code = "informational";
|
||||||
|
OperationOutcomeUtil.addIssue(getContext(), oo, severity, message, null, code);
|
||||||
|
outcome.setOperationOutcome(oo);
|
||||||
|
|
||||||
|
return outcome;
|
||||||
|
}
|
||||||
|
|
||||||
StopWatch w = new StopWatch();
|
StopWatch w = new StopWatch();
|
||||||
|
|
||||||
T resourceToDelete = toResource(myResourceType, entity, false);
|
T resourceToDelete = toResource(myResourceType, entity, false);
|
||||||
|
@ -206,7 +226,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validateOkToDelete(theDeleteConflicts, entity);
|
validateOkToDelete(theDeleteConflicts, entity, false);
|
||||||
|
|
||||||
preDelete(resourceToDelete, entity);
|
preDelete(resourceToDelete, entity);
|
||||||
|
|
||||||
|
@ -288,7 +308,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validateOkToDelete(deleteConflicts, entity);
|
validateOkToDelete(deleteConflicts, entity, false);
|
||||||
|
|
||||||
// Notify interceptors
|
// Notify interceptors
|
||||||
IdDt idToDelete = entity.getIdDt();
|
IdDt idToDelete = entity.getIdDt();
|
||||||
|
@ -1228,7 +1248,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
* we'll manually increase the version. This is important because we want the updated version number
|
* we'll manually increase the version. This is important because we want the updated version number
|
||||||
* to be reflected in the resource shared with interceptors
|
* to be reflected in the resource shared with interceptors
|
||||||
*/
|
*/
|
||||||
if (!thePerformIndexing && !savedEntity.isUnchangedInCurrentOperation()) {
|
if (!thePerformIndexing && !savedEntity.isUnchangedInCurrentOperation() && !ourDisableIncrementOnUpdateForUnitTest) {
|
||||||
if (resourceId.hasVersionIdPart() == false) {
|
if (resourceId.hasVersionIdPart() == false) {
|
||||||
resourceId = resourceId.withVersion(Long.toString(savedEntity.getVersion()));
|
resourceId = resourceId.withVersion(Long.toString(savedEntity.getVersion()));
|
||||||
}
|
}
|
||||||
|
@ -1260,7 +1280,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
return outcome;
|
return outcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DaoMethodOutcome update(T theResource, String theMatchUrl, boolean thePerformIndexing, RequestDetails theRequestDetails) {
|
public DaoMethodOutcome update(T theResource, String theMatchUrl, boolean thePerformIndexing, RequestDetails theRequestDetails) {
|
||||||
return update(theResource, theMatchUrl, thePerformIndexing, false, theRequestDetails);
|
return update(theResource, theMatchUrl, thePerformIndexing, false, theRequestDetails);
|
||||||
|
@ -1304,7 +1323,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void validateOkToDelete(List<DeleteConflict> theDeleteConflicts, ResourceTable theEntity) {
|
protected void validateOkToDelete(List<DeleteConflict> theDeleteConflicts, ResourceTable theEntity, boolean theForValidate) {
|
||||||
TypedQuery<ResourceLink> query = myEntityManager.createQuery("SELECT l FROM ResourceLink l WHERE l.myTargetResourcePid = :target_pid", ResourceLink.class);
|
TypedQuery<ResourceLink> query = myEntityManager.createQuery("SELECT l FROM ResourceLink l WHERE l.myTargetResourcePid = :target_pid", ResourceLink.class);
|
||||||
query.setParameter("target_pid", theEntity.getId());
|
query.setParameter("target_pid", theEntity.getId());
|
||||||
query.setMaxResults(1);
|
query.setMaxResults(1);
|
||||||
|
@ -1313,7 +1332,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete() == false) {
|
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete() == false && !theForValidate) {
|
||||||
ourLog.info("Deleting {} resource dependencies which can no longer be satisfied", resultList.size());
|
ourLog.info("Deleting {} resource dependencies which can no longer be satisfied", resultList.size());
|
||||||
myResourceLinkDao.delete(resultList);
|
myResourceLinkDao.delete(resultList);
|
||||||
return;
|
return;
|
||||||
|
@ -1337,4 +1356,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public static void setDisableIncrementOnUpdateForUnitTest(boolean theDisableIncrementOnUpdateForUnitTest) {
|
||||||
|
ourDisableIncrementOnUpdateForUnitTest = theDisableIncrementOnUpdateForUnitTest;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceEncodingEnum;
|
||||||
|
|
||||||
|
class EncodedResource {
|
||||||
|
|
||||||
|
private boolean myChanged;
|
||||||
|
private byte[] myResource;
|
||||||
|
private ResourceEncodingEnum myEncoding;
|
||||||
|
|
||||||
|
public ResourceEncodingEnum getEncoding() {
|
||||||
|
return myEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncoding(ResourceEncodingEnum theEncoding) {
|
||||||
|
myEncoding = theEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getResource() {
|
||||||
|
return myResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResource(byte[] theResource) {
|
||||||
|
myResource = theResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isChanged() {
|
||||||
|
return myChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChanged(boolean theChanged) {
|
||||||
|
myChanged = theChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -80,7 +80,9 @@ public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResou
|
||||||
// Validate that there are no resources pointing to the candidate that
|
// Validate that there are no resources pointing to the candidate that
|
||||||
// would prevent deletion
|
// would prevent deletion
|
||||||
List<DeleteConflict> deleteConflicts = new ArrayList<DeleteConflict>();
|
List<DeleteConflict> deleteConflicts = new ArrayList<DeleteConflict>();
|
||||||
validateOkToDelete(deleteConflicts, entity);
|
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete()) {
|
||||||
|
validateOkToDelete(deleteConflicts, entity, true);
|
||||||
|
}
|
||||||
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
|
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
|
||||||
|
|
||||||
OperationOutcome oo = new OperationOutcome();
|
OperationOutcome oo = new OperationOutcome();
|
||||||
|
|
|
@ -1587,6 +1587,10 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
for (ResourceTable next : resultList) {
|
for (ResourceTable next : resultList) {
|
||||||
Class<? extends IBaseResource> resourceType = context.getResourceDefinition(next.getResourceType()).getImplementingClass();
|
Class<? extends IBaseResource> resourceType = context.getResourceDefinition(next.getResourceType()).getImplementingClass();
|
||||||
IBaseResource resource = theDao.toResource(resourceType, next, theForHistoryOperation);
|
IBaseResource resource = theDao.toResource(resourceType, next, theForHistoryOperation);
|
||||||
|
if (resource == null) {
|
||||||
|
ourLog.warn("Unable to find resource {}/{}/_history/{} in database", next.getResourceType(), next.getIdDt().getIdPart(), next.getVersion());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Integer index = position.get(next.getId());
|
Integer index = position.get(next.getId());
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
ourLog.warn("Got back unexpected resource PID {}", next.getId());
|
ourLog.warn("Got back unexpected resource PID {}", next.getId());
|
||||||
|
|
|
@ -85,7 +85,9 @@ public class FhirResourceDaoDstu3<T extends IAnyResource> extends BaseHapiFhirRe
|
||||||
// Validate that there are no resources pointing to the candidate that
|
// Validate that there are no resources pointing to the candidate that
|
||||||
// would prevent deletion
|
// would prevent deletion
|
||||||
List<DeleteConflict> deleteConflicts = new ArrayList<DeleteConflict>();
|
List<DeleteConflict> deleteConflicts = new ArrayList<DeleteConflict>();
|
||||||
validateOkToDelete(deleteConflicts, entity);
|
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete()) {
|
||||||
|
validateOkToDelete(deleteConflicts, entity, true);
|
||||||
|
}
|
||||||
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
|
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
|
||||||
|
|
||||||
OperationOutcome oo = new OperationOutcome();
|
OperationOutcome oo = new OperationOutcome();
|
||||||
|
|
|
@ -85,7 +85,9 @@ public class FhirResourceDaoR4<T extends IAnyResource> extends BaseHapiFhirResou
|
||||||
// Validate that there are no resources pointing to the candidate that
|
// Validate that there are no resources pointing to the candidate that
|
||||||
// would prevent deletion
|
// would prevent deletion
|
||||||
List<DeleteConflict> deleteConflicts = new ArrayList<DeleteConflict>();
|
List<DeleteConflict> deleteConflicts = new ArrayList<DeleteConflict>();
|
||||||
validateOkToDelete(deleteConflicts, entity);
|
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete()) {
|
||||||
|
validateOkToDelete(deleteConflicts, entity, true);
|
||||||
|
}
|
||||||
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
|
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
|
||||||
|
|
||||||
OperationOutcome oo = new OperationOutcome();
|
OperationOutcome oo = new OperationOutcome();
|
||||||
|
|
|
@ -36,11 +36,6 @@ public abstract class BaseHasResource {
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
private Date myDeleted;
|
private Date myDeleted;
|
||||||
|
|
||||||
@Column(name = "RES_ENCODING", nullable = false, length = 5)
|
|
||||||
@Enumerated(EnumType.STRING)
|
|
||||||
@OptimisticLock(excluded = true)
|
|
||||||
private ResourceEncodingEnum myEncoding;
|
|
||||||
|
|
||||||
@Column(name = "RES_VERSION", nullable = true, length = 7)
|
@Column(name = "RES_VERSION", nullable = true, length = 7)
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
@OptimisticLock(excluded = true)
|
@OptimisticLock(excluded = true)
|
||||||
|
@ -60,11 +55,6 @@ public abstract class BaseHasResource {
|
||||||
@OptimisticLock(excluded = true)
|
@OptimisticLock(excluded = true)
|
||||||
private Date myPublished;
|
private Date myPublished;
|
||||||
|
|
||||||
@Column(name = "RES_TEXT", length = Integer.MAX_VALUE - 1, nullable = false)
|
|
||||||
@Lob()
|
|
||||||
@OptimisticLock(excluded = true)
|
|
||||||
private byte[] myResource;
|
|
||||||
|
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
@Column(name = "RES_UPDATED", nullable = false)
|
@Column(name = "RES_UPDATED", nullable = false)
|
||||||
@OptimisticLock(excluded = true)
|
@OptimisticLock(excluded = true)
|
||||||
|
@ -80,13 +70,6 @@ public abstract class BaseHasResource {
|
||||||
myDeleted = theDate;
|
myDeleted = theDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceEncodingEnum getEncoding() {
|
|
||||||
return myEncoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEncoding(ResourceEncodingEnum theEncoding) {
|
|
||||||
myEncoding = theEncoding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FhirVersionEnum getFhirVersion() {
|
public FhirVersionEnum getFhirVersion() {
|
||||||
return myFhirVersion;
|
return myFhirVersion;
|
||||||
|
@ -116,16 +99,8 @@ public abstract class BaseHasResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPublished(InstantDt thePublished) {
|
public void setPublished(Date thePublished) {
|
||||||
myPublished = thePublished.getValue();
|
myPublished = thePublished;
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getResource() {
|
|
||||||
return myResource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResource(byte[] theResource) {
|
|
||||||
myResource = theResource;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract String getResourceType();
|
public abstract String getResourceType();
|
||||||
|
@ -136,8 +111,8 @@ public abstract class BaseHasResource {
|
||||||
return new InstantDt(myUpdated);
|
return new InstantDt(myUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUpdated(InstantDt theUpdated) {
|
public void setUpdated(Date theUpdated) {
|
||||||
myUpdated = theUpdated.getValue();
|
myUpdated = theUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getUpdatedDate() {
|
public Date getUpdatedDate() {
|
||||||
|
@ -154,12 +129,12 @@ public abstract class BaseHasResource {
|
||||||
myHasTags = theHasTags;
|
myHasTags = theHasTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPublished(Date thePublished) {
|
public void setPublished(InstantDt thePublished) {
|
||||||
myPublished = thePublished;
|
myPublished = thePublished.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUpdated(Date theUpdated) {
|
public void setUpdated(InstantDt theUpdated) {
|
||||||
myUpdated = theUpdated;
|
myUpdated = theUpdated.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,22 @@ import ca.uhn.fhir.parser.IParser;
|
||||||
|
|
||||||
public enum ResourceEncodingEnum {
|
public enum ResourceEncodingEnum {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NB: Constants in this enum must be 5 chars long or less!!!
|
||||||
|
*
|
||||||
|
* See ResourceHistoryTable RES_ENCODING column
|
||||||
|
*/
|
||||||
|
|
||||||
/** Json */
|
/** Json */
|
||||||
JSON,
|
JSON,
|
||||||
|
|
||||||
/** Json Compressed */
|
/** Json Compressed */
|
||||||
JSONC;
|
JSONC,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource was deleted - No contents expected
|
||||||
|
*/
|
||||||
|
DEL;
|
||||||
|
|
||||||
public IParser newParser(FhirContext theContext) {
|
public IParser newParser(FhirContext theContext) {
|
||||||
return theContext.newJsonParser();
|
return theContext.newJsonParser();
|
||||||
|
|
|
@ -20,23 +20,23 @@ package ca.uhn.fhir.jpa.entity;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import org.hibernate.annotations.OptimisticLock;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "HFJ_RES_VER", uniqueConstraints = {
|
@Table(name = "HFJ_RES_VER", uniqueConstraints = {
|
||||||
@UniqueConstraint(name="IDX_RESVER_ID_VER", columnNames = { "RES_ID", "RES_VER" })
|
@UniqueConstraint(name = "IDX_RESVER_ID_VER", columnNames = {"RES_ID", "RES_VER"})
|
||||||
}, indexes= {
|
}, indexes = {
|
||||||
@Index(name="IDX_RESVER_TYPE_DATE", columnList="RES_TYPE,RES_UPDATED"),
|
@Index(name = "IDX_RESVER_TYPE_DATE", columnList = "RES_TYPE,RES_UPDATED"),
|
||||||
@Index(name="IDX_RESVER_ID_DATE", columnList="RES_ID,RES_UPDATED"),
|
@Index(name = "IDX_RESVER_ID_DATE", columnList = "RES_ID,RES_UPDATED"),
|
||||||
@Index(name="IDX_RESVER_DATE", columnList="RES_UPDATED")
|
@Index(name = "IDX_RESVER_DATE", columnList = "RES_UPDATED")
|
||||||
})
|
})
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
public class ResourceHistoryTable extends BaseHasResource implements Serializable {
|
public class ResourceHistoryTable extends BaseHasResource implements Serializable {
|
||||||
|
@ -61,11 +61,20 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
|
||||||
@OneToMany(mappedBy = "myResourceHistory", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
@OneToMany(mappedBy = "myResourceHistory", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||||
private Collection<ResourceHistoryTag> myTags;
|
private Collection<ResourceHistoryTag> myTags;
|
||||||
|
|
||||||
|
@Column(name = "RES_TEXT", length = Integer.MAX_VALUE - 1, nullable = true)
|
||||||
|
@Lob()
|
||||||
|
@OptimisticLock(excluded = true)
|
||||||
|
private byte[] myResource;
|
||||||
|
|
||||||
|
@Column(name = "RES_ENCODING", nullable = false, length = 5)
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@OptimisticLock(excluded = true)
|
||||||
|
private ResourceEncodingEnum myEncoding;
|
||||||
|
|
||||||
public ResourceHistoryTable() {
|
public ResourceHistoryTable() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addTag(ResourceHistoryTag theTag) {
|
public void addTag(ResourceHistoryTag theTag) {
|
||||||
for (ResourceHistoryTag next : getTags()) {
|
for (ResourceHistoryTag next : getTags()) {
|
||||||
if (next.getTag().equals(theTag)) {
|
if (next.getTag().equals(theTag)) {
|
||||||
|
@ -93,11 +102,23 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
|
||||||
return historyTag;
|
return historyTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ResourceEncodingEnum getEncoding() {
|
||||||
|
return myEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncoding(ResourceEncodingEnum theEncoding) {
|
||||||
|
myEncoding = theEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return myId;
|
return myId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setId(Long theId) {
|
||||||
|
myId = theId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IdDt getIdDt() {
|
public IdDt getIdDt() {
|
||||||
if (getForcedId() == null) {
|
if (getForcedId() == null) {
|
||||||
|
@ -108,15 +129,31 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] getResource() {
|
||||||
|
return myResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResource(byte[] theResource) {
|
||||||
|
myResource = theResource;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getResourceId() {
|
public Long getResourceId() {
|
||||||
return myResourceId;
|
return myResourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setResourceId(Long theResourceId) {
|
||||||
|
myResourceId = theResourceId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getResourceType() {
|
public String getResourceType() {
|
||||||
return myResourceType;
|
return myResourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setResourceType(String theResourceType) {
|
||||||
|
myResourceType = theResourceType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ResourceHistoryTag> getTags() {
|
public Collection<ResourceHistoryTag> getTags() {
|
||||||
if (myTags == null) {
|
if (myTags == null) {
|
||||||
|
@ -130,6 +167,10 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
|
||||||
return myResourceVersion;
|
return myResourceVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setVersion(long theVersion) {
|
||||||
|
myResourceVersion = theVersion;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasTag(String theTerm, String theScheme) {
|
public boolean hasTag(String theTerm, String theScheme) {
|
||||||
for (ResourceHistoryTag next : getTags()) {
|
for (ResourceHistoryTag next : getTags()) {
|
||||||
if (next.getTag().getSystem().equals(theScheme) && next.getTag().getCode().equals(theTerm)) {
|
if (next.getTag().getSystem().equals(theScheme) && next.getTag().getCode().equals(theTerm)) {
|
||||||
|
@ -139,20 +180,4 @@ public class ResourceHistoryTable extends BaseHasResource implements Serializabl
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(Long theId) {
|
|
||||||
myId = theId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResourceId(Long theResourceId) {
|
|
||||||
myResourceId = theResourceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResourceType(String theResourceType) {
|
|
||||||
myResourceType = theResourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVersion(long theVersion) {
|
|
||||||
myResourceVersion = theVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import ca.uhn.fhir.jpa.search.IndexNonDeletedInterceptor;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import org.hibernate.annotations.OptimisticLock;
|
import org.hibernate.annotations.OptimisticLock;
|
||||||
|
@ -39,7 +40,6 @@ import java.util.Set;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||||
|
|
||||||
//@formatter:off
|
|
||||||
@Indexed(interceptor = IndexNonDeletedInterceptor.class)
|
@Indexed(interceptor = IndexNonDeletedInterceptor.class)
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "HFJ_RESOURCE", uniqueConstraints = {}, indexes = {
|
@Table(name = "HFJ_RESOURCE", uniqueConstraints = {}, indexes = {
|
||||||
|
@ -49,13 +49,18 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||||
@Index(name = "IDX_RES_TYPE", columnList = "RES_TYPE"),
|
@Index(name = "IDX_RES_TYPE", columnList = "RES_TYPE"),
|
||||||
@Index(name = "IDX_INDEXSTATUS", columnList = "SP_INDEX_STATUS")
|
@Index(name = "IDX_INDEXSTATUS", columnList = "SP_INDEX_STATUS")
|
||||||
})
|
})
|
||||||
//@formatter:on
|
|
||||||
public class ResourceTable extends BaseHasResource implements Serializable {
|
public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
static final int RESTYPE_LEN = 30;
|
static final int RESTYPE_LEN = 30;
|
||||||
private static final int MAX_LANGUAGE_LENGTH = 20;
|
private static final int MAX_LANGUAGE_LENGTH = 20;
|
||||||
private static final int MAX_PROFILE_LENGTH = 200;
|
private static final int MAX_PROFILE_LENGTH = 200;
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// @Transient
|
||||||
|
// private transient byte[] myResource;
|
||||||
|
//
|
||||||
|
// @Transient
|
||||||
|
// private transient ResourceEncodingEnum myEncoding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the narrative text only - Used for Fulltext searching but not directly stored in the DB
|
* Holds the narrative text only - Used for Fulltext searching but not directly stored in the DB
|
||||||
*/
|
*/
|
||||||
|
@ -214,6 +219,15 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public ResourceEncodingEnum getEncoding() {
|
||||||
|
// Validate.notNull(myEncoding, "myEncoding is null");
|
||||||
|
// return myEncoding;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void setEncoding(ResourceEncodingEnum theEncoding) {
|
||||||
|
// myEncoding = theEncoding;
|
||||||
|
// }
|
||||||
|
|
||||||
public String getHashSha256() {
|
public String getHashSha256() {
|
||||||
return myHashSha256;
|
return myHashSha256;
|
||||||
}
|
}
|
||||||
|
@ -387,6 +401,15 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
myProfile = theProfile;
|
myProfile = theProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public byte[] getResource() {
|
||||||
|
// Validate.notNull(myEncoding, "myEncoding is null");
|
||||||
|
// return myResource;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void setResource(byte[] theResource) {
|
||||||
|
// myResource = theResource;
|
||||||
|
// }
|
||||||
|
|
||||||
public Collection<ResourceLink> getResourceLinks() {
|
public Collection<ResourceLink> getResourceLinks() {
|
||||||
if (myResourceLinks == null) {
|
if (myResourceLinks == null) {
|
||||||
myResourceLinks = new ArrayList<>();
|
myResourceLinks = new ArrayList<>();
|
||||||
|
@ -527,8 +550,8 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
myNarrativeText = theNarrativeText;
|
myNarrativeText = theNarrativeText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceHistoryTable toHistory(ResourceHistoryTable theResourceHistoryTable) {
|
public ResourceHistoryTable toHistory() {
|
||||||
ResourceHistoryTable retVal = theResourceHistoryTable != null ? theResourceHistoryTable : new ResourceHistoryTable();
|
ResourceHistoryTable retVal = new ResourceHistoryTable();
|
||||||
|
|
||||||
retVal.setResourceId(myId);
|
retVal.setResourceId(myId);
|
||||||
retVal.setResourceType(myResourceType);
|
retVal.setResourceType(myResourceType);
|
||||||
|
@ -536,9 +559,9 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
||||||
|
|
||||||
retVal.setPublished(getPublished());
|
retVal.setPublished(getPublished());
|
||||||
retVal.setUpdated(getUpdated());
|
retVal.setUpdated(getUpdated());
|
||||||
retVal.setEncoding(getEncoding());
|
// retVal.setEncoding(getEncoding());
|
||||||
retVal.setFhirVersion(getFhirVersion());
|
retVal.setFhirVersion(getFhirVersion());
|
||||||
retVal.setResource(getResource());
|
// retVal.setResource(getResource());
|
||||||
retVal.setDeleted(getDeleted());
|
retVal.setDeleted(getDeleted());
|
||||||
retVal.setForcedId(getForcedId());
|
retVal.setForcedId(getForcedId());
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.hl7.fhir.dstu3.model.Resource;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
@ -57,6 +58,11 @@ public abstract class BaseJpaTest {
|
||||||
when(mySrd.getUserData()).thenReturn(new HashMap<>());
|
when(mySrd.getUserData()).thenReturn(new HashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public final void afterPerformCleanup() {
|
||||||
|
BaseHapiFhirResourceDao.setDisableIncrementOnUpdateForUnitTest(false);
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract FhirContext getContext();
|
protected abstract FhirContext getContext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,10 +8,13 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallback;
|
import org.springframework.transaction.support.TransactionCallback;
|
||||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
|
@ -24,6 +27,7 @@ import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.param.*;
|
import ca.uhn.fhir.rest.param.*;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
|
public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
|
@ -392,13 +396,14 @@ public class FhirResourceDaoDstu2SearchFtTest extends BaseJpaDstu2Test {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSearchDontReindexForUpdateWithIndexDisabled() {
|
public void testSearchDontReindexForUpdateWithIndexDisabled() {
|
||||||
|
BaseHapiFhirResourceDao.setDisableIncrementOnUpdateForUnitTest(true);
|
||||||
Patient patient;
|
Patient patient;
|
||||||
SearchParameterMap map;
|
SearchParameterMap map;
|
||||||
|
|
||||||
patient = new Patient();
|
patient = new Patient();
|
||||||
patient.getText().setDiv("<div>DIVAAA</div>");
|
patient.getText().setDiv("<div>DIVAAA</div>");
|
||||||
patient.addName().addGiven("NAMEAAA");
|
patient.addName().addGiven("NAMEAAA");
|
||||||
IIdType pId1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
final IIdType pId1 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
||||||
|
|
|
@ -45,41 +45,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2Test.class);
|
||||||
|
|
||||||
@Before
|
|
||||||
public void beforeDisableResultReuse() {
|
|
||||||
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public final void after() {
|
public final void after() {
|
||||||
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
||||||
myDaoConfig.setTreatReferencesAsLogical(new DaoConfig().getTreatReferencesAsLogical());
|
myDaoConfig.setTreatReferencesAsLogical(new DaoConfig().getTreatReferencesAsLogical());
|
||||||
|
myDaoConfig.setEnforceReferentialIntegrityOnDelete(new DaoConfig().isEnforceReferentialIntegrityOnDelete());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* See #773
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testDeleteResourceWithOutboundDeletedResources() {
|
|
||||||
myDaoConfig.setEnforceReferentialIntegrityOnDelete(false);
|
|
||||||
|
|
||||||
Organization org = new Organization();
|
|
||||||
org.setId("ORG");
|
|
||||||
org.setName("ORG");
|
|
||||||
myOrganizationDao.update(org);
|
|
||||||
|
|
||||||
Patient pat = new Patient();
|
|
||||||
pat.setId("PAT");
|
|
||||||
pat.setActive(true);
|
|
||||||
pat.setManagingOrganization(new ResourceReferenceDt("Organization/ORG"));
|
|
||||||
myPatientDao.update(pat);
|
|
||||||
|
|
||||||
myOrganizationDao.delete(new IdDt("Organization/ORG"));
|
|
||||||
|
|
||||||
myPatientDao.delete(new IdDt("Patient/PAT"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void assertGone(IIdType theId) {
|
private void assertGone(IIdType theId) {
|
||||||
try {
|
try {
|
||||||
assertNotGone(theId);
|
assertNotGone(theId);
|
||||||
|
@ -102,6 +74,11 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeDisableResultReuse() {
|
||||||
|
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
|
||||||
|
}
|
||||||
|
|
||||||
private List<String> extractNames(IBundleProvider theSearch) {
|
private List<String> extractNames(IBundleProvider theSearch) {
|
||||||
ArrayList<String> retVal = new ArrayList<String>();
|
ArrayList<String> retVal = new ArrayList<String>();
|
||||||
for (IBaseResource next : theSearch.getResources(0, theSearch.size())) {
|
for (IBaseResource next : theSearch.getResources(0, theSearch.size())) {
|
||||||
|
@ -865,6 +842,29 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #773
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDeleteResourceWithOutboundDeletedResources() {
|
||||||
|
myDaoConfig.setEnforceReferentialIntegrityOnDelete(false);
|
||||||
|
|
||||||
|
Organization org = new Organization();
|
||||||
|
org.setId("ORG");
|
||||||
|
org.setName("ORG");
|
||||||
|
myOrganizationDao.update(org);
|
||||||
|
|
||||||
|
Patient pat = new Patient();
|
||||||
|
pat.setId("PAT");
|
||||||
|
pat.setActive(true);
|
||||||
|
pat.setManagingOrganization(new ResourceReferenceDt("Organization/ORG"));
|
||||||
|
myPatientDao.update(pat);
|
||||||
|
|
||||||
|
myOrganizationDao.delete(new IdDt("Organization/ORG"));
|
||||||
|
|
||||||
|
myPatientDao.delete(new IdDt("Patient/PAT"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteThenUndelete() {
|
public void testDeleteThenUndelete() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
|
|
@ -134,78 +134,6 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReindexing() {
|
|
||||||
Patient p = new Patient();
|
|
||||||
p.addName().addFamily("family");
|
|
||||||
final IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
|
|
||||||
|
|
||||||
ValueSet vs = new ValueSet();
|
|
||||||
vs.setUrl("http://foo");
|
|
||||||
myValueSetDao.create(vs, mySrd);
|
|
||||||
|
|
||||||
ResourceTable entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
|
||||||
@Override
|
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
|
||||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertEquals(Long.valueOf(1), entity.getIndexStatus());
|
|
||||||
|
|
||||||
mySystemDao.markAllResourcesForReindexing();
|
|
||||||
|
|
||||||
entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
|
||||||
@Override
|
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
|
||||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertEquals(null, entity.getIndexStatus());
|
|
||||||
|
|
||||||
mySystemDao.performReindexingPass(null);
|
|
||||||
|
|
||||||
entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
|
||||||
@Override
|
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
|
||||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertEquals(Long.valueOf(1), entity.getIndexStatus());
|
|
||||||
|
|
||||||
// Just make sure this doesn't cause a choke
|
|
||||||
mySystemDao.performReindexingPass(100000);
|
|
||||||
|
|
||||||
// Try making the resource unparseable
|
|
||||||
|
|
||||||
TransactionTemplate template = new TransactionTemplate(myTxManager);
|
|
||||||
template.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
|
||||||
template.execute(new TransactionCallback<ResourceTable>() {
|
|
||||||
@Override
|
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
|
||||||
ResourceTable table = myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
|
||||||
table.setEncoding(ResourceEncodingEnum.JSON);
|
|
||||||
table.setIndexStatus(null);
|
|
||||||
try {
|
|
||||||
table.setResource("{\"resourceType\":\"FOO\"}".getBytes("UTF-8"));
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
myEntityManager.merge(table);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mySystemDao.performReindexingPass(null);
|
|
||||||
|
|
||||||
entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
|
||||||
@Override
|
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
|
||||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertEquals(Long.valueOf(2), entity.getIndexStatus());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSystemMetaOperation() {
|
public void testSystemMetaOperation() {
|
||||||
|
|
|
@ -8,6 +8,8 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import org.hl7.fhir.dstu3.model.*;
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
|
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
@ -19,6 +21,9 @@ import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.param.*;
|
import ca.uhn.fhir.rest.param.*;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
|
@ -473,13 +478,14 @@ public class FhirResourceDaoDstu3SearchFtTest extends BaseJpaDstu3Test {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSearchDontReindexForUpdateWithIndexDisabled() {
|
public void testSearchDontReindexForUpdateWithIndexDisabled() {
|
||||||
|
BaseHapiFhirResourceDao.setDisableIncrementOnUpdateForUnitTest(true);
|
||||||
Patient patient;
|
Patient patient;
|
||||||
SearchParameterMap map;
|
SearchParameterMap map;
|
||||||
|
|
||||||
patient = new Patient();
|
patient = new Patient();
|
||||||
patient.getText().setDivAsString("<div>DIVAAA</div>");
|
patient.getText().setDivAsString("<div>DIVAAA</div>");
|
||||||
patient.addName().addGiven("NAMEAAA");
|
patient.addName().addGiven("NAMEAAA");
|
||||||
IIdType pId1 = myPatientDao.create(patient, mockSrd()).getId().toUnqualifiedVersionless();
|
final IIdType pId1 = myPatientDao.create(patient, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
||||||
|
|
|
@ -2508,36 +2508,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Can we handle content that was previously saved containing vocabulary that
|
|
||||||
* is no longer valid
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testResourceInDatabaseContainsInvalidVocabulary() {
|
|
||||||
final Patient p = new Patient();
|
|
||||||
p.setGender(AdministrativeGender.MALE);
|
|
||||||
final IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
|
||||||
|
|
||||||
TransactionTemplate tx = new TransactionTemplate(myTxManager);
|
|
||||||
tx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
|
||||||
tx.execute(new TransactionCallbackWithoutResult() {
|
|
||||||
@Override
|
|
||||||
protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
|
|
||||||
ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());
|
|
||||||
String newContent = myFhirCtx.newJsonParser().encodeResourceToString(p);
|
|
||||||
newContent = newContent.replace("male", "foo");
|
|
||||||
table.setResource(newContent.getBytes(Charsets.UTF_8));
|
|
||||||
table.setEncoding(ResourceEncodingEnum.JSON);
|
|
||||||
myResourceTableDao.save(table);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Patient read = myPatientDao.read(id);
|
|
||||||
String string = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(read);
|
|
||||||
ourLog.info(string);
|
|
||||||
assertThat(string, containsString("value=\"foo\""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResourceInstanceMetaOperation() {
|
public void testResourceInstanceMetaOperation() {
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@ package ca.uhn.fhir.jpa.dao.dstu3;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceEncodingEnum;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
||||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||||
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
||||||
|
@ -26,15 +24,12 @@ import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.springframework.transaction.TransactionDefinition;
|
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallback;
|
|
||||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -444,79 +439,6 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReindexing() {
|
|
||||||
Patient p = new Patient();
|
|
||||||
p.addName().setFamily("family");
|
|
||||||
final IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
|
|
||||||
|
|
||||||
ValueSet vs = new ValueSet();
|
|
||||||
vs.setUrl("http://foo");
|
|
||||||
myValueSetDao.create(vs, mySrd);
|
|
||||||
|
|
||||||
ResourceTable entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
|
||||||
@Override
|
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
|
||||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertEquals(Long.valueOf(1), entity.getIndexStatus());
|
|
||||||
|
|
||||||
mySystemDao.markAllResourcesForReindexing();
|
|
||||||
|
|
||||||
entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
|
||||||
@Override
|
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
|
||||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertEquals(null, entity.getIndexStatus());
|
|
||||||
|
|
||||||
mySystemDao.performReindexingPass(null);
|
|
||||||
|
|
||||||
entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
|
||||||
@Override
|
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
|
||||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertEquals(Long.valueOf(1), entity.getIndexStatus());
|
|
||||||
|
|
||||||
// Just make sure this doesn't cause a choke
|
|
||||||
mySystemDao.performReindexingPass(100000);
|
|
||||||
|
|
||||||
// Try making the resource unparseable
|
|
||||||
|
|
||||||
TransactionTemplate template = new TransactionTemplate(myTxManager);
|
|
||||||
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
|
||||||
template.execute(new TransactionCallback<ResourceTable>() {
|
|
||||||
@Override
|
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
|
||||||
ResourceTable table = myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
|
||||||
table.setEncoding(ResourceEncodingEnum.JSON);
|
|
||||||
table.setIndexStatus(null);
|
|
||||||
try {
|
|
||||||
table.setResource("{\"resourceType\":\"FOO\"}".getBytes("UTF-8"));
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
myEntityManager.merge(table);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mySystemDao.performReindexingPass(null);
|
|
||||||
|
|
||||||
entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
|
||||||
@Override
|
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
|
||||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
assertEquals(Long.valueOf(2), entity.getIndexStatus());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSystemMetaOperation() {
|
public void testSystemMetaOperation() {
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,8 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
protected IResourceTableDao myResourceTableDao;
|
protected IResourceTableDao myResourceTableDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
protected IResourceHistoryTableDao myResourceHistoryTableDao;
|
||||||
|
@Autowired
|
||||||
protected IResourceTagDao myResourceTagDao;
|
protected IResourceTagDao myResourceTagDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected ISearchCoordinatorSvc mySearchCoordinatorSvc;
|
protected ISearchCoordinatorSvc mySearchCoordinatorSvc;
|
||||||
|
@ -234,6 +236,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
|
||||||
@After()
|
@After()
|
||||||
public void afterCleanupDao() {
|
public void afterCleanupDao() {
|
||||||
myDaoConfig.setExpireSearchResults(new DaoConfig().isExpireSearchResults());
|
myDaoConfig.setExpireSearchResults(new DaoConfig().isExpireSearchResults());
|
||||||
|
myDaoConfig.setEnforceReferentialIntegrityOnDelete(new DaoConfig().isEnforceReferentialIntegrityOnDelete());
|
||||||
myDaoConfig.setExpireSearchResultsAfterMillis(new DaoConfig().getExpireSearchResultsAfterMillis());
|
myDaoConfig.setExpireSearchResultsAfterMillis(new DaoConfig().getExpireSearchResultsAfterMillis());
|
||||||
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
|
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
|
||||||
myDaoConfig.setSuppressUpdatesWithNoChange(new DaoConfig().isSuppressUpdatesWithNoChange());
|
myDaoConfig.setSuppressUpdatesWithNoChange(new DaoConfig().isSuppressUpdatesWithNoChange());
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class FhirResourceDaoR4CreateTest extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionCreateWithUuidResourceStrategy() throws Exception {
|
public void testTransactionCreateWithUuidResourceStrategy() {
|
||||||
myDaoConfig.setResourceServerIdStrategy(DaoConfig.IdStrategyEnum.UUID);
|
myDaoConfig.setResourceServerIdStrategy(DaoConfig.IdStrategyEnum.UUID);
|
||||||
|
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
|
|
|
@ -8,6 +8,8 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import org.hl7.fhir.r4.model.*;
|
import org.hl7.fhir.r4.model.*;
|
||||||
import org.hl7.fhir.r4.model.Observation.ObservationStatus;
|
import org.hl7.fhir.r4.model.Observation.ObservationStatus;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
@ -19,6 +21,9 @@ import ca.uhn.fhir.rest.api.Constants;
|
||||||
import ca.uhn.fhir.rest.param.*;
|
import ca.uhn.fhir.rest.param.*;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
|
public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
|
||||||
|
|
||||||
|
@ -488,13 +493,14 @@ public class FhirResourceDaoR4SearchFtTest extends BaseJpaR4Test {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSearchDontReindexForUpdateWithIndexDisabled() {
|
public void testSearchDontReindexForUpdateWithIndexDisabled() {
|
||||||
|
BaseHapiFhirResourceDao.setDisableIncrementOnUpdateForUnitTest(true);
|
||||||
Patient patient;
|
Patient patient;
|
||||||
SearchParameterMap map;
|
SearchParameterMap map;
|
||||||
|
|
||||||
patient = new Patient();
|
patient = new Patient();
|
||||||
patient.getText().setDivAsString("<div>DIVAAA</div>");
|
patient.getText().setDivAsString("<div>DIVAAA</div>");
|
||||||
patient.addName().addGiven("NAMEAAA");
|
patient.addName().addGiven("NAMEAAA");
|
||||||
IIdType pId1 = myPatientDao.create(patient, mockSrd()).getId().toUnqualifiedVersionless();
|
final IIdType pId1 = myPatientDao.create(patient, mockSrd()).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
map = new SearchParameterMap();
|
map = new SearchParameterMap();
|
||||||
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
map.add(Constants.PARAM_CONTENT, new StringParam("NAMEAAA"));
|
||||||
|
|
|
@ -1108,9 +1108,52 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteTwicePerformsNoOp() {
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.setActive(true);
|
||||||
|
|
||||||
|
IIdType id = myPatientDao.create(patient, mySrd).getId();
|
||||||
|
assertNotNull(id.getIdPartAsLong());
|
||||||
|
assertEquals("1", id.getVersionIdPart());
|
||||||
|
|
||||||
|
IIdType id2 = myPatientDao.delete(id.toUnqualifiedVersionless()).getId();
|
||||||
|
assertEquals(id.getIdPart(), id2.getIdPart());
|
||||||
|
assertEquals("2", id2.getVersionIdPart());
|
||||||
|
|
||||||
|
IIdType id3 = myPatientDao.delete(id.toUnqualifiedVersionless()).getId();
|
||||||
|
assertEquals(id.getIdPart(), id3.getIdPart());
|
||||||
|
assertEquals("2", id3.getVersionIdPart());
|
||||||
|
|
||||||
|
IIdType id4 = myPatientDao.delete(id.toUnqualifiedVersionless()).getId();
|
||||||
|
assertEquals(id.getIdPart(), id4.getIdPart());
|
||||||
|
assertEquals("2", id4.getVersionIdPart());
|
||||||
|
|
||||||
|
patient = new Patient();
|
||||||
|
patient.setId(id.getIdPart());
|
||||||
|
patient.setActive(false);
|
||||||
|
IIdType id5 = myPatientDao.update(patient).getId();
|
||||||
|
assertEquals(id.getIdPart(), id5.getIdPart());
|
||||||
|
assertEquals("3", id5.getVersionIdPart());
|
||||||
|
|
||||||
|
patient = myPatientDao.read(id.withVersion("1"));
|
||||||
|
assertEquals(true, patient.getActive());
|
||||||
|
|
||||||
|
try {
|
||||||
|
myPatientDao.read(id.withVersion("2"));
|
||||||
|
fail();
|
||||||
|
} catch (ResourceGoneException e) {
|
||||||
|
// good
|
||||||
|
}
|
||||||
|
|
||||||
|
patient = myPatientDao.read(id.withVersion("3"));
|
||||||
|
assertEquals(false, patient.getActive());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteResource() {
|
public void testDeleteResource() {
|
||||||
int initialHistory = myPatientDao.history((Date) null, null, mySrd).size();
|
int initialHistory = myPatientDao.history(null, null, mySrd).size();
|
||||||
|
|
||||||
IIdType id1;
|
IIdType id1;
|
||||||
IIdType id2;
|
IIdType id2;
|
||||||
|
@ -1132,7 +1175,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
patient.addIdentifier().setSystem("ZZZZZZZ").setValue("ZZZZZZZZZ");
|
patient.addIdentifier().setSystem("ZZZZZZZ").setValue("ZZZZZZZZZ");
|
||||||
id2b = myPatientDao.update(patient, mySrd).getId();
|
id2b = myPatientDao.update(patient, mySrd).getId();
|
||||||
}
|
}
|
||||||
ourLog.info("ID1:{} ID2:{} ID2b:{}", new Object[] { id1, id2, id2b });
|
ourLog.info("ID1:{} ID2:{} ID2b:{}", id1, id2, id2b);
|
||||||
|
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.setLoadSynchronous(true);
|
params.setLoadSynchronous(true);
|
||||||
|
@ -1153,7 +1196,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
// good
|
// good
|
||||||
}
|
}
|
||||||
|
|
||||||
IBundleProvider history = myPatientDao.history((Date) null, null, mySrd);
|
IBundleProvider history = myPatientDao.history(null, null, mySrd);
|
||||||
assertEquals(4 + initialHistory, history.size().intValue());
|
assertEquals(4 + initialHistory, history.size().intValue());
|
||||||
List<IBaseResource> resources = history.getResources(0, 4);
|
List<IBaseResource> resources = history.getResources(0, 4);
|
||||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IAnyResource) resources.get(0)));
|
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IAnyResource) resources.get(0)));
|
||||||
|
@ -1525,7 +1568,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
// By type
|
// By type
|
||||||
history = myPatientDao.history((Date) null, null, mySrd);
|
history = myPatientDao.history(null, null, mySrd);
|
||||||
assertEquals(fullSize + 1, history.size().intValue());
|
assertEquals(fullSize + 1, history.size().intValue());
|
||||||
for (int i = 0; i < fullSize; i++) {
|
for (int i = 0; i < fullSize; i++) {
|
||||||
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
|
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
|
||||||
|
@ -1592,7 +1635,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
// By type
|
// By type
|
||||||
history = myPatientDao.history((Date) null, null, mySrd);
|
history = myPatientDao.history(null, null, mySrd);
|
||||||
assertEquals(fullSize + 1, history.size().intValue());
|
assertEquals(fullSize + 1, history.size().intValue());
|
||||||
for (int i = 0; i < fullSize; i++) {
|
for (int i = 0; i < fullSize; i++) {
|
||||||
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
|
String expected = id.withVersion(Integer.toString(fullSize + 1 - i)).getValue();
|
||||||
|
@ -1643,13 +1686,13 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHistoryReflectsMetaOperations() throws Exception {
|
public void testHistoryReflectsMetaOperations() {
|
||||||
Patient inPatient = new Patient();
|
Patient inPatient = new Patient();
|
||||||
inPatient.addName().setFamily("version1");
|
inPatient.addName().setFamily("version1");
|
||||||
inPatient.getMeta().addProfile("http://example.com/1");
|
inPatient.getMeta().addProfile("http://example.com/1");
|
||||||
IIdType id = myPatientDao.create(inPatient, mySrd).getId().toUnqualifiedVersionless();
|
IIdType id = myPatientDao.create(inPatient, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
IBundleProvider history = myPatientDao.history((Date) null, null, mySrd);
|
IBundleProvider history = myPatientDao.history(null, null, mySrd);
|
||||||
assertEquals(1, history.size().intValue());
|
assertEquals(1, history.size().intValue());
|
||||||
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
|
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
|
||||||
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
||||||
|
@ -1663,7 +1706,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
inPatient.getMeta().addProfile("http://example.com/2");
|
inPatient.getMeta().addProfile("http://example.com/2");
|
||||||
myPatientDao.metaAddOperation(id, inPatient.getMeta(), mySrd);
|
myPatientDao.metaAddOperation(id, inPatient.getMeta(), mySrd);
|
||||||
|
|
||||||
history = myPatientDao.history((Date) null, null, mySrd);
|
history = myPatientDao.history(null, null, mySrd);
|
||||||
assertEquals(1, history.size().intValue());
|
assertEquals(1, history.size().intValue());
|
||||||
outPatient = (Patient) history.getResources(0, 1).get(0);
|
outPatient = (Patient) history.getResources(0, 1).get(0);
|
||||||
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
||||||
|
@ -1679,7 +1722,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
inPatient.getName().get(0).setFamily("version2");
|
inPatient.getName().get(0).setFamily("version2");
|
||||||
myPatientDao.update(inPatient, mySrd);
|
myPatientDao.update(inPatient, mySrd);
|
||||||
|
|
||||||
history = myPatientDao.history((Date) null, null, mySrd);
|
history = myPatientDao.history(null, null, mySrd);
|
||||||
assertEquals(2, history.size().intValue());
|
assertEquals(2, history.size().intValue());
|
||||||
outPatient = (Patient) history.getResources(0, 2).get(0);
|
outPatient = (Patient) history.getResources(0, 2).get(0);
|
||||||
assertEquals("version2", outPatient.getName().get(0).getFamily());
|
assertEquals("version2", outPatient.getName().get(0).getFamily());
|
||||||
|
@ -1694,7 +1737,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHistoryWithDeletedResource() throws Exception {
|
public void testHistoryWithDeletedResource() {
|
||||||
String methodName = "testHistoryWithDeletedResource";
|
String methodName = "testHistoryWithDeletedResource";
|
||||||
|
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -1707,9 +1750,9 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
IBundleProvider history = myPatientDao.history(id, null, null, mySrd);
|
IBundleProvider history = myPatientDao.history(id, null, null, mySrd);
|
||||||
List<IBaseResource> entries = history.getResources(0, 3);
|
List<IBaseResource> entries = history.getResources(0, 3);
|
||||||
ourLog.info(((IAnyResource) entries.get(0)).getIdElement() + " - " + ((IAnyResource) entries.get(0)).getMeta().getLastUpdated());
|
ourLog.info(entries.get(0).getIdElement() + " - " + entries.get(0).getMeta().getLastUpdated());
|
||||||
ourLog.info(((IAnyResource) entries.get(1)).getIdElement() + " - " + ((IAnyResource) entries.get(1)).getMeta().getLastUpdated());
|
ourLog.info(entries.get(1).getIdElement() + " - " + entries.get(1).getMeta().getLastUpdated());
|
||||||
ourLog.info(((IAnyResource) entries.get(2)).getIdElement() + " - " + ((IAnyResource) entries.get(2)).getMeta().getLastUpdated());
|
ourLog.info(entries.get(2).getIdElement() + " - " + entries.get(2).getMeta().getLastUpdated());
|
||||||
assertEquals(3, history.size().intValue());
|
assertEquals(3, history.size().intValue());
|
||||||
|
|
||||||
assertEquals(id.withVersion("3"), entries.get(0).getIdElement());
|
assertEquals(id.withVersion("3"), entries.get(0).getIdElement());
|
||||||
|
@ -1773,7 +1816,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
// No since
|
// No since
|
||||||
|
|
||||||
IBundleProvider history = myPatientDao.history((Date) null, null, mySrd);
|
IBundleProvider history = myPatientDao.history(null, null, mySrd);
|
||||||
assertEquals(1, history.size().intValue());
|
assertEquals(1, history.size().intValue());
|
||||||
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
|
Patient outPatient = (Patient) history.getResources(0, 1).get(0);
|
||||||
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
assertEquals("version1", inPatient.getName().get(0).getFamily());
|
||||||
|
@ -1797,7 +1840,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHistoryWithInvalidId() throws Exception {
|
public void testHistoryWithInvalidId() {
|
||||||
try {
|
try {
|
||||||
myPatientDao.history(new IdType("Patient/FOOFOOFOO"), null, null, mySrd);
|
myPatientDao.history(new IdType("Patient/FOOFOOFOO"), null, null, mySrd);
|
||||||
fail();
|
fail();
|
||||||
|
@ -2175,7 +2218,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
dr01.setSubject(new Reference(patientId01));
|
dr01.setSubject(new Reference(patientId01));
|
||||||
IIdType drId01 = myDiagnosticReportDao.create(dr01, mySrd).getId();
|
IIdType drId01 = myDiagnosticReportDao.create(dr01, mySrd).getId();
|
||||||
|
|
||||||
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
|
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", patientId01, patientId02, obsId01, obsId02, drId01);
|
||||||
|
|
||||||
List<Observation> result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam(patientId01.getIdPart())).setLoadSynchronous(true)));
|
List<Observation> result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam(patientId01.getIdPart())).setLoadSynchronous(true)));
|
||||||
assertEquals(1, result.size());
|
assertEquals(1, result.size());
|
||||||
|
@ -2185,7 +2228,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
assertEquals(1, result.size());
|
assertEquals(1, result.size());
|
||||||
assertEquals(obsId02.getIdPart(), result.get(0).getIdElement().getIdPart());
|
assertEquals(obsId02.getIdPart(), result.get(0).getIdElement().getIdPart());
|
||||||
|
|
||||||
result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam("999999999999")).setLoadSynchronous(true)));;
|
result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam("999999999999")).setLoadSynchronous(true)));
|
||||||
assertEquals(0, result.size());
|
assertEquals(0, result.size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2268,7 +2311,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
long id = outcome.getId().getIdPartAsLong();
|
long id = outcome.getId().getIdPartAsLong();
|
||||||
|
|
||||||
TokenParam value = new TokenParam("urn:system", "001testPersistSearchParams");
|
TokenParam value = new TokenParam("urn:system", "001testPersistSearchParams");
|
||||||
List<Patient> found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_IDENTIFIER, value).setLoadSynchronous(true)));;
|
List<Patient> found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_IDENTIFIER, value).setLoadSynchronous(true)));
|
||||||
assertEquals(1, found.size());
|
assertEquals(1, found.size());
|
||||||
assertEquals(id, found.get(0).getIdElement().getIdPartAsLong().longValue());
|
assertEquals(id, found.get(0).getIdElement().getIdPartAsLong().longValue());
|
||||||
|
|
||||||
|
@ -2380,7 +2423,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadInvalidVersion() throws Exception {
|
public void testReadInvalidVersion() {
|
||||||
String methodName = "testReadInvalidVersion";
|
String methodName = "testReadInvalidVersion";
|
||||||
|
|
||||||
Patient pat = new Patient();
|
Patient pat = new Patient();
|
||||||
|
@ -2565,12 +2608,12 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
tx.execute(new TransactionCallbackWithoutResult() {
|
tx.execute(new TransactionCallbackWithoutResult() {
|
||||||
@Override
|
@Override
|
||||||
protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
|
protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
|
||||||
ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());
|
ResourceHistoryTable table = myResourceHistoryTableDao.findForIdAndVersion(id.getIdPartAsLong(), 1L);
|
||||||
String newContent = myFhirCtx.newJsonParser().encodeResourceToString(p);
|
String newContent = myFhirCtx.newJsonParser().encodeResourceToString(p);
|
||||||
newContent = newContent.replace("male", "foo");
|
newContent = newContent.replace("male", "foo");
|
||||||
table.setResource(newContent.getBytes(Charsets.UTF_8));
|
table.setResource(newContent.getBytes(Charsets.UTF_8));
|
||||||
table.setEncoding(ResourceEncodingEnum.JSON);
|
table.setEncoding(ResourceEncodingEnum.JSON);
|
||||||
myResourceTableDao.save(table);
|
myResourceHistoryTableDao.save(table);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2592,7 +2635,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
id1 = myPatientDao.create(patient, mySrd).getId();
|
id1 = myPatientDao.create(patient, mySrd).getId();
|
||||||
|
|
||||||
Meta metaAdd = new Meta();
|
Meta metaAdd = new Meta();
|
||||||
metaAdd.addTag().setSystem((String) null).setCode("Dog").setDisplay("Puppies");
|
metaAdd.addTag().setSystem(null).setCode("Dog").setDisplay("Puppies");
|
||||||
metaAdd.addSecurity().setSystem("seclabel:sys:1").setCode("seclabel:code:1").setDisplay("seclabel:dis:1");
|
metaAdd.addSecurity().setSystem("seclabel:sys:1").setCode("seclabel:code:1").setDisplay("seclabel:dis:1");
|
||||||
metaAdd.addProfile("http://profile/1");
|
metaAdd.addProfile("http://profile/1");
|
||||||
myPatientDao.metaAddOperation(id1, metaAdd, mySrd);
|
myPatientDao.metaAddOperation(id1, metaAdd, mySrd);
|
||||||
|
@ -2662,7 +2705,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
{
|
{
|
||||||
Meta metaDel = new Meta();
|
Meta metaDel = new Meta();
|
||||||
metaDel.addTag().setSystem((String) null).setCode("Dog");
|
metaDel.addTag().setSystem(null).setCode("Dog");
|
||||||
metaDel.addSecurity().setSystem("seclabel:sys:1").setCode("seclabel:code:1");
|
metaDel.addSecurity().setSystem("seclabel:sys:1").setCode("seclabel:code:1");
|
||||||
metaDel.addProfile("http://profile/1");
|
metaDel.addProfile("http://profile/1");
|
||||||
myPatientDao.metaDeleteOperation(id1, metaDel, mySrd);
|
myPatientDao.metaDeleteOperation(id1, metaDel, mySrd);
|
||||||
|
@ -3387,7 +3430,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
* Test for issue #60
|
* Test for issue #60
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testStoreUtf8Characters() throws Exception {
|
public void testStoreUtf8Characters() {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName("測試醫院");
|
org.setName("測試醫院");
|
||||||
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
|
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
|
||||||
|
@ -3547,7 +3590,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTimingSearchParams() throws Exception {
|
public void testTimingSearchParams() {
|
||||||
Date before = new DateTimeType("2011-01-01T10:00:00Z").getValue();
|
Date before = new DateTimeType("2011-01-01T10:00:00Z").getValue();
|
||||||
Date middle = new DateTimeType("2011-01-02T10:00:00Z").getValue();
|
Date middle = new DateTimeType("2011-01-02T10:00:00Z").getValue();
|
||||||
Date after = new DateTimeType("2011-01-03T10:00:00Z").getValue();
|
Date after = new DateTimeType("2011-01-03T10:00:00Z").getValue();
|
||||||
|
@ -3613,7 +3656,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateRejectsIdWhichPointsToForcedId() throws InterruptedException {
|
public void testUpdateRejectsIdWhichPointsToForcedId() {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsIdWhichPointsToForcedId01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsIdWhichPointsToForcedId01");
|
||||||
p1.addName().setFamily("Tester").addGiven("testUpdateRejectsIdWhichPointsToForcedId01");
|
p1.addName().setFamily("Tester").addGiven("testUpdateRejectsIdWhichPointsToForcedId01");
|
||||||
|
|
|
@ -270,6 +270,46 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateForDeleteWithReferentialIntegrityDisabled() {
|
||||||
|
myDaoConfig.setEnforceReferentialIntegrityOnDelete(false);
|
||||||
|
String methodName = "testValidateForDelete";
|
||||||
|
|
||||||
|
Organization org = new Organization();
|
||||||
|
org.setName(methodName);
|
||||||
|
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
Patient pat = new Patient();
|
||||||
|
pat.addName().setFamily(methodName);
|
||||||
|
pat.getManagingOrganization().setReference(orgId.getValue());
|
||||||
|
IIdType patId = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
myOrganizationDao.validate(null, orgId, null, null, ValidationModeEnum.DELETE, null, mySrd);
|
||||||
|
|
||||||
|
myDaoConfig.setEnforceReferentialIntegrityOnDelete(true);
|
||||||
|
try {
|
||||||
|
myOrganizationDao.validate(null, orgId, null, null, ValidationModeEnum.DELETE, null, mySrd);
|
||||||
|
fail();
|
||||||
|
} catch (ResourceVersionConflictException e) {
|
||||||
|
// good
|
||||||
|
}
|
||||||
|
|
||||||
|
myDaoConfig.setEnforceReferentialIntegrityOnDelete(false);
|
||||||
|
|
||||||
|
|
||||||
|
myOrganizationDao.read(orgId);
|
||||||
|
|
||||||
|
myOrganizationDao.delete(orgId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
myOrganizationDao.read(orgId);
|
||||||
|
fail();
|
||||||
|
} catch (ResourceGoneException e) {
|
||||||
|
// good
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private IBaseResource findResourceByIdInBundle(Bundle vss, String name) {
|
private IBaseResource findResourceByIdInBundle(Bundle vss, String name) {
|
||||||
IBaseResource retVal = null;
|
IBaseResource retVal = null;
|
||||||
for (BundleEntryComponent next : vss.getEntry()) {
|
for (BundleEntryComponent next : vss.getEntry()) {
|
||||||
|
|
|
@ -3,10 +3,8 @@ package ca.uhn.fhir.jpa.dao.r4;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceEncodingEnum;
|
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.entity.*;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
|
||||||
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
@ -26,6 +24,7 @@ import org.hl7.fhir.r4.model.Observation.ObservationStatus;
|
||||||
import org.hl7.fhir.r4.model.OperationOutcome.IssueSeverity;
|
import org.hl7.fhir.r4.model.OperationOutcome.IssueSeverity;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.transaction.TransactionDefinition;
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallback;
|
import org.springframework.transaction.support.TransactionCallback;
|
||||||
|
@ -443,7 +442,7 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
|
||||||
public void testReindexing() {
|
public void testReindexing() {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addName().setFamily("family");
|
p.addName().setFamily("family");
|
||||||
final IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
|
final IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualified();
|
||||||
|
|
||||||
ValueSet vs = new ValueSet();
|
ValueSet vs = new ValueSet();
|
||||||
vs.setUrl("http://foo");
|
vs.setUrl("http://foo");
|
||||||
|
@ -487,15 +486,19 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
|
||||||
template.execute(new TransactionCallback<ResourceTable>() {
|
template.execute(new TransactionCallback<ResourceTable>() {
|
||||||
@Override
|
@Override
|
||||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
||||||
ResourceTable table = myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
ResourceHistoryTable resourceHistoryTable = myResourceHistoryTableDao.findForIdAndVersion(id.getIdPartAsLong(), id.getVersionIdPartAsLong());
|
||||||
table.setEncoding(ResourceEncodingEnum.JSON);
|
resourceHistoryTable.setEncoding(ResourceEncodingEnum.JSON);
|
||||||
table.setIndexStatus(null);
|
|
||||||
try {
|
try {
|
||||||
table.setResource("{\"resourceType\":\"FOO\"}".getBytes("UTF-8"));
|
resourceHistoryTable.setResource("{\"resourceType\":\"FOO\"}".getBytes("UTF-8"));
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new Error(e);
|
throw new Error(e);
|
||||||
}
|
}
|
||||||
myEntityManager.merge(table);
|
myResourceHistoryTableDao.save(resourceHistoryTable);
|
||||||
|
|
||||||
|
ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());
|
||||||
|
table.setIndexStatus(null);
|
||||||
|
myResourceTableDao.save(table);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,45 +1,48 @@
|
||||||
package ca.uhn.fhir.jpa.provider;
|
package ca.uhn.fhir.jpa.provider;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
|
||||||
import org.junit.*;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.dstu2.BaseJpaDstu2Test;
|
import ca.uhn.fhir.jpa.dao.dstu2.BaseJpaDstu2Test;
|
||||||
import ca.uhn.fhir.jpa.rp.dstu2.*;
|
import ca.uhn.fhir.jpa.rp.dstu2.ObservationResourceProvider;
|
||||||
|
import ca.uhn.fhir.jpa.rp.dstu2.OrganizationResourceProvider;
|
||||||
|
import ca.uhn.fhir.jpa.rp.dstu2.PatientResourceProvider;
|
||||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.*;
|
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||||
|
import ca.uhn.fhir.model.dstu2.valueset.BundleTypeEnum;
|
||||||
|
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
import ca.uhn.fhir.rest.client.interceptor.SimpleRequestHeaderInterceptor;
|
import ca.uhn.fhir.rest.client.interceptor.SimpleRequestHeaderInterceptor;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class SystemProviderTransactionSearchDstu2Test extends BaseJpaDstu2Test {
|
public class SystemProviderTransactionSearchDstu2Test extends BaseJpaDstu2Test {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SystemProviderTransactionSearchDstu2Test.class);
|
||||||
private static RestfulServer myRestServer;
|
private static RestfulServer myRestServer;
|
||||||
private static IGenericClient ourClient;
|
private static IGenericClient ourClient;
|
||||||
private static FhirContext ourCtx;
|
private static FhirContext ourCtx;
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SystemProviderTransactionSearchDstu2Test.class);
|
|
||||||
private static Server ourServer;
|
private static Server ourServer;
|
||||||
private static String ourServerBase;
|
private static String ourServerBase;
|
||||||
private SimpleRequestHeaderInterceptor mySimpleHeaderInterceptor;
|
private SimpleRequestHeaderInterceptor mySimpleHeaderInterceptor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@After
|
@After
|
||||||
public void after() {
|
public void after() {
|
||||||
|
@ -108,7 +111,7 @@ public class SystemProviderTransactionSearchDstu2Test extends BaseJpaDstu2Test {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.setGender(AdministrativeGenderEnum.MALE);
|
patient.setGender(AdministrativeGenderEnum.MALE);
|
||||||
patient.addIdentifier().setSystem("urn:foo").setValue("A");
|
patient.addIdentifier().setSystem("urn:foo").setValue("A");
|
||||||
patient.addName().addFamily("abcdefghijklmnopqrstuvwxyz".substring(i, i+1));
|
patient.addName().addFamily("abcdefghijklmnopqrstuvwxyz".substring(i, i + 1));
|
||||||
String id = myPatientDao.create(patient).getId().toUnqualifiedVersionless().getValue();
|
String id = myPatientDao.create(patient).getId().toUnqualifiedVersionless().getValue();
|
||||||
ids.add(id);
|
ids.add(id);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +119,7 @@ public class SystemProviderTransactionSearchDstu2Test extends BaseJpaDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBatchWithGetHardLimitLargeSynchronous() throws Exception {
|
public void testBatchWithGetHardLimitLargeSynchronous() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -141,7 +144,7 @@ public class SystemProviderTransactionSearchDstu2Test extends BaseJpaDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBatchWithGetNormalSearch() throws Exception {
|
public void testBatchWithGetNormalSearch() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -173,7 +176,7 @@ public class SystemProviderTransactionSearchDstu2Test extends BaseJpaDstu2Test {
|
||||||
* 30 searches in one batch! Whoa!
|
* 30 searches in one batch! Whoa!
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBatchWithManyGets() throws Exception {
|
public void testBatchWithManyGets() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,7 +204,7 @@ public class SystemProviderTransactionSearchDstu2Test extends BaseJpaDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionWithGetHardLimitLargeSynchronous() throws Exception {
|
public void testTransactionWithGetHardLimitLargeSynchronous() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -210,7 +213,7 @@ public class SystemProviderTransactionSearchDstu2Test extends BaseJpaDstu2Test {
|
||||||
.addEntry()
|
.addEntry()
|
||||||
.getRequest()
|
.getRequest()
|
||||||
.setMethod(HTTPVerbEnum.GET)
|
.setMethod(HTTPVerbEnum.GET)
|
||||||
.setUrl("Patient?_count=5");
|
.setUrl("Patient?_count=5&_sort=_id");
|
||||||
|
|
||||||
myDaoConfig.setMaximumSearchResultCountInTransaction(100);
|
myDaoConfig.setMaximumSearchResultCountInTransaction(100);
|
||||||
|
|
||||||
|
@ -226,7 +229,7 @@ public class SystemProviderTransactionSearchDstu2Test extends BaseJpaDstu2Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionWithGetNormalSearch() throws Exception {
|
public void testTransactionWithGetNormalSearch() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -258,7 +261,7 @@ public class SystemProviderTransactionSearchDstu2Test extends BaseJpaDstu2Test {
|
||||||
* 30 searches in one Transaction! Whoa!
|
* 30 searches in one Transaction! Whoa!
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionWithManyGets() throws Exception {
|
public void testTransactionWithManyGets() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ public class SystemProviderTransactionSearchDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBatchWithGetHardLimitLargeSynchronous() throws Exception {
|
public void testBatchWithGetHardLimitLargeSynchronous() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -135,7 +135,7 @@ public class SystemProviderTransactionSearchDstu3Test extends BaseJpaDstu3Test {
|
||||||
.addEntry()
|
.addEntry()
|
||||||
.getRequest()
|
.getRequest()
|
||||||
.setMethod(HTTPVerb.GET)
|
.setMethod(HTTPVerb.GET)
|
||||||
.setUrl("Patient?_count=5");
|
.setUrl("Patient?_count=5&_sort=_id");
|
||||||
|
|
||||||
myDaoConfig.setMaximumSearchResultCountInTransaction(100);
|
myDaoConfig.setMaximumSearchResultCountInTransaction(100);
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ public class SystemProviderTransactionSearchDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBatchWithGetNormalSearch() throws Exception {
|
public void testBatchWithGetNormalSearch() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -183,7 +183,7 @@ public class SystemProviderTransactionSearchDstu3Test extends BaseJpaDstu3Test {
|
||||||
* 30 searches in one batch! Whoa!
|
* 30 searches in one batch! Whoa!
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBatchWithManyGets() throws Exception {
|
public void testBatchWithManyGets() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ public class SystemProviderTransactionSearchDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionWithGetHardLimitLargeSynchronous() throws Exception {
|
public void testTransactionWithGetHardLimitLargeSynchronous() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -220,7 +220,7 @@ public class SystemProviderTransactionSearchDstu3Test extends BaseJpaDstu3Test {
|
||||||
.addEntry()
|
.addEntry()
|
||||||
.getRequest()
|
.getRequest()
|
||||||
.setMethod(HTTPVerb.GET)
|
.setMethod(HTTPVerb.GET)
|
||||||
.setUrl("Patient?_count=5");
|
.setUrl("Patient?_count=5&_sort=_id");
|
||||||
|
|
||||||
myDaoConfig.setMaximumSearchResultCountInTransaction(100);
|
myDaoConfig.setMaximumSearchResultCountInTransaction(100);
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ public class SystemProviderTransactionSearchDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionWithGetNormalSearch() throws Exception {
|
public void testTransactionWithGetNormalSearch() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -268,7 +268,7 @@ public class SystemProviderTransactionSearchDstu3Test extends BaseJpaDstu3Test {
|
||||||
* 30 searches in one Transaction! Whoa!
|
* 30 searches in one Transaction! Whoa!
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionWithManyGets() throws Exception {
|
public void testTransactionWithManyGets() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.provider.r4;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.config.TestR4Config;
|
import ca.uhn.fhir.jpa.config.TestR4Config;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
|
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
|
||||||
import ca.uhn.fhir.jpa.entity.Search;
|
import ca.uhn.fhir.jpa.entity.Search;
|
||||||
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
|
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
|
||||||
import ca.uhn.fhir.jpa.util.StopWatch;
|
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||||
|
@ -54,6 +55,8 @@ import org.junit.*;
|
||||||
import org.springframework.test.util.AopTestUtils;
|
import org.springframework.test.util.AopTestUtils;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallback;
|
import org.springframework.transaction.support.TransactionCallback;
|
||||||
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -1642,31 +1645,6 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void delete(String theResourceType, String theParamName, String theParamValue) {
|
|
||||||
// Bundle resources;
|
|
||||||
// do {
|
|
||||||
// IQuery<Bundle> forResource = myClient.search().forResource(theResourceType);
|
|
||||||
// if (theParamName != null) {
|
|
||||||
// forResource = forResource.where(new StringClientParam(theParamName).matches().value(theParamValue));
|
|
||||||
// }
|
|
||||||
// resources = forResource.execute();
|
|
||||||
// for (IResource next : resources.toListOfResources()) {
|
|
||||||
// ourLog.info("Deleting resource: {}", next.getId());
|
|
||||||
// myClient.delete().resource(next).execute();
|
|
||||||
// }
|
|
||||||
// } while (resources.size() > 0);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue)
|
|
||||||
// {
|
|
||||||
// Bundle resources = myClient.search().forResource(theResourceType).where(new
|
|
||||||
// TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
|
|
||||||
// for (IResource next : resources.toListOfResources()) {
|
|
||||||
// ourLog.info("Deleting resource: {}", next.getId());
|
|
||||||
// myClient.delete().resource(next).execute();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHasParameter() throws Exception {
|
public void testHasParameter() throws Exception {
|
||||||
IIdType pid0;
|
IIdType pid0;
|
||||||
|
@ -1704,6 +1682,31 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
assertThat(ids, contains(pid0.getValue()));
|
assertThat(ids, contains(pid0.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private void delete(String theResourceType, String theParamName, String theParamValue) {
|
||||||
|
// Bundle resources;
|
||||||
|
// do {
|
||||||
|
// IQuery<Bundle> forResource = myClient.search().forResource(theResourceType);
|
||||||
|
// if (theParamName != null) {
|
||||||
|
// forResource = forResource.where(new StringClientParam(theParamName).matches().value(theParamValue));
|
||||||
|
// }
|
||||||
|
// resources = forResource.execute();
|
||||||
|
// for (IResource next : resources.toListOfResources()) {
|
||||||
|
// ourLog.info("Deleting resource: {}", next.getId());
|
||||||
|
// myClient.delete().resource(next).execute();
|
||||||
|
// }
|
||||||
|
// } while (resources.size() > 0);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue)
|
||||||
|
// {
|
||||||
|
// Bundle resources = myClient.search().forResource(theResourceType).where(new
|
||||||
|
// TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
|
||||||
|
// for (IResource next : resources.toListOfResources()) {
|
||||||
|
// ourLog.info("Deleting resource: {}", next.getId());
|
||||||
|
// myClient.delete().resource(next).execute();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHasParameterNoResults() throws Exception {
|
public void testHasParameterNoResults() throws Exception {
|
||||||
|
|
||||||
|
@ -2347,6 +2350,54 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRetrieveMissingVersionsDoesntCrashSearch() {
|
||||||
|
Patient p1 = new Patient();
|
||||||
|
p1.setActive(true);
|
||||||
|
final IIdType id1 = myClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
|
Patient p2 = new Patient();
|
||||||
|
p2.setActive(false);
|
||||||
|
IIdType id2 = myClient.create().resource(p2).execute().getId();
|
||||||
|
|
||||||
|
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||||
|
@Override
|
||||||
|
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||||
|
ResourceHistoryTable version = myResourceHistoryTableDao.findForIdAndVersion(id1.getIdPartAsLong(), 1);
|
||||||
|
myResourceHistoryTableDao.delete(version);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Bundle bundle = myClient.search().forResource("Patient").returnBundle(Bundle.class).execute();
|
||||||
|
assertEquals(2, bundle.getTotal());
|
||||||
|
assertEquals(1, bundle.getEntry().size());
|
||||||
|
assertEquals(id2.getIdPart(), bundle.getEntry().get(0).getResource().getIdElement().getIdPart());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRetrieveMissingVersionsDoesntCrashHistory() {
|
||||||
|
Patient p1 = new Patient();
|
||||||
|
p1.setActive(true);
|
||||||
|
final IIdType id1 = myClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
|
Patient p2 = new Patient();
|
||||||
|
p2.setActive(false);
|
||||||
|
IIdType id2 = myClient.create().resource(p2).execute().getId();
|
||||||
|
|
||||||
|
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||||
|
@Override
|
||||||
|
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||||
|
ResourceHistoryTable version = myResourceHistoryTableDao.findForIdAndVersion(id1.getIdPartAsLong(), 1);
|
||||||
|
myResourceHistoryTableDao.delete(version);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Bundle bundle = myClient.history().onServer().andReturnBundle(Bundle.class).execute();
|
||||||
|
assertEquals(1, bundle.getTotal());
|
||||||
|
assertEquals(1, bundle.getEntry().size());
|
||||||
|
assertEquals(id2.getIdPart(), bundle.getEntry().get(0).getResource().getIdElement().getIdPart());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSaveAndRetrieveExistingNarrativeJson() {
|
public void testSaveAndRetrieveExistingNarrativeJson() {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
|
|
|
@ -33,11 +33,11 @@ import ca.uhn.fhir.util.TestUtil;
|
||||||
|
|
||||||
public class SystemProviderTransactionSearchR4Test extends BaseJpaR4Test {
|
public class SystemProviderTransactionSearchR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SystemProviderTransactionSearchR4Test.class);
|
||||||
private static RestfulServer myRestServer;
|
private static RestfulServer myRestServer;
|
||||||
private static IGenericClient ourClient;
|
private static IGenericClient ourClient;
|
||||||
private static FhirContext ourCtx;
|
private static FhirContext ourCtx;
|
||||||
private static CloseableHttpClient ourHttpClient;
|
private static CloseableHttpClient ourHttpClient;
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SystemProviderTransactionSearchR4Test.class);
|
|
||||||
private static Server ourServer;
|
private static Server ourServer;
|
||||||
private static String ourServerBase;
|
private static String ourServerBase;
|
||||||
private SimpleRequestHeaderInterceptor mySimpleHeaderInterceptor;
|
private SimpleRequestHeaderInterceptor mySimpleHeaderInterceptor;
|
||||||
|
@ -116,17 +116,19 @@ public class SystemProviderTransactionSearchR4Test extends BaseJpaR4Test {
|
||||||
List<String> ids = new ArrayList<String>();
|
List<String> ids = new ArrayList<String>();
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
char letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(i);
|
||||||
|
patient.setId("" + letter);
|
||||||
patient.setGender(AdministrativeGender.MALE);
|
patient.setGender(AdministrativeGender.MALE);
|
||||||
patient.addIdentifier().setSystem("urn:foo").setValue("A");
|
patient.addIdentifier().setSystem("urn:foo").setValue("A");
|
||||||
patient.addName().setFamily("abcdefghijklmnopqrstuvwxyz".substring(i, i+1));
|
patient.addName().setFamily("abcdefghijklmnopqrstuvwxyz".substring(i, i+1));
|
||||||
String id = myPatientDao.create(patient).getId().toUnqualifiedVersionless().getValue();
|
String id = myPatientDao.update(patient).getId().toUnqualifiedVersionless().getValue();
|
||||||
ids.add(id);
|
ids.add(id);
|
||||||
}
|
}
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBatchWithGetHardLimitLargeSynchronous() throws Exception {
|
public void testBatchWithGetHardLimitLargeSynchronous() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -135,7 +137,7 @@ public class SystemProviderTransactionSearchR4Test extends BaseJpaR4Test {
|
||||||
.addEntry()
|
.addEntry()
|
||||||
.getRequest()
|
.getRequest()
|
||||||
.setMethod(HTTPVerb.GET)
|
.setMethod(HTTPVerb.GET)
|
||||||
.setUrl("Patient?_count=5");
|
.setUrl("Patient?_count=5&_sort=_id");
|
||||||
|
|
||||||
myDaoConfig.setMaximumSearchResultCountInTransaction(100);
|
myDaoConfig.setMaximumSearchResultCountInTransaction(100);
|
||||||
|
|
||||||
|
@ -151,7 +153,7 @@ public class SystemProviderTransactionSearchR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBatchWithGetNormalSearch() throws Exception {
|
public void testBatchWithGetNormalSearch() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -183,7 +185,7 @@ public class SystemProviderTransactionSearchR4Test extends BaseJpaR4Test {
|
||||||
* 30 searches in one batch! Whoa!
|
* 30 searches in one batch! Whoa!
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBatchWithManyGets() throws Exception {
|
public void testBatchWithManyGets() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,7 +213,7 @@ public class SystemProviderTransactionSearchR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionWithGetHardLimitLargeSynchronous() throws Exception {
|
public void testTransactionWithGetHardLimitLargeSynchronous() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -220,7 +222,7 @@ public class SystemProviderTransactionSearchR4Test extends BaseJpaR4Test {
|
||||||
.addEntry()
|
.addEntry()
|
||||||
.getRequest()
|
.getRequest()
|
||||||
.setMethod(HTTPVerb.GET)
|
.setMethod(HTTPVerb.GET)
|
||||||
.setUrl("Patient?_count=5");
|
.setUrl("Patient?_count=5&_sort=_id");
|
||||||
|
|
||||||
myDaoConfig.setMaximumSearchResultCountInTransaction(100);
|
myDaoConfig.setMaximumSearchResultCountInTransaction(100);
|
||||||
|
|
||||||
|
@ -236,7 +238,7 @@ public class SystemProviderTransactionSearchR4Test extends BaseJpaR4Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionWithGetNormalSearch() throws Exception {
|
public void testTransactionWithGetNormalSearch() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
Bundle input = new Bundle();
|
Bundle input = new Bundle();
|
||||||
|
@ -268,7 +270,7 @@ public class SystemProviderTransactionSearchR4Test extends BaseJpaR4Test {
|
||||||
* 30 searches in one Transaction! Whoa!
|
* 30 searches in one Transaction! Whoa!
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionWithManyGets() throws Exception {
|
public void testTransactionWithManyGets() {
|
||||||
List<String> ids = create20Patients();
|
List<String> ids = create20Patients();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.util.CollectionUtil;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
|
@ -308,6 +309,29 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove any null entries in the list - This generally shouldn't happen but can if
|
||||||
|
* data has been manually purged from the JPA database
|
||||||
|
*/
|
||||||
|
boolean hasNull = false;
|
||||||
|
for (IBaseResource next : resourceList) {
|
||||||
|
if (next == null) {
|
||||||
|
hasNull = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasNull) {
|
||||||
|
for (Iterator<IBaseResource> iter = resourceList.iterator(); iter.hasNext(); ) {
|
||||||
|
if (iter.next() == null) {
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure all returned resources have an ID (if not, this is a bug
|
||||||
|
* in the user server code)
|
||||||
|
*/
|
||||||
for (IBaseResource next : resourceList) {
|
for (IBaseResource next : resourceList) {
|
||||||
if (next.getIdElement() == null || next.getIdElement().isEmpty()) {
|
if (next.getIdElement() == null || next.getIdElement().isEmpty()) {
|
||||||
if (!(next instanceof BaseOperationOutcome)) {
|
if (!(next instanceof BaseOperationOutcome)) {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
|
|
||||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
|
<level>INFO</level>
|
||||||
|
</filter>
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%file:%line] - %msg%n
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%file:%line] %msg%n</pattern>
|
||||||
</pattern>
|
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
|
|
8
pom.xml
8
pom.xml
|
@ -1026,6 +1026,14 @@
|
||||||
<build>
|
<build>
|
||||||
<pluginManagement>
|
<pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.gemnasium</groupId>
|
||||||
|
<artifactId>gemnasium-maven-plugin</artifactId>
|
||||||
|
<version>0.2.0</version>
|
||||||
|
<configuration>
|
||||||
|
<projectSlug>github.com/jamesagnew/hapi-fhir</projectSlug>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.basepom.maven</groupId>
|
<groupId>org.basepom.maven</groupId>
|
||||||
<artifactId>duplicate-finder-maven-plugin</artifactId>
|
<artifactId>duplicate-finder-maven-plugin</artifactId>
|
||||||
|
|
|
@ -86,6 +86,12 @@
|
||||||
DSTU3/R4 structure in the getMeta() version field instead of in the
|
DSTU3/R4 structure in the getMeta() version field instead of in the
|
||||||
getIdElement() ID. Thanks to GitHub user @Chrisjobling for reporting!
|
getIdElement() ID. Thanks to GitHub user @Chrisjobling for reporting!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
A bug was fixed in the JPA server when performing a validate operation with a mode
|
||||||
|
of DELETE on a server with referential integrity disabled, the validate operation would delete
|
||||||
|
resource reference indexes as though the delete was actually happening, which negatively
|
||||||
|
affected searching for the resource being validated.
|
||||||
|
</action>
|
||||||
<action type="add">
|
<action type="add">
|
||||||
The HAPI FHIR Server framework now has initial support for
|
The HAPI FHIR Server framework now has initial support for
|
||||||
multitenancy. At this time the support is limited to the server
|
multitenancy. At this time the support is limited to the server
|
||||||
|
|
|
@ -19,6 +19,15 @@
|
||||||
and support for draft pre-release versions of FHIR are shown in
|
and support for draft pre-release versions of FHIR are shown in
|
||||||
<span style="background: #EEB; padding: 3px;">YELLOW</span>.
|
<span style="background: #EEB; padding: 3px;">YELLOW</span>.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
Note also that after the release of the FHIR DSTU2 specification, the FHIR
|
||||||
|
standard itself stopped using the DSTUx naming scheme, in favour or naming
|
||||||
|
new releases STUx or simply Rx. Because HAPI FHIR already had draft support
|
||||||
|
for what was then called DSTU3 at this time, we did not update our naming
|
||||||
|
conventions until R4 in order to avoid breaking existing users' code.
|
||||||
|
From the perspective of a user of HAPI FHIR, consider the terms
|
||||||
|
DSTU3 / STU3 / R3 to be interchangeable.
|
||||||
|
</p>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
Loading…
Reference in New Issue