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.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URISyntaxException;
import java.util.Map;
public class TerminologyClientR5 implements TerminologyClient {
private final Logger logger = LoggerFactory.getLogger(TerminologyClientR5.class);
private final FHIRToolingClient client;
private ClientHeaders clientHeaders;
public TerminologyClientR5(String address, String userAgent) throws URISyntaxException {
logger.info("TerminologyClientR5(String address, String userAgent)");
this.client = new FHIRToolingClient(address, userAgent);
setClientHeaders(new ClientHeaders());
}
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);
setClientHeaders(clientHeaders);
}

View File

@ -119,6 +119,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
public BaseWorkerContext() throws FileNotFoundException, IOException, FHIRException {
super();
//CACHE
txCache = new TerminologyCache(lock, null);
}
@ -129,6 +130,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
this.maps = maps;
this.structures = profiles;
this.guides = guides;
//CACHE
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()) {
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.ParserType;
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.CanonicalResource;
import org.hl7.fhir.r5.model.CapabilityStatement;
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.TypeDerivationRule;
import org.hl7.fhir.r5.model.StructureMap;
import org.hl7.fhir.r5.model.StructureMap.StructureMapModelMode;
import org.hl7.fhir.r5.model.StructureMap.StructureMapStructureComponent;
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 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.
@ -99,6 +94,8 @@ import ca.uhn.fhir.parser.DataFormatException;
public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerContext, ProfileKnowledgeProvider {
private final Logger dlogger = LoggerFactory.getLogger(SimpleWorkerContext.class);
public static class PackageResourceLoader extends CanonicalResourceProxy {
private String filename;
@ -292,9 +289,18 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
}
txClient.setLogger(txLog);
txClient.setUserAgent(userAgent);
CapabilityStatement cps = txClient.getCapabilitiesStatementQuick();
setTxCaps(txClient.getTerminologyCapabilities());
return cps.getSoftware().getVersion();
//CACHE
dlogger.info("SimpleWorkerContext.connectToTSServer");
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) {
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.OutputStreamWriter;
import java.util.*;
import java.util.stream.Collectors;
import lombok.Getter;
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.formats.IParser.OutputStyle;
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.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.ConceptSetFilterComponent;
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 com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
/**
* This implements a two level cache.
* - a temporary cache for remmbering previous local operations
* - a persistent cache for rembering tx server operations
* - a temporary cache for remembering previous local 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
*
@ -84,6 +79,11 @@ public class TerminologyCache {
private static final String ENTRY_MARKER = "-------------------------------------------------------------------------------------";
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
private int requestCount;
@Getter
@ -121,6 +121,44 @@ public class TerminologyCache {
private Object lock;
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>();
@Getter @Setter
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) {
if (folder == null)
return;
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");
JsonParser json = new JsonParser();
json.setOutputStyle(OutputStyle.PRETTY);
@ -421,57 +476,94 @@ public class TerminologyCache {
}
}
private boolean isCapabilityCache(String fn) {
if (fn == null) {
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;
try {
String src = TextFile.fileToString(Utilities.path(folder, fn));
String title = fn.substring(0, fn.lastIndexOf("."));
NamedCache nc = new NamedCache();
nc.name = title;
caches.put(title, nc);
if (src.startsWith("?"))
src = src.substring(1);
int i = src.indexOf(ENTRY_MARKER);
while (i > -1) {
c++;
String s = src.substring(0, i);
src = src.substring(i + ENTRY_MARKER.length() + 1);
i = src.indexOf(ENTRY_MARKER);
if (!Utilities.noString(s)) {
int j = s.indexOf(BREAK);
String q = s.substring(0, j);
String p = s.substring(j + BREAK.length() + 1).trim();
CacheEntry ce = new CacheEntry();
ce.persistent = true;
ce.request = q;
boolean e = p.charAt(0) == 'e';
p = p.substring(3);
JsonObject o = (JsonObject) new com.google.gson.JsonParser().parse(p);
String error = loadJS(o.get("error"));
if (e) {
if (o.has("valueSet"))
ce.e = new ValueSetExpansionOutcome((ValueSet) new JsonParser().parse(o.getAsJsonObject("valueSet")), error, TerminologyServiceErrorClass.UNKNOWN);
else
ce.e = new ValueSetExpansionOutcome(error, TerminologyServiceErrorClass.UNKNOWN);
} else {
String t = loadJS(o.get("severity"));
IssueSeverity severity = t == null ? null : IssueSeverity.fromCode(t);
String display = loadJS(o.get("display"));
String code = loadJS(o.get("code"));
String system = loadJS(o.get("system"));
String definition = loadJS(o.get("definition"));
t = loadJS(o.get("class"));
TerminologyServiceErrorClass errorClass = t == null ? null : TerminologyServiceErrorClass.valueOf(t);
ce.v = new ValidationResult(severity, error, system, new ConceptDefinitionComponent().setDisplay(display).setDefinition(definition).setCode(code)).setErrorClass(errorClass);
}
nc.map.put(String.valueOf(hashNWS(ce.request)), ce);
nc.list.add(ce);
}
}
} catch (Exception 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") && !fn.equals("validation.cache")) {
int c = 0;
if (fn.endsWith(CACHE_FILE_EXTENSION) && !fn.equals("validation" + CACHE_FILE_EXTENSION)) {
try {
String title = fn.substring(0, fn.lastIndexOf("."));
NamedCache nc = new NamedCache();
nc.name = title;
caches.put(title, nc);
String src = TextFile.fileToString(Utilities.path(folder, fn));
if (src.startsWith("?"))
src = src.substring(1);
int i = src.indexOf(ENTRY_MARKER);
while (i > -1) {
c++;
String s = src.substring(0, i);
src = src.substring(i + ENTRY_MARKER.length() + 1);
i = src.indexOf(ENTRY_MARKER);
if (!Utilities.noString(s)) {
int j = s.indexOf(BREAK);
String q = s.substring(0, j);
String p = s.substring(j + BREAK.length() + 1).trim();
CacheEntry ce = new CacheEntry();
ce.persistent = true;
ce.request = q;
boolean e = p.charAt(0) == 'e';
p = p.substring(3);
JsonObject o = (JsonObject) new com.google.gson.JsonParser().parse(p);
String error = loadJS(o.get("error"));
if (e) {
if (o.has("valueSet"))
ce.e = new ValueSetExpansionOutcome((ValueSet) new JsonParser().parse(o.getAsJsonObject("valueSet")), error, TerminologyServiceErrorClass.UNKNOWN);
else
ce.e = new ValueSetExpansionOutcome(error, TerminologyServiceErrorClass.UNKNOWN);
} else {
String t = loadJS(o.get("severity"));
IssueSeverity severity = t == null ? null : IssueSeverity.fromCode(t);
String display = loadJS(o.get("display"));
String code = loadJS(o.get("code"));
String system = loadJS(o.get("system"));
String definition = loadJS(o.get("definition"));
t = loadJS(o.get("class"));
TerminologyServiceErrorClass errorClass = t == null ? null : TerminologyServiceErrorClass.valueOf(t);
ce.v = new ValidationResult(severity, error, system, new ConceptDefinitionComponent().setDisplay(display).setDefinition(definition).setCode(code)).setErrorClass(errorClass);
}
nc.map.put(String.valueOf(hashNWS(ce.request)), ce);
nc.list.add(ce);
}
if (isCapabilityCache(fn)) {
loadCapabilityCache(fn);
} else {
loadNamedCache(fn);
}
} catch (Exception e) {
throw new FHIRException("Error loading " + fn + ": " + e.getMessage() + " entry " + c, e);
} 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.utilities.ToolingClientLogger;
import org.hl7.fhir.utilities.Utilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.MalformedURLException;
@ -75,6 +77,8 @@ import java.util.*;
*/
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 DATE_FORMAT = "yyyy-MM-dd";
public static final String hostKey = "http.proxyHost";
@ -108,7 +112,6 @@ public class FHIRToolingClient {
base = baseServiceUrl;
resourceAddress = new ResourceAddress(baseServiceUrl);
this.maxResultSetSize = -1;
checkCapabilities();
}
public Client getClient() {
@ -119,13 +122,6 @@ public class FHIRToolingClient {
this.client = client;
}
private void checkCapabilities() {
try {
capabilities = getCapabilitiesStatementQuick();
} catch (Throwable e) {
}
}
public String getPreferredResourceFormat() {
return preferredResourceFormat.getHeader();
}
@ -157,27 +153,33 @@ public class FHIRToolingClient {
}
public CapabilityStatement getCapabilitiesStatement() {
CapabilityStatement conformance = null;
logger.info("FHIRToolingClient.getCapabilitiesStatement");
CapabilityStatement capabilityStatement = null;
try {
conformance = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false),
capabilityStatement = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false),
getPreferredResourceFormat(),
generateHeaders(),
"CapabilitiesStatement",
TIMEOUT_NORMAL).getReference();
logger.info("FHIRToolingClient.getCapabilitiesStatement - fetched capabilities from server: " + (capabilities != null ? capabilities.getVersion() : "no version"));
} catch (Exception e) {
throw new FHIRException("Error fetching the server's conformance statement", e);
}
return conformance;
return capabilityStatement;
}
public CapabilityStatement getCapabilitiesStatementQuick() throws EFhirClientException {
logger.info("FHIRToolingClient.getCapabilitiesStatementQuick");
if (capabilities != null) return capabilities;
try {
capabilities = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true),
capabilities = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true),
getPreferredResourceFormat(),
generateHeaders(),
"CapabilitiesStatement-Quick",
TIMEOUT_NORMAL).getReference();
logger.info("FHIRToolingClient.getCapabilitiesStatementQuick - fetched capabilities from server: " + capabilities.getVersion());
} catch (Exception e) {
throw new FHIRException("Error fetching the server's capability statement: "+e.getMessage(), e);
}
@ -583,6 +585,13 @@ public class FHIRToolingClient {
}
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();
}

View File

@ -194,19 +194,19 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
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);
getContext().setUserAgent(userAgent);
getContext().setCanRunWithoutTerminology(canRunWithoutTerminologyServer);
setTerminologyServer(txsrvr, txLog, version);
setTerminologyServer(txsrvr, txLog, txCachePath, version);
setVersion(vString);
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);
getContext().setUserAgent(userAgent);
setTerminologyServer(txsrvr, txLog, version);
setTerminologyServer(txsrvr, txLog, txCachePath, version);
setVersion(vString);
igLoader = new IgLoader(getPcm(), getContext(), getVersion(), isDebug());
}
@ -280,7 +280,11 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
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);
if (url == null) {
context.setCanRunWithoutTerminology(true);
@ -288,6 +292,10 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
return "n/a: No Terminology Server";
} else {
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);
} catch (Exception e) {
if (context.isCanRunWithoutTerminology()) {
@ -689,8 +697,12 @@ 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 {
return connectToTSServer(src, log, version);
public String setTerminologyServer(String src, String log, FhirPublication version) throws FHIRException, IOException, URISyntaxException {
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 {

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 {
txLog = TestConstants.TX_CACHE_LOG;
final ValidationEngine validationEngine = new ValidationEngine(src, txsrvr, txLog, version, canRunWithoutTerminologyServer, vString, userAgent);
validationEngine.getContext().initTS(Paths.get(TestConstants.TX_CACHE, vString).toString());
final ValidationEngine validationEngine = new ValidationEngine(src, txsrvr, txLog, Paths.get(TestConstants.TX_CACHE, vString).toString(), version, canRunWithoutTerminologyServer, vString, userAgent);
TerminologyCache.setCacheErrors(true);
validationEngine.getContext().setUserAgent("fhir/test-cases");
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 {
txLog = TestConstants.TX_CACHE_LOG;
final ValidationEngine validationEngine = new ValidationEngine(src, txsrvr, txLog, version, vString, userAgent);
validationEngine.getContext().initTS(Paths.get(TestConstants.TX_CACHE, vString).toString());
final ValidationEngine validationEngine = new ValidationEngine(src, txsrvr, txLog, Paths.get(TestConstants.TX_CACHE, vString).toString(), version, vString, userAgent);
TerminologyCache.setCacheErrors(true);
validationEngine.getContext().setUserAgent("fhir/test-cases");
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"
}]
}]
}