Changes to enable request delete of specific Code System version.

This commit is contained in:
ianmarshall 2020-08-25 12:06:07 -04:00
parent 29b293f179
commit 749c2bc4be
11 changed files with 242 additions and 69 deletions

View File

@ -25,7 +25,9 @@ import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.HapiFhirResourceDaoCodeSystemUtil;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
@ -67,6 +69,8 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
@Autowired
private ITermCodeSystemDao myCsDao;
@Autowired
private ITermCodeSystemVersionDao myCsvDao;
@Autowired
private IValidationSupport myValidationSupport;
@Autowired
private FhirContext myFhirContext;
@ -148,13 +152,9 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
protected void preDelete(CodeSystem theResourceToDelete, ResourceTable theEntityToDelete) {
super.preDelete(theResourceToDelete, theEntityToDelete);
String codeSystemUrl = theResourceToDelete.getUrl();
if (isNotBlank(codeSystemUrl)) {
TermCodeSystem persCs = myCsDao.findByCodeSystemUri(codeSystemUrl);
if (persCs != null) {
myTermDeferredStorageSvc.deleteCodeSystem(persCs);
}
}
HapiFhirResourceDaoCodeSystemUtil.deleteCodeSystemEntities(myCsDao, myCsvDao, myTermDeferredStorageSvc, theResourceToDelete.getUrl(),
theResourceToDelete.getVersion());
}
@Override

View File

@ -25,7 +25,9 @@ import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.HapiFhirResourceDaoCodeSystemUtil;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
@ -61,6 +63,8 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSys
@Autowired
private ITermCodeSystemDao myCsDao;
@Autowired
private ITermCodeSystemVersionDao myCsvDao;
@Autowired
private IValidationSupport myValidationSupport;
@Autowired
protected ITermCodeSystemStorageSvc myTerminologyCodeSystemStorageSvc;
@ -146,13 +150,9 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSys
protected void preDelete(CodeSystem theResourceToDelete, ResourceTable theEntityToDelete) {
super.preDelete(theResourceToDelete, theEntityToDelete);
String codeSystemUrl = theResourceToDelete.getUrl();
if (isNotBlank(codeSystemUrl)) {
TermCodeSystem persCs = myCsDao.findByCodeSystemUri(codeSystemUrl);
if (persCs != null) {
myTermDeferredStorageSvc.deleteCodeSystem(persCs);
}
}
HapiFhirResourceDaoCodeSystemUtil.deleteCodeSystemEntities(myCsDao, myCsvDao, myTermDeferredStorageSvc, theResourceToDelete.getUrl(),
theResourceToDelete.getVersion());
}
@Override

View File

@ -25,7 +25,9 @@ import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.HapiFhirResourceDaoCodeSystemUtil;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
@ -65,6 +67,8 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
@Autowired
private ITermCodeSystemDao myCsDao;
@Autowired
private ITermCodeSystemVersionDao myCsvDao;
@Autowired
private IValidationSupport myValidationSupport;
@Autowired
private FhirContext myFhirContext;
@ -117,11 +121,11 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
codeSystemVersion = theVersion.getValue();
}
ourLog.info("Looking up {} / {}, version {}", system, code, codeSystemVersion);
ourLog.debug("Looking up {} / {}, version {}", system, code, codeSystemVersion);
if (myValidationSupport.isCodeSystemSupported(new ValidationSupportContext(myValidationSupport), system)) {
ourLog.info("Code system {} is supported", system);
ourLog.debug("Code system {} is supported", system);
IValidationSupport.LookupCodeResult retVal = myValidationSupport.lookupCode(new ValidationSupportContext(myValidationSupport), system, code, codeSystemVersion);
if (retVal != null) {
return retVal;
@ -148,13 +152,9 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
protected void preDelete(CodeSystem theResourceToDelete, ResourceTable theEntityToDelete) {
super.preDelete(theResourceToDelete, theEntityToDelete);
String codeSystemUrl = theResourceToDelete.getUrl();
if (isNotBlank(codeSystemUrl)) {
TermCodeSystem persCs = myCsDao.findByCodeSystemUri(codeSystemUrl);
if (persCs != null) {
myTermDeferredStorageSvc.deleteCodeSystem(persCs);
}
}
HapiFhirResourceDaoCodeSystemUtil.deleteCodeSystemEntities(myCsDao, myCsvDao, myTermDeferredStorageSvc, theResourceToDelete.getUrl(),
theResourceToDelete.getVersion());
}
@Override

View File

@ -58,7 +58,7 @@ public class TermCodeSystem implements Serializable {
@Column(name = "PID")
private Long myPid;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, updatable = false, foreignKey = @ForeignKey(name = "FK_TRMCODESYSTEM_RES"))
@JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, updatable = true, foreignKey = @ForeignKey(name = "FK_TRMCODESYSTEM_RES"))
private ResourceTable myResource;
@Column(name = "RES_ID", insertable = false, updatable = false)
private Long myResourcePid;

View File

@ -231,6 +231,14 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
});
}
@Override
@Transactional(propagation = Propagation.NEVER)
public void deleteCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion) {
ourLog.info(" * Deleting code system version {}", theCodeSystemVersion.getPid());
deleteCodeSystemVersion(theCodeSystemVersion.getPid());
}
/**
* Returns the number of saved concepts
*/
@ -680,9 +688,9 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
if (codeSystem == null) {
codeSystem = new TermCodeSystem();
}
codeSystem.setResource(theCodeSystemResourceTable);
}
codeSystem.setResource(theCodeSystemResourceTable);
codeSystem.setCodeSystemUri(theSystemUri);
codeSystem.setName(theSystemName);
codeSystem = myCodeSystemDao.save(codeSystem);
@ -692,15 +700,19 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
private void validateCodeSystemVersionUpdate(TermCodeSystem theCodeSystem, String theSystemUri, String theSystemVersionId, ResourceTable theCodeSystemResourceTable) {
// Check if CodeSystemVersion entity already exists.
TermCodeSystemVersion codeSystemVersionEntity;
String msg;
String msg = null;
if (theSystemVersionId == null) {
codeSystemVersionEntity = myCodeSystemVersionDao.findByCodeSystemPidVersionIsNull(theCodeSystem.getPid());
msg = myContext.getLocalizer().getMessage(BaseTermReadSvcImpl.class, "cannotCreateDuplicateCodeSystemUrl", theSystemUri,
theCodeSystem.getResource().getIdDt().toUnqualifiedVersionless().getValue());
if (codeSystemVersionEntity != null) {
msg = myContext.getLocalizer().getMessage(BaseTermReadSvcImpl.class, "cannotCreateDuplicateCodeSystemUrl", theSystemUri,
codeSystemVersionEntity.getResource().getIdDt().toUnqualifiedVersionless().getValue());
}
} else {
codeSystemVersionEntity = myCodeSystemVersionDao.findByCodeSystemPidAndVersion(theCodeSystem.getPid(), theSystemVersionId);
msg = myContext.getLocalizer().getMessage(BaseTermReadSvcImpl.class, "cannotCreateDuplicateCodeSystemUrlAndVersion", theSystemUri,
theSystemVersionId, theCodeSystem.getResource().getIdDt().toUnqualifiedVersionless().getValue());
if (codeSystemVersionEntity != null) {
msg = myContext.getLocalizer().getMessage(BaseTermReadSvcImpl.class, "cannotCreateDuplicateCodeSystemUrlAndVersion", theSystemUri,
theSystemVersionId, codeSystemVersionEntity.getResource().getIdDt().toUnqualifiedVersionless().getValue());
}
}
// Throw exception if the CodeSystemVersion is being duplicated.
if (codeSystemVersionEntity != null) {

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptParentChildLinkDao;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import ca.uhn.fhir.jpa.model.sched.HapiJob;
@ -68,6 +69,7 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
protected PlatformTransactionManager myTransactionMgr;
private boolean myProcessDeferred = true;
private List<TermCodeSystem> myDefferedCodeSystemsDeletions = Collections.synchronizedList(new ArrayList<>());
private List<TermCodeSystemVersion> myDefferedCodeSystemVersionsDeletions = Collections.synchronizedList(new ArrayList<>());
private List<TermConcept> myDeferredConcepts = Collections.synchronizedList(new ArrayList<>());
private List<ValueSet> myDeferredValueSets = Collections.synchronizedList(new ArrayList<>());
private List<ConceptMap> myDeferredConceptMaps = Collections.synchronizedList(new ArrayList<>());
@ -115,6 +117,12 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
myDefferedCodeSystemsDeletions.add(theCodeSystem);
}
@Override
@Transactional
public void deleteCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion) {
myDefferedCodeSystemVersionsDeletions.add(theCodeSystemVersion);
}
@Override
public void saveAllDeferred() {
while (!isStorageQueueEmpty()) {
@ -266,6 +274,12 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
}
private void processDeferredCodeSystemDeletions() {
for (TermCodeSystemVersion next : myDefferedCodeSystemVersionsDeletions) {
myCodeSystemStorageSvc.deleteCodeSystemVersion(next);
}
myDefferedCodeSystemVersionsDeletions.clear();
for (TermCodeSystem next : myDefferedCodeSystemsDeletions) {
myCodeSystemStorageSvc.deleteCodeSystem(next);
}
@ -300,7 +314,7 @@ public class TermDeferredStorageSvcImpl implements ITermDeferredStorageSvc {
}
private boolean isDeferredCodeSystemDeletions() {
return !myDefferedCodeSystemsDeletions.isEmpty();
return !myDefferedCodeSystemsDeletions.isEmpty() || !myDefferedCodeSystemVersionsDeletions.isEmpty();
}
private boolean isDeferredConcepts() {

View File

@ -41,6 +41,8 @@ public interface ITermCodeSystemStorageSvc {
void deleteCodeSystem(TermCodeSystem theCodeSystem);
void deleteCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion);
void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable);
/**

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.term.api;
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
import org.hl7.fhir.r4.model.ConceptMap;
@ -54,6 +55,8 @@ public interface ITermDeferredStorageSvc {
void deleteCodeSystem(TermCodeSystem theCodeSystem);
void deleteCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion);
/**
* This is mostly here for unit tests - Saves any and all deferred concepts and links
*/

View File

@ -1,11 +1,19 @@
package ca.uhn.fhir.jpa.term;
import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeType;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
@ -14,47 +22,123 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
@Test
public void testStoreNewCodeSystemVersionForExistingCodeSystemNoVersionId() {
CodeSystem upload = createCodeSystemWithMoreThan100Concepts();
CodeSystem firstUpload = createCodeSystemWithMoreThan100Concepts();
CodeSystem duplicateUpload = createCodeSystemWithMoreThan100Concepts();
// Create CodeSystem resource
ResourceTable codeSystemResourceEntity = (ResourceTable) myCodeSystemDao.create(upload, mySrd).getEntity();
testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 125, "Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\", already have one with resource ID: CodeSystem/");
// Update the CodeSystem resource
runInTransaction(() -> myTermCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(upload, codeSystemResourceEntity));
runInTransaction(() -> {
assertEquals(1, myTermCodeSystemDao.count());
assertEquals(1, myTermCodeSystemVersionDao.count());
TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri(URL_MY_CODE_SYSTEM);
/*
Because there are more than 100 concepts in the code system, the first 100 will be persisted immediately and
the remaining 25 concepts will be queued up for "deferred save".
As the CodeSystem was persisted twice, the extra 25 term concepts will be queued twice, each with a different
CodeSystem version PID. Only one set of the term concepts should be persisted (i.e. 125 term concepts in total).
*/
myTerminologyDeferredStorageSvc.setProcessDeferred(true);
myTerminologyDeferredStorageSvc.saveDeferred();
assertEquals(125, myTermConceptDao.count());
TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull( myTermCodeSystem.getPid());
assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion.getPid());
assertEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion.getResource().getId());
});
}
@Test
public void testStoreNewCodeSystemVersionForExistingCodeSystemVersionId() {
CodeSystem upload = createCodeSystemWithMoreThan100Concepts();
upload.setVersion("1");
CodeSystem firstUpload = createCodeSystemWithMoreThan100Concepts();
firstUpload.setVersion("1");
// Create CodeSystem resource
ResourceTable codeSystemResourceEntity = (ResourceTable) myCodeSystemDao.create(upload, mySrd).getEntity();
CodeSystem duplicateUpload = createCodeSystemWithMoreThan100Concepts();
duplicateUpload.setVersion("1");
// Update the CodeSystem resource
runInTransaction(() -> myTermCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(upload, codeSystemResourceEntity));
testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 125,"Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"1\", already have one with resource ID: CodeSystem/");
/*
Because there are more than 100 concepts in the code system, the first 100 will be persisted immediately and
the remaining 25 concepts will be queued up for "deferred save".
runInTransaction(() -> {
assertEquals(1, myTermCodeSystemDao.count());
assertEquals(1, myTermCodeSystemVersionDao.count());
TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri(URL_MY_CODE_SYSTEM);
TermCodeSystemVersion myTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion( myTermCodeSystem.getPid(), "1");
assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion.getPid());
assertEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion.getResource().getId());
});
// Now add a second version
firstUpload = createCodeSystemWithMoreThan100Concepts();
firstUpload.setVersion("2");
duplicateUpload = createCodeSystemWithMoreThan100Concepts();
duplicateUpload.setVersion("2");
testCreatingAndUpdatingCodeSystemEntity(firstUpload, duplicateUpload, 251,"Can not create multiple CodeSystem resources with CodeSystem.url \"http://example.com/my_code_system\" and CodeSystem.version \"2\", already have one with resource ID: CodeSystem/");
runInTransaction(() -> {
assertEquals(1, myTermCodeSystemDao.count());
assertEquals(2, myTermCodeSystemVersionDao.count());
TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri(URL_MY_CODE_SYSTEM);
TermCodeSystemVersion mySecondTermCodeSystemVersion = myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "2");
assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), mySecondTermCodeSystemVersion.getPid());
assertEquals(myTermCodeSystem.getResource().getId(), mySecondTermCodeSystemVersion.getResource().getId());
});
}
@Test
public void testDeleteCodeSystem() {
CodeSystem codeSystemToDelete = createSmallCodeSystem();
// Create CodeSystem resource and entity
ResourceTable codeSystemResourceEntity = (ResourceTable)myCodeSystemDao.create(codeSystemToDelete, mySrd).getEntity();
validateCodeSystemUpdates(10);
runInTransaction(() -> {
assertEquals(1, myTermCodeSystemDao.count());
assertEquals(1, myTermCodeSystemVersionDao.count());
});
// Attempt to delete
myCodeSystemDao.delete(codeSystemResourceEntity.getIdDt(), mySrd);
validateCodeSystemUpdates(0);
runInTransaction(() -> {
assertEquals(0, myTermCodeSystemDao.count());
assertEquals(0, myTermCodeSystemVersionDao.count());
});
}
@Test
public void testDeleteCodeSystemVersion() {
CodeSystem firstCodeSystemVersion = createSmallCodeSystem();
firstCodeSystemVersion.setVersion("1");
// Create first CodeSystem resource and entity
ResourceTable codeSystemResourceEntity = (ResourceTable)myCodeSystemDao.create(firstCodeSystemVersion, mySrd).getEntity();
validateCodeSystemUpdates(10);
runInTransaction(() -> {
assertEquals(1, myTermCodeSystemDao.count());
assertEquals(1, myTermCodeSystemVersionDao.count());
});
CodeSystem secondCodeSystemVersion = createSmallCodeSystem();
secondCodeSystemVersion.setVersion("2");
// Create CodeSystem resource and entity
myCodeSystemDao.create(secondCodeSystemVersion, mySrd);
validateCodeSystemUpdates(20);
runInTransaction(() -> {
assertEquals(1, myTermCodeSystemDao.count());
assertEquals(2, myTermCodeSystemVersionDao.count());
});
// Attempt to delete first version
myCodeSystemDao.delete(codeSystemResourceEntity.getIdDt(), mySrd);
validateCodeSystemUpdates(10);
runInTransaction(() -> {
assertEquals(1, myTermCodeSystemDao.count());
assertEquals(1, myTermCodeSystemVersionDao.count());
});
As the CodeSystem was persisted twice, the extra 25 term concepts will be queued twice, each with a different
CodeSystem version PID. Only one set of the term concepts should be persisted (i.e. 125 term concepts in total).
*/
myTerminologyDeferredStorageSvc.setProcessDeferred(true);
myTerminologyDeferredStorageSvc.saveDeferred();
assertEquals(125, myTermConceptDao.count());
}
private CodeSystem createCodeSystemWithMoreThan100Concepts() {
@ -70,5 +154,56 @@ public class TermCodeSystemStorageSvcTest extends BaseJpaR4Test {
}
private CodeSystem createSmallCodeSystem() {
CodeSystem codeSystem = new CodeSystem();
codeSystem.setUrl(URL_MY_CODE_SYSTEM);
for (int i = 0; i < 10; i++) {
codeSystem.addConcept(new CodeSystem.ConceptDefinitionComponent(new CodeType("codeA " + i)));
}
codeSystem.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
return codeSystem;
}
private void testCreatingAndUpdatingCodeSystemEntity(CodeSystem theUpload, CodeSystem theDuplicate, int expectedCnt, String theDuplicateErrorBaseMsg) {
// Create CodeSystem resource
ResourceTable codeSystemResourceEntity = (ResourceTable) myCodeSystemDao.create(theUpload, mySrd).getEntity();
// Create the CodeSystem and CodeSystemVersion entities
validateCodeSystemUpdates(expectedCnt);
// Update the CodeSystem
theUpload.addConcept(new CodeSystem.ConceptDefinitionComponent(new CodeType("codeB")));
// Update the CodeSystem and CodeSystemVersion entities
runInTransaction(() -> myTermCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(theUpload, codeSystemResourceEntity));
validateCodeSystemUpdates(expectedCnt+1);
// Try duplicating the CodeSystem
Long originalResId = codeSystemResourceEntity.getId();
try {
myCodeSystemDao.create(theDuplicate, mySrd);
fail();
} catch (UnprocessableEntityException e) {
assertEquals(theDuplicateErrorBaseMsg + originalResId, e.getMessage());
}
// Try updating code system when content mode is NOT PRESENT
theUpload.setConcept(new ArrayList<>());
theUpload.setContent((CodeSystem.CodeSystemContentMode.NOTPRESENT));
runInTransaction(() -> myTermCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(theUpload, codeSystemResourceEntity));
validateCodeSystemUpdates(expectedCnt+1);
}
private void validateCodeSystemUpdates(int theExpectedConceptCount) {
myTerminologyDeferredStorageSvc.setProcessDeferred(true);
myTerminologyDeferredStorageSvc.saveDeferred();
myTerminologyDeferredStorageSvc.setProcessDeferred(false);
assertEquals(theExpectedConceptCount, myTermConceptDao.count());
}
}

View File

@ -351,12 +351,21 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
CodeSystem loincCS = mySystemCaptor.getValue();
assertEquals("2.67", loincCS.getVersion());
// Update LOINC marked as version 2.67
myFiles = new ZipCollectionBuilder();
addLoincMandatoryFilesWithPropertiesFileToZip(myFiles, "v267_loincupload.properties");
mySvc.loadLoinc(myFiles.getFiles(), mySrd);
verify(myTermCodeSystemStorageSvc, times(2)).storeNewCodeSystemVersion(mySystemCaptor.capture(), myCsvCaptor.capture(), any(RequestDetails.class), myValueSetsCaptor.capture(), myConceptMapCaptor.capture());
loincCS = mySystemCaptor.getValue();
assertEquals("2.67", loincCS.getVersion());
// Load LOINC marked as version 2.68
myFiles = new ZipCollectionBuilder();
addLoincMandatoryFilesWithPropertiesFileToZip(myFiles, "v268_loincupload.properties");
mySvc.loadLoinc(myFiles.getFiles(), mySrd);
verify(myTermCodeSystemStorageSvc, times(2)).storeNewCodeSystemVersion(mySystemCaptor.capture(), myCsvCaptor.capture(), any(RequestDetails.class), myValueSetsCaptor.capture(), myConceptMapCaptor.capture());
verify(myTermCodeSystemStorageSvc, times(3)).storeNewCodeSystemVersion(mySystemCaptor.capture(), myCsvCaptor.capture(), any(RequestDetails.class), myValueSetsCaptor.capture(), myConceptMapCaptor.capture());
loincCS = mySystemCaptor.getValue();
assertEquals("2.68", loincCS.getVersion());

View File

@ -12,7 +12,6 @@ import ca.uhn.fhir.jpa.entity.TermConceptMapGroup;
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElement;
import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.model.dstu2.valueset.ContentTypeEnum;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CanonicalType;
@ -25,7 +24,6 @@ import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
import org.hl7.fhir.r4.model.UriType;
import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r4.model.codesystems.HttpVerb;
import org.hl7.fhir.utilities.validation.ValidationOptions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -1787,10 +1785,10 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
createCodeSystem();
IValidationSupport.CodeValidationResult validation = myTermSvc.validateCode(new ValidationSupportContext(myValidationSupport), new ConceptValidationOptions(), CS_URL, "ParentWithNoChildrenA", null, null);
assertEquals(true, validation.isOk());
assertTrue(validation.isOk());
validation = myTermSvc.validateCode(new ValidationSupportContext(myValidationSupport), new ConceptValidationOptions(), CS_URL, "ZZZZZZZ", null, null);
assertEquals(false, validation.isOk());
assertFalse(validation.isOk());
}
@Test
@ -1927,8 +1925,8 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
codeSystem
.addConcept().setCode("C").setDisplay("Code C");
myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
codes = myTermSvc.findCodesBelow(id.getIdPartAsLong(), id.getVersionIdPartAsLong(), "C");
IIdType id_v2 = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
codes = myTermSvc.findCodesBelow(id_v2.getIdPartAsLong(), id_v2.getVersionIdPartAsLong(), "C");
assertThat(toCodes(codes), containsInAnyOrder("C"));
runInTransaction(() -> {
@ -1939,7 +1937,7 @@ public class TerminologySvcImplR4Test extends BaseTermR4Test {
Set<TermConcept> termConcepts_updated = new HashSet<>(termCodeSystemVersion_2.getConcepts());
assertThat(toCodes(termConcepts_updated), containsInAnyOrder("A", "B", "C"));
TermCodeSystem termCodeSystem = myTermCodeSystemDao.findByResourcePid(id.getIdPartAsLong());
TermCodeSystem termCodeSystem = myTermCodeSystemDao.findByResourcePid(id_v2.getIdPartAsLong());
assertEquals("2", termCodeSystem.getCurrentVersion().getCodeSystemVersionId());
});
}