Accurately reflect codesystem URL

This commit is contained in:
James Agnew 2019-09-16 15:55:32 -04:00
parent 9997b02506
commit 38cf830384
5 changed files with 124 additions and 17 deletions

View File

@ -1538,9 +1538,6 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
codeSystem = new TermCodeSystem();
}
codeSystem.setResource(theCodeSystemVersion.getResource());
codeSystem.setCodeSystemUri(theSystemUri);
codeSystem.setName(theSystemName);
myCodeSystemDao.save(codeSystem);
} else {
if (!ObjectUtil.equals(codeSystem.getResource().getId(), theCodeSystemVersion.getResource().getId())) {
String msg = myContext.getLocalizer().getMessage(BaseHapiTerminologySvcImpl.class, "cannotCreateDuplicateCodeSystemUrl", theSystemUri,
@ -1548,6 +1545,11 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
throw new UnprocessableEntityException(msg);
}
}
codeSystem.setCodeSystemUri(theSystemUri);
codeSystem.setName(theSystemName);
codeSystem = myCodeSystemDao.save(codeSystem);
theCodeSystemVersion.setCodeSystem(codeSystem);
theCodeSystemVersion.setCodeSystemDisplayName(theSystemName);
@ -1626,6 +1628,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
}
@Override
@Transactional(propagation = Propagation.MANDATORY)
public void storeNewCodeSystemVersionIfNeeded(CodeSystem theCodeSystem, ResourceTable theResourceEntity) {
if (theCodeSystem != null && isNotBlank(theCodeSystem.getUrl())) {
String codeSystemUrl = theCodeSystem.getUrl();
@ -1633,20 +1636,13 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
ourLog.info("CodeSystem {} has a status of {}, going to store concepts in terminology tables", theResourceEntity.getIdDt().getValue(), theCodeSystem.getContentElement().getValueAsString());
Long codeSystemResourcePid = getCodeSystemResourcePid(theCodeSystem.getIdElement());
TermCodeSystemVersion persCs = myCodeSystemVersionDao.findCurrentVersionForCodeSystemResourcePid(codeSystemResourcePid);
if (persCs != null) {
ourLog.info("Code system version already exists in database");
} else {
TermCodeSystemVersion persCs = new TermCodeSystemVersion();
persCs = new TermCodeSystemVersion();
populateCodeSystemVersionProperties(persCs, theCodeSystem, theResourceEntity);
persCs.getConcepts().addAll(toPersistedConcepts(theCodeSystem.getConcept(), persCs));
ourLog.info("Code system has {} concepts", persCs.getConcepts().size());
storeNewCodeSystemVersion(codeSystemResourcePid, codeSystemUrl, theCodeSystem.getName(), theCodeSystem.getVersion(), persCs);
}
populateCodeSystemVersionProperties(persCs, theCodeSystem, theResourceEntity);
persCs.getConcepts().addAll(toPersistedConcepts(theCodeSystem.getConcept(), persCs));
ourLog.info("Code system has {} concepts", persCs.getConcepts().size());
storeNewCodeSystemVersion(codeSystemResourcePid, codeSystemUrl, theCodeSystem.getName(), theCodeSystem.getVersion(), persCs);
}
}
}

View File

@ -612,6 +612,59 @@ public class ResourceProviderR4ValueSetTest extends BaseResourceProviderR4Test {
}
}
@Test
public void testExpandValueSetBasedOnCodeSystemWithChangedUrl() throws IOException {
CodeSystem cs = new CodeSystem();
cs.setId("CodeSystem/CS");
cs.setContent(CodeSystemContentMode.COMPLETE);
cs.setUrl("http://foo1");
cs.addConcept().setCode("foo1").setDisplay("foo1");
ourClient.update().resource(cs).execute();
ValueSet vs = new ValueSet();
vs.setId("ValueSet/VS179789");
vs.setUrl("http://bar");
vs.getCompose().addInclude().setSystem("http://foo1").addConcept().setCode("foo1");
ourClient.update().resource(vs).execute();
ValueSet expanded = ourClient
.operation()
.onInstance(new IdType("ValueSet/VS179789"))
.named("$expand")
.withNoParameters(Parameters.class)
.returnResourceType(ValueSet.class)
.execute();
ourLog.info("Expanded: {}",myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expanded));
assertEquals(1, expanded.getExpansion().getContains().size());
// Update the CodeSystem URL and Codes
cs = new CodeSystem();
cs.setId("CodeSystem/CS");
cs.setContent(CodeSystemContentMode.COMPLETE);
cs.setUrl("http://foo2");
cs.addConcept().setCode("foo2").setDisplay("foo2");
ourClient.update().resource(cs).execute();
vs = new ValueSet();
vs.setId("ValueSet/VS179789");
vs.setUrl("http://bar");
vs.getCompose().addInclude().setSystem("http://foo2").addConcept().setCode("foo2");
ourClient.update().resource(vs).execute();
expanded = ourClient
.operation()
.onInstance(new IdType("ValueSet/VS179789"))
.named("$expand")
.withNoParameters(Parameters.class)
.returnResourceType(ValueSet.class)
.execute();
ourLog.info("Expanded: {}",myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(expanded));
assertEquals(1, expanded.getExpansion().getContains().size());
}
/**
* #516
*/

View File

@ -49,7 +49,9 @@ public class ValidationSupportChain implements IValidationSupport {
@Override
public ValueSetExpander.ValueSetExpansionOutcome expandValueSet(FhirContext theCtx, ConceptSetComponent theInclude) {
for (IValidationSupport next : myChain) {
if (next.isCodeSystemSupported(theCtx, theInclude.getSystem())) {
boolean codeSystemSupported = next.isCodeSystemSupported(theCtx, theInclude.getSystem());
ourLog.trace("Support {} supports: {}", next, codeSystemSupported);
if (codeSystemSupported) {
ValueSetExpander.ValueSetExpansionOutcome expansion = next.expandValueSet(theCtx, theInclude);
if (expansion != null) {
return expansion;
@ -57,7 +59,7 @@ public class ValidationSupportChain implements IValidationSupport {
}
}
throw new InvalidRequestException("unable to find code system " + theInclude.getSystem());
throw new InvalidRequestException("Unable to find code system " + theInclude.getSystem());
}
@Override

View File

@ -633,6 +633,57 @@ public class QuestionnaireResponseValidatorR4Test {
}
@Test
public void testOpenchoiceAnswerWithOptions() {
String questionnaireRef = "http://example.com/Questionnaire/q1";
List<Questionnaire.QuestionnaireItemAnswerOptionComponent> options = new ArrayList<>();
options.add(new Questionnaire.QuestionnaireItemAnswerOptionComponent().setValue(new Coding("http://foo", "foo", "FOOOO")));
options.add(new Questionnaire.QuestionnaireItemAnswerOptionComponent().setValue(new Coding("http://bar", "bar", "FOOOO")));
Questionnaire q = new Questionnaire();
QuestionnaireItemComponent item = q.addItem();
item.setLinkId("link0")
.setRequired(true)
.setType(QuestionnaireItemType.OPENCHOICE)
.setAnswerOption(options);
when(myValSupport.fetchResource(any(FhirContext.class), eq(Questionnaire.class), eq(questionnaireRef))).thenReturn(q);
QuestionnaireResponse qa;
ValidationResult errors;
qa = new QuestionnaireResponse();
qa.getText().setDiv(new XhtmlNode().setValue("<div>AA</div>")).setStatus(Narrative.NarrativeStatus.GENERATED);
qa.setStatus(QuestionnaireResponseStatus.COMPLETED);
qa.getQuestionnaireElement().setValue(questionnaireRef);
qa.addItem().setLinkId("link0").addAnswer().setValue(new Coding().setSystem("http://foo").setCode("foo"));
errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
assertEquals(true, errors.isSuccessful());
qa = new QuestionnaireResponse();
qa.getText().setDiv(new XhtmlNode().setValue("<div>AA</div>")).setStatus(Narrative.NarrativeStatus.GENERATED);
qa.setStatus(QuestionnaireResponseStatus.COMPLETED);
qa.getQuestionnaireElement().setValue(questionnaireRef);
qa.addItem().setLinkId("link0").addAnswer().setValue(new StringType("Hello"));
errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
assertEquals(true, errors.isSuccessful());
qa = new QuestionnaireResponse();
qa.getText().setDiv(new XhtmlNode().setValue("<div>AA</div>")).setStatus(Narrative.NarrativeStatus.GENERATED);
qa.setStatus(QuestionnaireResponseStatus.COMPLETED);
qa.getQuestionnaireElement().setValue(questionnaireRef);
qa.addItem().setLinkId("link0").addAnswer().setValue(new Coding().setSystem("http://foo").setCode("hello"));
errors = myVal.validateWithResult(qa);
ourLog.info(errors.toString());
// This is set in InstanceValidator#validateAnswerCode
assertEquals(false, errors.isSuccessful());
}
@Test
public void testUnexpectedAnswer() {
Questionnaire q = new Questionnaire();

View File

@ -137,6 +137,11 @@
Fix a failure in FhirTerser#visit when fields in model classes being visited contain custom subclasses of the
expected type.
</action>
<action type="fix">
Updating an existing CodeSystem resource with a content mode of COMPLETE did not cause the
terminology service to accurately reflect the new CodeSystem URL and/or concepts. This is now
corrected.
</action>
</release>
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
<action type="fix">