Merge pull request #1540 from hapifhir/2024-01-gg-multi_tx

more work on multiple terminology servers
This commit is contained in:
Grahame Grieve 2024-01-12 12:15:33 +11:00 committed by GitHub
commit 13dd587f38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 80 additions and 16 deletions

View File

@ -1,6 +1,6 @@
## Validator Changes
* no changes
* Fix issues with multiple terminology servers (should be live soon)
## Other code changes

View File

@ -231,7 +231,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
private Object lock = new Object(); // used as a lock for the data that follows
protected String version; // although the internal resources are all R5, the version of FHIR they describe may not be
protected TerminologyClientManager terminologyClientManager = new TerminologyClientManager(new TerminologyClientR5Factory());
protected TerminologyClientManager terminologyClientManager = new TerminologyClientManager(null);
private boolean minimalMemory = false;
private Map<String, Map<String, ResourceProxy>> allResourcesById = new HashMap<String, Map<String, ResourceProxy>>();
@ -850,6 +850,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
}
Set<String> systems = findRelevantSystems(vs);
TerminologyClientContext tc = terminologyClientManager.chooseServer(systems, true);
if (tc == null) {
res = new ValueSetExpansionOutcome("No server available", TerminologyServiceErrorClass.INTERNAL_ERROR, true);
}
Parameters p = constructParameters(tc, vs, hierarchical);
for (ConceptSetComponent incl : vs.getCompose().getInclude()) {
codeSystemsUsed.add(incl.getSystem());
@ -1885,8 +1888,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
return expParameters;
}
public void setExpansionProfile(Parameters expParameters) {
public void setExpansionParameters(Parameters expParameters) {
this.expParameters = expParameters;
this.terminologyClientManager.setExpansionParameters(expParameters);
}
@Override

View File

@ -284,7 +284,7 @@ public interface IWorkerContext {
*
* Note that the Validation Options override these when they are specified on validateCode
*/
public void setExpansionProfile(Parameters expParameters);
public void setExpansionParameters(Parameters expParameters);
// these are the terminology services used internally by the tools
/**

View File

@ -535,7 +535,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
version = "5.0.0";
}
}
if (loader != null) {
if (loader != null && terminologyClientManager.getFactory() == null) {
terminologyClientManager.setFactory(loader.txFactory());
}
return t;

View File

@ -1512,7 +1512,14 @@ public String toString() {
}
return s;
}
public boolean hasValuePrimitive() {
return hasValue() && getValue() instanceof PrimitiveType<?>;
}
// end addition
}
/**

View File

@ -2,7 +2,9 @@ package org.hl7.fhir.r5.terminologies.client;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -11,6 +13,8 @@ import java.util.Map;
import java.util.Set;
import org.hl7.fhir.exceptions.TerminologyServiceException;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r5.model.TerminologyCapabilities;
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache;
import org.hl7.fhir.utilities.ToolingClientLogger;
@ -37,10 +41,12 @@ public class TerminologyClientManager {
private Map<String, TerminologyClientContext> serverMap = new HashMap<>(); // clients by server address
private Map<String, String> resMap = new HashMap<>(); // client resolution list
private List<String> internalErrors = new ArrayList<>();
protected Parameters expParameters;
private TerminologyCache cache;
private File cacheFile;
private String usage;
private String monitorServiceURL;
@ -65,7 +71,6 @@ public class TerminologyClientManager {
this.isTxCaching = isTxCaching;
}
public void copy(TerminologyClientManager other) {
cacheId = other.cacheId;
isTxCaching = other.isTxCaching;
@ -74,6 +79,7 @@ public class TerminologyClientManager {
resMap.putAll(other.resMap);
monitorServiceURL = other.monitorServiceURL;
factory = other.factory;
usage = other.usage;
}
public boolean usingCache() {
@ -105,6 +111,13 @@ public class TerminologyClientManager {
String server = resMap.get(s);
if (server == null) {
server = decideWhichServer(s);
// testing support
if (server != null && server.contains("://tx.fhir.org")) {
try {
server = server.replace("tx.fhir.org", new URL(getMasterClient().getAddress()).getHost());
} catch (MalformedURLException e) {
}
}
resMap.put(s, server);
save();
}
@ -123,7 +136,27 @@ public class TerminologyClientManager {
}
private String decideWhichServer(String url) {
if (expParameters != null) {
if (!url.contains("|")) {
// the client hasn''t specified an explicit version, but the expansion parameters might
for (ParametersParameterComponent p : expParameters.getParameter()) {
if (Utilities.existsInList(p.getName(), "system-version", "force-system-version") && p.hasValuePrimitive() && p.getValue().primitiveValue().startsWith(url+"|")) {
url = p.getValue().primitiveValue();
}
}
} else {
// the expansion parameters might override the version
for (ParametersParameterComponent p : expParameters.getParameter()) {
if (Utilities.existsInList(p.getName(), "force-system-version") && p.hasValueCanonicalType() && p.getValue().primitiveValue().startsWith(url+"|")) {
url = p.getValue().primitiveValue();
}
}
}
}
String request = Utilities.pathURL(monitorServiceURL, "resolve?fhirVersion="+factory.getVersion()+"&url="+url);
if (usage != null) {
request = request + "&usage="+usage;
}
try {
JsonObject json = JsonParser.parseObjectFromUrl(request);
for (JsonObject item : json.getJsonObjects("authoritative")) {
@ -209,6 +242,7 @@ public class TerminologyClientManager {
public void setFactory(ITerminologyClientFactory factory) {
this.factory = factory;
System.out.println("tcc factory version = "+factory.getVersion());
}
public void setCache(TerminologyCache cache) {
@ -264,4 +298,20 @@ public class TerminologyClientManager {
public Parameters getExpansionParameters() {
return expParameters;
}
public void setExpansionParameters(Parameters expParameters) {
this.expParameters = expParameters;
}
public String getUsage() {
return usage;
}
public void setUsage(String usage) {
this.usage = usage;
}
}

View File

@ -86,7 +86,7 @@ public class TestingUtilities extends BaseTestingUtilities {
fcontext = getWorkerContext(pcm.loadPackage(VersionUtilities.packageForVersion(version), version));
}
fcontext.setUcumService(new UcumEssenceService(TestingUtilities.loadTestResourceStream("ucum", "ucum-essence.xml")));
fcontext.setExpansionProfile(new Parameters());
fcontext.setExpansionParameters(new Parameters());
if (!fcontext.hasPackage("hl7.terminology.r5", null)) {
NpmPackage utg = pcm.loadPackage("hl7.terminology.r5");
System.out.println("Loading THO: "+utg.name()+"#"+utg.version());

View File

@ -1,6 +1,8 @@
package org.hl7.fhir.r5.context;
import static org.junit.jupiter.api.Assertions.*;
import org.hl7.fhir.r5.terminologies.client.TerminologyClientR5.TerminologyClientR5Factory;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.argThat;
@ -432,7 +434,7 @@ public class SimpleWorkerContextTests {
Mockito.doReturn(terminologyCapabilities).when(terminologyCache).getTerminologyCapabilities();
Mockito.doReturn(capabilitiesStatement).when(terminologyCache).getCapabilityStatement();
String actual = context.connectToTSServer(null, terminologyClient, null);
String actual = context.connectToTSServer(new TerminologyClientR5Factory(), terminologyClient, null);
assertEquals("dummyVersion", actual);
@ -454,7 +456,7 @@ public class SimpleWorkerContextTests {
Mockito.doReturn(terminologyCapabilities).when(terminologyClient).getTerminologyCapabilities();
Mockito.doReturn(capabilitiesStatement).when(terminologyClient).getCapabilitiesStatementQuick();
String actual = context.connectToTSServer(null, terminologyClient, null);
String actual = context.connectToTSServer(new TerminologyClientR5Factory(), terminologyClient, null);
assertEquals("dummyVersion", actual);

View File

@ -477,7 +477,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
context.setCanNoTS(true);
context.setCacheId(UUID.randomUUID().toString());
context.setAllowLoadingDuplicates(true); // because of Forge
context.setExpansionProfile(makeExpProfile());
context.setExpansionParameters(makeExpProfile());
if (tt != null) {
context.setClock(tt);
}
@ -841,6 +841,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
public InstanceValidator getValidator(FhirFormat format) throws FHIRException, IOException {
InstanceValidator validator = new InstanceValidator(context, null, null);
context.getTxClientManager().setUsage("validation");
validator.setHintAboutNonMustSupport(hintAboutNonMustSupport);
validator.setAnyExtensionsAllowed(anyExtensionsAllowed);
validator.getExtensionDomains().clear();

View File

@ -196,7 +196,7 @@ public class R4R5MapTester implements IValidatorResourceFetcher {
validator.setDebug(false);
validator.setForPublication(true);
validator.setNoTerminologyChecks(true);
context.setExpansionProfile(new Parameters());
context.setExpansionParameters(new Parameters());
log("Load R4 Examples");
NpmPackage r4Examples = pcm.loadPackage("hl7.fhir.r4.examples");

View File

@ -90,7 +90,7 @@ public class UtilitiesXTests {
pcm = new FilesystemPackageCacheManager.Builder().build();
IWorkerContext fcontext = TestingUtilities.getWorkerContext(pcm.loadPackage(VersionUtilities.packageForVersion(version), version), loaderForVersion(version));
fcontext.setUcumService(new UcumEssenceService(UtilitiesXTests.loadTestResourceStream("ucum", "ucum-essence.xml")));
fcontext.setExpansionProfile(new Parameters());
fcontext.setExpansionParameters(new Parameters());
fcontexts.put(version, fcontext);
} catch (Exception e) {
throw new Error(e);

View File

@ -140,9 +140,9 @@ public class TerminologyServiceTests {
fo.delete();
}
if (setup.test.has("profile")) {
engine.getContext().setExpansionProfile((org.hl7.fhir.r5.model.Parameters) loadResource(setup.test.asString("profile")));
engine.getContext().setExpansionParameters((org.hl7.fhir.r5.model.Parameters) loadResource(setup.test.asString("profile")));
} else {
engine.getContext().setExpansionProfile((org.hl7.fhir.r5.model.Parameters) loadResource("parameters-default.json"));
engine.getContext().setExpansionParameters((org.hl7.fhir.r5.model.Parameters) loadResource("parameters-default.json"));
}
if (setup.test.asString("operation").equals("expand")) {
expand(engine, req, resp, setup.test.asString("Content-Language"), fp, ext);

View File

@ -20,7 +20,7 @@
<properties>
<guava_version>32.0.1-jre</guava_version>
<hapi_fhir_version>6.4.1</hapi_fhir_version>
<validator_test_case_version>1.4.23</validator_test_case_version>
<validator_test_case_version>1.4.23-SNAPSHOT</validator_test_case_version>
<jackson_version>2.16.0</jackson_version>
<junit_jupiter_version>5.9.2</junit_jupiter_version>
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>