Merge remote-tracking branch 'origin/master' into do-20240327-language-translation-coverage
This commit is contained in:
commit
dab6150e9a
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -125,6 +125,7 @@ import org.hl7.fhir.r5.terminologies.utilities.TerminologyOperationContext.Termi
|
|||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.CacheToken;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedCodeSystem;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedValueSet;
|
||||
import org.hl7.fhir.r5.terminologies.validation.VSCheckerException;
|
||||
import org.hl7.fhir.r5.terminologies.validation.ValueSetValidator;
|
||||
|
@ -3234,6 +3235,28 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
cacheResource(svs.getVs());
|
||||
return (T) svs.getVs();
|
||||
}
|
||||
} else if (class_ == CodeSystem.class) {
|
||||
SourcedCodeSystem scs = null;
|
||||
if (txCache.hasCodeSystem(canonical)) {
|
||||
scs = txCache.getCodeSystem(canonical);
|
||||
} else {
|
||||
scs = terminologyClientManager.findCodeSystemOnServer(canonical);
|
||||
txCache.cacheCodeSystem(canonical, scs);
|
||||
}
|
||||
if (scs != null) {
|
||||
String web = ToolingExtensions.readStringExtension(scs.getCs(), ToolingExtensions.EXT_WEB_SOURCE);
|
||||
if (web == null) {
|
||||
web = Utilities.pathURL(scs.getServer(), "ValueSet", scs.getCs().getIdBase());
|
||||
}
|
||||
scs.getCs().setWebPath(web);
|
||||
scs.getCs().setUserData("External.Link", scs.getServer()); // so we can render it differently
|
||||
}
|
||||
if (scs == null) {
|
||||
return null;
|
||||
} else {
|
||||
cacheResource(scs.getCs());
|
||||
return (T) scs.getCs();
|
||||
}
|
||||
} else {
|
||||
throw new Error("Not supported");
|
||||
}
|
||||
|
|
|
@ -332,12 +332,12 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
loadBytes(name, stream);
|
||||
}
|
||||
|
||||
public void connectToTSServer(ITerminologyClientFactory factory, ITerminologyClient client) {
|
||||
public void connectToTSServer(ITerminologyClientFactory factory, ITerminologyClient client, boolean useEcosystem) {
|
||||
terminologyClientManager.setFactory(factory);
|
||||
if (txLog == null) {
|
||||
txLog = client.getLogger();
|
||||
}
|
||||
TerminologyClientContext tcc = terminologyClientManager.setMasterClient(client);
|
||||
TerminologyClientContext tcc = terminologyClientManager.setMasterClient(client, useEcosystem);
|
||||
txLog("Connect to "+client.getAddress());
|
||||
try {
|
||||
tcc.initialize();
|
||||
|
@ -357,7 +357,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
}
|
||||
}
|
||||
|
||||
public void connectToTSServer(ITerminologyClientFactory factory, String address, String software, String log) {
|
||||
public void connectToTSServer(ITerminologyClientFactory factory, String address, String software, String log, boolean useEcosystem) {
|
||||
try {
|
||||
terminologyClientManager.setFactory(factory);
|
||||
if (log != null && (log.endsWith(".htm") || log.endsWith(".html"))) {
|
||||
|
@ -369,7 +369,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
// txFactory.makeClient("Tx-Server", txServer, "fhir/publisher", null)
|
||||
// terminologyClientManager.setLogger(txLog);
|
||||
// terminologyClientManager.setUserAgent(userAgent);
|
||||
connectToTSServer(factory, client);
|
||||
connectToTSServer(factory, client, useEcosystem);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -71,9 +71,42 @@ import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
|||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.StandardsStatus;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
|
||||
public class CodeSystemUtilities extends TerminologyUtilities {
|
||||
|
||||
public static class CodeSystemSorter implements Comparator<CodeSystem> {
|
||||
|
||||
@Override
|
||||
public int compare(CodeSystem o1, CodeSystem o2) {
|
||||
String url1 = o1.getUrl();
|
||||
String url2 = o2.getUrl();
|
||||
int c = compareString(url1, url2);
|
||||
if (c == 0) {
|
||||
String ver1 = o1.getVersion();
|
||||
String ver2 = o2.getVersion();
|
||||
c = VersionUtilities.compareVersions(ver1, ver2);
|
||||
if (c == 0) {
|
||||
String d1 = o1.getDateElement().asStringValue();
|
||||
String d2 = o2.getDateElement().asStringValue();
|
||||
c = compareString(url1, url2);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private int compareString(String s1, String s2) {
|
||||
if (s1 == null) {
|
||||
return s2 == null ? 0 : 1;
|
||||
} else {
|
||||
return s1.compareTo(s2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class SystemReference {
|
||||
private String link;
|
||||
private String text;
|
||||
|
|
|
@ -16,19 +16,26 @@ import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache;
|
|||
|
||||
public class TerminologyClientContext {
|
||||
public enum TerminologyClientContextUseType {
|
||||
expand, validate, readVS
|
||||
expand, validate, readVS, readCS
|
||||
}
|
||||
public class TerminologyClientContextUseCount {
|
||||
private int expands;
|
||||
private int validates;
|
||||
private int readVS;
|
||||
|
||||
private int readCS;
|
||||
|
||||
public int getReadVS() {
|
||||
return readVS;
|
||||
}
|
||||
public void setReadVS(int readVS) {
|
||||
this.readVS = readVS;
|
||||
}
|
||||
public int getReadCS() {
|
||||
return readCS;
|
||||
}
|
||||
public void setReadCS(int readCS) {
|
||||
this.readCS = readCS;
|
||||
}
|
||||
public int getExpands() {
|
||||
return expands;
|
||||
}
|
||||
|
@ -94,6 +101,9 @@ public class TerminologyClientContext {
|
|||
case readVS:
|
||||
uc.readVS++;
|
||||
break;
|
||||
case readCS:
|
||||
uc.readCS++;
|
||||
break;
|
||||
case validate:
|
||||
uc.validates++;
|
||||
break;
|
||||
|
|
|
@ -17,15 +17,18 @@ import org.hl7.fhir.exceptions.TerminologyServiceException;
|
|||
import org.hl7.fhir.r5.context.CanonicalResourceManager;
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.r5.model.CodeSystem;
|
||||
import org.hl7.fhir.r5.model.Parameters;
|
||||
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
|
||||
import org.hl7.fhir.r5.model.TerminologyCapabilities.TerminologyCapabilitiesCodeSystemComponent;
|
||||
import org.hl7.fhir.r5.model.TerminologyCapabilities;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.TerminologyClientContextUseType;
|
||||
import org.hl7.fhir.r5.terminologies.client.TerminologyClientManager.ServerOptionList;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedCodeSystem;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedValueSet;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
|
@ -100,6 +103,8 @@ public class TerminologyClientManager {
|
|||
|
||||
private String monitorServiceURL;
|
||||
|
||||
private boolean useEcosystem;
|
||||
|
||||
public TerminologyClientManager(ITerminologyClientFactory factory, String cacheId) {
|
||||
super();
|
||||
this.factory = factory;
|
||||
|
@ -115,6 +120,7 @@ public class TerminologyClientManager {
|
|||
serverList.addAll(other.serverList);
|
||||
serverMap.putAll(other.serverMap);
|
||||
resMap.putAll(other.resMap);
|
||||
useEcosystem = other.useEcosystem;
|
||||
monitorServiceURL = other.monitorServiceURL;
|
||||
factory = other.factory;
|
||||
usage = other.usage;
|
||||
|
@ -238,7 +244,7 @@ public class TerminologyClientManager {
|
|||
}
|
||||
|
||||
private ServerOptionList decideWhichServer(String url) {
|
||||
if (IGNORE_TX_REGISTRY) {
|
||||
if (IGNORE_TX_REGISTRY || !useEcosystem) {
|
||||
return new ServerOptionList(getMasterClient().getAddress());
|
||||
}
|
||||
if (expParameters != null) {
|
||||
|
@ -315,7 +321,8 @@ public class TerminologyClientManager {
|
|||
}
|
||||
}
|
||||
|
||||
public TerminologyClientContext setMasterClient(ITerminologyClient client) {
|
||||
public TerminologyClientContext setMasterClient(ITerminologyClient client, boolean useEcosystem) {
|
||||
this.useEcosystem = useEcosystem;
|
||||
TerminologyClientContext details = new TerminologyClientContext(client, cacheId, true);
|
||||
details.setTxCache(cache);
|
||||
serverList.clear();
|
||||
|
@ -419,7 +426,7 @@ public class TerminologyClientManager {
|
|||
}
|
||||
|
||||
public SourcedValueSet findValueSetOnServer(String canonical) {
|
||||
if (IGNORE_TX_REGISTRY || getMasterClient() == null) {
|
||||
if (IGNORE_TX_REGISTRY || getMasterClient() == null || !useEcosystem) {
|
||||
return null;
|
||||
}
|
||||
String request = Utilities.pathURL(monitorServiceURL, "resolve?fhirVersion="+factory.getVersion()+"&valueSet="+Utilities.URLEncode(canonical));
|
||||
|
@ -498,6 +505,86 @@ public class TerminologyClientManager {
|
|||
}
|
||||
}
|
||||
|
||||
public SourcedCodeSystem findCodeSystemOnServer(String canonical) {
|
||||
if (IGNORE_TX_REGISTRY || getMasterClient() == null || !useEcosystem) {
|
||||
return null;
|
||||
}
|
||||
String request = Utilities.pathURL(monitorServiceURL, "resolve?fhirVersion="+factory.getVersion()+"&url="+Utilities.URLEncode(canonical));
|
||||
if (usage != null) {
|
||||
request = request + "&usage="+usage;
|
||||
}
|
||||
String server = null;
|
||||
try {
|
||||
JsonObject json = JsonParser.parseObjectFromUrl(request);
|
||||
for (JsonObject item : json.getJsonObjects("authoritative")) {
|
||||
if (server == null) {
|
||||
server = item.asString("url");
|
||||
}
|
||||
}
|
||||
for (JsonObject item : json.getJsonObjects("candidates")) {
|
||||
if (server == null) {
|
||||
server = item.asString("url");
|
||||
}
|
||||
}
|
||||
if (server == null) {
|
||||
return null;
|
||||
}
|
||||
if (server.contains("://tx.fhir.org")) {
|
||||
try {
|
||||
server = server.replace("tx.fhir.org", new URL(getMasterClient().getAddress()).getHost());
|
||||
} catch (MalformedURLException e) {
|
||||
}
|
||||
}
|
||||
TerminologyClientContext client = serverMap.get(server);
|
||||
if (client == null) {
|
||||
try {
|
||||
client = new TerminologyClientContext(factory.makeClient("id"+(serverList.size()+1), server, getMasterClient().getUserAgent(), getMasterClient().getLogger()), cacheId, false);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new TerminologyServiceException(e);
|
||||
}
|
||||
client.setTxCache(cache);
|
||||
serverList.add(client);
|
||||
serverMap.put(server, client);
|
||||
}
|
||||
client.seeUse(canonical, TerminologyClientContextUseType.readCS);
|
||||
String criteria = canonical.contains("|") ?
|
||||
"?_format=json&url="+Utilities.URLEncode(canonical.substring(0, canonical.lastIndexOf("|")))+"&version="+Utilities.URLEncode(canonical.substring(canonical.lastIndexOf("|")+1)):
|
||||
"?_format=json&url="+Utilities.URLEncode(canonical);
|
||||
request = Utilities.pathURL(client.getAddress(), "CodeSystem"+ criteria);
|
||||
Bundle bnd = client.getClient().search("CodeSystem", criteria);
|
||||
String rid = null;
|
||||
if (bnd.getEntry().size() == 0) {
|
||||
return null;
|
||||
} else if (bnd.getEntry().size() > 1) {
|
||||
List<CodeSystem> cslist = new ArrayList<>();
|
||||
for (BundleEntryComponent be : bnd.getEntry()) {
|
||||
if (be.hasResource() && be.getResource() instanceof CodeSystem) {
|
||||
cslist.add((CodeSystem) be.getResource());
|
||||
}
|
||||
}
|
||||
Collections.sort(cslist, new CodeSystemUtilities.CodeSystemSorter());
|
||||
rid = cslist.get(cslist.size()-1).getIdBase();
|
||||
} else {
|
||||
if (bnd.getEntryFirstRep().hasResource() && bnd.getEntryFirstRep().getResource() instanceof CodeSystem) {
|
||||
rid = bnd.getEntryFirstRep().getResource().getIdBase();
|
||||
}
|
||||
}
|
||||
if (rid == null) {
|
||||
return null;
|
||||
}
|
||||
CodeSystem vs = (CodeSystem) client.getClient().read("CodeSystem", rid);
|
||||
return new SourcedCodeSystem(server, vs);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
String msg = "Error resolving valueSet "+canonical+": "+e.getMessage()+" ("+request+")";
|
||||
if (!internalLog.contains(msg)) {
|
||||
internalLog.add(msg);
|
||||
}
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean supportsSystem(String system) throws IOException {
|
||||
for (TerminologyClientContext client : serverList) {
|
||||
if (client.supportsSystem(system)) {
|
||||
|
|
|
@ -83,6 +83,42 @@ import com.google.gson.JsonPrimitive;
|
|||
*/
|
||||
public class TerminologyCache {
|
||||
|
||||
public static class SourcedCodeSystem {
|
||||
private String server;
|
||||
private CodeSystem cs;
|
||||
|
||||
public SourcedCodeSystem(String server, CodeSystem cs) {
|
||||
super();
|
||||
this.server = server;
|
||||
this.cs = cs;
|
||||
}
|
||||
public String getServer() {
|
||||
return server;
|
||||
}
|
||||
public CodeSystem getCs() {
|
||||
return cs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class SourcedCodeSystemEntry {
|
||||
private String server;
|
||||
private String filename;
|
||||
|
||||
public SourcedCodeSystemEntry(String server, String filename) {
|
||||
super();
|
||||
this.server = server;
|
||||
this.filename = filename;
|
||||
}
|
||||
public String getServer() {
|
||||
return server;
|
||||
}
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class SourcedValueSet {
|
||||
private String server;
|
||||
private ValueSet vs;
|
||||
|
@ -253,6 +289,7 @@ public class TerminologyCache {
|
|||
private Map<String, TerminologyCapabilities> terminologyCapabilitiesCache = new HashMap<>();
|
||||
private Map<String, NamedCache> caches = new HashMap<String, NamedCache>();
|
||||
private Map<String, SourcedValueSetEntry> vsCache = new HashMap<>();
|
||||
private Map<String, SourcedCodeSystemEntry> csCache = new HashMap<>();
|
||||
private Map<String, String> serverMap = new HashMap<>();
|
||||
@Getter @Setter private static boolean noCaching;
|
||||
|
||||
|
@ -320,12 +357,14 @@ public class TerminologyCache {
|
|||
// not useable after this is called
|
||||
caches.clear();
|
||||
vsCache.clear();
|
||||
csCache.clear();
|
||||
}
|
||||
|
||||
private void clear() throws IOException {
|
||||
Utilities.clearDirectory(folder);
|
||||
caches.clear();
|
||||
vsCache.clear();
|
||||
csCache.clear();
|
||||
}
|
||||
|
||||
public boolean hasCapabilityStatement(String address) {
|
||||
|
@ -872,6 +911,22 @@ public class TerminologyCache {
|
|||
} catch (Exception e) {
|
||||
System.out.println("Error loading vs external cache: "+e.getMessage());
|
||||
}
|
||||
try {
|
||||
File f = ManagedFileAccess.file(Utilities.path(folder, "cs-externals.json"));
|
||||
if (f.exists()) {
|
||||
org.hl7.fhir.utilities.json.model.JsonObject json = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(f);
|
||||
for (JsonProperty p : json.getProperties()) {
|
||||
if (p.getValue().isJsonNull()) {
|
||||
csCache.put(p.getName(), null);
|
||||
} else {
|
||||
org.hl7.fhir.utilities.json.model.JsonObject j = p.getValue().asJsonObject();
|
||||
csCache.put(p.getName(), new SourcedCodeSystemEntry(j.asString("server"), j.asString("filename")));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error loading vs external cache: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String loadJS(JsonElement e) {
|
||||
|
@ -978,6 +1033,10 @@ public class TerminologyCache {
|
|||
return vsCache.containsKey(canonical);
|
||||
}
|
||||
|
||||
public boolean hasCodeSystem(String canonical) {
|
||||
return csCache.containsKey(canonical);
|
||||
}
|
||||
|
||||
public SourcedValueSet getValueSet(String canonical) {
|
||||
SourcedValueSetEntry sp = vsCache.get(canonical);
|
||||
if (sp == null) {
|
||||
|
@ -991,6 +1050,19 @@ public class TerminologyCache {
|
|||
}
|
||||
}
|
||||
|
||||
public SourcedCodeSystem getCodeSystem(String canonical) {
|
||||
SourcedCodeSystemEntry sp = csCache.get(canonical);
|
||||
if (sp == null) {
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
return new SourcedCodeSystem(sp.getServer(), sp.getFilename() == null ? null : (CodeSystem) new JsonParser().parse(ManagedFileAccess.inStream(Utilities.path(folder, sp.getFilename()))));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cacheValueSet(String canonical, SourcedValueSet svs) {
|
||||
if (canonical == null) {
|
||||
return;
|
||||
|
@ -1024,6 +1096,39 @@ public class TerminologyCache {
|
|||
}
|
||||
}
|
||||
|
||||
public void cacheCodeSystem(String canonical, SourcedCodeSystem scs) {
|
||||
if (canonical == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (scs == null) {
|
||||
csCache.put(canonical, null);
|
||||
} else {
|
||||
String uuid = Utilities.makeUuidLC();
|
||||
String fn = "cs-"+uuid+".json";
|
||||
new JsonParser().compose(ManagedFileAccess.outStream(Utilities.path(folder, fn)), scs.getCs());
|
||||
csCache.put(canonical, new SourcedCodeSystemEntry(scs.getServer(), fn));
|
||||
}
|
||||
org.hl7.fhir.utilities.json.model.JsonObject j = new org.hl7.fhir.utilities.json.model.JsonObject();
|
||||
for (String k : csCache.keySet()) {
|
||||
SourcedCodeSystemEntry sve = csCache.get(k);
|
||||
if (sve == null) {
|
||||
j.add(k, new JsonNull());
|
||||
} else {
|
||||
org.hl7.fhir.utilities.json.model.JsonObject e = new org.hl7.fhir.utilities.json.model.JsonObject();
|
||||
e.set("server", sve.getServer());
|
||||
if (sve.getFilename() != null) {
|
||||
e.set("filename", sve.getFilename());
|
||||
}
|
||||
j.add(k, e);
|
||||
}
|
||||
}
|
||||
org.hl7.fhir.utilities.json.parser.JsonParser.compose(j, ManagedFileAccess.file(Utilities.path(folder, "cs-externals.json")), true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public CacheToken generateSubsumesToken(ValidationOptions options, Coding parent, Coding child, Parameters expParameters) {
|
||||
try {
|
||||
CacheToken ct = new CacheToken();
|
||||
|
|
|
@ -97,7 +97,7 @@ public class SimpleWorkerContextTests {
|
|||
Mockito.doReturn(DUMMY_URL).when(terminologyClient).getAddress();
|
||||
context.initTxCache(terminologyCache);
|
||||
context.expParameters = expParameters;
|
||||
context.terminologyClientManager.setMasterClient(terminologyClient);
|
||||
context.terminologyClientManager.setMasterClient(terminologyClient, false);
|
||||
context.txLog = txLog;
|
||||
}
|
||||
|
||||
|
@ -437,7 +437,7 @@ public class SimpleWorkerContextTests {
|
|||
|
||||
Mockito.doReturn(terminologyCapabilities).when(terminologyCache).getTerminologyCapabilities(address);
|
||||
|
||||
context.connectToTSServer(new TerminologyClientR5Factory(), terminologyClient);
|
||||
context.connectToTSServer(new TerminologyClientR5Factory(), terminologyClient, false);
|
||||
|
||||
Mockito.verify(terminologyCache).getTerminologyCapabilities(address);
|
||||
Mockito.verify(terminologyClient).getCapabilitiesStatementQuick();
|
||||
|
@ -455,7 +455,7 @@ public class SimpleWorkerContextTests {
|
|||
Mockito.doReturn(terminologyCapabilities).when(terminologyClient).getTerminologyCapabilities();
|
||||
Mockito.doReturn(capabilitiesStatement).when(terminologyClient).getCapabilitiesStatementQuick();
|
||||
|
||||
context.connectToTSServer(new TerminologyClientR5Factory(), terminologyClient);
|
||||
context.connectToTSServer(new TerminologyClientR5Factory(), terminologyClient, false);
|
||||
|
||||
Mockito.verify(terminologyCache, times(0)).getTerminologyCapabilities(address);
|
||||
Mockito.verify(terminologyCache, times(0)).getCapabilityStatement(address);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -1125,7 +1125,7 @@ CODESYSTEM_PROPERTY_WRONG_TYPE = The property ''{0}'' has the invalid type ''{1}
|
|||
CODESYSTEM_DESIGNATION_DISP_CLASH_NO_LANG = The designation ''{0}'' has no use and no language, so is not differentiated from the base display (''{1}'')
|
||||
CODESYSTEM_DESIGNATION_DISP_CLASH_LANG = The designation ''{0}'' has no use and is in the same language (''{2}''), so is not differentiated from the base display (''{1}'')
|
||||
VALUESET_UNKNOWN_FILTER_PROPERTY = The property ''{0}'' is not known for the system ''{1}'', so may not be understood by the terminology ecosystem. Known properties for this system: {2}
|
||||
VALUESET_UNKNOWN_FILTER_PROPERTY_NO_CS = No definition can be found for the system {1}, and the property ''{0}'' is not a generally known property, so the property might not be valid, or understood by the terminology ecosystem. In case it's useful, the list of generally known properties for all systems is {2}
|
||||
VALUESET_UNKNOWN_FILTER_PROPERTY_NO_CS = No definition can be found for the system {1}, and the property ''{0}'' is not a generally known property, so the property might not be valid, or understood by the terminology ecosystem. In case it''s useful, the list of generally known properties for all systems is {2}
|
||||
VALUESET_BAD_FILTER_VALUE_BOOLEAN = The value for a filter based on property ''{0}'' must be either ''true'' or ''false'', not ''{1}''
|
||||
VALUESET_BAD_FILTER_VALUE_CODE = The value for a filter based on property ''{0}'' must be a valid code, not ''{1}''
|
||||
VALUESET_BAD_FILTER_VALUE_DATETIME = The value for a filter based on property ''{0}'' must be a valid date(/time), not ''{1}''
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ public class NativeHostServices {
|
|||
* @throws Exception
|
||||
*/
|
||||
public void connectToTxSvc(String txServer, String log) throws Exception {
|
||||
validator.connectToTSServer(txServer, log, FhirPublication.R5);
|
||||
validator.connectToTSServer(txServer, log, FhirPublication.R5, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -171,7 +171,7 @@ public class NativeHostServices {
|
|||
* @throws Exception
|
||||
*/
|
||||
public void connectToTxSvc(String txServer, String log, String txCache) throws Exception {
|
||||
validator.connectToTSServer(txServer, log, txCache, FhirPublication.R5);
|
||||
validator.connectToTSServer(txServer, log, txCache, FhirPublication.R5, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -325,6 +325,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
private final String txServer;
|
||||
private final String txLog;
|
||||
private final FhirPublication txVersion;
|
||||
private final boolean useEcosystem;
|
||||
|
||||
@With
|
||||
private final TimeTracker timeTracker;
|
||||
|
@ -348,10 +349,11 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
txVersion = null;
|
||||
timeTracker = null;
|
||||
canRunWithoutTerminologyServer = false;
|
||||
useEcosystem = true;
|
||||
loggingService = new SystemOutLoggingService();
|
||||
}
|
||||
|
||||
public ValidationEngineBuilder(String terminologyCachePath, String userAgent, String version, String txServer, String txLog, FhirPublication txVersion, TimeTracker timeTracker, boolean canRunWithoutTerminologyServer, ILoggingService loggingService, boolean THO) {
|
||||
public ValidationEngineBuilder(String terminologyCachePath, String userAgent, String version, String txServer, String txLog, FhirPublication txVersion, boolean useEcosystem, TimeTracker timeTracker, boolean canRunWithoutTerminologyServer, ILoggingService loggingService, boolean THO) {
|
||||
this.terminologyCachePath = terminologyCachePath;
|
||||
this.userAgent = userAgent;
|
||||
this.version = version;
|
||||
|
@ -361,15 +363,16 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
this.timeTracker = timeTracker;
|
||||
this.canRunWithoutTerminologyServer = canRunWithoutTerminologyServer;
|
||||
this.loggingService = loggingService;
|
||||
this.useEcosystem = true;
|
||||
this.THO = THO;
|
||||
}
|
||||
|
||||
public ValidationEngineBuilder withTxServer(String txServer, String txLog, FhirPublication txVersion) {
|
||||
return new ValidationEngineBuilder(terminologyCachePath, userAgent, version, txServer, txLog, txVersion, timeTracker, canRunWithoutTerminologyServer, loggingService, THO);
|
||||
public ValidationEngineBuilder withTxServer(String txServer, String txLog, FhirPublication txVersion, boolean useEcosystem) {
|
||||
return new ValidationEngineBuilder(terminologyCachePath, userAgent, version, txServer, txLog, txVersion, useEcosystem, timeTracker, canRunWithoutTerminologyServer, loggingService, THO);
|
||||
}
|
||||
|
||||
public ValidationEngineBuilder withNoTerminologyServer() {
|
||||
return new ValidationEngineBuilder(terminologyCachePath, userAgent, version, null, null, txVersion, timeTracker, true, loggingService, THO);
|
||||
return new ValidationEngineBuilder(terminologyCachePath, userAgent, version, null, null, txVersion, useEcosystem, timeTracker, true, loggingService, THO);
|
||||
}
|
||||
|
||||
public ValidationEngine fromNothing() throws IOException {
|
||||
|
@ -393,7 +396,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
engine.getContext().setCanRunWithoutTerminology(canRunWithoutTerminologyServer);
|
||||
engine.getContext().setPackageTracker(engine);
|
||||
if (txServer != null) {
|
||||
engine.setTerminologyServer(txServer, txLog, txVersion);
|
||||
engine.setTerminologyServer(txServer, txLog, txVersion, useEcosystem);
|
||||
}
|
||||
engine.setVersion(version);
|
||||
engine.setIgLoader(new IgLoader(engine.getPcm(), engine.getContext(), engine.getVersion(), engine.isDebug()));
|
||||
|
@ -514,11 +517,11 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
return ep;
|
||||
}
|
||||
|
||||
public String connectToTSServer(String url, String log, FhirPublication version) throws URISyntaxException, IOException, FHIRException {
|
||||
return connectToTSServer(url, log, null, version);
|
||||
public String connectToTSServer(String url, String log, FhirPublication version, boolean useEcosystem) throws URISyntaxException, IOException, FHIRException {
|
||||
return connectToTSServer(url, log, null, version, useEcosystem);
|
||||
}
|
||||
|
||||
public String connectToTSServer(String url, String log, String txCachePath, FhirPublication version) throws URISyntaxException, IOException, FHIRException {
|
||||
public String connectToTSServer(String url, String log, String txCachePath, FhirPublication version, boolean useEcosystem) throws URISyntaxException, IOException, FHIRException {
|
||||
context.setTlogging(false);
|
||||
if (url == null) {
|
||||
context.setCanRunWithoutTerminology(true);
|
||||
|
@ -527,7 +530,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
} else {
|
||||
try {
|
||||
TerminologyClientFactory factory = new TerminologyClientFactory(version);
|
||||
context.connectToTSServer(factory, url, context.getUserAgent(), log);
|
||||
context.connectToTSServer(factory, url, context.getUserAgent(), log, useEcosystem);
|
||||
return "Connected to Terminology Server at "+url;
|
||||
} catch (Exception e) {
|
||||
if (context.isCanRunWithoutTerminology()) {
|
||||
|
@ -1044,8 +1047,8 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
throw new FHIRException("Source/Target version not supported: " + version + " -> " + targetVer);
|
||||
}
|
||||
|
||||
public String setTerminologyServer(String src, String log, FhirPublication version) throws FHIRException, URISyntaxException, IOException {
|
||||
return connectToTSServer(src, log, version);
|
||||
public String setTerminologyServer(String src, String log, FhirPublication version, boolean useEcosystem) throws FHIRException, URISyntaxException, IOException {
|
||||
return connectToTSServer(src, log, version, useEcosystem);
|
||||
}
|
||||
|
||||
public ValidationEngine setMapLog(String mapLog) throws FileNotFoundException {
|
||||
|
|
|
@ -88,6 +88,8 @@ public class CliContext {
|
|||
private String snomedCT = "900000000000207008";
|
||||
@JsonProperty("targetVer")
|
||||
private String targetVer = null;
|
||||
@JsonProperty("noEcosystem")
|
||||
private boolean noEcosystem = false;
|
||||
|
||||
@JsonProperty("extensions")
|
||||
private List<String> extensions = new ArrayList<String>();
|
||||
|
@ -245,6 +247,17 @@ public class CliContext {
|
|||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("txServer")
|
||||
public boolean getNoEcosystem() {
|
||||
return noEcosystem;
|
||||
}
|
||||
|
||||
@JsonProperty("txServer")
|
||||
public CliContext setNoEcosystem(boolean noEcosystem) {
|
||||
this.noEcosystem = noEcosystem;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("doNative")
|
||||
public boolean isDoNative() {
|
||||
return doNative;
|
||||
|
|
|
@ -493,6 +493,11 @@ public class ValidationService {
|
|||
System.out.println(" - " + validationEngine.getContext().countAllCaches() + " resources (" + timeTracker.milestone() + ")");
|
||||
|
||||
loadIgsAndExtensions(validationEngine, cliContext, timeTracker);
|
||||
if (validationEngine.getContext().getTxCache() == null) {
|
||||
System.out.println(" No Terminology Cache");
|
||||
} else {
|
||||
System.out.println(" Terminology Cache at "+validationEngine.getContext().getTxCache().getFolder());
|
||||
}
|
||||
System.out.print(" Get set... ");
|
||||
validationEngine.setQuestionnaireMode(cliContext.getQuestionnaireMode());
|
||||
validationEngine.setLevel(cliContext.getLevel());
|
||||
|
@ -546,7 +551,7 @@ public class ValidationService {
|
|||
igLoader.loadIg(validationEngine.getIgs(), validationEngine.getBinaries(), "hl7.fhir.uv.extensions", false);
|
||||
}
|
||||
System.out.print(" Terminology server " + cliContext.getTxServer());
|
||||
String txver = validationEngine.setTerminologyServer(cliContext.getTxServer(), cliContext.getTxLog(), ver);
|
||||
String txver = validationEngine.setTerminologyServer(cliContext.getTxServer(), cliContext.getTxLog(), ver, !cliContext.getNoEcosystem());
|
||||
System.out.println(" - Version " + txver + " (" + timeTracker.milestone() + ")");
|
||||
validationEngine.setDebug(cliContext.isDoDebug());
|
||||
validationEngine.getContext().setLogger(new SystemOutLoggingService(cliContext.isDoDebug()));
|
||||
|
|
|
@ -340,8 +340,10 @@ public class Params {
|
|||
} else if (args[i].equals(TERMINOLOGY)) {
|
||||
if (i + 1 == args.length)
|
||||
throw new Error("Specified -tx without indicating terminology server");
|
||||
else
|
||||
else {
|
||||
cliContext.setTxServer("n/a".equals(args[++i]) ? null : args[i]);
|
||||
cliContext.setNoEcosystem(true);
|
||||
}
|
||||
} else if (args[i].equals(TERMINOLOGY_LOG)) {
|
||||
if (i + 1 == args.length)
|
||||
throw new Error("Specified -txLog without indicating file");
|
||||
|
|
|
@ -256,6 +256,10 @@ public class ValueSetValidator extends BaseValidator {
|
|||
CodeSystem cs = null;
|
||||
if (!Utilities.noString(system)) {
|
||||
cs = context.fetchCodeSystem(system, version);
|
||||
if (cs == null) {
|
||||
// can we get it from a terminology server?
|
||||
cs = context.findTxResource(CodeSystem.class, system, version);
|
||||
}
|
||||
if (cs != null) { // if it's null, we can't analyse this
|
||||
switch (cs.getContent()) {
|
||||
case EXAMPLE:
|
||||
|
|
|
@ -22,7 +22,7 @@ public class TestUtilities {
|
|||
.withVersion(vString)
|
||||
.withUserAgent(TestConstants.USER_AGENT)
|
||||
.withTerminologyCachePath(getTerminologyCacheDirectory(vString))
|
||||
.withTxServer(txServer, txLog, version)
|
||||
.withTxServer(txServer, txLog, version, false)
|
||||
.fromSource(src);
|
||||
|
||||
TerminologyCache.setCacheErrors(true);
|
||||
|
@ -59,7 +59,7 @@ public class TestUtilities {
|
|||
.withVersion(vString)
|
||||
.withUserAgent(TestConstants.USER_AGENT)
|
||||
.withTerminologyCachePath(getTerminologyCacheDirectory(vString))
|
||||
.withTxServer(txServer, TestConstants.TX_CACHE_LOG, version)
|
||||
.withTxServer(txServer, TestConstants.TX_CACHE_LOG, version, false)
|
||||
.fromSource(src);
|
||||
TerminologyCache.setCacheErrors(true);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"#f3b2bd36-199b-4591-b4db-f49db0912b6|null" : null,
|
||||
"#c1|null" : null,
|
||||
"http://something/something|null" : null,
|
||||
"http://hl7.org/fhir/CodeSystem/c1|null" : null,
|
||||
"http://hl7.org/fhir/uv/sdc/CodeSystem/CSPHQ9|null" : null,
|
||||
"#f3b2bd36-199b-4591-b4db-f49db0912b62|null" : null
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"#cs1|null" : null,
|
||||
"#cs|null" : null,
|
||||
"http://something|null" : null,
|
||||
"http://snomed.info/sct|null" : null
|
||||
}
|
4
pom.xml
4
pom.xml
|
@ -14,14 +14,14 @@
|
|||
HAPI FHIR
|
||||
-->
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>6.3.6-SNAPSHOT</version>
|
||||
<version>6.3.7-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<commons_compress_version>1.26.0</commons_compress_version>
|
||||
<guava_version>32.0.1-jre</guava_version>
|
||||
<hapi_fhir_version>6.4.1</hapi_fhir_version>
|
||||
<validator_test_case_version>1.5.6-SNAPSHOT</validator_test_case_version>
|
||||
<validator_test_case_version>1.5.6</validator_test_case_version>
|
||||
<jackson_version>2.17.0</jackson_version>
|
||||
<junit_jupiter_version>5.9.2</junit_jupiter_version>
|
||||
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
||||
|
|
Loading…
Reference in New Issue