Allow storing ConceptMap with StructureDefinition as a source or target
This commit is contained in:
parent
93bf2788ec
commit
63b8a70e8a
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.term;
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -25,9 +25,9 @@ import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
|||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
|
||||
import ca.uhn.fhir.jpa.dao.data.*;
|
||||
import ca.uhn.fhir.jpa.model.entity.*;
|
||||
import ca.uhn.fhir.jpa.entity.*;
|
||||
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.util.ScrollableResultsIterator;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
|
@ -137,6 +137,8 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
private int myFetchSize = DEFAULT_FETCH_SIZE;
|
||||
private ApplicationContext myApplicationContext;
|
||||
private TransactionTemplate myTxTemplate;
|
||||
@Autowired
|
||||
private PlatformTransactionManager myTransactionManager;
|
||||
|
||||
/**
|
||||
* @param theAdd If true, add the code. If false, remove the code.
|
||||
|
@ -368,9 +370,6 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private PlatformTransactionManager myTransactionManager;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteConceptMapAndChildren(ResourceTable theResourceTable) {
|
||||
|
@ -391,7 +390,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(myTransactionManager);
|
||||
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||
txTemplate.execute(t->{
|
||||
txTemplate.execute(t -> {
|
||||
theDao.deleteInBatch(link);
|
||||
return null;
|
||||
});
|
||||
|
@ -1190,6 +1189,22 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
termConceptMap.setResource(theResourceTable);
|
||||
termConceptMap.setUrl(theConceptMap.getUrl());
|
||||
|
||||
String source = theConceptMap.hasSourceUriType() ? theConceptMap.getSourceUriType().getValueAsString() : null;
|
||||
String target = theConceptMap.hasTargetUriType() ? theConceptMap.getTargetUriType().getValueAsString() : null;
|
||||
|
||||
/*
|
||||
* If this is a mapping between "resources" instead of purely between
|
||||
* "concepts" (this is a weird concept that is technically possible, at least as of
|
||||
* FHIR R4), don't try to store the mappings.
|
||||
*
|
||||
* See here for a description of what that is:
|
||||
* http://hl7.org/fhir/conceptmap.html#bnr
|
||||
*/
|
||||
if ("StructureDefinition".equals(new IdType(source).getResourceType()) ||
|
||||
"StructureDefinition".equals(new IdType(target).getResourceType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* For now we always delete old versions. At some point, it would be nice to allow configuration to keep old versions.
|
||||
*/
|
||||
|
@ -1202,11 +1217,9 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
Optional<TermConceptMap> optionalExistingTermConceptMapByUrl = myConceptMapDao.findTermConceptMapByUrl(conceptMapUrl);
|
||||
if (!optionalExistingTermConceptMapByUrl.isPresent()) {
|
||||
try {
|
||||
String source = theConceptMap.hasSourceUriType() ? theConceptMap.getSourceUriType().getValueAsString() : null;
|
||||
if (isNotBlank(source)) {
|
||||
termConceptMap.setSource(source);
|
||||
}
|
||||
String target = theConceptMap.hasTargetUriType() ? theConceptMap.getTargetUriType().getValueAsString() : null;
|
||||
if (isNotBlank(target)) {
|
||||
termConceptMap.setTarget(target);
|
||||
}
|
||||
|
@ -1244,12 +1257,12 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
|
|||
|
||||
if (element.hasTarget()) {
|
||||
TermConceptMapGroupElementTarget termConceptMapGroupElementTarget;
|
||||
for (ConceptMap.TargetElementComponent target : element.getTarget()) {
|
||||
for (ConceptMap.TargetElementComponent elementTarget : element.getTarget()) {
|
||||
termConceptMapGroupElementTarget = new TermConceptMapGroupElementTarget();
|
||||
termConceptMapGroupElementTarget.setConceptMapGroupElement(termConceptMapGroupElement);
|
||||
termConceptMapGroupElementTarget.setCode(target.getCode());
|
||||
termConceptMapGroupElementTarget.setDisplay(target.getDisplay());
|
||||
termConceptMapGroupElementTarget.setEquivalence(target.getEquivalence());
|
||||
termConceptMapGroupElementTarget.setCode(elementTarget.getCode());
|
||||
termConceptMapGroupElementTarget.setDisplay(elementTarget.getDisplay());
|
||||
termConceptMapGroupElementTarget.setEquivalence(elementTarget.getEquivalence());
|
||||
myConceptMapGroupElementTargetDao.save(termConceptMapGroupElementTarget);
|
||||
|
||||
if (codesSaved++ % 250 == 0) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ca.uhn.fhir.jpa.term;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test;
|
||||
import ca.uhn.fhir.jpa.entity.TermConceptMap;
|
||||
import ca.uhn.fhir.jpa.entity.TermConceptMapGroup;
|
||||
|
@ -8,12 +9,11 @@ import ca.uhn.fhir.jpa.entity.TermConceptMapGroupElementTarget;
|
|||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.CanonicalType;
|
||||
import org.hl7.fhir.r4.model.ConceptMap;
|
||||
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
|
||||
import org.hl7.fhir.r4.model.UriType;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.*;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -32,11 +32,26 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
public final ExpectedException expectedException = ExpectedException.none();
|
||||
private IIdType myConceptMapId;
|
||||
|
||||
private void persistConceptMap() {
|
||||
@Before
|
||||
public void before() {
|
||||
myDaoConfig.setAllowExternalReferences(true);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
||||
}
|
||||
|
||||
private void createAndPersistConceptMap() {
|
||||
ConceptMap conceptMap = createConceptMap();
|
||||
persistConceptMap(conceptMap);
|
||||
}
|
||||
|
||||
private void persistConceptMap(ConceptMap theConceptMap) {
|
||||
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
|
||||
myConceptMapId = myConceptMapDao.create(createConceptMap(), mySrd).getId().toUnqualifiedVersionless();
|
||||
myConceptMapId = myConceptMapDao.create(theConceptMap, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -63,6 +78,17 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateConceptMapWithVirtualSourceSystem() {
|
||||
ConceptMap conceptMap = createConceptMap();
|
||||
conceptMap.getGroup().forEach(t->t.setSource(null));
|
||||
conceptMap.setSource(new CanonicalType("http://hl7.org/fhir/uv/livd/StructureDefinition/loinc-livd"));
|
||||
|
||||
persistConceptMap(conceptMap);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateConceptMapWithMissingTargetSystems() {
|
||||
|
||||
|
@ -113,17 +139,17 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testDuplicateConceptMapUrls() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
|
||||
expectedException.expect(UnprocessableEntityException.class);
|
||||
expectedException.expectMessage("Can not create multiple ConceptMap resources with ConceptMap.url \"http://example.com/my_concept_map\", already have one with resource ID: ConceptMap/" + myConceptMapId.getIdPart());
|
||||
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreTermConceptMapAndChildren() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -301,7 +327,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateByCodeSystemsAndSourceCodeOneToMany() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -355,7 +381,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateByCodeSystemsAndSourceCodeOneToOne() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -429,7 +455,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateByCodeSystemsAndSourceCodeUnmapped() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -482,7 +508,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateUsingPredicatesWithCodeOnly() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -550,7 +576,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateUsingPredicatesWithSourceAndTargetSystem2() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -598,7 +624,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateUsingPredicatesWithSourceAndTargetSystem3() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -658,7 +684,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateUsingPredicatesWithSourceSystem() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -728,7 +754,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateUsingPredicatesWithSourceSystemAndVersion1() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -776,7 +802,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateUsingPredicatesWithSourceSystemAndVersion3() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -836,7 +862,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateUsingPredicatesWithSourceValueSet() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -906,7 +932,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateUsingPredicatesWithTargetValueSet() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -976,7 +1002,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateWithReverse() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -1025,7 +1051,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateWithReverseByCodeSystemsAndSourceCodeUnmapped() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -1048,7 +1074,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateWithReverseUsingPredicatesWithCodeOnly() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -1104,7 +1130,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateWithReverseUsingPredicatesWithSourceAndTargetSystem1() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -1153,7 +1179,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateWithReverseUsingPredicatesWithSourceAndTargetSystem4() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -1202,7 +1228,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateWithReverseUsingPredicatesWithSourceSystem() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -1260,7 +1286,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateWithReverseUsingPredicatesWithSourceSystemAndVersion() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -1320,7 +1346,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateWithReverseUsingPredicatesWithSourceValueSet() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
@ -1378,7 +1404,7 @@ public class TerminologySvcImplR4Test extends BaseJpaR4Test {
|
|||
|
||||
@Test
|
||||
public void testTranslateWithReverseUsingPredicatesWithTargetValueSet() {
|
||||
persistConceptMap();
|
||||
createAndPersistConceptMap();
|
||||
ConceptMap conceptMap = myConceptMapDao.read(myConceptMapId);
|
||||
|
||||
ourLog.info("ConceptMap:\n" + myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
|
|
@ -289,6 +289,12 @@
|
|||
an exception with a misleading error about the Conformance resource not existing. This
|
||||
has been corrected. Thanks to Shayaan Munshi for reporting and providing a test case!
|
||||
</action>
|
||||
<action type="fix">
|
||||
It is now possible to upload a ConceptMap to the JPA server containing mappings where the
|
||||
source or target is a StructureDefinition canonical URI. This was previously blocked, as the
|
||||
system could not apply these mappings. It is now permitted to be stored, although
|
||||
the system will still not apply these mappings.
|
||||
</action>
|
||||
</release>
|
||||
<release version="3.6.0" date="2018-11-12" description="Food">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue