Correctly Expand ValueSets in non-lucene mode (#1573)
This commit is contained in:
commit
cacd243a44
|
@ -424,13 +424,13 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
|
|
||||||
private void logConceptsExpanded(String theLogDescriptionPrefix, TermValueSet theTermValueSet, int theConceptsExpanded) {
|
private void logConceptsExpanded(String theLogDescriptionPrefix, TermValueSet theTermValueSet, int theConceptsExpanded) {
|
||||||
if (theConceptsExpanded > 0) {
|
if (theConceptsExpanded > 0) {
|
||||||
ourLog.info("{}Have expanded {} concepts in ValueSet[{}]", theLogDescriptionPrefix, theConceptsExpanded, theTermValueSet.getUrl());
|
ourLog.debug("{}Have expanded {} concepts in ValueSet[{}]", theLogDescriptionPrefix, theConceptsExpanded, theTermValueSet.getUrl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logDesignationsExpanded(String theLogDescriptionPrefix, TermValueSet theTermValueSet, int theDesignationsExpanded) {
|
private void logDesignationsExpanded(String theLogDescriptionPrefix, TermValueSet theTermValueSet, int theDesignationsExpanded) {
|
||||||
if (theDesignationsExpanded > 0) {
|
if (theDesignationsExpanded > 0) {
|
||||||
ourLog.info("{}Have expanded {} designations in ValueSet[{}]", theLogDescriptionPrefix, theDesignationsExpanded, theTermValueSet.getUrl());
|
ourLog.debug("{}Have expanded {} designations in ValueSet[{}]", theLogDescriptionPrefix, theDesignationsExpanded, theTermValueSet.getUrl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
|
|
||||||
StopWatch sw = new StopWatch();
|
StopWatch sw = new StopWatch();
|
||||||
String valueSetInfo = getValueSetInfo(theValueSetToExpand);
|
String valueSetInfo = getValueSetInfo(theValueSetToExpand);
|
||||||
ourLog.info("Working with {}", valueSetInfo);
|
ourLog.debug("Working with {}", valueSetInfo);
|
||||||
|
|
||||||
// Handle includes
|
// Handle includes
|
||||||
ourLog.debug("Handling includes");
|
ourLog.debug("Handling includes");
|
||||||
|
@ -488,7 +488,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
myTxTemplate.execute(t -> ((ValueSetConceptAccumulator) theValueSetCodeAccumulator).removeGapsFromConceptOrder());
|
myTxTemplate.execute(t -> ((ValueSetConceptAccumulator) theValueSetCodeAccumulator).removeGapsFromConceptOrder());
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Done working with {} in {}ms", valueSetInfo, sw.getMillis());
|
ourLog.debug("Done working with {} in {}ms", valueSetInfo, sw.getMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getValueSetInfo(ValueSet theValueSet) {
|
private String getValueSetInfo(ValueSet theValueSet) {
|
||||||
|
@ -553,7 +553,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Starting {} expansion around CodeSystem: {}", (theAdd ? "inclusion" : "exclusion"), system);
|
ourLog.debug("Starting {} expansion around CodeSystem: {}", (theAdd ? "inclusion" : "exclusion"), system);
|
||||||
|
|
||||||
TermCodeSystem cs = myCodeSystemDao.findByCodeSystemUri(system);
|
TermCodeSystem cs = myCodeSystemDao.findByCodeSystemUri(system);
|
||||||
if (cs != null) {
|
if (cs != null) {
|
||||||
|
@ -566,7 +566,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
* since we're going to do it without the database.
|
* since we're going to do it without the database.
|
||||||
*/
|
*/
|
||||||
if (myFulltextSearchSvc == null) {
|
if (myFulltextSearchSvc == null) {
|
||||||
expandWithoutHibernateSearch(theValueSetCodeAccumulator, theAddedCodes, theIncludeOrExclude, system, theAdd, theCodeCounter);
|
expandWithoutHibernateSearch(theValueSetCodeAccumulator, csv, theAddedCodes, theIncludeOrExclude, system, theAdd, theCodeCounter);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,7 +642,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
jpaQuery.setMaxResults(maxResultsPerBatch);
|
jpaQuery.setMaxResults(maxResultsPerBatch);
|
||||||
jpaQuery.setFirstResult(theQueryIndex * maxResultsPerBatch);
|
jpaQuery.setFirstResult(theQueryIndex * maxResultsPerBatch);
|
||||||
|
|
||||||
ourLog.info("Beginning batch expansion for {} with max results per batch: {}", (theAdd ? "inclusion" : "exclusion"), maxResultsPerBatch);
|
ourLog.debug("Beginning batch expansion for {} with max results per batch: {}", (theAdd ? "inclusion" : "exclusion"), maxResultsPerBatch);
|
||||||
|
|
||||||
StopWatch swForBatch = new StopWatch();
|
StopWatch swForBatch = new StopWatch();
|
||||||
AtomicInteger countForBatch = new AtomicInteger(0);
|
AtomicInteger countForBatch = new AtomicInteger(0);
|
||||||
|
@ -661,10 +661,10 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Batch expansion for {} with starting index of {} produced {} results in {}ms", (theAdd ? "inclusion" : "exclusion"), firstResult, countForBatch, swForBatch.getMillis());
|
ourLog.debug("Batch expansion for {} with starting index of {} produced {} results in {}ms", (theAdd ? "inclusion" : "exclusion"), firstResult, countForBatch, swForBatch.getMillis());
|
||||||
|
|
||||||
if (resultsInBatch < maxResultsPerBatch) {
|
if (resultsInBatch < maxResultsPerBatch) {
|
||||||
ourLog.info("Expansion for {} produced {} results in {}ms", (theAdd ? "inclusion" : "exclusion"), count, sw.getMillis());
|
ourLog.debug("Expansion for {} produced {} results in {}ms", (theAdd ? "inclusion" : "exclusion"), count, sw.getMillis());
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
@ -712,7 +712,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
} else if (hasValueSet) {
|
} else if (hasValueSet) {
|
||||||
|
|
||||||
for (CanonicalType nextValueSet : theIncludeOrExclude.getValueSet()) {
|
for (CanonicalType nextValueSet : theIncludeOrExclude.getValueSet()) {
|
||||||
ourLog.info("Starting {} expansion around ValueSet: {}", (theAdd ? "inclusion" : "exclusion"), nextValueSet.getValueAsString());
|
ourLog.debug("Starting {} expansion around ValueSet: {}", (theAdd ? "inclusion" : "exclusion"), nextValueSet.getValueAsString());
|
||||||
|
|
||||||
List<VersionIndependentConcept> expanded = expandValueSet(nextValueSet.getValueAsString());
|
List<VersionIndependentConcept> expanded = expandValueSet(nextValueSet.getValueAsString());
|
||||||
Map<String, TermCodeSystem> uriToCodeSystem = new HashMap<>();
|
Map<String, TermCodeSystem> uriToCodeSystem = new HashMap<>();
|
||||||
|
@ -848,7 +848,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
.orElseThrow(() -> new InvalidRequestException("Invalid filter criteria - code does not exist: {" + theSystem + "}" + theFilter.getValue()));
|
.orElseThrow(() -> new InvalidRequestException("Invalid filter criteria - code does not exist: {" + theSystem + "}" + theFilter.getValue()));
|
||||||
|
|
||||||
if (theFilter.getOp() == ValueSet.FilterOperator.ISA) {
|
if (theFilter.getOp() == ValueSet.FilterOperator.ISA) {
|
||||||
ourLog.info(" * Filtering on codes with a parent of {}/{}/{}", code.getId(), code.getCode(), code.getDisplay());
|
ourLog.debug(" * Filtering on codes with a parent of {}/{}/{}", code.getId(), code.getCode(), code.getDisplay());
|
||||||
theBool.must(theQb.keyword().onField("myParentPids").matching("" + code.getId()).createQuery());
|
theBool.must(theQb.keyword().onField("myParentPids").matching("" + code.getId()).createQuery());
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidRequestException("Don't know how to handle op=" + theFilter.getOp() + " on property " + theFilter.getProperty());
|
throw new InvalidRequestException("Don't know how to handle op=" + theFilter.getOp() + " on property " + theFilter.getProperty());
|
||||||
|
@ -1015,7 +1015,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logFilteringValueOnProperty(String theValue, String theProperty) {
|
private void logFilteringValueOnProperty(String theValue, String theProperty) {
|
||||||
ourLog.info(" * Filtering with value={} on property {}", theValue, theProperty);
|
ourLog.debug(" * Filtering with value={} on property {}", theValue, theProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void throwInvalidRequestForOpOnProperty(ValueSet.FilterOperator theOp, String theProperty) {
|
private void throwInvalidRequestForOpOnProperty(ValueSet.FilterOperator theOp, String theProperty) {
|
||||||
|
@ -1060,7 +1060,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expandWithoutHibernateSearch(IValueSetConceptAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theInclude, String theSystem, boolean theAdd, AtomicInteger theCodeCounter) {
|
private void expandWithoutHibernateSearch(IValueSetConceptAccumulator theValueSetCodeAccumulator, TermCodeSystemVersion theVersion, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theInclude, String theSystem, boolean theAdd, AtomicInteger theCodeCounter) {
|
||||||
ourLog.trace("Hibernate search is not enabled");
|
ourLog.trace("Hibernate search is not enabled");
|
||||||
if (theValueSetCodeAccumulator instanceof ValueSetExpansionComponentWithConceptAccumulator) {
|
if (theValueSetCodeAccumulator instanceof ValueSetExpansionComponentWithConceptAccumulator) {
|
||||||
Validate.isTrue(((ValueSetExpansionComponentWithConceptAccumulator) theValueSetCodeAccumulator).getParameter().isEmpty(), "Can not expand ValueSet with parameters - Hibernate Search is not enabled on this server.");
|
Validate.isTrue(((ValueSetExpansionComponentWithConceptAccumulator) theValueSetCodeAccumulator).getParameter().isEmpty(), "Can not expand ValueSet with parameters - Hibernate Search is not enabled on this server.");
|
||||||
|
@ -1068,12 +1068,21 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
Validate.isTrue(theInclude.getFilter().isEmpty(), "Can not expand ValueSet with filters - Hibernate Search is not enabled on this server.");
|
Validate.isTrue(theInclude.getFilter().isEmpty(), "Can not expand ValueSet with filters - Hibernate Search is not enabled on this server.");
|
||||||
Validate.isTrue(isNotBlank(theSystem), "Can not expand ValueSet without explicit system - Hibernate Search is not enabled on this server.");
|
Validate.isTrue(isNotBlank(theSystem), "Can not expand ValueSet without explicit system - Hibernate Search is not enabled on this server.");
|
||||||
|
|
||||||
|
|
||||||
|
if (theInclude.getConcept().isEmpty()) {
|
||||||
|
for (TermConcept next : theVersion.getConcepts()) {
|
||||||
|
addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, null, theAdd, theCodeCounter, theSystem, next.getCode(), next.getDisplay());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (ValueSet.ConceptReferenceComponent next : theInclude.getConcept()) {
|
for (ValueSet.ConceptReferenceComponent next : theInclude.getConcept()) {
|
||||||
if (!theSystem.equals(theInclude.getSystem())) {
|
if (!theSystem.equals(theInclude.getSystem())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, null, theAdd, theCodeCounter, theSystem, next.getCode(), next.getDisplay());
|
addCodeIfNotAlreadyAdded(theValueSetCodeAccumulator, theAddedCodes, null, theAdd, theCodeCounter, theSystem, next.getCode(), next.getDisplay());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1215,7 +1224,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
|
|
||||||
fetchParents(concept.get(), retVal);
|
fetchParents(concept.get(), retVal);
|
||||||
|
|
||||||
ourLog.info("Fetched {} codes above code {} in {}ms", retVal.size(), theCode, stopwatch.getMillis());
|
ourLog.debug("Fetched {} codes above code {} in {}ms", retVal.size(), theCode, stopwatch.getMillis());
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,7 +1255,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
|
|
||||||
fetchChildren(concept.get(), retVal);
|
fetchChildren(concept.get(), retVal);
|
||||||
|
|
||||||
ourLog.info("Fetched {} codes below code {} in {}ms", retVal.size(), theCode, stopwatch.elapsed(TimeUnit.MILLISECONDS));
|
ourLog.debug("Fetched {} codes below code {} in {}ms", retVal.size(), theCode, stopwatch.elapsed(TimeUnit.MILLISECONDS));
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1295,7 +1304,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc, ApplicationCo
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void storeTermConceptMapAndChildren(ResourceTable theResourceTable, ConceptMap theConceptMap) {
|
public void storeTermConceptMapAndChildren(ResourceTable theResourceTable, ConceptMap theConceptMap) {
|
||||||
ourLog.info("Storing TermConceptMap for {}", theConceptMap.getIdElement().toVersionless().getValueAsString());
|
ourLog.debug("Storing TermConceptMap for {}", theConceptMap.getIdElement().toVersionless().getValueAsString());
|
||||||
|
|
||||||
ValidateUtil.isTrueOrThrowInvalidRequest(theResourceTable != null, "No resource supplied");
|
ValidateUtil.isTrueOrThrowInvalidRequest(theResourceTable != null, "No resource supplied");
|
||||||
ValidateUtil.isNotBlankOrThrowUnprocessableEntity(theConceptMap.getUrl(), "ConceptMap has no value for ConceptMap.url");
|
ValidateUtil.isNotBlankOrThrowUnprocessableEntity(theConceptMap.getUrl(), "ConceptMap has no value for ConceptMap.url");
|
||||||
|
|
|
@ -335,7 +335,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
populateCodeSystemVersionProperties(persCs, theCodeSystem, theResourceEntity);
|
populateCodeSystemVersionProperties(persCs, theCodeSystem, theResourceEntity);
|
||||||
|
|
||||||
persCs.getConcepts().addAll(BaseTermReadSvcImpl.toPersistedConcepts(theCodeSystem.getConcept(), persCs));
|
persCs.getConcepts().addAll(BaseTermReadSvcImpl.toPersistedConcepts(theCodeSystem.getConcept(), persCs));
|
||||||
ourLog.info("Code system has {} concepts", persCs.getConcepts().size());
|
ourLog.debug("Code system has {} concepts", persCs.getConcepts().size());
|
||||||
storeNewCodeSystemVersion(codeSystemResourcePid, codeSystemUrl, theCodeSystem.getName(), theCodeSystem.getVersion(), persCs, theResourceEntity);
|
storeNewCodeSystemVersion(codeSystemResourcePid, codeSystemUrl, theCodeSystem.getName(), theCodeSystem.getVersion(), persCs, theResourceEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
@Override
|
@Override
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
public void storeNewCodeSystemVersion(Long theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable) {
|
public void storeNewCodeSystemVersion(Long theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable) {
|
||||||
ourLog.info("Storing code system");
|
ourLog.debug("Storing code system");
|
||||||
|
|
||||||
ValidateUtil.isTrueOrThrowInvalidRequest(theCodeSystemVersion.getResource() != null, "No resource supplied");
|
ValidateUtil.isTrueOrThrowInvalidRequest(theCodeSystemVersion.getResource() != null, "No resource supplied");
|
||||||
ValidateUtil.isNotBlankOrThrowInvalidRequest(theSystemUri, "No system URI supplied");
|
ValidateUtil.isNotBlankOrThrowInvalidRequest(theSystemUri, "No system URI supplied");
|
||||||
|
@ -378,15 +378,15 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
* For now we always delete old versions. At some point it would be nice to allow configuration to keep old versions.
|
* For now we always delete old versions. At some point it would be nice to allow configuration to keep old versions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ourLog.info("Deleting old code system versions");
|
|
||||||
for (TermCodeSystemVersion next : existing) {
|
for (TermCodeSystemVersion next : existing) {
|
||||||
|
ourLog.info("Deleting old code system version {}", next.getPid());
|
||||||
Long codeSystemVersionPid = next.getPid();
|
Long codeSystemVersionPid = next.getPid();
|
||||||
deleteCodeSystemVersion(codeSystemVersionPid);
|
deleteCodeSystemVersion(codeSystemVersionPid);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Flushing...");
|
ourLog.debug("Flushing...");
|
||||||
myConceptDao.flush();
|
myConceptDao.flush();
|
||||||
ourLog.info("Done flushing");
|
ourLog.debug("Done flushing");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the upload
|
* Do the upload
|
||||||
|
@ -399,7 +399,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
theCodeSystemVersion.setCodeSystemDisplayName(theSystemName);
|
theCodeSystemVersion.setCodeSystemDisplayName(theSystemName);
|
||||||
theCodeSystemVersion.setCodeSystemVersionId(theSystemVersionId);
|
theCodeSystemVersion.setCodeSystemVersionId(theSystemVersionId);
|
||||||
|
|
||||||
ourLog.info("Validating all codes in CodeSystem for storage (this can take some time for large sets)");
|
ourLog.debug("Validating all codes in CodeSystem for storage (this can take some time for large sets)");
|
||||||
|
|
||||||
// Validate the code system
|
// Validate the code system
|
||||||
ArrayList<String> conceptsStack = new ArrayList<>();
|
ArrayList<String> conceptsStack = new ArrayList<>();
|
||||||
|
@ -409,35 +409,33 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
totalCodeCount += validateConceptForStorage(next, theCodeSystemVersion, conceptsStack, allConcepts);
|
totalCodeCount += validateConceptForStorage(next, theCodeSystemVersion, conceptsStack, allConcepts);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Saving version containing {} concepts", totalCodeCount);
|
ourLog.debug("Saving version containing {} concepts", totalCodeCount);
|
||||||
|
|
||||||
TermCodeSystemVersion codeSystemVersion = myCodeSystemVersionDao.saveAndFlush(theCodeSystemVersion);
|
TermCodeSystemVersion codeSystemVersion = myCodeSystemVersionDao.saveAndFlush(theCodeSystemVersion);
|
||||||
|
|
||||||
ourLog.info("Saving code system");
|
ourLog.debug("Saving code system");
|
||||||
|
|
||||||
codeSystem.setCurrentVersion(theCodeSystemVersion);
|
codeSystem.setCurrentVersion(theCodeSystemVersion);
|
||||||
codeSystem = myCodeSystemDao.saveAndFlush(codeSystem);
|
codeSystem = myCodeSystemDao.saveAndFlush(codeSystem);
|
||||||
|
|
||||||
ourLog.info("Setting CodeSystemVersion[{}] on {} concepts...", codeSystem.getPid(), totalCodeCount);
|
ourLog.debug("Setting CodeSystemVersion[{}] on {} concepts...", codeSystem.getPid(), totalCodeCount);
|
||||||
|
|
||||||
for (TermConcept next : theCodeSystemVersion.getConcepts()) {
|
for (TermConcept next : theCodeSystemVersion.getConcepts()) {
|
||||||
populateVersion(next, codeSystemVersion);
|
populateVersion(next, codeSystemVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Saving {} concepts...", totalCodeCount);
|
ourLog.debug("Saving {} concepts...", totalCodeCount);
|
||||||
|
|
||||||
IdentityHashMap<TermConcept, Object> conceptsStack2 = new IdentityHashMap<>();
|
IdentityHashMap<TermConcept, Object> conceptsStack2 = new IdentityHashMap<>();
|
||||||
for (TermConcept next : theCodeSystemVersion.getConcepts()) {
|
for (TermConcept next : theCodeSystemVersion.getConcepts()) {
|
||||||
persistChildren(next, codeSystemVersion, conceptsStack2, totalCodeCount);
|
persistChildren(next, codeSystemVersion, conceptsStack2, totalCodeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Done saving concepts, flushing to database");
|
ourLog.debug("Done saving concepts, flushing to database");
|
||||||
|
|
||||||
myConceptDao.flush();
|
myConceptDao.flush();
|
||||||
myConceptParentChildLinkDao.flush();
|
myConceptParentChildLinkDao.flush();
|
||||||
|
|
||||||
ourLog.info("Done deleting old code system versions");
|
|
||||||
|
|
||||||
if (myDeferredStorageSvc.isStorageQueueEmpty() == false) {
|
if (myDeferredStorageSvc.isStorageQueueEmpty() == false) {
|
||||||
ourLog.info("Note that some concept saving has been deferred");
|
ourLog.info("Note that some concept saving has been deferred");
|
||||||
}
|
}
|
||||||
|
@ -612,7 +610,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theConceptsStack.size() == 1 || theConceptsStack.size() % 10000 == 0) {
|
if ((theConceptsStack.size() + 1) % 10000 == 0) {
|
||||||
float pct = (float) theConceptsStack.size() / (float) theTotalConcepts;
|
float pct = (float) theConceptsStack.size() / (float) theTotalConcepts;
|
||||||
ourLog.info("Have processed {}/{} concepts ({}%)", theConceptsStack.size(), theTotalConcepts, (int) (pct * 100.0f));
|
ourLog.info("Have processed {}/{} concepts ({}%)", theConceptsStack.size(), theTotalConcepts, (int) (pct * 100.0f));
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,33 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateQuestionnaireResponseWithValueSetIncludingCompleteCodeSystem() throws IOException {
|
||||||
|
CodeSystem cs = loadResourceFromClasspath(CodeSystem.class, "/dstu3/iar/CodeSystem-iar-citizenship-status.xml");
|
||||||
|
myCodeSystemDao.create(cs);
|
||||||
|
|
||||||
|
ValueSet vs = loadResourceFromClasspath(ValueSet.class, "/dstu3/iar/ValueSet-iar-citizenship-status.xml");
|
||||||
|
myValueSetDao.create(vs);
|
||||||
|
|
||||||
|
ValueSet expansion = myValueSetDao.expandByIdentifier("http://ccim.on.ca/fhir/iar/ValueSet/iar-citizenship-status", null);
|
||||||
|
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expansion));
|
||||||
|
|
||||||
|
// Questionnaire q = loadResourceFromClasspath(Questionnaire.class,"/dstu3/iar/Questionnaire-iar-test.xml" );
|
||||||
|
// myQuestionnaireDao.create(q);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Bundle bundleForValidation = loadResourceFromClasspath(Bundle.class, "/dstu3/iar/Bundle-for-validation.xml");
|
||||||
|
// try {
|
||||||
|
// MethodOutcome outcome = myBundleDao.validate(bundleForValidation, null, null, null, null, null, null);
|
||||||
|
// ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome.getOperationOutcome()));
|
||||||
|
// } catch (PreconditionFailedException e) {
|
||||||
|
// ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void after() {
|
public void after() {
|
||||||
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
|
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
|
||||||
|
|
|
@ -4,17 +4,21 @@ import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.bulk.IBulkDataExportSvc;
|
import ca.uhn.fhir.jpa.bulk.IBulkDataExportSvc;
|
||||||
import ca.uhn.fhir.jpa.config.TestR4WithLuceneDisabledConfig;
|
import ca.uhn.fhir.jpa.config.TestR4WithLuceneDisabledConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.*;
|
import ca.uhn.fhir.jpa.dao.*;
|
||||||
|
import ca.uhn.fhir.jpa.dao.dstu2.FhirResourceDaoDstu2SearchNoFtTest;
|
||||||
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
|
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
|
||||||
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
|
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
|
||||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
|
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||||
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||||
|
import ca.uhn.fhir.parser.IParser;
|
||||||
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.param.StringParam;
|
import ca.uhn.fhir.rest.param.StringParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
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.hl7.fhir.r4.hapi.ctx.IValidationSupport;
|
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
|
||||||
|
@ -31,11 +35,13 @@ import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@ContextConfiguration(classes = {TestR4WithLuceneDisabledConfig.class})
|
@ContextConfiguration(classes = {TestR4WithLuceneDisabledConfig.class})
|
||||||
|
@ -71,7 +77,7 @@ public class FhirResourceDaoR4SearchWithLuceneDisabledTest extends BaseJpaTest {
|
||||||
private IFhirResourceDao<CodeSystem> myCodeSystemDao;
|
private IFhirResourceDao<CodeSystem> myCodeSystemDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("myValueSetDaoR4")
|
@Qualifier("myValueSetDaoR4")
|
||||||
private IFhirResourceDao<ValueSet> myValueSetDao;
|
private IFhirResourceDaoValueSet<ValueSet, ?, ?> myValueSetDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("myObservationDaoR4")
|
@Qualifier("myObservationDaoR4")
|
||||||
private IFhirResourceDao<Observation> myObservationDao;
|
private IFhirResourceDao<Observation> myObservationDao;
|
||||||
|
@ -219,6 +225,34 @@ public class FhirResourceDaoR4SearchWithLuceneDisabledTest extends BaseJpaTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected <T extends IBaseResource> T loadResourceFromClasspath(Class<T> type, String resourceName) throws IOException {
|
||||||
|
InputStream stream = FhirResourceDaoDstu2SearchNoFtTest.class.getResourceAsStream(resourceName);
|
||||||
|
if (stream == null) {
|
||||||
|
fail("Unable to load resource: " + resourceName);
|
||||||
|
}
|
||||||
|
String string = IOUtils.toString(stream, StandardCharsets.UTF_8);
|
||||||
|
IParser newJsonParser = EncodingEnum.detectEncodingNoDefault(string).newParser(myFhirCtx);
|
||||||
|
return newJsonParser.parseResource(type, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A valueset that includes a whole system (i.e. no properties) should expand
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testExpandValueSetContainingSystemIncludeWithNoCodes() throws IOException {
|
||||||
|
CodeSystem cs = loadResourceFromClasspath(CodeSystem.class, "/dstu3/iar/CodeSystem-iar-citizenship-status.xml");
|
||||||
|
myCodeSystemDao.create(cs);
|
||||||
|
|
||||||
|
ValueSet vs = loadResourceFromClasspath(ValueSet.class, "/dstu3/iar/ValueSet-iar-citizenship-status.xml");
|
||||||
|
myValueSetDao.create(vs);
|
||||||
|
|
||||||
|
ValueSet expansion = myValueSetDao.expandByIdentifier("http://ccim.on.ca/fhir/iar/ValueSet/iar-citizenship-status", null);
|
||||||
|
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expansion));
|
||||||
|
|
||||||
|
assertEquals(4, expansion.getExpansion().getContains().size());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
|
|
@ -730,6 +730,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
|
||||||
assertEquals("The questionnaire \"Questionnaire/DOES_NOT_EXIST\" could not be resolved, so no validation can be performed against the base questionnaire", oo.getIssueFirstRep().getDiagnostics());
|
assertEquals("The questionnaire \"Questionnaire/DOES_NOT_EXIST\" could not be resolved, so no validation can be performed against the base questionnaire", oo.getIssueFirstRep().getDiagnostics());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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()) {
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CodeSystem xmlns="http://hl7.org/fhir">
|
||||||
|
<id value="iar-citizenship-status"/>
|
||||||
|
<url value="http://ccim.on.ca/fhir/iar/CodeSystem/iar-citizenship-status"/>
|
||||||
|
<version value="0.1"/>
|
||||||
|
<name value="Citizenship Status"/>
|
||||||
|
<status value="draft"/>
|
||||||
|
<date value="2019-08-22"/>
|
||||||
|
<publisher value="CCIM"/>
|
||||||
|
<contact>
|
||||||
|
<telecom>
|
||||||
|
<system value="other"/>
|
||||||
|
<value value="https://www.ccim.on.ca"/>
|
||||||
|
</telecom>
|
||||||
|
</contact>
|
||||||
|
<compositional value="false"/>
|
||||||
|
<content value="complete"/>
|
||||||
|
<concept>
|
||||||
|
<code value="CDN"/>
|
||||||
|
<display value="Canadian Citizen"/>
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="PR"/>
|
||||||
|
<display value="Permanent Resident"/>
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="TR"/>
|
||||||
|
<display value="Temporary Resident "/>
|
||||||
|
</concept>
|
||||||
|
<concept>
|
||||||
|
<code value="REF"/>
|
||||||
|
<display value="Refugee"/>
|
||||||
|
</concept>
|
||||||
|
</CodeSystem>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ValueSet xmlns="http://hl7.org/fhir">
|
||||||
|
<id value="iar-citizenship-status"/>
|
||||||
|
<url value="http://ccim.on.ca/fhir/iar/ValueSet/iar-citizenship-status"/>
|
||||||
|
<version value="0.1"/>
|
||||||
|
<name value="Citizenship Status"/>
|
||||||
|
<status value="draft"/>
|
||||||
|
<date value="2019-08-08"/>
|
||||||
|
<publisher value="CCIM"/>
|
||||||
|
<contact>
|
||||||
|
<telecom>
|
||||||
|
<system value="other"/>
|
||||||
|
<value value="https://www.ccim.on.ca"/>
|
||||||
|
</telecom>
|
||||||
|
</contact>
|
||||||
|
<compose>
|
||||||
|
<include>
|
||||||
|
<system value="http://ccim.on.ca/fhir/iar/CodeSystem/iar-citizenship-status"/>
|
||||||
|
<version value="0.1"/>
|
||||||
|
</include>
|
||||||
|
<include>
|
||||||
|
<system value="http://hl7.org/fhir/v3/NullFlavor"/>
|
||||||
|
<concept>
|
||||||
|
<code value="UNK"/>
|
||||||
|
<display value="unknown"/>
|
||||||
|
</concept>
|
||||||
|
</include>
|
||||||
|
<include>
|
||||||
|
<system value="http://hl7.org/fhir/v3/NullFlavor"/>
|
||||||
|
<concept>
|
||||||
|
<code value="ASKU"/>
|
||||||
|
<display value="asked but unknown"/>
|
||||||
|
</concept>
|
||||||
|
</include>
|
||||||
|
</compose>
|
||||||
|
</ValueSet>
|
|
@ -480,6 +480,11 @@
|
||||||
JPA servers accidentally stripped the type attribute from the server-exported CapabilityStatement
|
JPA servers accidentally stripped the type attribute from the server-exported CapabilityStatement
|
||||||
when search parameters of type "special" were found. This has been corrected.
|
when search parameters of type "special" were found. This has been corrected.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
When running the JPA server without Lucene indexing enabled and performing ValueSet expansion,
|
||||||
|
the server would incorrectly ignore inclusion rules that specified a system but no codes (i.e.
|
||||||
|
include the whole system). This has been corrected.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
|
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
|
||||||
<action type="fix">
|
<action type="fix">
|
||||||
|
|
Loading…
Reference in New Issue