update terminology server for test reconciliation with tx.fhir.org

This commit is contained in:
Grahame Grieve 2023-12-25 00:28:39 +11:00
parent 8e55d76a2e
commit 3ed816209d
16 changed files with 122 additions and 43 deletions

View File

@ -211,8 +211,14 @@ public class TerminologyClientR2 implements ITerminologyClient {
}
@Override
public ITerminologyClient setLanguage(String lang) {
client.setLanguage(lang);
public ITerminologyClient setAcceptLanguage(String lang) {
client.setAcceptLanguage(lang);
return this;
}
@Override
public ITerminologyClient setContentLanguage(String lang) {
client.setContentLanguage(lang);
return this;
}
}

View File

@ -213,8 +213,14 @@ public class TerminologyClientR3 implements ITerminologyClient {
}
@Override
public ITerminologyClient setLanguage(String lang) {
client.setLanguage(lang);
public ITerminologyClient setAcceptLanguage(String lang) {
client.setAcceptLanguage(lang);
return this;
}
@Override
public ITerminologyClient setContentLanguage(String lang) {
client.setContentLanguage(lang);
return this;
}
}

View File

@ -223,9 +223,16 @@ public class TerminologyClientR4 implements ITerminologyClient {
return client.getServerVersion();
}
@Override
public ITerminologyClient setLanguage(String lang) {
client.setLanguage(lang);
public ITerminologyClient setAcceptLanguage(String lang) {
client.setAcceptLanguage(lang);
return this;
}
@Override
public ITerminologyClient setContentLanguage(String lang) {
client.setContentLanguage(lang);
return this;
}
}

View File

@ -201,8 +201,14 @@ public class TerminologyClientR5 implements ITerminologyClient {
}
@Override
public ITerminologyClient setLanguage(String lang) {
client.setLanguage(lang);
public ITerminologyClient setAcceptLanguage(String lang) {
client.setAcceptLanguage(lang);
return this;
}
@Override
public ITerminologyClient setContentLanguage(String lang) {
client.setContentLanguage(lang);
return this;
}
}

View File

@ -106,6 +106,7 @@ public class ClientUtils {
private int retryCount;
private String userAgent;
private String acceptLang;
private String contentLang;
public HttpHost getProxy() {
return proxy;
@ -298,6 +299,9 @@ public class ClientUtils {
if (!Utilities.noString(acceptLang)) {
request.addHeader("Accept-Language", acceptLang);
}
if (!Utilities.noString(contentLang)) {
request.addHeader("Content-Language", acceptLang);
}
if (format != null) {
request.addHeader("Accept", format);
@ -726,7 +730,10 @@ public class ClientUtils {
this.userAgent = userAgent;
}
public void setLanguage(String language) {
public void setAcceptLanguage(String language) {
this.acceptLang = language;
}
public void setContentLanguage(String language) {
this.contentLang = language;
}
}

View File

@ -894,8 +894,12 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
return conf == null ? null : conf.getSoftware().getVersion();
}
public void setLanguage(String lang) {
utils.setLanguage(lang);
public void setContentLanguage(String lang) {
utils.setContentLanguage(lang);
}
public void setAcceptLanguage(String lang) {
utils.setAcceptLanguage(lang);
}
}

View File

@ -78,6 +78,7 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
private String userAgent;
private EnumSet<FhirPublication> allowedVersions;
private String acceptLang;
private String contentLang;
//Pass endpoint for client - URI
public FHIRToolingClient(String baseServiceUrl, String userAgent) throws URISyntaxException {
@ -593,6 +594,9 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
if (!Utilities.noString(acceptLang)) {
builder.add("Accept-Language: "+acceptLang);
}
if (!Utilities.noString(contentLang)) {
builder.add("Content-Language: "+contentLang);
}
return builder.build();
}
@ -619,8 +623,11 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
return capabilities == null ? null : capabilities.getSoftware().getVersion();
}
public void setLanguage(String lang) {
public void setAcceptLanguage(String lang) {
this.acceptLang = lang;
}
public void setContentLanguage(String lang) {
this.contentLang = lang;
}
}

View File

@ -79,6 +79,7 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
private String password;
private String userAgent;
private String acceptLang;
private String contentLang;
// Pass endpoint for client - URI
public FHIRToolingClient(String baseServiceUrl, String userAgent) throws URISyntaxException {
@ -579,6 +580,9 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
if (!Utilities.noString(acceptLang)) {
builder.add("Accept-Language: "+acceptLang);
}
if (!Utilities.noString(contentLang)) {
builder.add("Content-Language: "+contentLang);
}
return builder.build();
}
@ -606,7 +610,11 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
return capabilities == null ? null : capabilities.getSoftware().getVersion();
}
public void setLanguage(String lang) {
public void setAcceptLanguage(String lang) {
this.acceptLang = lang;
}
public void setContentLanguage(String lang) {
this.acceptLang = lang;
}

View File

@ -65,6 +65,7 @@ public interface ITerminologyClient {
ClientHeaders getClientHeaders();
ITerminologyClient setClientHeaders(ClientHeaders clientHeaders);
ITerminologyClient setUserAgent(String userAgent);
ITerminologyClient setLanguage(String lang);
ITerminologyClient setAcceptLanguage(String lang);
ITerminologyClient setContentLanguage(String lang);
String getUserAgent();
}

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.r5.terminologies.utilities;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@ -8,6 +9,7 @@ import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
public class ValidationResult {
@ -16,7 +18,7 @@ public class ValidationResult {
private String system;
private String version;
private IssueSeverity severity;
private String message;
private List<String> messages = new ArrayList<>();
private TerminologyServiceErrorClass errorClass;
private String txLink;
private String diagnostics;
@ -28,13 +30,13 @@ public class ValidationResult {
@Override
public String toString() {
return "ValidationResult [definition=" + definition + ", system=" + system + ", severity=" + severity + ", message=" + message + ", errorClass="
return "ValidationResult [definition=" + definition + ", system=" + system + ", severity=" + severity + ", message=" + getMessage() + ", errorClass="
+ errorClass + ", txLink=" + txLink + "]";
}
public ValidationResult(IssueSeverity severity, String message, List<OperationOutcomeIssueComponent> issues) {
this.severity = severity;
this.message = message;
this.messages.add(message);
if (issues != null) {
this.issues.addAll(issues);
}
@ -49,7 +51,7 @@ public class ValidationResult {
public ValidationResult(IssueSeverity severity, String message, String system, String version, ConceptDefinitionComponent definition, String preferredDisplay, List<OperationOutcomeIssueComponent> issues) {
this.severity = severity;
this.message = message;
this.messages.add(message);
this.system = system;
this.version = version;
this.definition = definition;
@ -61,7 +63,7 @@ public class ValidationResult {
public ValidationResult(IssueSeverity severity, String message, TerminologyServiceErrorClass errorClass, List<OperationOutcomeIssueComponent> issues) {
this.severity = severity;
this.message = message;
this.messages.add(message);
this.errorClass = errorClass;
if (issues != null) {
this.issues.addAll(issues);
@ -121,7 +123,11 @@ public class ValidationResult {
}
public String getMessage() {
return message;
if (messages.size() == 0) {
return null;
}
Collections.sort(messages);
return CommaSeparatedStringBuilder.join("; ", messages);
}
public boolean IsNoService() {
@ -138,12 +144,13 @@ public class ValidationResult {
}
public ValidationResult setMessage(String message) {
this.message = message;
this.messages.clear();
this.messages.add(message);
return this;
}
public ValidationResult addToMessage(String message) {
this.message = this.message == null ? message : this.message +"; "+ message;
public ValidationResult addMessage(String message) {
this.messages.add(message);
return this;
}
@ -162,7 +169,7 @@ public class ValidationResult {
}
public boolean hasMessage() {
return message != null;
return !messages.isEmpty();
}
public String getDiagnostics() {

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.r5.terminologies.validation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity;
@ -41,10 +42,11 @@ public class ValidationProcessInfo {
return false;
}
public String summary() {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder("; ");
List<String> msgs = new ArrayList<>();
for (OperationOutcomeIssueComponent issue : issues) {
b.append(issue.getDetails().getText());
msgs.add(issue.getDetails().getText());
}
return b.toString();
Collections.sort(msgs);
return CommaSeparatedStringBuilder.join("; ", msgs);
}
}

View File

@ -239,8 +239,10 @@ public class ValueSetValidator extends ValueSetProcessBase {
if (valueset != null && options.getValueSetMode() != ValueSetMode.NO_MEMBERSHIP_CHECK) {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(", ");
int i = 0;
for (Coding c : code.getCoding()) {
b.append("'"+c.getSystem()+(c.hasVersion() ? "|"+c.getVersion() : "")+"#"+c.getCode()+"'");
String cs = "'"+c.getSystem()+(c.hasVersion() ? "|"+c.getVersion() : "")+"#"+c.getCode()+"'";
b.append(cs);
Boolean ok = codeInValueSet(path, c.getSystem(), c.getVersion(), c.getCode(), info);
if (ok == null && result != null && result == false) {
result = null;
@ -254,18 +256,23 @@ public class ValueSetValidator extends ValueSetProcessBase {
if (ok == null || !ok) {
vcc.removeCoding(c.getSystem(), c.getVersion(), c.getCode());
}
if (ok != null && !ok) {
msg = context.formatMessage(I18nConstants.NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ONE, null, valueset.getVersionedUrl(), cs);
info.getIssues().addAll(makeIssue(IssueSeverity.WARNING, IssueType.CODEINVALID, path+".coding["+i+"].code", msg));
}
i++;
}
if (result == null) {
msg = context.formatMessage(I18nConstants.UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getVersionedUrl(), b.toString());
info.getIssues().addAll(makeIssue(IssueSeverity.WARNING, unknownSystems.isEmpty() ? IssueType.CODEINVALID : IssueType.NOTFOUND, path, msg));
} else if (!result) {
// to match Ontoserver
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR, org.hl7.fhir.r5.model.OperationOutcome.IssueType.INVALID);
OperationOutcomeIssueComponent iss = new OperationOutcomeIssueComponent(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.ERROR, org.hl7.fhir.r5.model.OperationOutcome.IssueType.CODEINVALID);
iss.getDetails().setText(context.formatMessage(I18nConstants.TX_GENERAL_CC_ERROR_MESSAGE, valueset.getVersionedUrl()));
info.getIssues().add(iss);
msg = context.formatMessagePlural(code.getCoding().size(), I18nConstants.NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getVersionedUrl(), b.toString());
info.getIssues().addAll(makeIssue(IssueSeverity.ERROR, IssueType.CODEINVALID, code.getCoding().size() == 1 ? path+".coding[0].code" : path, msg));
// msg = context.formatMessagePlural(code.getCoding().size(), I18nConstants.NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getVersionedUrl(), b.toString());
// info.getIssues().addAll(makeIssue(IssueSeverity.ERROR, IssueType.CODEINVALID, code.getCoding().size() == 1 ? path+".coding[0].code" : path, msg));
}
}
if (vcc.hasCoding() && code.hasText()) {
@ -484,7 +491,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
// we'll take it on faith
String disp = getPreferredDisplay(cc);
res = new ValidationResult(system, cs.getVersion(), new ConceptDefinitionComponent().setCode(cc.getCode()).setDisplay(disp), disp);
res.addToMessage("Resolved system "+system+", but the definition is not complete, so assuming value set include is correct");
res.addMessage("Resolved system "+system+", but the definition is not complete, so assuming value set include is correct");
return res;
}
}
@ -497,7 +504,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
// we just take the value set as face value then
res = new ValidationResult(system, wv, new ConceptDefinitionComponent().setCode(code.getCode()).setDisplay(code.getDisplay()), code.getDisplay());
if (!preferServerSide(system)) {
res.addToMessage("Code System unknown, so assuming value set expansion is correct ("+warningMessage+")");
res.addMessage("Code System unknown, so assuming value set expansion is correct ("+warningMessage+")");
}
} else {
// well, we didn't find a code system - try the expansion?
@ -529,7 +536,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
}
if (ok == null) {
String m = "Unable to check whether the code is in the value set "+valueset.getVersionedUrl();
res.addToMessage(m);
res.addMessage(m);
res.getIssues().addAll(makeIssue(IssueSeverity.WARNING, IssueType.NOTFOUND, path, m));
res.setUnknownSystems(unknownSystems);
res.setSeverity(IssueSeverity.ERROR); // back patching for display logic issue
@ -541,7 +548,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
// } else
// {
String msg = context.formatMessagePlural(1, I18nConstants.NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getVersionedUrl(), "'"+code.toString()+"'");
res.addToMessage(msg).setSeverity(IssueSeverity.ERROR);
res.addMessage(msg).setSeverity(IssueSeverity.ERROR);
res.getIssues().addAll(makeIssue(IssueSeverity.ERROR, IssueType.CODEINVALID, path+".code", msg));
res.setDefinition(null);
res.setSystem(null);
@ -563,7 +570,7 @@ public class ValueSetValidator extends ValueSetProcessBase {
}
} else if ((res != null && !res.isOk())) {
String msg = context.formatMessagePlural(1, I18nConstants.NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getVersionedUrl(), "'"+code.toString()+"'");
res.setMessage(res.getMessage()+"; "+msg);
res.addMessage(msg);
res.getIssues().addAll(makeIssue(IssueSeverity.ERROR, IssueType.CODEINVALID, path+".code", msg));
}
}

View File

@ -104,6 +104,7 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
private String acceptLang;
private String contentLang;
//Pass endpoint for client - URI
public FHIRToolingClient(String baseServiceUrl, String userAgent) throws URISyntaxException {
@ -608,6 +609,10 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
builder.add("Accept-Language: "+acceptLang);
}
if (!Utilities.noString(contentLang)) {
builder.add("Content-Language: "+contentLang);
}
return builder.build();
}
@ -640,10 +645,14 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
return capabilities == null ? null : capabilities.getSoftware().getVersion();
}
public void setLanguage(String lang) {
public void setAcceptLanguage(String lang) {
this.acceptLang = lang;
}
public void setContentLanguage(String lang) {
this.contentLang = lang;
}
public Bundle search(String type, String criteria) {
return fetchFeed(Utilities.pathURL(base, type+criteria));
}

View File

@ -265,6 +265,7 @@ public class I18nConstants {
public static final String NEEDS_A_SNAPSHOT = "needs_a_snapshot";
public static final String NODE_TYPE__IS_NOT_ALLOWED = "Node_type__is_not_allowed";
public static final String NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ = "None_of_the_provided_codes_are_in_the_value_set";
public static final String NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ONE = "None_of_the_provided_codes_are_in_the_value_set_one";
public static final String UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_ = "UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_";
public static final String NOT_DONE_YET = "Not_done_yet";
public static final String NOT_DONE_YET_CANT_FETCH_ = "not_done_yet_cant_fetch_";

View File

@ -190,7 +190,7 @@ public class TxTester {
}
JsonObject ext = externals == null ? null : externals.getJsonObject(fn);
String lang = test.asString("Accept-Language");
String lang = test.asString("Content-Language");
String msg = null;
if (test.asString("operation").equals("expand")) {
msg = expand(tx, setup, req, resp, fp, lang, profile, ext);
@ -248,7 +248,7 @@ public class TxTester {
for (Resource r : setup) {
p.addParameter().setName("tx-resource").setResource(r);
}
tx.setLanguage(lang);
tx.setContentLanguage(lang);
p.getParameter().addAll(profile.getParameter());
String vsj;
try {
@ -274,7 +274,7 @@ public class TxTester {
p.addParameter().setName("tx-resource").setResource(r);
}
p.getParameter().addAll(profile.getParameter());
tx.setLanguage(lang);
tx.setContentLanguage(lang);
String pj;
try {
Parameters po = tx.validateVS(p);

View File

@ -324,9 +324,10 @@ public class TerminologyServiceTests {
if (vm.getDisplay() != null) {
res.addParameter("display", vm.getDisplay());
}
if (vm.getCodeableConcept() != null) {
res.addParameter("codeableConcept", vm.getCodeableConcept());
} else if (cc != null) {
// if (vm.getCodeableConcept() != null) {
// res.addParameter("codeableConcept", vm.getCodeableConcept());
// } else
if (cc != null) {
res.addParameter("codeableConcept", cc);
}
if (vm.isInactive()) {