cache CapabilityStatement and TerminologyCapabilities

This commit is contained in:
dotasek 2022-01-18 16:09:59 -05:00
parent 6e0b14b0b6
commit d9d0f22ff3
20 changed files with 24714 additions and 121 deletions

View File

@ -37,21 +37,27 @@ import org.hl7.fhir.r5.utils.client.FHIRToolingClient;
import org.hl7.fhir.r5.utils.client.network.ClientHeaders; import org.hl7.fhir.r5.utils.client.network.ClientHeaders;
import org.hl7.fhir.utilities.ToolingClientLogger; import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Map; import java.util.Map;
public class TerminologyClientR5 implements TerminologyClient { public class TerminologyClientR5 implements TerminologyClient {
private final Logger logger = LoggerFactory.getLogger(TerminologyClientR5.class);
private final FHIRToolingClient client; private final FHIRToolingClient client;
private ClientHeaders clientHeaders; private ClientHeaders clientHeaders;
public TerminologyClientR5(String address, String userAgent) throws URISyntaxException { public TerminologyClientR5(String address, String userAgent) throws URISyntaxException {
logger.info("TerminologyClientR5(String address, String userAgent)");
this.client = new FHIRToolingClient(address, userAgent); this.client = new FHIRToolingClient(address, userAgent);
setClientHeaders(new ClientHeaders()); setClientHeaders(new ClientHeaders());
} }
public TerminologyClientR5(String address, String userAgent, ClientHeaders clientHeaders) throws URISyntaxException { public TerminologyClientR5(String address, String userAgent, ClientHeaders clientHeaders) throws URISyntaxException {
logger.info("TerminologyClientR5(String address, String userAgent, ClientHeaders clientHeaders)");
this.client = new FHIRToolingClient(address, userAgent); this.client = new FHIRToolingClient(address, userAgent);
setClientHeaders(clientHeaders); setClientHeaders(clientHeaders);
} }

View File

@ -119,6 +119,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
public BaseWorkerContext() throws FileNotFoundException, IOException, FHIRException { public BaseWorkerContext() throws FileNotFoundException, IOException, FHIRException {
super(); super();
//CACHE
txCache = new TerminologyCache(lock, null); txCache = new TerminologyCache(lock, null);
} }
@ -129,6 +130,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
this.maps = maps; this.maps = maps;
this.structures = profiles; this.structures = profiles;
this.guides = guides; this.guides = guides;
//CACHE
txCache = new TerminologyCache(lock, null); txCache = new TerminologyCache(lock, null);
} }

View File

@ -1216,7 +1216,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
// -------------------------------------------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------------------------------------------
public void initTS(String cachePath) throws Exception { public void initTS(String cachePath) throws IOException {
if (!new File(cachePath).exists()) { if (!new File(cachePath).exists()) {
Utilities.createDirectory(cachePath); Utilities.createDirectory(cachePath);
} }

View File

@ -59,18 +59,11 @@ import org.hl7.fhir.r5.formats.IParser;
import org.hl7.fhir.r5.formats.JsonParser; import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.formats.ParserType; import org.hl7.fhir.r5.formats.ParserType;
import org.hl7.fhir.r5.formats.XmlParser; import org.hl7.fhir.r5.formats.XmlParser;
import org.hl7.fhir.r5.model.Bundle; import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent; import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CapabilityStatement;
import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent; import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent;
import org.hl7.fhir.r5.model.Questionnaire;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.ResourceType;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule; import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
import org.hl7.fhir.r5.model.StructureMap;
import org.hl7.fhir.r5.model.StructureMap.StructureMapModelMode; import org.hl7.fhir.r5.model.StructureMap.StructureMapModelMode;
import org.hl7.fhir.r5.model.StructureMap.StructureMapStructureComponent; import org.hl7.fhir.r5.model.StructureMap.StructureMapStructureComponent;
import org.hl7.fhir.r5.terminologies.TerminologyClient; import org.hl7.fhir.r5.terminologies.TerminologyClient;
@ -90,6 +83,8 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.validation.ValidationMessage.Source; import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.DataFormatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/* /*
* This is a stand alone implementation of worker context for use inside a tool. * This is a stand alone implementation of worker context for use inside a tool.
@ -99,6 +94,8 @@ import ca.uhn.fhir.parser.DataFormatException;
public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerContext, ProfileKnowledgeProvider { public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerContext, ProfileKnowledgeProvider {
private final Logger dlogger = LoggerFactory.getLogger(SimpleWorkerContext.class);
public static class PackageResourceLoader extends CanonicalResourceProxy { public static class PackageResourceLoader extends CanonicalResourceProxy {
private String filename; private String filename;
@ -292,9 +289,18 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
} }
txClient.setLogger(txLog); txClient.setLogger(txLog);
txClient.setUserAgent(userAgent); txClient.setUserAgent(userAgent);
CapabilityStatement cps = txClient.getCapabilitiesStatementQuick(); //CACHE
setTxCaps(txClient.getTerminologyCapabilities()); dlogger.info("SimpleWorkerContext.connectToTSServer");
return cps.getSoftware().getVersion();
final CapabilityStatement capabilitiesStatementQuick = txCache.hasCapabilityStatement() ? txCache.getCapabilityStatement() : txClient.getCapabilitiesStatementQuick();
txCache.cacheCapabilityStatement(capabilitiesStatementQuick);
final TerminologyCapabilities capabilityStatement = txCache.hasTerminologyCapabilities() ? txCache.getTerminologyCapabilities() : txClient.getTerminologyCapabilities();
txCache.cacheTerminologyCapabilities(capabilityStatement);
setTxCaps(capabilityStatement);
return capabilitiesStatementQuick.getSoftware().getVersion();
} catch (Exception e) { } catch (Exception e) {
throw new FHIRException(formatMessage(canNoTS ? I18nConstants.UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER_USE_PARAMETER_TX_NA_TUN_RUN_WITHOUT_USING_TERMINOLOGY_SERVICES_TO_VALIDATE_LOINC_SNOMED_ICDX_ETC_ERROR__ : I18nConstants.UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER, e.getMessage()), e); throw new FHIRException(formatMessage(canNoTS ? I18nConstants.UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER_USE_PARAMETER_TX_NA_TUN_RUN_WITHOUT_USING_TERMINOLOGY_SERVICES_TO_VALIDATE_LOINC_SNOMED_ICDX_ETC_ERROR__ : I18nConstants.UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER, e.getMessage()), e);
} }

View File

@ -37,7 +37,6 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -46,11 +45,8 @@ import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult; import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.formats.JsonParser; import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
@ -63,16 +59,15 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationOptions; import org.hl7.fhir.utilities.validation.ValidationOptions;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
/** /**
* This implements a two level cache. * This implements a two level cache.
* - a temporary cache for remmbering previous local operations * - a temporary cache for remembering previous local operations
* - a persistent cache for rembering tx server operations * - a persistent cache for remembering tx server operations
* *
* the cache is a series of pairs: a map, and a list. the map is the loaded cache, the list is the persiistent cache, carefully maintained in order for version control consistency * the cache is a series of pairs: a map, and a list. the map is the loaded cache, the list is the persistent cache, carefully maintained in order for version control consistency
* *
* @author graha * @author graha
* *
@ -84,6 +79,11 @@ public class TerminologyCache {
private static final String ENTRY_MARKER = "-------------------------------------------------------------------------------------"; private static final String ENTRY_MARKER = "-------------------------------------------------------------------------------------";
private static final String BREAK = "####"; private static final String BREAK = "####";
private static final String CACHE_FILE_EXTENSION = ".cache";
private static final String CAPABILITY_STATEMENT_TITLE = ".capabilityStatement";
private static final String TERMINOLOGY_CAPABILITIES_TITLE = ".terminologyCapabilities";
@Getter @Getter
private int requestCount; private int requestCount;
@Getter @Getter
@ -121,6 +121,44 @@ public class TerminologyCache {
private Object lock; private Object lock;
private String folder; private String folder;
private CapabilityStatement capabilityStatementCache = null;
public boolean hasCapabilityStatement() {
return capabilityStatementCache != null;
}
public CapabilityStatement getCapabilityStatement() {
return capabilityStatementCache;
}
public void cacheCapabilityStatement(CapabilityStatement capabilityStatement) {
if (noCaching) {
return;
}
this.capabilityStatementCache = capabilityStatement;
save(capabilityStatementCache, CAPABILITY_STATEMENT_TITLE);
}
private TerminologyCapabilities terminologyCapabilitiesCache = null;
public boolean hasTerminologyCapabilities() {
return terminologyCapabilitiesCache != null;
}
public TerminologyCapabilities getTerminologyCapabilities() {
return terminologyCapabilitiesCache;
}
public void cacheTerminologyCapabilities(TerminologyCapabilities terminologyCapabilities) {
if (noCaching) {
return;
}
this.terminologyCapabilitiesCache = terminologyCapabilities;
save(terminologyCapabilitiesCache, TERMINOLOGY_CAPABILITIES_TITLE);
}
private Map<String, NamedCache> caches = new HashMap<String, NamedCache>(); private Map<String, NamedCache> caches = new HashMap<String, NamedCache>();
@Getter @Setter @Getter @Setter
private static boolean noCaching; private static boolean noCaching;
@ -363,12 +401,29 @@ public class TerminologyCache {
} }
private <K extends Resource> void save(K resource, String title) {
if (folder == null)
return;
try {
OutputStreamWriter sw = new OutputStreamWriter(new FileOutputStream(Utilities.path(folder, title + CACHE_FILE_EXTENSION)), "UTF-8");
JsonParser json = new JsonParser();
json.setOutputStyle(OutputStyle.PRETTY);
sw.write(json.composeString(resource).trim());
sw.close();
} catch (Exception e) {
System.out.println("error saving capability statement "+e.getMessage());
}
}
private void save(NamedCache nc) { private void save(NamedCache nc) {
if (folder == null) if (folder == null)
return; return;
try { try {
OutputStreamWriter sw = new OutputStreamWriter(new FileOutputStream(Utilities.path(folder, nc.name+".cache")), "UTF-8"); OutputStreamWriter sw = new OutputStreamWriter(new FileOutputStream(Utilities.path(folder, nc.name+"CACHE_FILE_EXTENSION")), "UTF-8");
sw.write(ENTRY_MARKER+"\r\n"); sw.write(ENTRY_MARKER+"\r\n");
JsonParser json = new JsonParser(); JsonParser json = new JsonParser();
json.setOutputStyle(OutputStyle.PRETTY); json.setOutputStyle(OutputStyle.PRETTY);
@ -421,16 +476,39 @@ public class TerminologyCache {
} }
} }
private void load() throws FHIRException { private boolean isCapabilityCache(String fn) {
for (String fn : new File(folder).list()) { if (fn == null) {
if (fn.endsWith(".cache") && !fn.equals("validation.cache")) { return false;
}
return fn.startsWith(CAPABILITY_STATEMENT_TITLE) || fn.startsWith(TERMINOLOGY_CAPABILITIES_TITLE);
}
private void loadCapabilityCache(String fn) {
try {
String src = TextFile.fileToString(Utilities.path(folder, fn));
JsonObject o = (JsonObject) new com.google.gson.JsonParser().parse(src);
Resource resource = new JsonParser().parse(o);
if (fn.startsWith(CAPABILITY_STATEMENT_TITLE)) {
this.capabilityStatementCache = (CapabilityStatement) resource;
} else if (fn.startsWith(TERMINOLOGY_CAPABILITIES_TITLE)) {
this.terminologyCapabilitiesCache = (TerminologyCapabilities) resource;
}
} catch (Exception e) {
throw new FHIRException("Error loading " + fn + ": " + e.getMessage(), e);
}
}
private void loadNamedCache(String fn) {
int c = 0; int c = 0;
try { try {
String src = TextFile.fileToString(Utilities.path(folder, fn));
String title = fn.substring(0, fn.lastIndexOf(".")); String title = fn.substring(0, fn.lastIndexOf("."));
NamedCache nc = new NamedCache(); NamedCache nc = new NamedCache();
nc.name = title; nc.name = title;
caches.put(title, nc); caches.put(title, nc);
String src = TextFile.fileToString(Utilities.path(folder, fn));
if (src.startsWith("?")) if (src.startsWith("?"))
src = src.substring(1); src = src.substring(1);
int i = src.indexOf(ENTRY_MARKER); int i = src.indexOf(ENTRY_MARKER);
@ -474,6 +552,20 @@ public class TerminologyCache {
throw new FHIRException("Error loading " + fn + ": " + e.getMessage() + " entry " + c, e); throw new FHIRException("Error loading " + fn + ": " + e.getMessage() + " entry " + c, e);
} }
} }
private void load() throws FHIRException {
for (String fn : new File(folder).list()) {
if (fn.endsWith(CACHE_FILE_EXTENSION) && !fn.equals("validation" + CACHE_FILE_EXTENSION)) {
try {
if (isCapabilityCache(fn)) {
loadCapabilityCache(fn);
} else {
loadNamedCache(fn);
}
} catch (FHIRException e) {
throw e;
}
}
} }
} }

View File

@ -41,6 +41,8 @@ import org.hl7.fhir.r5.utils.client.network.ClientHeaders;
import org.hl7.fhir.r5.utils.client.network.ResourceRequest; import org.hl7.fhir.r5.utils.client.network.ResourceRequest;
import org.hl7.fhir.utilities.ToolingClientLogger; import org.hl7.fhir.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
@ -75,6 +77,8 @@ import java.util.*;
*/ */
public class FHIRToolingClient { public class FHIRToolingClient {
private final Logger logger = LoggerFactory.getLogger(FHIRToolingClient.class);
public static final String DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssK"; public static final String DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ssK";
public static final String DATE_FORMAT = "yyyy-MM-dd"; public static final String DATE_FORMAT = "yyyy-MM-dd";
public static final String hostKey = "http.proxyHost"; public static final String hostKey = "http.proxyHost";
@ -108,7 +112,6 @@ public class FHIRToolingClient {
base = baseServiceUrl; base = baseServiceUrl;
resourceAddress = new ResourceAddress(baseServiceUrl); resourceAddress = new ResourceAddress(baseServiceUrl);
this.maxResultSetSize = -1; this.maxResultSetSize = -1;
checkCapabilities();
} }
public Client getClient() { public Client getClient() {
@ -119,13 +122,6 @@ public class FHIRToolingClient {
this.client = client; this.client = client;
} }
private void checkCapabilities() {
try {
capabilities = getCapabilitiesStatementQuick();
} catch (Throwable e) {
}
}
public String getPreferredResourceFormat() { public String getPreferredResourceFormat() {
return preferredResourceFormat.getHeader(); return preferredResourceFormat.getHeader();
} }
@ -157,20 +153,24 @@ public class FHIRToolingClient {
} }
public CapabilityStatement getCapabilitiesStatement() { public CapabilityStatement getCapabilitiesStatement() {
CapabilityStatement conformance = null; logger.info("FHIRToolingClient.getCapabilitiesStatement");
CapabilityStatement capabilityStatement = null;
try { try {
conformance = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false), capabilityStatement = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false),
getPreferredResourceFormat(), getPreferredResourceFormat(),
generateHeaders(), generateHeaders(),
"CapabilitiesStatement", "CapabilitiesStatement",
TIMEOUT_NORMAL).getReference(); TIMEOUT_NORMAL).getReference();
logger.info("FHIRToolingClient.getCapabilitiesStatement - fetched capabilities from server: " + (capabilities != null ? capabilities.getVersion() : "no version"));
} catch (Exception e) { } catch (Exception e) {
throw new FHIRException("Error fetching the server's conformance statement", e); throw new FHIRException("Error fetching the server's conformance statement", e);
} }
return conformance; return capabilityStatement;
} }
public CapabilityStatement getCapabilitiesStatementQuick() throws EFhirClientException { public CapabilityStatement getCapabilitiesStatementQuick() throws EFhirClientException {
logger.info("FHIRToolingClient.getCapabilitiesStatementQuick");
if (capabilities != null) return capabilities; if (capabilities != null) return capabilities;
try { try {
capabilities = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true), capabilities = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true),
@ -178,6 +178,8 @@ public class FHIRToolingClient {
generateHeaders(), generateHeaders(),
"CapabilitiesStatement-Quick", "CapabilitiesStatement-Quick",
TIMEOUT_NORMAL).getReference(); TIMEOUT_NORMAL).getReference();
logger.info("FHIRToolingClient.getCapabilitiesStatementQuick - fetched capabilities from server: " + capabilities.getVersion());
} catch (Exception e) { } catch (Exception e) {
throw new FHIRException("Error fetching the server's capability statement: "+e.getMessage(), e); throw new FHIRException("Error fetching the server's capability statement: "+e.getMessage(), e);
} }
@ -583,6 +585,13 @@ public class FHIRToolingClient {
} }
public String getServerVersion() { public String getServerVersion() {
if (capabilities == null) {
try {
getCapabilitiesStatementQuick();
} catch (Throwable e) {
//FIXME This is creepy. Shouldn't we report this at some level?
}
}
return capabilities == null ? null : capabilities.getSoftware().getVersion(); return capabilities == null ? null : capabilities.getSoftware().getVersion();
} }

View File

@ -194,19 +194,19 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
igLoader = new IgLoader(getPcm(), getContext(), getVersion(), isDebug()); igLoader = new IgLoader(getPcm(), getContext(), getVersion(), isDebug());
} }
public ValidationEngine(String src, String txsrvr, String txLog, FhirPublication version, boolean canRunWithoutTerminologyServer, String vString, String userAgent) throws FHIRException, IOException, URISyntaxException { public ValidationEngine(String src, String txsrvr, String txLog, String txCachePath, FhirPublication version, boolean canRunWithoutTerminologyServer, String vString, String userAgent) throws FHIRException, IOException, URISyntaxException {
loadCoreDefinitions(src, false, null); loadCoreDefinitions(src, false, null);
getContext().setUserAgent(userAgent); getContext().setUserAgent(userAgent);
getContext().setCanRunWithoutTerminology(canRunWithoutTerminologyServer); getContext().setCanRunWithoutTerminology(canRunWithoutTerminologyServer);
setTerminologyServer(txsrvr, txLog, version); setTerminologyServer(txsrvr, txLog, txCachePath, version);
setVersion(vString); setVersion(vString);
igLoader = new IgLoader(getPcm(), getContext(), getVersion(), isDebug()); igLoader = new IgLoader(getPcm(), getContext(), getVersion(), isDebug());
} }
public ValidationEngine(String src, String txsrvr, String txLog, FhirPublication version, String vString, String userAgent) throws FHIRException, IOException, URISyntaxException { public ValidationEngine(String src, String txsrvr, String txLog, String txCachePath, FhirPublication version, String vString, String userAgent) throws FHIRException, IOException, URISyntaxException {
loadCoreDefinitions(src, false, null); loadCoreDefinitions(src, false, null);
getContext().setUserAgent(userAgent); getContext().setUserAgent(userAgent);
setTerminologyServer(txsrvr, txLog, version); setTerminologyServer(txsrvr, txLog, txCachePath, version);
setVersion(vString); setVersion(vString);
igLoader = new IgLoader(getPcm(), getContext(), getVersion(), isDebug()); igLoader = new IgLoader(getPcm(), getContext(), getVersion(), isDebug());
} }
@ -280,7 +280,11 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
return ep; return ep;
} }
public String connectToTSServer(String url, String log, FhirPublication version) throws URISyntaxException, FHIRException { 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, String txCachePath, FhirPublication version) throws URISyntaxException, IOException, FHIRException {
context.setTlogging(false); context.setTlogging(false);
if (url == null) { if (url == null) {
context.setCanRunWithoutTerminology(true); context.setCanRunWithoutTerminology(true);
@ -288,6 +292,10 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
return "n/a: No Terminology Server"; return "n/a: No Terminology Server";
} else { } else {
try { try {
//FIXME this can fail for a different reason than connectToTSServer
if (txCachePath != null) {
context.initTS(txCachePath);
}
return context.connectToTSServer(TerminologyClientFactory.makeClient(url, context.getUserAgent(), version), log); return context.connectToTSServer(TerminologyClientFactory.makeClient(url, context.getUserAgent(), version), log);
} catch (Exception e) { } catch (Exception e) {
if (context.isCanRunWithoutTerminology()) { if (context.isCanRunWithoutTerminology()) {
@ -689,8 +697,12 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
throw new FHIRException("Source/Target version not supported: " + version + " -> " + targetVer); throw new FHIRException("Source/Target version not supported: " + version + " -> " + targetVer);
} }
public String setTerminologyServer(String src, String log, FhirPublication version) throws FHIRException, URISyntaxException { public String setTerminologyServer(String src, String log, FhirPublication version) throws FHIRException, IOException, URISyntaxException {
return connectToTSServer(src, log, version); return setTerminologyServer(src, log, null, version);
}
public String setTerminologyServer(String src, String log, String txCachePath, FhirPublication version) throws FHIRException, IOException, URISyntaxException {
return connectToTSServer(src, log, txCachePath, version);
} }
public ValidationEngine setMapLog(String mapLog) throws FileNotFoundException { public ValidationEngine setMapLog(String mapLog) throws FileNotFoundException {

View File

@ -15,8 +15,7 @@ public class TestUtilities {
// } // }
public static final ValidationEngine getValidationEngine(java.lang.String src, java.lang.String txsrvr, java.lang.String txLog, FhirPublication version, boolean canRunWithoutTerminologyServer, java.lang.String vString, java.lang.String userAgent) throws Exception { public static final ValidationEngine getValidationEngine(java.lang.String src, java.lang.String txsrvr, java.lang.String txLog, FhirPublication version, boolean canRunWithoutTerminologyServer, java.lang.String vString, java.lang.String userAgent) throws Exception {
txLog = TestConstants.TX_CACHE_LOG; txLog = TestConstants.TX_CACHE_LOG;
final ValidationEngine validationEngine = new ValidationEngine(src, txsrvr, txLog, version, canRunWithoutTerminologyServer, vString, userAgent); final ValidationEngine validationEngine = new ValidationEngine(src, txsrvr, txLog, Paths.get(TestConstants.TX_CACHE, vString).toString(), version, canRunWithoutTerminologyServer, vString, userAgent);
validationEngine.getContext().initTS(Paths.get(TestConstants.TX_CACHE, vString).toString());
TerminologyCache.setCacheErrors(true); TerminologyCache.setCacheErrors(true);
validationEngine.getContext().setUserAgent("fhir/test-cases"); validationEngine.getContext().setUserAgent("fhir/test-cases");
return validationEngine; return validationEngine;
@ -24,8 +23,7 @@ public class TestUtilities {
public static ValidationEngine getValidationEngine(java.lang.String src, java.lang.String txsrvr, java.lang.String txLog, FhirPublication version, java.lang.String vString, java.lang.String userAgent) throws Exception { public static ValidationEngine getValidationEngine(java.lang.String src, java.lang.String txsrvr, java.lang.String txLog, FhirPublication version, java.lang.String vString, java.lang.String userAgent) throws Exception {
txLog = TestConstants.TX_CACHE_LOG; txLog = TestConstants.TX_CACHE_LOG;
final ValidationEngine validationEngine = new ValidationEngine(src, txsrvr, txLog, version, vString, userAgent); final ValidationEngine validationEngine = new ValidationEngine(src, txsrvr, txLog, Paths.get(TestConstants.TX_CACHE, vString).toString(), version, vString, userAgent);
validationEngine.getContext().initTS(Paths.get(TestConstants.TX_CACHE, vString).toString());
TerminologyCache.setCacheErrors(true); TerminologyCache.setCacheErrors(true);
validationEngine.getContext().setUserAgent("fhir/test-cases"); validationEngine.getContext().setUserAgent("fhir/test-cases");
return validationEngine; return validationEngine;

View File

@ -0,0 +1,39 @@
{
"resourceType" : "CapabilityStatement",
"id" : "FhirServer",
"meta" : {
"tag" : [{
"system" : "http://hl7.org/fhir/v3/ObservationValue",
"code" : "SUBSETTED",
"display" : "Subsetted"
}]
},
"extension" : [{
"url" : "http://hl7.org/fhir/3.0/StructureDefinition/extension-CapabilityStatement.acceptUnknown",
"valueCode" : "both"
}],
"url" : "http://fhir.healthintersections.com.au/open/metadata",
"version" : "1.0.2-2.0.12-SNAPSHOT",
"name" : "FHIR Reference Server Conformance Statement",
"status" : "active",
"date" : "2022-01-06T15:44:28.286Z",
"contact" : [{
"telecom" : [{
"system" : "other",
"value" : "http://healthintersections.com.au/"
}]
}],
"description" : "Standard Conformance Statement for the open source Reference FHIR Server provided by Health Intersections",
"kind" : "instance",
"software" : {
"name" : "Reference Server",
"version" : "2.0.12-SNAPSHOT",
"releaseDate" : "2021-12-20T02:28:03.769Z"
},
"fhirVersion" : "1.0.2",
"format" : ["application/xml+fhir",
"application/json+fhir"],
"rest" : [{
"mode" : "server"
}]
}

View File

@ -0,0 +1,66 @@
{
"resourceType" : "CapabilityStatement",
"id" : "FhirServer",
"meta" : {
"tag" : [{
"system" : "http://hl7.org/fhir/v3/ObservationValue",
"code" : "SUBSETTED",
"display" : "Subsetted"
}]
},
"extension" : [{
"url" : "http://hl7.org/fhir/3.0/StructureDefinition/extension-CapabilityStatement.acceptUnknown",
"valueCode" : "both"
}],
"url" : "http://fhir.healthintersections.com.au/open/metadata",
"version" : "3.0.2-2.0.12-SNAPSHOT",
"name" : "FHIR Reference Server Conformance Statement",
"status" : "active",
"date" : "2022-01-10T11:02:52.097Z",
"contact" : [{
"telecom" : [{
"system" : "other",
"value" : "http://healthintersections.com.au/"
}]
}],
"kind" : "instance",
"instantiates" : ["http://hl7.org/fhir/CapabilityStatement/terminology-server"],
"software" : {
"name" : "Reference Server",
"version" : "2.0.12-SNAPSHOT",
"releaseDate" : "2021-12-20T02:28:03.769Z"
},
"fhirVersion" : "3.0.2",
"format" : ["application/fhir+xml",
"application/fhir+json"],
"rest" : [{
"mode" : "server",
"security" : {
"cors" : true
},
"operation" : [{
"name" : "expand",
"definition" : "http://hl7.org/fhir/OperationDefinition/ValueSet-expand"
},
{
"name" : "lookup",
"definition" : "http://hl7.org/fhir/OperationDefinition/ValueSet-lookup"
},
{
"name" : "validate-code",
"definition" : "http://hl7.org/fhir/OperationDefinition/Resource-validate"
},
{
"name" : "translate",
"definition" : "http://hl7.org/fhir/OperationDefinition/ConceptMap-translate"
},
{
"name" : "closure",
"definition" : "http://hl7.org/fhir/OperationDefinition/ConceptMap-closure"
},
{
"name" : "versions",
"definition" : "/OperationDefinition/fso-versions"
}]
}]
}

View File

@ -0,0 +1,66 @@
{
"resourceType" : "CapabilityStatement",
"id" : "FhirServer",
"meta" : {
"tag" : [{
"system" : "http://hl7.org/fhir/v3/ObservationValue",
"code" : "SUBSETTED",
"display" : "Subsetted"
}]
},
"extension" : [{
"url" : "http://hl7.org/fhir/3.0/StructureDefinition/extension-CapabilityStatement.acceptUnknown",
"valueCode" : "both"
}],
"url" : "http://fhir.healthintersections.com.au/open/metadata",
"version" : "3.0.2-2.0.12-SNAPSHOT",
"name" : "FHIR Reference Server Conformance Statement",
"status" : "active",
"date" : "2022-01-10T11:02:52.097Z",
"contact" : [{
"telecom" : [{
"system" : "other",
"value" : "http://healthintersections.com.au/"
}]
}],
"kind" : "instance",
"instantiates" : ["http://hl7.org/fhir/CapabilityStatement/terminology-server"],
"software" : {
"name" : "Reference Server",
"version" : "2.0.12-SNAPSHOT",
"releaseDate" : "2021-12-20T02:28:03.769Z"
},
"fhirVersion" : "3.0.2",
"format" : ["application/fhir+xml",
"application/fhir+json"],
"rest" : [{
"mode" : "server",
"security" : {
"cors" : true
},
"operation" : [{
"name" : "expand",
"definition" : "http://hl7.org/fhir/OperationDefinition/ValueSet-expand"
},
{
"name" : "lookup",
"definition" : "http://hl7.org/fhir/OperationDefinition/ValueSet-lookup"
},
{
"name" : "validate-code",
"definition" : "http://hl7.org/fhir/OperationDefinition/Resource-validate"
},
{
"name" : "translate",
"definition" : "http://hl7.org/fhir/OperationDefinition/ConceptMap-translate"
},
{
"name" : "closure",
"definition" : "http://hl7.org/fhir/OperationDefinition/ConceptMap-closure"
},
{
"name" : "versions",
"definition" : "/OperationDefinition/fso-versions"
}]
}]
}

View File

@ -0,0 +1,62 @@
{
"resourceType" : "CapabilityStatement",
"id" : "FhirServer",
"meta" : {
"tag" : [{
"system" : "http://hl7.org/fhir/v3/ObservationValue",
"code" : "SUBSETTED",
"display" : "Subsetted"
}]
},
"url" : "http://fhir.healthintersections.com.au/open/metadata",
"version" : "4.0.1-2.0.12-SNAPSHOT",
"name" : "FHIR Reference Server Conformance Statement",
"status" : "active",
"date" : "2022-01-10T11:07:19.254Z",
"contact" : [{
"telecom" : [{
"system" : "other",
"value" : "http://healthintersections.com.au/"
}]
}],
"kind" : "instance",
"instantiates" : ["http://hl7.org/fhir/CapabilityStatement/terminology-server"],
"software" : {
"name" : "Reference Server",
"version" : "2.0.12-SNAPSHOT",
"releaseDate" : "2021-12-20T02:28:03.769Z"
},
"fhirVersion" : "4.0.1",
"format" : ["application/fhir+xml",
"application/fhir+json"],
"rest" : [{
"mode" : "server",
"security" : {
"cors" : true
},
"operation" : [{
"name" : "expand",
"definition" : "http://hl7.org/fhir/OperationDefinition/ValueSet-expand"
},
{
"name" : "lookup",
"definition" : "http://hl7.org/fhir/OperationDefinition/ValueSet-lookup"
},
{
"name" : "validate-code",
"definition" : "http://hl7.org/fhir/OperationDefinition/Resource-validate"
},
{
"name" : "translate",
"definition" : "http://hl7.org/fhir/OperationDefinition/ConceptMap-translate"
},
{
"name" : "closure",
"definition" : "http://hl7.org/fhir/OperationDefinition/ConceptMap-closure"
},
{
"name" : "versions",
"definition" : "/OperationDefinition/fso-versions"
}]
}]
}

View File

@ -0,0 +1,62 @@
{
"resourceType" : "CapabilityStatement",
"id" : "FhirServer",
"meta" : {
"tag" : [{
"system" : "http://hl7.org/fhir/v3/ObservationValue",
"code" : "SUBSETTED",
"display" : "Subsetted"
}]
},
"url" : "http://fhir.healthintersections.com.au/open/metadata",
"version" : "4.0.1-2.0.12-SNAPSHOT",
"name" : "FHIR Reference Server Conformance Statement",
"status" : "active",
"date" : "2022-01-10T11:07:19.254Z",
"contact" : [{
"telecom" : [{
"system" : "other",
"value" : "http://healthintersections.com.au/"
}]
}],
"kind" : "instance",
"instantiates" : ["http://hl7.org/fhir/CapabilityStatement/terminology-server"],
"software" : {
"name" : "Reference Server",
"version" : "2.0.12-SNAPSHOT",
"releaseDate" : "2021-12-20T02:28:03.769Z"
},
"fhirVersion" : "4.0.1",
"format" : ["application/fhir+xml",
"application/fhir+json"],
"rest" : [{
"mode" : "server",
"security" : {
"cors" : true
},
"operation" : [{
"name" : "expand",
"definition" : "http://hl7.org/fhir/OperationDefinition/ValueSet-expand"
},
{
"name" : "lookup",
"definition" : "http://hl7.org/fhir/OperationDefinition/ValueSet-lookup"
},
{
"name" : "validate-code",
"definition" : "http://hl7.org/fhir/OperationDefinition/Resource-validate"
},
{
"name" : "translate",
"definition" : "http://hl7.org/fhir/OperationDefinition/ConceptMap-translate"
},
{
"name" : "closure",
"definition" : "http://hl7.org/fhir/OperationDefinition/ConceptMap-closure"
},
{
"name" : "versions",
"definition" : "/OperationDefinition/fso-versions"
}]
}]
}

View File

@ -0,0 +1,62 @@
{
"resourceType" : "CapabilityStatement",
"id" : "FhirServer",
"meta" : {
"tag" : [{
"system" : "http://hl7.org/fhir/v3/ObservationValue",
"code" : "SUBSETTED",
"display" : "Subsetted"
}]
},
"url" : "http://fhir.healthintersections.com.au/open/metadata",
"version" : "4.0.1-2.0.12-SNAPSHOT",
"name" : "FHIR Reference Server Conformance Statement",
"status" : "active",
"date" : "2022-01-10T11:07:19.254Z",
"contact" : [{
"telecom" : [{
"system" : "other",
"value" : "http://healthintersections.com.au/"
}]
}],
"kind" : "instance",
"instantiates" : ["http://hl7.org/fhir/CapabilityStatement/terminology-server"],
"software" : {
"name" : "Reference Server",
"version" : "2.0.12-SNAPSHOT",
"releaseDate" : "2021-12-20T02:28:03.769Z"
},
"fhirVersion" : "4.0.1",
"format" : ["application/fhir+xml",
"application/fhir+json"],
"rest" : [{
"mode" : "server",
"security" : {
"cors" : true
},
"operation" : [{
"name" : "expand",
"definition" : "http://hl7.org/fhir/OperationDefinition/ValueSet-expand"
},
{
"name" : "lookup",
"definition" : "http://hl7.org/fhir/OperationDefinition/ValueSet-lookup"
},
{
"name" : "validate-code",
"definition" : "http://hl7.org/fhir/OperationDefinition/Resource-validate"
},
{
"name" : "translate",
"definition" : "http://hl7.org/fhir/OperationDefinition/ConceptMap-translate"
},
{
"name" : "closure",
"definition" : "http://hl7.org/fhir/OperationDefinition/ConceptMap-closure"
},
{
"name" : "versions",
"definition" : "/OperationDefinition/fso-versions"
}]
}]
}