Compare commits

...

66 Commits

Author SHA1 Message Date
Brian Postlethwaite cbb0953eea
Merge 323ec42c32 into 82cbb6067f 2024-11-11 22:38:00 -08:00
Grahame Grieve 82cbb6067f
Merge pull request #1806 from hapifhir/2024-11-gg-tx-test-metadata
Start testing metadata in tx tests, and consequent bugs and library u…
2024-11-12 15:54:54 +10:30
Grahame Grieve 8a831a9e45 Start testing metadata in tx tests, and consequent bugs and library upgrades for that (patternMode in ComparisonUtilities) 2024-11-12 13:24:09 +10:30
Grahame Grieve 097f493099
Merge pull request #1805 from hapifhir/do-20241111-server-auth-per-type
Use server type to select server settings in combination with URL
2024-11-12 12:14:03 +10:30
dotasek d0b0bd694b Remove unneeded test
***NO_CI***
2024-11-11 19:00:53 -05:00
dotasek a155475feb Fix test and set up apiKey for package client servers 2024-11-11 17:59:40 -05:00
dotasek 36142f4904 Fixes for getting configured servers from fhir-settings 2024-11-11 16:50:39 -05:00
dotasek 7c796b4ba4 Simplify FhirSettings format. 2024-11-11 16:25:18 -05:00
dotasek 730a1781ee Remove FIXMEs reviewed as OK by Grahame 2024-11-11 15:21:17 -05:00
dotasek 5cbb45abec Allow ManagedWebAccess to fetch specific server types for auth 2024-11-11 14:35:06 -05:00
dotasek 4ee4a89a76 Fix refactor misses 2024-11-11 11:06:09 -05:00
dotasek cac080b5bd Fix merge issue. 2024-11-11 09:23:59 -05:00
dotasek 4c5c71411b
Merge branch 'master' into 2024-11-gg-web-mode2 2024-11-09 11:19:10 -05:00
Grahame Grieve 60acdd0b88 Add mode to web access 2024-11-09 18:39:12 +10:30
dotasek 765ba8baed Fix get bytes for -1 or chunked content 2024-11-08 15:22:50 -05:00
Grahame Grieve 8b43a95aa8 update vsac access code 2024-11-09 06:33:07 +10:30
dotasek d724a27d95 Final rename 2024-11-08 14:35:36 -05:00
dotasek fb6a22c3b1 Clean up comments and JavaDoc 2024-11-08 14:29:40 -05:00
dotasek cc00bb903c Move tests to utilities. Clarify missing functionality 2024-11-08 11:26:43 -05:00
dotasek ebcbf4db49 More TODO erasures. Plus found missing functionality 2024-11-08 11:18:57 -05:00
dotasek 2bbfcb8845 Resolve all deletions enclosed in FIXME + fix headers in dstu2 postfeed 2024-11-08 11:08:06 -05:00
dotasek 822f0866b4 Fix api-key token mixup, more tests 2024-11-07 18:07:23 -05:00
dotasek e9917defb0 Rename ...AccessBuilder classes to ...Accessor 2024-11-07 17:53:14 -05:00
dotasek 4592dc1a82 Tests 1 2024-11-07 17:42:32 -05:00
Grahame Grieve d98e575795 Merge remote-tracking branch 'origin/do-20241021-tx-auth' into do-20241021-tx-auth 2024-11-08 08:46:59 +10:30
Grahame Grieve 7aef291a0c fix VSAC importer for changes to ManagedWebAccess 2024-11-08 08:46:23 +10:30
dotasek 2c57f5954e Remove conflicting authorization header setting methods 2024-11-07 15:44:25 -05:00
Grahame Grieve a93ab69231 Validate fhirpath expression in slice discriminators 2024-11-07 22:16:27 +10:30
Grahame Grieve ee7dc203f6 List measure choices when a match by version can't be found 2024-11-07 22:15:54 +10:30
Grahame Grieve 0c4da028b3 fix slicing by type and profile to allow multiple options per slice 2024-11-07 22:14:49 +10:30
dotasek afd9e7a471 Merge remote-tracking branch 'origin/master' into do-20241021-tx-auth 2024-11-06 19:19:53 -05:00
dotasek b6ef81c9f3 Switch to static fhirBuilder for all FhirRequestBuilders
+ Fix null user agent issue
+ Load ManagedWebAccess from FHIR settings
+ Add terminology servers to FhirSettings
2024-11-06 09:47:27 -05:00
dotasek e45c0b2bf0 Merge remote-tracking branch 'origin/master' into do-20241021-tx-auth 2024-11-05 10:51:21 -05:00
dotasek 07b31d94fd Fix format header issues 2024-11-05 10:20:06 -05:00
dotasek f1d5f714d3 WIP restore format header tests - turns out they break 2024-11-05 09:08:40 -05:00
dotasek ac7c7332d3 Use ManagedFhirWebAccess for DSTU2 2024-11-04 17:49:31 -05:00
dotasek 11a11da7c3 Add FHIRToolingClient tests 2024-11-01 12:40:48 -04:00
dotasek bdc02a5622 Merge remote-tracking branch 'origin/master' into do-20241021-tx-auth 2024-11-01 09:16:36 -04:00
dotasek a76078a5a5 Add test coverage (some failing) for DSTU2 ClientUtils 2024-11-01 09:12:37 -04:00
dotasek c5aaf43121 Make sure we get response headers 2024-10-30 19:08:38 -04:00
Brian Postlethwaite 323ec42c32 Corrent the parameter order for the assert parameters 2024-10-31 10:05:40 +11:00
Brian Postlethwaite 01af08030f #1794
Update the implementation of the `toString` fhirpath function to: (pending FHIR-48737)
* not return the text 'null' when no primitive value exists (when extension only)
* throw an error if more than 1 item is to be returned (doesn't support collections)
* return an empty set when no primitive values exist (when extension only)
2024-10-31 10:04:57 +11:00
Brian Postlethwaite bcf2ee886a Tip for Windows users for building 2024-10-31 07:55:02 +11:00
dotasek eb7144053d Make dstu3 use ManagedFhirWebAccess 2024-10-30 13:11:51 -04:00
dotasek 2f95e3fe9f Remove unused classes and okhttp usages and add tests for r4 2024-10-30 09:30:09 -04:00
dotasek 2fdfaf8602 Removing leftover okttp usage 2024-10-29 18:32:58 -04:00
dotasek a5ef974c3d Use ManagedFhirWebAccess in r4 2024-10-29 17:07:41 -04:00
dotasek fe58a8a2c5 Actually add headers from HTTPRequest to OkHttp request 2024-10-29 11:09:47 -04:00
dotasek d8ca1cc144 Apply changes to r4b 2024-10-29 10:06:42 -04:00
dotasek cbafe2a28f Adjust pipeline mem again 2024-10-28 16:00:20 -04:00
dotasek 2de5c65347 Merge remote-tracking branch 'origin/master' into do-20241021-tx-auth 2024-10-28 13:44:54 -04:00
dotasek 555edcf329 Change mem settings for build 2024-10-28 11:46:07 -04:00
dotasek b51ac15051 Fix for renamed class 2024-10-28 10:45:06 -04:00
dotasek f82f8764cf Tidy up code
***NO_CI***
2024-10-25 17:01:09 -04:00
dotasek 0308d18107 WIP fix removed import 2024-10-25 16:58:34 -04:00
dotasek 03b0c163be Merge branch 'master' into do-20241021-tx-auth 2024-10-25 13:56:06 -04:00
dotasek 0b45b0b882 WIP some HTTP Header refactoring, rename FhirRequest to HTTPRequest 2024-10-25 13:55:33 -04:00
dotasek b33de12e49 WIP move accept to parameter 2024-10-24 13:57:51 -04:00
dotasek ddb0a661dd Merge branch '2024-10-gg-tx-server-auth-1' into do-20241021-tx-auth 2024-10-23 11:55:58 -04:00
dotasek fdbf0da576 WIP move logging, retry, timeout and proxy 2024-10-23 11:55:27 -04:00
dotasek fa19dc44b1 Merge remote-tracking branch 'origin/2024-10-gg-tx-server-auth' into do-20241021-tx-auth 2024-10-22 17:34:08 -04:00
dotasek a94e1bc2af WIP keep moving FhirRequestBuilder to ManagedWebAccess + fix some tests 2024-10-22 17:33:50 -04:00
Grahame Grieve 12ee505fbd
Merge pull request #1786 from jkiddo/patch-4
Update PECodeGenerator.java
2024-10-23 07:10:58 +10:30
Jens Kristian Villadsen f9ce823d7c
Update PECodeGenerator.java 2024-10-22 22:37:28 +02:00
dotasek ac6ef81797 Merge remote-tracking branch 'origin/master' into do-20241021-tx-auth 2024-10-21 17:50:47 -04:00
dotasek 435dbbec9b WIP start moving FhirRequestBuilder to ManagedWebAccess 2024-10-21 17:19:53 -04:00
66 changed files with 1161 additions and 728 deletions

View File

@ -57,6 +57,10 @@ To skip unit tests:
```
mvn -Dmaven.test.skip install
```
> **Note:** If you're on Windows and use PowerShell, The `-` needs to be escaped with a backtick (`)
> ```
> mvn `-Dmaven.test.skip install
> ```
To clean and rebuild the terminology server caches:

View File

@ -3,12 +3,7 @@ package org.hl7.fhir.convertors.analytics;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import javax.xml.parsers.ParserConfigurationException;
@ -241,7 +236,7 @@ public class PackageVisitor {
File co = ManagedFileAccess.file(Utilities.path(cache, pid+"."+manifest.asString("date")+".tgz"));
if (!co.exists()) {
HTTPResult res = ManagedWebAccess.get(repo+"/package.tgz?nocache=" + System.currentTimeMillis());
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), repo+"/package.tgz?nocache=" + System.currentTimeMillis());
res.checkThrowException();
TextFile.bytesToFile(res.getContent(), co);
}
@ -338,7 +333,7 @@ public class PackageVisitor {
System.out.println("Feed "+str);
try {
HTTPResult res = ManagedWebAccess.get(str+"?nocache=" + System.currentTimeMillis());
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), str+"?nocache=" + System.currentTimeMillis());
res.checkThrowException();
Document xml = XMLUtil.parseToDom(res.getContent());
for (Element channel : XMLUtil.getNamedChildren(xml.getDocumentElement(), "channel")) {

View File

@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
@ -126,7 +127,7 @@ public class CKMImporter {
private Document loadXml(String address) throws Exception {
HTTPResult res = ManagedWebAccess.get(address, "application/xml");
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), address, "application/xml");
res.checkThrowException();
InputStream xml = new ByteArrayInputStream(res.getContent());

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.convertors.misc;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@ -394,7 +395,7 @@ public class ICD11Generator {
private JsonObject fetchJson(String source) throws IOException {
HTTPResult res = ManagedWebAccess.accessor().withHeader("API-Version", "v2").withHeader("Accept-Language", "en").get(source,"application/json");
HTTPResult res = ManagedWebAccess.accessor(Arrays.asList("web")).withHeader("API-Version", "v2").withHeader("Accept-Language", "en").get(source,"application/json");
res.checkThrowException();
return JsonParser.parseObject(res.getContent());
}

View File

@ -163,6 +163,11 @@ public class TerminologyClientR2 implements ITerminologyClient {
return (CapabilityStatement) VersionConvertorFactory_10_50.convertResource(client.getConformanceStatementQuick());
}
@Override
public CapabilityStatement getCapabilitiesStatement() throws FHIRException {
return (CapabilityStatement) VersionConvertorFactory_10_50.convertResource(client.getConformanceStatement());
}
@Override
public Parameters lookupCode(Map<String, String> params) throws FHIRException {
return (Parameters) VersionConvertorFactory_10_50.convertResource(client.lookupCode(params));

View File

@ -153,6 +153,11 @@ public class TerminologyClientR3 implements ITerminologyClient {
return (CapabilityStatement) VersionConvertorFactory_30_50.convertResource(client.getCapabilitiesStatementQuick());
}
@Override
public CapabilityStatement getCapabilitiesStatement() throws FHIRException {
return (CapabilityStatement) VersionConvertorFactory_30_50.convertResource(client.getCapabilitiesStatement());
}
@Override
public Parameters lookupCode(Map<String, String> params) throws FHIRException {
return (Parameters) VersionConvertorFactory_30_50.convertResource(client.lookupCode(params));

View File

@ -64,7 +64,7 @@ public class TerminologyClientR4 implements ITerminologyClient {
}
public FhirPublication getActualVersion() {
return FhirPublication.STU3;
return FhirPublication.R4;
}
@ -177,6 +177,11 @@ public class TerminologyClientR4 implements ITerminologyClient {
return (CapabilityStatement) VersionConvertorFactory_40_50.convertResource(client.getCapabilitiesStatementQuick());
}
@Override
public CapabilityStatement getCapabilitiesStatement() throws FHIRException {
return (CapabilityStatement) VersionConvertorFactory_40_50.convertResource(client.getCapabilitiesStatement());
}
@Override
public Parameters lookupCode(Map<String, String> params) throws FHIRException {
return (Parameters) VersionConvertorFactory_40_50.convertResource(client.lookupCode(params));

View File

@ -31,12 +31,7 @@ package org.hl7.fhir.r4.conformance;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRFormatError;
@ -1384,7 +1379,7 @@ public class ProfileComparer {
if (f.exists())
return TextFile.fileToString(f);
HTTPResult res = ManagedWebAccess.get(source);
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), source);
res.checkThrowException();
String result = TextFile.bytesToString(res.getContent());
TextFile.stringToFile(result, f);

View File

@ -4949,7 +4949,15 @@ public class FHIRPathEngine {
private List<Base> funcToString(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
List<Base> result = new ArrayList<Base>();
result.add(new StringType(convertToString(focus)).noExtensions());
for (Base item : focus) {
String value = convertToString(item);
if (value != null)
result.add(new StringType(value).noExtensions());
}
if (result.size() > 1) {
throw makeException(exp, I18nConstants.FHIRPATH_NO_COLLECTION, "toString", result.size());
}
return result;
}

View File

@ -71,7 +71,6 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
@Setter
private ResourceFormat preferredResourceFormat;
private int maxResultSetSize = -1;// _count
private CapabilityStatement capabilities;
@Getter
@Setter
private Client client = new Client();
@ -100,13 +99,6 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
this.maxResultSetSize = -1;
}
private void checkCapabilities() {
try {
capabilities = getCapabilitiesStatementQuick();
} catch (Throwable e) {
}
}
public String getPreferredResourceFormat() {
return preferredResourceFormat.getHeader();
}
@ -130,10 +122,10 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
return capabilities;
}
public CapabilityStatement getCapabilitiesStatement() {
public CapabilityStatement getCapabilitiesStatementQuick() {
CapabilityStatement conformance = null;
try {
conformance = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false),
conformance = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true),
withVer(getPreferredResourceFormat(), "4.0"), generateHeaders(false), "CapabilitiesStatement", timeoutNormal).getReference();
} catch (Exception e) {
throw new FHIRException("Error fetching the server's conformance statement", e);
@ -141,18 +133,15 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
return conformance;
}
public CapabilityStatement getCapabilitiesStatementQuick() throws EFhirClientException {
if (capabilities != null)
return capabilities;
try {
capabilities = (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(true),
withVer(getPreferredResourceFormat(), "4.0"), generateHeaders(false), "CapabilitiesStatement-Quick", timeoutNormal)
.getReference();
} catch (Exception e) {
throw new FHIRException("Error fetching the server's capability statement: " + e.getMessage(), e);
}
return capabilities;
}
public CapabilityStatement getCapabilitiesStatement() throws EFhirClientException {
try {
return (CapabilityStatement) client.issueGetResourceRequest(resourceAddress.resolveMetadataUri(false),
withVer(getPreferredResourceFormat(), "4.0"), generateHeaders(false), "CapabilitiesStatement-Quick", timeoutNormal)
.getReference();
} catch (Exception e) {
throw new FHIRException("Error fetching the server's capability statement: " + e.getMessage(), e);
}
}
public Resource read(String resourceClass, String id) {// TODO Change this to AddressableResource
recordUse();
@ -562,8 +551,7 @@ public class FHIRToolingClient extends FHIRBaseToolingClient {
}
public String getServerVersion() {
checkCapabilities();
return capabilities == null ? null : capabilities.getSoftware().getVersion();
return getCapabilitiesStatementQuick().getSoftware().getVersion();
}
public Bundle search(String type, String criteria) {

View File

@ -61,11 +61,11 @@ public class TextClientLogger extends BaseLogger implements ToolingClientLogger
file.println("\r\n--- " + id + " -----------------\r\nRequest: \r\n");
file.println(method + " " + url + " HTTP/1.0");
for (String s : headers)
file.println(Utilities.escapeXml(s));
file.println(s);
if (body != null) {
file.println("");
try {
file.println(Utilities.escapeXml(new String(body, "UTF-8")));
file.println(new String(body, "UTF-8"));
} catch (UnsupportedEncodingException e) {
}
}
@ -82,7 +82,7 @@ public class TextClientLogger extends BaseLogger implements ToolingClientLogger
if (body != null) {
file.println("");
try {
file.println(Utilities.escapeXml(new String(body, "UTF-8")));
file.println(new String(body, "UTF-8"));
} catch (UnsupportedEncodingException e) {
}
}

View File

@ -4820,7 +4820,15 @@ public class FHIRPathEngine {
private List<Base> funcToString(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
List<Base> result = new ArrayList<Base>();
result.add(new StringType(convertToString(focus)).noExtensions());
for (Base item : focus) {
String value = convertToString(item);
if (value != null)
result.add(new StringType(value).noExtensions());
}
if (result.size() > 1) {
throw makeException(exp, I18nConstants.FHIRPATH_NO_COLLECTION, "toString", result.size());
}
return result;
}

View File

@ -9,6 +9,7 @@ import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -79,7 +80,7 @@ public class TerminologyCacheManager {
try {
System.out.println("Initialise terminology cache from " + source);
HTTPResult res = ManagedWebAccess.get(source + "?nocache=" + System.currentTimeMillis());
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), source + "?nocache=" + System.currentTimeMillis());
res.checkThrowException();
unzip(new ByteArrayInputStream(res.getContent()), cacheFolder);
} catch (Exception e) {
@ -148,7 +149,7 @@ public class TerminologyCacheManager {
String url = "https://tx.fhir.org/post/tx-cache/" + ghOrg + "/" + ghRepo + "/" + ghBranch + ".zip";
System.out.println("Sending tx-cache to " + url + " (" + Utilities.describeSize(bs.toByteArray().length) + ")");
HTTPResult res = ManagedWebAccess.accessor()
HTTPResult res = ManagedWebAccess.accessor(Arrays.asList("web"))
.withBasicAuth(token.substring(0, token.indexOf(':')), token.substring(token.indexOf(':') + 1))
.put(url, bs.toByteArray(), null, "application/zip");
if (res.getCode() >= 300) {

View File

@ -336,4 +336,23 @@ public class FHIRPathTests {
assertEquals(1, results.size());
assertEquals("123", results.get(0).toString());
}
@Test
public void testEvaluate_ToStringOnDateValue() {
Patient input = new Patient();
var dtv = new DateType("2024");
input.setBirthDateElement(dtv);
List<Base> results = fp.evaluate(input, "Patient.birthDate.toString()");
assertEquals(1, results.size());
assertEquals("2024", results.get(0).toString());
}
@Test
public void testEvaluate_ToStringOnExtensionOnlyValue() {
Patient input = new Patient();
var dtv = new DateType();
input.setBirthDateElement(dtv);
List<Base> results = fp.evaluate(input, "Patient.birthDate.toString()");
assertEquals(0, results.size());
}
}

View File

@ -29,6 +29,9 @@ import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.utilities.TextFile;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.http.HTTPRequest;
import org.hl7.fhir.utilities.http.HTTPResult;
import org.hl7.fhir.utilities.http.ManagedWebAccess;
import org.hl7.fhir.utilities.json.JsonException;
import org.hl7.fhir.utilities.json.model.JsonArray;
import org.hl7.fhir.utilities.json.model.JsonElement;
@ -428,6 +431,20 @@ public class SHCParser extends ParserBase {
private String getVCIIssuer(List<ValidationMessage> errors, String issuer) {
try {
JsonObject vci = org.hl7.fhir.utilities.json.parser.JsonParser.parseObjectFromUrl("https://raw.githubusercontent.com/the-commons-project/vci-directory/main/vci-issuers.json");
/* HTTPResult httpResult = ManagedWebAccess.httpCall(
new HTTPRequest().withMethod(HTTPVerb.GET).withUrl(new URL("https://raw.githubusercontent.com/the-commons-project/vci-directory/main/vci-issuers.json"))
new URL("https://raw.githubusercontent.com/the-commons-project/vci-directory/main/vci-issuers.json")
HTTPRequest.HttpMethod.GET,
null,
null,
null
)
)
*/
//JsonObject vci = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject();
for (JsonObject j : vci.getJsonObjects("participating_issuers")) {
if (issuer.equals(j.asString("iss"))) {
return j.asString("name");

View File

@ -287,7 +287,7 @@ public class SHLParser extends ParserBase {
private HTTPResult fetchFile(String url, String ct) throws IOException {
HTTPResult res = ManagedWebAccess.get(url, ct);
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), url, ct);
res.checkThrowException();
return res;
}
@ -299,7 +299,7 @@ public class SHLParser extends ParserBase {
JsonObject j = new JsonObject();
j.add("recipient", "FHIR Validator");
HTTPResult res = ManagedWebAccess.post(url, org.hl7.fhir.utilities.json.parser.JsonParser.composeBytes(j), "application/json", "application/json");
HTTPResult res = ManagedWebAccess.post(Arrays.asList("web"), url, org.hl7.fhir.utilities.json.parser.JsonParser.composeBytes(j), "application/json", "application/json");
res.checkThrowException();
return res;
}

View File

@ -4958,7 +4958,15 @@ public class FHIRPathEngine {
private List<Base> funcToString(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
List<Base> result = new ArrayList<Base>();
result.add(new StringType(convertToString(focus)).noExtensions());
for (Base item : focus) {
String value = convertToString(item);
if (value != null)
result.add(new StringType(value).noExtensions());
}
if (result.size() > 1) {
throw makeException(exp, I18nConstants.FHIRPATH_NO_COLLECTION, "toString", result.size());
}
return result;
}

View File

@ -9,6 +9,7 @@ import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -78,7 +79,7 @@ public class TerminologyCacheManager {
try {
System.out.println("Initialise terminology cache from "+source);
HTTPResult res = ManagedWebAccess.get(source+"?nocache=" + System.currentTimeMillis());
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), source+"?nocache=" + System.currentTimeMillis());
res.checkThrowException();
unzip(new ByteArrayInputStream(res.getContent()), cacheFolder);
} catch (Exception e) {
@ -148,7 +149,7 @@ public class TerminologyCacheManager {
// post it to
String url = "https://tx.fhir.org/post/tx-cache/"+ghOrg+"/"+ghRepo+"/"+ghBranch+".zip";
System.out.println("Sending tx-cache to "+url+" ("+Utilities.describeSize(bs.toByteArray().length)+")");
HTTPResult res = ManagedWebAccess.accessor()
HTTPResult res = ManagedWebAccess.accessor(Arrays.asList("web"))
.withBasicAuth(token.substring(0, token.indexOf(':')), token.substring(token.indexOf(':') + 1))
.put(url, bs.toByteArray(), null, "application/zip");

View File

@ -60,6 +60,7 @@ public interface ITerminologyClient {
ITerminologyClient setLogger(ToolingClientLogger txLog) throws FHIRException;
int getRetryCount() throws FHIRException;
ITerminologyClient setRetryCount(int retryCount) throws FHIRException;
CapabilityStatement getCapabilitiesStatement() throws FHIRException;
CapabilityStatement getCapabilitiesStatementQuick() throws FHIRException;
Parameters lookupCode(Map<String, String> params) throws FHIRException;
Parameters lookupCode(Parameters params) throws FHIRException;

View File

@ -165,6 +165,11 @@ public class TerminologyClientR5 implements ITerminologyClient {
return client.getCapabilitiesStatementQuick();
}
@Override
public CapabilityStatement getCapabilitiesStatement() {
return client.getCapabilitiesStatement();
}
@Override
public Parameters lookupCode(Map<String, String> params) {
return client.lookupCode(params);

View File

@ -3,6 +3,7 @@ package org.hl7.fhir.r5.test.utils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.model.Constants;
import org.hl7.fhir.utilities.*;
import org.hl7.fhir.utilities.filesystem.CSFile;
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
@ -27,6 +28,7 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -34,12 +36,51 @@ public class CompareUtilities extends BaseTestingUtilities {
private static final boolean SHOW_DIFF = false;
private JsonObject externals;
private Map<String, String> variables;
private boolean patternMode;
public CompareUtilities() {
super();
this.variables = new HashMap<String, String>();
}
public CompareUtilities(JsonObject externals) {
super();
this.externals = externals;
this.variables = new HashMap<String, String>();
}
public CompareUtilities(JsonObject externals, Map<String, String> variables) {
super();
this.externals = externals;
this.variables = variables;
}
/**
* in pattern mode, the comparison is only looking to find the expected properties. anything else is ignored
* @return
*/
public boolean isPatternMode() {
return patternMode;
}
public CompareUtilities setPatternMode(boolean patternMode) {
this.patternMode = patternMode;
return this;
}
public String createNotEqualMessage(String id, final String message, final String expected, final String actual) {
if (patternMode) {
return new StringBuilder()
.append(message).append('\n')
.append("Expected:").append(presentExpected(expected)).append(" for "+id).append('\n')
.append(message).append(". ")
.append("Expected:").append(presentExpected(expected)).append(" for "+id).append(". ")
.append("Actual :").append("\""+actual+"\"").toString();
} else {
return new StringBuilder()
.append(message).append('\n')
.append("Expected:").append(presentExpected(expected)).append(" for "+id).append('\n')
.append("Actual :").append("\""+actual+"\"").toString();
}
}
private String presentExpected(String expected) {
@ -64,8 +105,13 @@ public class CompareUtilities extends BaseTestingUtilities {
switch (expected) {
case "$$" : return "$$";
case "$instant$": return "\"An Instant\"";
case "$date$": return "\"A date\"";
case "$uuid$": return "\"A Uuid\"";
case "$string$": return "\"A string\"";
case "$id$": return "\"An Id\"";
case "$url$": return "\"A URL\"";
case "$token$": return "\"A Token\"";
case "$version$": return variables.containsKey("version") ? variables.get("version") : "(anything)";
default: return "Unhandled template: "+expected;
}
}
@ -74,15 +120,13 @@ public class CompareUtilities extends BaseTestingUtilities {
}
}
public static String checkXMLIsSame(String id, InputStream expected, InputStream actual) throws Exception {
CompareUtilities self = new CompareUtilities();
String result = self.compareXml(id, expected, actual);
public String checkXMLIsSame(String id, InputStream expected, InputStream actual) throws Exception {
String result = compareXml(id, expected, actual);
return result;
}
public static String checkXMLIsSame(String id, String expected, String actual) throws Exception {
CompareUtilities self = new CompareUtilities();
String result = self.compareXml(id, expected, actual);
public String checkXMLIsSame(String id, String expected, String actual) throws Exception {
String result = compareXml(id, expected, actual);
if (result != null && SHOW_DIFF) {
String diff = getDiffTool();
if (diff != null && ManagedFileAccess.file(diff).exists() || Utilities.isToken(diff)) {
@ -92,7 +136,7 @@ public class CompareUtilities extends BaseTestingUtilities {
return result;
}
private static String getDiffTool() throws IOException {
private String getDiffTool() throws IOException {
if (FhirSettings.hasDiffToolPath()) {
return FhirSettings.getDiffToolPath();
} else if (System.getenv("ProgramFiles") != null) {
@ -219,14 +263,12 @@ public class CompareUtilities extends BaseTestingUtilities {
return builder.parse(fn);
}
public static String checkJsonSrcIsSame(String id, String expected, String actual, JsonObject externals) throws FileNotFoundException, IOException {
return checkJsonSrcIsSame(id, expected, actual, true, externals);
public String checkJsonSrcIsSame(String id, String expected, String actual) throws FileNotFoundException, IOException {
return checkJsonSrcIsSame(id, expected, actual, true);
}
public static String checkJsonSrcIsSame(String id, String expectedString, String actualString, boolean showDiff, JsonObject externals) throws FileNotFoundException, IOException {
CompareUtilities self = new CompareUtilities();
self.externals = externals;
String result = self.compareJsonSrc(id, expectedString, actualString);
public String checkJsonSrcIsSame(String id, String expectedString, String actualString, boolean showDiff) throws FileNotFoundException, IOException {
String result = compareJsonSrc(id, expectedString, actualString);
if (result != null && SHOW_DIFF && showDiff) {
String diff = null;
if (System.getProperty("os.name").contains("Linux"))
@ -259,9 +301,8 @@ public class CompareUtilities extends BaseTestingUtilities {
return result;
}
public static String checkJsonIsSame(String id, String expected, String actual) throws FileNotFoundException, IOException {
CompareUtilities self = new CompareUtilities();
String result = self.compareJson(id, expected, actual);
public String checkJsonIsSame(String id, String expected, String actual) throws FileNotFoundException, IOException {
String result = compareJson(id, expected, actual);
if (result != null && SHOW_DIFF) {
String diff = Utilities.path(System.getenv("ProgramFiles(X86)"), "WinMerge", "WinMergeU.exe");
List<String> command = new ArrayList<String>();
@ -294,16 +335,17 @@ public class CompareUtilities extends BaseTestingUtilities {
String n = en.getName();
if (!n.equals("fhir_comments")) {
if (expectedJsonObject.has(n)) {
String s = compareNodes(id, path + '.' + n, expectedJsonObject.get(n), en.getValue(), countOnlys.contains(n));
String s = compareNodes(id, path + '.' + n, expectedJsonObject.get(n), en.getValue(), countOnlys.contains(n), n, actualJsonObject);
if (!Utilities.noString(s))
return s;
} else
return "properties differ at " + path + ": missing property " + n;
} else if (!patternMode) {
return "properties differ at " + path + ": unexpected property " + n;
}
}
}
for (JsonProperty en : expectedJsonObject.getProperties()) {
String n = en.getName();
if (!n.equals("fhir_comments") && !n.equals("$optional$") && !optionals.contains(n)) {
if (!n.equals("fhir_comments") && !isOptional(n, optionals)) {
if (!actualJsonObject.has(n) && !allOptional(en.getValue()))
return "properties differ at " + path + ": missing property " + n;
}
@ -311,6 +353,10 @@ public class CompareUtilities extends BaseTestingUtilities {
return null;
}
private boolean isOptional(String n, List<String> optionals) {
return n.equals("$optional$") || optionals.contains("*") || optionals.contains(n);
}
private boolean allOptional(JsonElement value) {
if (value.isJsonArray()) {
JsonArray a = value.asJsonArray();
@ -352,7 +398,7 @@ public class CompareUtilities extends BaseTestingUtilities {
return res;
}
private String compareNodes(String id, String path, JsonElement expectedJsonElement, JsonElement actualJsonElement, boolean countOnly) {
private String compareNodes(String id, String path, JsonElement expectedJsonElement, JsonElement actualJsonElement, boolean countOnly, String name, JsonObject parent) {
if (!(expectedJsonElement instanceof JsonPrimitive && actualJsonElement instanceof JsonPrimitive)) {
if (actualJsonElement.getClass() != expectedJsonElement.getClass()) {
return createNotEqualMessage(id, "properties differ at " + path, expectedJsonElement.getClass().getName(), actualJsonElement.getClass().getName());
@ -394,30 +440,51 @@ public class CompareUtilities extends BaseTestingUtilities {
return createNotEqualMessage(id, "array item count differs at " + path, Integer.toString(es), Integer.toString(as));
}
} else {
int expectedMin = countExpectedMin(expectedArray);
int oc = optionalCount(expectedArray);
int expectedMin = countExpectedMin(expectedArray, name, parent);
int oc = optionalCount(expectedArray, name, parent);
if (as > es || as < expectedMin)
return createNotEqualMessage(id, "array item count differs at " + path, Integer.toString(es), Integer.toString(as));
int c = 0;
for (int i = 0; i < es; i++) {
if (c >= as) {
if (i >= es - oc && isOptional(expectedArray.get(i))) {
return null; // this is OK
} else {
return "One or more array items did not match at "+path+" starting at index "+i;
if (patternMode) {
int c = 0;
for (int i = 0; i < expectedArray.size(); i++) {
String s = "Doesn't exist";
CommaSeparatedStringBuilder cs = new CommaSeparatedStringBuilder("\r\n");
cs.append("");
while (s != null && c < actualArray.size()) {
s = compareNodes(id, path + "[" + Integer.toString(i) + "]", expectedArray.get(i), actualArray.get(c), false, null, null);
if (s != null) {
cs.append(" "+s);
}
c++;
}
if (s != null) {
return "The expected item at "+path+" at index "+i+" was not found: "+cs.toString();
}
}
String s = compareNodes(id, path + "[" + Integer.toString(i) + "]", expectedArray.get(i), actualArray.get(c), false);
if (!Utilities.noString(s) && !isOptional(expectedArray.get(i))) {
return s;
} else {
if (as > es || as < expectedMin) {
return createNotEqualMessage(id, "array item count differs at " + path, Integer.toString(es), Integer.toString(as));
}
if (Utilities.noString(s)) {
c++;
int c = 0;
for (int i = 0; i < es; i++) {
if (c >= as) {
if (i >= es - oc && isOptional(expectedArray.get(i), name, parent)) {
return null; // this is OK
} else {
return "One or more array items did not match at "+path+" starting at index "+i;
}
}
String s = compareNodes(id, path + "[" + Integer.toString(i) + "]", expectedArray.get(i), actualArray.get(c), false, null, null);
if (!Utilities.noString(s) && !isOptional(expectedArray.get(i), name, parent)) {
return s;
}
if (Utilities.noString(s)) {
c++;
}
}
if (c < as) {
return "Unexpected Node found in array at '"+path+"' at index "+c;
}
}
if (c < as) {
return "Unexpected Node found in array at '"+path+"' at index "+c;
}
}
} else
@ -425,7 +492,7 @@ public class CompareUtilities extends BaseTestingUtilities {
return null;
}
private int optionalCount(JsonArray arr) {
private int optionalCount(JsonArray arr, String name, JsonObject parent) {
int c = 0;
for (JsonElement e : arr) {
if (e.isJsonObject()) {
@ -438,14 +505,14 @@ public class CompareUtilities extends BaseTestingUtilities {
return c;
}
private boolean isOptional(JsonElement e) {
private boolean isOptional(JsonElement e, String name, JsonObject parent) {
return e.isJsonObject() && e.asJsonObject().has("$optional$");
}
private int countExpectedMin(JsonArray array) {
private int countExpectedMin(JsonArray array, String name, JsonObject parent) {
int count = array.size();
for (JsonElement e : array) {
if (isOptional(e)) {
if (isOptional(e, name, parent)) {
count--;
}
}
@ -485,8 +552,13 @@ public class CompareUtilities extends BaseTestingUtilities {
switch (expectedJsonString) {
case "$$" : return true;
case "$instant$": return actualJsonString.matches("([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]{1,9})?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))");
case "$date$": return actualJsonString.matches("([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]{1,9})?(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00)))?");
case "$uuid$": return actualJsonString.matches("urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}");
case "$string$": return actualJsonString.equals(actualJsonString.trim());
case "$id$": return actualJsonString.matches("[A-Za-z0-9\\-\\.]{1,64}");
case "$url$": return actualJsonString.matches("(https?://|www\\.)[-a-zA-Z0-9+&@#/%?=~_|!:.;]*[-a-zA-Z0-9+&@#/%=~_|]");
case "$token$": return actualJsonString.matches("[0-9a-zA-Z_][0-9a-zA-Z_\\.\\-]*");
case "$version$": return matchesVariable(actualJsonString, "version");
default:
throw new Error("Unhandled template: "+expectedJsonString);
}
@ -496,6 +568,14 @@ public class CompareUtilities extends BaseTestingUtilities {
}
}
private boolean matchesVariable(String value, String name) {
if (variables.containsKey(name)) {
return value.equals(variables.get(name));
} else {
return true;
}
}
private List<String> readChoices(String s) {
List<String> list = new ArrayList<>();
for (String p : s.split("\\|")) {
@ -504,13 +584,12 @@ public class CompareUtilities extends BaseTestingUtilities {
return list;
}
public static String checkTextIsSame(String id, String expected, String actual) throws FileNotFoundException, IOException {
public String checkTextIsSame(String id, String expected, String actual) throws FileNotFoundException, IOException {
return checkTextIsSame(id, expected, actual, true);
}
public static String checkTextIsSame(String id, String expectedString, String actualString, boolean showDiff) throws FileNotFoundException, IOException {
CompareUtilities self = new CompareUtilities();
String result = self.compareText(id, expectedString, actualString);
public String checkTextIsSame(String id, String expectedString, String actualString, boolean showDiff) throws FileNotFoundException, IOException {
String result = compareText(id, expectedString, actualString);
if (result != null && SHOW_DIFF && showDiff) {
String diff = null;
if (System.getProperty("os.name").contains("Linux"))

View File

@ -47,7 +47,7 @@ class LanguageUtilsTest implements ResourceLoaderTests {
.lines()
.collect(Collectors.joining("\n"));
String msg = CompareUtilities.checkJsonSrcIsSame("", generatedResource.toString(),text, null);
String msg = new CompareUtilities().checkJsonSrcIsSame("", generatedResource.toString(),text);
Assertions.assertNull(msg);
}

View File

@ -138,7 +138,7 @@ public class SQLOnFhirTests {
// sortResults(rows);
String expS = JsonParser.compose(exp, true);
String rowS = JsonParser.compose(rows, true);
String c = CompareUtilities.checkJsonSrcIsSame(name, expS, rowS, null);
String c = new CompareUtilities().checkJsonSrcIsSame(name, expS, rowS);
Assertions.assertNull(c, c);
} else if (test.testCase.has("expectCount")) {
Assertions.assertEquals(test.testCase.asInteger("expectCount"), results.size());

View File

@ -1,340 +1,359 @@
package org.hl7.fhir.r5.test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.stream.Stream;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.lang3.NotImplementedException;
import org.fhir.ucum.UcumException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.elementmodel.Manager;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
import org.hl7.fhir.r5.fhirpath.ExpressionNode;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine;
import org.hl7.fhir.r5.fhirpath.TypeDetails;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IEvaluationContext;
import org.hl7.fhir.r5.fhirpath.FHIRPathUtilityClasses.FunctionDetails;
import org.hl7.fhir.r5.elementmodel.ValidatedFragment;
import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.formats.XmlParser;
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.test.utils.TestingUtilities;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.xml.XMLUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
public class FHIRPathTests {
public enum TestResultType {OK, SYNTAX, SEMANTICS, EXECUTION}
public class FHIRPathTestEvaluationServices implements IEvaluationContext {
@Override
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveConstant), when item is element");
}
@Override
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveConstantType), when item is element");
}
@Override
public boolean log(String argument, List<Base> focus) {
return false;
}
@Override
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveFunction), when item is element (for " + functionName + ")");
}
@Override
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.checkFunction), when item is element");
}
@Override
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.executeFunction), when item is element");
}
@Override
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveReference), when item is element");
}
@Override
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
if (url.equals("http://hl7.org/fhir/StructureDefinition/Patient"))
return true;
if (url.equals("http://hl7.org/fhir/StructureDefinition/Person"))
return false;
throw new FHIRException("unknown profile " + url);
}
@Override
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return context.fetchResource(ValueSet.class, url);
}
@Override
public boolean paramIsType(String name, int index) {
return false;
}
}
private static FHIRPathEngine fp;
private final Map<String, Base> resources = new HashMap<String, Base>();
private static SimpleWorkerContext context;
@BeforeAll
public static void setUp() throws FileNotFoundException, FHIRException, IOException {
context = new SimpleWorkerContext((SimpleWorkerContext) TestingUtilities.getSharedWorkerContext());
if (!context.hasPackage("hl7.cda.us.ccda", null)) {
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager.Builder().build();
NpmPackage npm = pcm.loadPackage("hl7.cda.uv.core", "2.0.0");
context.loadFromPackage(npm, null);
npm = pcm.loadPackage("hl7.cda.us.ccda", "current");
context.loadFromPackage(npm, null);
}
if (fp == null) {
fp = new FHIRPathEngine(context);
}
}
public static Stream<Arguments> data() throws ParserConfigurationException, SAXException, IOException {
Document dom = XMLUtil.parseToDom(TestingUtilities.loadTestResource("r5", "fhirpath", "tests-fhir-r5.xml"));
List<Element> list = new ArrayList<Element>();
List<Element> groups = new ArrayList<Element>();
XMLUtil.getNamedChildren(dom.getDocumentElement(), "group", groups);
for (Element g : groups) {
XMLUtil.getNamedChildren(g, "test", list);
XMLUtil.getNamedChildren(g, "modeTest", list);
}
List<Arguments> objects = new ArrayList<>();
for (Element e : list) {
objects.add(Arguments.of(getName(e), e));
}
return objects.stream();
}
private static Object getName(Element e) {
String s = e.getAttribute("name");
Element p = (Element) e.getParentNode();
int ndx = 0;
for (int i = 0; i < p.getChildNodes().getLength(); i++) {
Node c = p.getChildNodes().item(i);
if (c == e) {
break;
} else if (c instanceof Element) {
ndx++;
}
}
if (Utilities.noString(s)) {
s = "?? - G " + p.getAttribute("name") + "[" + Integer.toString(ndx + 1) + "]";
} else {
s = s + " - G " + p.getAttribute("name") + "[" + Integer.toString(ndx + 1) + "]";
}
return s;
}
@SuppressWarnings("deprecation")
@ParameterizedTest(name = "{index}: file {0}")
@MethodSource("data")
public void test(String name, Element test) throws FileNotFoundException, IOException, FHIRException, org.hl7.fhir.exceptions.FHIRException, UcumException {
// Setting timezone for this test. Grahame is in UTC+11, Travis is in GMT, and I'm here in Toronto, Canada with
// all my time based tests failing locally...
TimeZone.setDefault(TimeZone.getTimeZone("UTC+1100"));
fp.setHostServices(new FHIRPathTestEvaluationServices());
String input = test.getAttribute("inputfile");
String expression = XMLUtil.getNamedChild(test, "expression").getTextContent();
TestResultType fail = TestResultType.OK;
if ("syntax".equals(XMLUtil.getNamedChild(test, "expression").getAttribute("invalid"))) {
fail = TestResultType.SYNTAX;
} else if ("semantic".equals(XMLUtil.getNamedChild(test, "expression").getAttribute("invalid"))) {
fail = TestResultType.SEMANTICS;
} else if ("execution".equals(XMLUtil.getNamedChild(test, "expression").getAttribute("invalid"))) {
fail = TestResultType.EXECUTION;
};
fp.setAllowPolymorphicNames("lenient/polymorphics".equals(test.getAttribute("mode")));
boolean skipStaticCheck = false;
if ("true".equals(test.getAttribute("skipStaticCheck")))
skipStaticCheck = true;
Base res = null;
List<Base> outcome = new ArrayList<Base>();
System.out.println(name);
ExpressionNode node = null;
try {
node = fp.parse(expression);
Assertions.assertTrue(fail != TestResultType.SYNTAX, String.format("Expected exception didn't occur parsing %s", expression));
} catch (Exception e) {
System.out.println("Parsing Error: "+e.getMessage());
Assertions.assertTrue(fail == TestResultType.SYNTAX, String.format("Unexpected exception parsing %s: " + e.getMessage(), expression));
}
if (node != null) {
if (!Utilities.noString(input)) {
res = resources.get(input);
if (res == null) {
if ("cda".equals(test.getAttribute("mode"))) {
res = Manager.makeParser(fp.getWorker(), FhirFormat.XML).parseSingle(TestingUtilities.loadTestResourceStream("r5", input), null);
} else if (input.endsWith(".json")) {
res = new JsonParser().parse(TestingUtilities.loadTestResourceStream("r5", input));
} else {
res = new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", input));
}
resources.put(input, res);
}
}
if (!skipStaticCheck) {
try {
if (Utilities.noString(input)) {
fp.check(null, null, node);
} else {
fp.check(res, res.fhirType(), res.fhirType(), node);
}
Assertions.assertTrue(fail != TestResultType.SEMANTICS, String.format("Expected exception didn't occur checking %s", expression));
} catch (Exception e) {
System.out.println("Checking Error: "+e.getMessage());
Assertions.assertTrue(fail == TestResultType.SEMANTICS, String.format("Unexpected exception checking %s: " + e.getMessage(), expression));
node = null;
}
}
}
if (node != null) {
try {
if ("element".equals(test.getAttribute("mode"))) {
List<ValidatedFragment> e = Manager.parse(fp.getWorker(), TestingUtilities.loadTestResourceStream("r5", input), input.endsWith(".json") ? FhirFormat.JSON : FhirFormat.XML);
outcome = fp.evaluate(e.get(0).getElement(), node);
} else {
outcome = fp.evaluate(res, node);
}
Assertions.assertTrue(fail == TestResultType.OK, String.format("Expected exception didn't occur executing %s", expression));
} catch (Exception e) {
System.out.println("Execution Error: "+e.getMessage());
Assertions.assertTrue(fail == TestResultType.EXECUTION, String.format("Unexpected exception executing %s: " + e.getMessage(), expression));
node = null;
}
}
if (fp.hasLog()) {
System.out.println(name);
System.out.println(fp.takeLog());
}
if (node != null) {
if ("true".equals(test.getAttribute("predicate"))) {
boolean ok = fp.convertToBoolean(outcome);
outcome.clear();
outcome.add(new BooleanType(ok));
}
List<Element> expected = new ArrayList<Element>();
XMLUtil.getNamedChildren(test, "output", expected);
assertEquals(outcome.size(), expected.size(), String.format("Expected %d objects but found %d for expression %s", expected.size(), outcome.size(), expression));
if ("false".equals(test.getAttribute("ordered"))) {
for (int i = 0; i < Math.min(outcome.size(), expected.size()); i++) {
String tn = outcome.get(i).fhirType();
String s;
if (outcome.get(i) instanceof Quantity) {
s = fp.convertToString(outcome.get(i));
} else {
s = ((PrimitiveType) outcome.get(i)).asStringValue();
}
boolean found = false;
for (Element e : expected) {
if ((Utilities.noString(e.getAttribute("type")) || e.getAttribute("type").equals(tn)) &&
(Utilities.noString(e.getTextContent()) || e.getTextContent().equals(s))) {
found = true;
}
}
Assertions.assertTrue(found, String.format("Outcome %d: Value %s of type %s not expected for %s", i, s, tn, expression));
}
} else {
for (int i = 0; i < Math.min(outcome.size(), expected.size()); i++) {
String tn = expected.get(i).getAttribute("type");
if (!Utilities.noString(tn)) {
assertEquals(tn, outcome.get(i).fhirType(), String.format("Outcome %d: Type should be %s but was %s", i, tn, outcome.get(i).fhirType()));
}
String v = expected.get(i).getTextContent();
if (!Utilities.noString(v)) {
if (outcome.get(i) instanceof Quantity) {
Quantity q = fp.parseQuantityString(v);
Assertions.assertTrue(outcome.get(i).equalsDeep(q), String.format("Outcome %d: Value should be %s but was %s", i, v, outcome.get(i).toString()));
} else {
Assertions.assertTrue(outcome.get(i) instanceof PrimitiveType, String.format("Outcome %d: Value should be a primitive type but was %s", i, outcome.get(i).fhirType()));
if (!(v.equals(((PrimitiveType) outcome.get(i)).fpValue()))) {
System.out.println(name);
System.out.println(String.format("Outcome %d: Value should be %s but was %s for expression %s", i, v, ((PrimitiveType) outcome.get(i)).fpValue(), expression));
}
assertEquals(v, ((PrimitiveType) outcome.get(i)).fpValue(), String.format("Outcome %d: Value should be %s but was %s for expression %s", i, v, ((PrimitiveType) outcome.get(i)).fpValue(), expression));
}
}
}
}
}
}
@Test
@DisplayName("resolveConstant returns a list of Base")
public void resolveConstantReturnsList() {
final String DUMMY_CONSTANT_1 = "dummyConstant1";
final String DUMMY_CONSTANT_2 = "dummyConstant2";
fp.setHostServices(new FHIRPathTestEvaluationServices() {
@Override
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
return Arrays.asList(
new StringType(DUMMY_CONSTANT_1).noExtensions(),
new StringType(DUMMY_CONSTANT_2).noExtensions());
}
});
ExpressionNode expressionNode = fp.parse("%dummyConstant");
List<Base> result = fp.evaluate(null, expressionNode);
assertEquals(2, result.size());
assertEquals(DUMMY_CONSTANT_1, result.get(0).primitiveValue());
assertEquals(DUMMY_CONSTANT_2, result.get(1).primitiveValue());
}
@Test
public void testEvaluate_Id() {
Patient input = new Patient();
input.setId(new IdType("http://base/Patient/123/_history/222"));
List<Base> results = fp.evaluate(input, "Patient.id");
assertEquals(1, results.size());
assertEquals("123", results.get(0).toString());
}
package org.hl7.fhir.r5.test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.stream.Stream;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.lang3.NotImplementedException;
import org.fhir.ucum.UcumException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.PathEngineException;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.elementmodel.Manager;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
import org.hl7.fhir.r5.fhirpath.ExpressionNode;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine;
import org.hl7.fhir.r5.fhirpath.TypeDetails;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IEvaluationContext;
import org.hl7.fhir.r5.fhirpath.FHIRPathUtilityClasses.FunctionDetails;
import org.hl7.fhir.r5.elementmodel.ValidatedFragment;
import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.formats.XmlParser;
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.test.utils.TestingUtilities;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.npm.NpmPackage;
import org.hl7.fhir.utilities.xml.XMLUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
public class FHIRPathTests {
public enum TestResultType {OK, SYNTAX, SEMANTICS, EXECUTION}
public class FHIRPathTestEvaluationServices implements IEvaluationContext {
@Override
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveConstant), when item is element");
}
@Override
public TypeDetails resolveConstantType(FHIRPathEngine engine, Object appContext, String name, boolean explicitConstant) throws PathEngineException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveConstantType), when item is element");
}
@Override
public boolean log(String argument, List<Base> focus) {
return false;
}
@Override
public FunctionDetails resolveFunction(FHIRPathEngine engine, String functionName) {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveFunction), when item is element (for " + functionName + ")");
}
@Override
public TypeDetails checkFunction(FHIRPathEngine engine, Object appContext, String functionName, TypeDetails focus, List<TypeDetails> parameters) throws PathEngineException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.checkFunction), when item is element");
}
@Override
public List<Base> executeFunction(FHIRPathEngine engine, Object appContext, List<Base> focus, String functionName, List<List<Base>> parameters) {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.executeFunction), when item is element");
}
@Override
public Base resolveReference(FHIRPathEngine engine, Object appContext, String url, Base refContext) throws FHIRException {
throw new NotImplementedException("Not done yet (FHIRPathTestEvaluationServices.resolveReference), when item is element");
}
@Override
public boolean conformsToProfile(FHIRPathEngine engine, Object appContext, Base item, String url) throws FHIRException {
if (url.equals("http://hl7.org/fhir/StructureDefinition/Patient"))
return true;
if (url.equals("http://hl7.org/fhir/StructureDefinition/Person"))
return false;
throw new FHIRException("unknown profile " + url);
}
@Override
public ValueSet resolveValueSet(FHIRPathEngine engine, Object appContext, String url) {
return context.fetchResource(ValueSet.class, url);
}
@Override
public boolean paramIsType(String name, int index) {
return false;
}
}
private static FHIRPathEngine fp;
private final Map<String, Base> resources = new HashMap<String, Base>();
private static SimpleWorkerContext context;
@BeforeAll
public static void setUp() throws FileNotFoundException, FHIRException, IOException {
context = new SimpleWorkerContext((SimpleWorkerContext) TestingUtilities.getSharedWorkerContext());
if (!context.hasPackage("hl7.cda.us.ccda", null)) {
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager.Builder().build();
NpmPackage npm = pcm.loadPackage("hl7.cda.uv.core", "2.0.0");
context.loadFromPackage(npm, null);
npm = pcm.loadPackage("hl7.cda.us.ccda", "current");
context.loadFromPackage(npm, null);
}
if (fp == null) {
fp = new FHIRPathEngine(context);
}
}
public static Stream<Arguments> data() throws ParserConfigurationException, SAXException, IOException {
Document dom = XMLUtil.parseToDom(TestingUtilities.loadTestResource("r5", "fhirpath", "tests-fhir-r5.xml"));
List<Element> list = new ArrayList<Element>();
List<Element> groups = new ArrayList<Element>();
XMLUtil.getNamedChildren(dom.getDocumentElement(), "group", groups);
for (Element g : groups) {
XMLUtil.getNamedChildren(g, "test", list);
XMLUtil.getNamedChildren(g, "modeTest", list);
}
List<Arguments> objects = new ArrayList<>();
for (Element e : list) {
objects.add(Arguments.of(getName(e), e));
}
return objects.stream();
}
private static Object getName(Element e) {
String s = e.getAttribute("name");
Element p = (Element) e.getParentNode();
int ndx = 0;
for (int i = 0; i < p.getChildNodes().getLength(); i++) {
Node c = p.getChildNodes().item(i);
if (c == e) {
break;
} else if (c instanceof Element) {
ndx++;
}
}
if (Utilities.noString(s)) {
s = "?? - G " + p.getAttribute("name") + "[" + Integer.toString(ndx + 1) + "]";
} else {
s = s + " - G " + p.getAttribute("name") + "[" + Integer.toString(ndx + 1) + "]";
}
return s;
}
@SuppressWarnings("deprecation")
@ParameterizedTest(name = "{index}: file {0}")
@MethodSource("data")
public void test(String name, Element test) throws FileNotFoundException, IOException, FHIRException, org.hl7.fhir.exceptions.FHIRException, UcumException {
// Setting timezone for this test. Grahame is in UTC+11, Travis is in GMT, and I'm here in Toronto, Canada with
// all my time based tests failing locally...
TimeZone.setDefault(TimeZone.getTimeZone("UTC+1100"));
fp.setHostServices(new FHIRPathTestEvaluationServices());
String input = test.getAttribute("inputfile");
String expression = XMLUtil.getNamedChild(test, "expression").getTextContent();
TestResultType fail = TestResultType.OK;
if ("syntax".equals(XMLUtil.getNamedChild(test, "expression").getAttribute("invalid"))) {
fail = TestResultType.SYNTAX;
} else if ("semantic".equals(XMLUtil.getNamedChild(test, "expression").getAttribute("invalid"))) {
fail = TestResultType.SEMANTICS;
} else if ("execution".equals(XMLUtil.getNamedChild(test, "expression").getAttribute("invalid"))) {
fail = TestResultType.EXECUTION;
};
fp.setAllowPolymorphicNames("lenient/polymorphics".equals(test.getAttribute("mode")));
boolean skipStaticCheck = false;
if ("true".equals(test.getAttribute("skipStaticCheck")))
skipStaticCheck = true;
Base res = null;
List<Base> outcome = new ArrayList<Base>();
System.out.println(name);
ExpressionNode node = null;
try {
node = fp.parse(expression);
Assertions.assertTrue(fail != TestResultType.SYNTAX, String.format("Expected exception didn't occur parsing %s", expression));
} catch (Exception e) {
System.out.println("Parsing Error: "+e.getMessage());
Assertions.assertTrue(fail == TestResultType.SYNTAX, String.format("Unexpected exception parsing %s: " + e.getMessage(), expression));
}
if (node != null) {
if (!Utilities.noString(input)) {
res = resources.get(input);
if (res == null) {
if ("cda".equals(test.getAttribute("mode"))) {
res = Manager.makeParser(fp.getWorker(), FhirFormat.XML).parseSingle(TestingUtilities.loadTestResourceStream("r5", input), null);
} else if (input.endsWith(".json")) {
res = new JsonParser().parse(TestingUtilities.loadTestResourceStream("r5", input));
} else {
res = new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", input));
}
resources.put(input, res);
}
}
if (!skipStaticCheck) {
try {
if (Utilities.noString(input)) {
fp.check(null, null, node);
} else {
fp.check(res, res.fhirType(), res.fhirType(), node);
}
Assertions.assertTrue(fail != TestResultType.SEMANTICS, String.format("Expected exception didn't occur checking %s", expression));
} catch (Exception e) {
System.out.println("Checking Error: "+e.getMessage());
Assertions.assertTrue(fail == TestResultType.SEMANTICS, String.format("Unexpected exception checking %s: " + e.getMessage(), expression));
node = null;
}
}
}
if (node != null) {
try {
if ("element".equals(test.getAttribute("mode"))) {
List<ValidatedFragment> e = Manager.parse(fp.getWorker(), TestingUtilities.loadTestResourceStream("r5", input), input.endsWith(".json") ? FhirFormat.JSON : FhirFormat.XML);
outcome = fp.evaluate(e.get(0).getElement(), node);
} else {
outcome = fp.evaluate(res, node);
}
Assertions.assertTrue(fail == TestResultType.OK, String.format("Expected exception didn't occur executing %s", expression));
} catch (Exception e) {
System.out.println("Execution Error: "+e.getMessage());
Assertions.assertTrue(fail == TestResultType.EXECUTION, String.format("Unexpected exception executing %s: " + e.getMessage(), expression));
node = null;
}
}
if (fp.hasLog()) {
System.out.println(name);
System.out.println(fp.takeLog());
}
if (node != null) {
if ("true".equals(test.getAttribute("predicate"))) {
boolean ok = fp.convertToBoolean(outcome);
outcome.clear();
outcome.add(new BooleanType(ok));
}
List<Element> expected = new ArrayList<Element>();
XMLUtil.getNamedChildren(test, "output", expected);
assertEquals(expected.size(), outcome.size(), String.format("Expected %d objects but found %d for expression %s", expected.size(), outcome.size(), expression));
if ("false".equals(test.getAttribute("ordered"))) {
for (int i = 0; i < Math.min(outcome.size(), expected.size()); i++) {
String tn = outcome.get(i).fhirType();
String s;
if (outcome.get(i) instanceof Quantity) {
s = fp.convertToString(outcome.get(i));
} else {
s = ((PrimitiveType) outcome.get(i)).asStringValue();
}
boolean found = false;
for (Element e : expected) {
if ((Utilities.noString(e.getAttribute("type")) || e.getAttribute("type").equals(tn)) &&
(Utilities.noString(e.getTextContent()) || e.getTextContent().equals(s))) {
found = true;
}
}
Assertions.assertTrue(found, String.format("Outcome %d: Value %s of type %s not expected for %s", i, s, tn, expression));
}
} else {
for (int i = 0; i < Math.min(outcome.size(), expected.size()); i++) {
String tn = expected.get(i).getAttribute("type");
if (!Utilities.noString(tn)) {
assertEquals(tn, outcome.get(i).fhirType(), String.format("Outcome %d: Type should be %s but was %s", i, tn, outcome.get(i).fhirType()));
}
String v = expected.get(i).getTextContent();
if (!Utilities.noString(v)) {
if (outcome.get(i) instanceof Quantity) {
Quantity q = fp.parseQuantityString(v);
Assertions.assertTrue(outcome.get(i).equalsDeep(q), String.format("Outcome %d: Value should be %s but was %s", i, v, outcome.get(i).toString()));
} else {
Assertions.assertTrue(outcome.get(i) instanceof PrimitiveType, String.format("Outcome %d: Value should be a primitive type but was %s", i, outcome.get(i).fhirType()));
if (!(v.equals(((PrimitiveType) outcome.get(i)).fpValue()))) {
System.out.println(name);
System.out.println(String.format("Outcome %d: Value should be %s but was %s for expression %s", i, v, ((PrimitiveType) outcome.get(i)).fpValue(), expression));
}
assertEquals(v, ((PrimitiveType) outcome.get(i)).fpValue(), String.format("Outcome %d: Value should be %s but was %s for expression %s", i, v, ((PrimitiveType) outcome.get(i)).fpValue(), expression));
}
}
}
}
}
}
@Test
@DisplayName("resolveConstant returns a list of Base")
public void resolveConstantReturnsList() {
final String DUMMY_CONSTANT_1 = "dummyConstant1";
final String DUMMY_CONSTANT_2 = "dummyConstant2";
fp.setHostServices(new FHIRPathTestEvaluationServices() {
@Override
public List<Base> resolveConstant(FHIRPathEngine engine, Object appContext, String name, boolean beforeContext, boolean explicitConstant) throws PathEngineException {
return Arrays.asList(
new StringType(DUMMY_CONSTANT_1).noExtensions(),
new StringType(DUMMY_CONSTANT_2).noExtensions());
}
});
ExpressionNode expressionNode = fp.parse("%dummyConstant");
List<Base> result = fp.evaluate(null, expressionNode);
assertEquals(2, result.size());
assertEquals(DUMMY_CONSTANT_1, result.get(0).primitiveValue());
assertEquals(DUMMY_CONSTANT_2, result.get(1).primitiveValue());
}
@Test
public void testEvaluate_Id() {
Patient input = new Patient();
input.setId(new IdType("http://base/Patient/123/_history/222"));
List<Base> results = fp.evaluate(input, "Patient.id");
assertEquals(1, results.size());
assertEquals("123", results.get(0).toString());
}
@Test
public void testEvaluate_ToStringOnDateValue() {
Patient input = new Patient();
var dtv = new DateType("2024");
input.setBirthDateElement(dtv);
List<Base> results = fp.evaluate(input, "Patient.birthDate.toString()");
assertEquals(1, results.size());
assertEquals("2024", results.get(0).toString());
}
@Test
public void testEvaluate_ToStringOnExtensionOnlyValue() {
Patient input = new Patient();
var dtv = new DateType();
input.setBirthDateElement(dtv);
List<Base> results = fp.evaluate(input, "Patient.birthDate.toString()");
assertEquals(0, results.size());
}
}

View File

@ -98,7 +98,7 @@ public class GraphQLEngineTests implements IGraphQLStorageServices {
IOUtils.copy(CompareUtilities.loadTestResourceStream("r5", "graphql", source), ManagedFileAccess.outStream(CompareUtilities.tempFile("graphql", source)));
IOUtils.copy(CompareUtilities.loadTestResourceStream("r5", "graphql", output), ManagedFileAccess.outStream(CompareUtilities.tempFile("graphql", output)));
TextFile.stringToFile(str.toString(), CompareUtilities.tempFile("graphql", output+".out"));
msg = CompareUtilities.checkJsonIsSame(id, CompareUtilities.tempFile("graphql", output), CompareUtilities.tempFile("graphql", output+".out"));
msg = new CompareUtilities().checkJsonIsSame(id, CompareUtilities.tempFile("graphql", output), CompareUtilities.tempFile("graphql", output+".out"));
Assertions.assertTrue(Utilities.noString(msg), msg);
}
else

View File

@ -279,7 +279,7 @@ public class NarrativeGenerationTests {
String actualFileName = CompareUtilities.tempFile("narrative", test.getId() + ".html");
TextFile.stringToFile(expected, expectedFileName);
TextFile.stringToFile(actual, actualFileName);
String msg = CompareUtilities.checkXMLIsSame(id, expectedFileName, actualFileName);
String msg = new CompareUtilities().checkXMLIsSame(id, expectedFileName, actualFileName);
Assertions.assertTrue(msg == null, "Output does not match expected: "+msg);
String disp = RendererFactory.factory(source, rc).buildSummary(ResourceWrapper.forResource(rc.getContextUtilities(), source));
@ -289,7 +289,7 @@ public class NarrativeGenerationTests {
actualFileName = CompareUtilities.tempFile("narrative", test.getId() + ".txt");
TextFile.stringToFile(expected, expectedFileName);
TextFile.stringToFile(actual, actualFileName);
msg = CompareUtilities.checkTextIsSame(id, expected, actual);
msg = new CompareUtilities().checkTextIsSame(id, expected, actual);
Assertions.assertTrue(msg == null, "Summary Output does not match expected: "+msg);
//

View File

@ -58,7 +58,7 @@ public class ParsingTests {
r = new XmlParser().parse(b);
b = new JsonParser().setOutputStyle(OutputStyle.PRETTY).composeBytes(r);
String output = new String(b);
String msg = CompareUtilities.checkJsonSrcIsSame(name, src, output, null);
String msg = new CompareUtilities().checkJsonSrcIsSame(name, src, output);
Assertions.assertTrue(msg == null, msg);
}

View File

@ -40,7 +40,7 @@ public class ResourceToElementTest {
Element e = p.parse(res);
new org.hl7.fhir.r5.elementmodel.XmlParser(ctxt).compose(e, ManagedFileAccess.outStream(src), OutputStyle.PRETTY, null);
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(dst), res);
String msg = CompareUtilities.checkXMLIsSame(filename, src, dst);
String msg = new CompareUtilities().checkXMLIsSame(filename, src, dst);
Assertions.assertNull(msg);
}

View File

@ -157,7 +157,7 @@ public class VocabTests {
String actualFileName = CompareUtilities.tempFile("vocab", test.getId() + ".actual.html");
TextFile.stringToFile(expected, expectedFileName);
TextFile.stringToFile(actual, actualFileName);
String msg = CompareUtilities.checkXMLIsSame(test.id, expectedFileName, actualFileName);
String msg = new CompareUtilities().checkXMLIsSame(test.id, expectedFileName, actualFileName);
Assertions.assertTrue(msg == null, "Output does not match expected: "+msg);
} else {
Assertions.fail("Expansion Failed: "+outcome.getError());

View File

@ -68,7 +68,7 @@ public class GeneratedPEModelTest {
Observation tgt = tp.build(ctxt);
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(Utilities.path("[tmp]", "pe-instance-gen.xml")), tgt);
String msg = CompareUtilities.checkXMLIsSame("PEGEN", TestingUtilities.loadTestResourceStream("r5", "profiles", "pe-instance.xml"), ManagedFileAccess.inStream(Utilities.path("[tmp]", "pe-instance-gen.xml")));
String msg = new CompareUtilities().checkXMLIsSame("PEGEN", TestingUtilities.loadTestResourceStream("r5", "profiles", "pe-instance.xml"), ManagedFileAccess.inStream(Utilities.path("[tmp]", "pe-instance-gen.xml")));
Assertions.assertNull(msg, msg);
}

View File

@ -422,7 +422,7 @@ public class PETests {
private void checkGeneratedJava(String name) throws FileNotFoundException, IOException {
String actual = Utilities.normalize(TextFile.fileToString(Utilities.path("[tmp]", "codegen", name+".java")));
String expected = Utilities.normalize(TestingUtilities.loadTestResource("r5", "profiles", name+".java"));
String msg = CompareUtilities.checkTextIsSame(name, expected, actual);
String msg = new CompareUtilities().checkTextIsSame(name, expected, actual);
if (msg != null) {
Assertions.fail("Generated code for "+name+" is different: "+msg);
}

View File

@ -59,7 +59,7 @@ public class CompareUtilitiesTests implements ResourceLoaderTests {
InputStream expectedXMLStream = classLoader.getResourceAsStream(expectedXMLPath);
InputStream actualXMLStream = classLoader.getResourceAsStream(actualXMLPath);
final String actualOutput = CompareUtilities.checkXMLIsSame(expectedFileName, expectedXMLStream, actualXMLStream);
final String actualOutput = new CompareUtilities().checkXMLIsSame(expectedFileName, expectedXMLStream, actualXMLStream);
if (expectedOutputFileName == null) {
assertNull(actualOutput);
@ -91,7 +91,7 @@ public class CompareUtilitiesTests implements ResourceLoaderTests {
final String expectedJSONPath = ROOT_JSON_TEST_PATH.resolve(expectedFileName).toString();
final String actualJSONPath = ROOT_JSON_TEST_PATH.resolve(actualFileName).toString();
final String actualOutput = CompareUtilities.checkJsonSrcIsSame(expectedFileName, getResourceAsString(expectedJSONPath), getResourceAsString(actualJSONPath), false, null);
final String actualOutput = new CompareUtilities().checkJsonSrcIsSame(expectedFileName, getResourceAsString(expectedJSONPath), getResourceAsString(actualJSONPath), false);
if (expectedOutputFileName == null) {
assertNull(actualOutput);
} else {

View File

@ -1 +1 @@
properties differ at : missing property unexpectedProperty
properties differ at : unexpected property unexpectedProperty

View File

@ -9,6 +9,7 @@ import org.hl7.fhir.utilities.settings.ServerDetailsPOJO;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@ -45,7 +46,7 @@ public class ManagedFhirWebAccessor extends ManagedWebAccessorBase<ManagedFhirWe
public ManagedFhirWebAccessor(String userAgent, List<ServerDetailsPOJO> serverAuthDetails) {
super(userAgent, serverAuthDetails);
super(Arrays.asList("fhir"), userAgent, serverAuthDetails);
this.timeout = 5000;
this.timeoutUnit = TimeUnit.MILLISECONDS;
}
@ -88,7 +89,7 @@ public class ManagedFhirWebAccessor extends ManagedWebAccessorBase<ManagedFhirWe
}
}
} else {
ServerDetailsPOJO settings = ManagedWebAccessUtils.getServer(httpRequest.getUrl().toString(), getServerAuthDetails());
ServerDetailsPOJO settings = ManagedWebAccessUtils.getServer(getServerTypes(), httpRequest.getUrl().toString(), getServerAuthDetails());
if (settings != null) {
switch (settings.getAuthenticationType()) {
case "basic":

View File

@ -52,9 +52,9 @@ import org.hl7.fhir.utilities.settings.ServerDetailsPOJO;
public class ManagedWebAccess {
public interface IWebAccessor {
HTTPResult get(String url, String accept, Map<String, String> headers) throws IOException;
HTTPResult post(String url, byte[] bytes, String contentType, String accept, Map<String, String> headers) throws IOException;
HTTPResult put(String url, byte[] bytes, String contentType, String accept, Map<String, String> headers) throws IOException;
HTTPResult get(Iterable<String> serverTypes, String url, String accept, Map<String, String> headers) throws IOException;
HTTPResult post(Iterable<String> serverTypes, String url, byte[] bytes, String contentType, String accept, Map<String, String> headers) throws IOException;
HTTPResult put(Iterable<String> serverTypes, String url, byte[] bytes, String contentType, String accept, Map<String, String> headers) throws IOException;
}
public interface IFhirWebAccessor {
@ -104,28 +104,28 @@ public class ManagedWebAccess {
ManagedWebAccess.userAgent = userAgent;
}
public static ManagedWebAccessor accessor() {
return new ManagedWebAccessor(userAgent, serverAuthDetails);
public static ManagedWebAccessor accessor(Iterable<String> serverTypes) {
return new ManagedWebAccessor(serverTypes, userAgent, serverAuthDetails);
}
public static ManagedFhirWebAccessor fhirAccessor() {
return new ManagedFhirWebAccessor(userAgent, serverAuthDetails);
}
public static HTTPResult get(String url) throws IOException {
return accessor().get(url);
public static HTTPResult get(Iterable<String> serverTypes, String url) throws IOException {
return accessor(serverTypes).get(url);
}
public static HTTPResult get(String url, String accept) throws IOException {
return accessor().get(url, accept);
public static HTTPResult get(Iterable<String> serverTypes, String url, String accept) throws IOException {
return accessor(serverTypes).get(url, accept);
}
public static HTTPResult post(String url, byte[] content, String contentType, String accept) throws IOException {
return accessor().post(url, content, contentType, accept);
public static HTTPResult post(Iterable<String> serverTypes, String url, byte[] content, String contentType, String accept) throws IOException {
return accessor(serverTypes).post(url, content, contentType, accept);
}
public static HTTPResult put(String url, byte[] content, String contentType, String accept) throws IOException {
return accessor().put(url, content, contentType, accept);
public static HTTPResult put(Iterable<String> serverTypes, String url, byte[] content, String contentType, String accept) throws IOException {
return accessor(serverTypes).put(url, content, contentType, accept);
}
public static HTTPResult httpCall(HTTPRequest httpRequest) throws IOException {
@ -136,15 +136,13 @@ public class ManagedWebAccess {
setAccessPolicy(FhirSettings.isProhibitNetworkAccess() ? WebAccessPolicy.PROHIBITED : WebAccessPolicy.DIRECT);
setUserAgent("hapi-fhir-tooling-client");
serverAuthDetails = new ArrayList<>();
serverAuthDetails.addAll(FhirSettings.getPackageServers());
serverAuthDetails.addAll(FhirSettings.getTerminologyServers());
serverAuthDetails.addAll(FhirSettings.getServers());
}
public static void loadFromFHIRSettings(FhirSettings settings) {
setAccessPolicy(settings.isProhibitNetworkAccess() ? WebAccessPolicy.PROHIBITED : WebAccessPolicy.DIRECT);
setUserAgent("hapi-fhir-tooling-client");
serverAuthDetails = new ArrayList<>();
serverAuthDetails.addAll(settings.getPackageServers());
serverAuthDetails.addAll(settings.getTerminologyServers());
serverAuthDetails.addAll(settings.getServers());
}
}

View File

@ -4,14 +4,21 @@ import org.hl7.fhir.utilities.settings.ServerDetailsPOJO;
public class ManagedWebAccessUtils {
public static ServerDetailsPOJO getServer(String url, Iterable<ServerDetailsPOJO> serverAuthDetails) {
public static ServerDetailsPOJO getServer(Iterable<String> serverTypes, String url, Iterable<ServerDetailsPOJO> serverAuthDetails) {
if (serverAuthDetails != null) {
for (ServerDetailsPOJO t : serverAuthDetails) {
if (url.startsWith(t.getUrl())) {
return t;
for (ServerDetailsPOJO serverDetails : serverAuthDetails) {
for (String serverType : serverTypes) {
if (url.startsWith(serverDetails.getUrl()) && typesMatch(serverType, serverDetails.getType())) {
return serverDetails;
}
}
}
}
return null;
}
private static boolean typesMatch(String criteria, String value) {
return criteria == null || value == null || criteria.equals(value);
}
}

View File

@ -14,8 +14,8 @@ import org.hl7.fhir.utilities.settings.ServerDetailsPOJO;
*/
public class ManagedWebAccessor extends ManagedWebAccessorBase<ManagedWebAccessor> {
public ManagedWebAccessor(String userAgent, List<ServerDetailsPOJO> serverAuthDetails) {
super(userAgent, serverAuthDetails);
public ManagedWebAccessor(Iterable<String> serverTypes, String userAgent, List<ServerDetailsPOJO> serverAuthDetails) {
super(serverTypes, userAgent, serverAuthDetails);
}
private Map<String, String> newHeaders() {
@ -66,7 +66,7 @@ public class ManagedWebAccessor extends ManagedWebAccessorBase<ManagedWebAccesso
}
}
} else {
ServerDetailsPOJO settings = ManagedWebAccessUtils.getServer(url, getServerAuthDetails());
ServerDetailsPOJO settings = ManagedWebAccessUtils.getServer(getServerTypes(), url, getServerAuthDetails());
if (settings != null) {
switch (settings.getAuthenticationType()) {
case "basic" :
@ -101,7 +101,7 @@ public class ManagedWebAccessor extends ManagedWebAccessorBase<ManagedWebAccesso
SimpleHTTPClient client = setupClient(url);
return client.get(url, accept);
case MANAGED:
return ManagedWebAccess.getAccessor().get(url, accept, newHeaders());
return ManagedWebAccess.getAccessor().get(getServerTypes(), url, accept, newHeaders());
case PROHIBITED:
throw new IOException("Access to the internet is not allowed by local security policy");
default:
@ -119,7 +119,7 @@ public class ManagedWebAccessor extends ManagedWebAccessorBase<ManagedWebAccesso
SimpleHTTPClient client = setupClient(url);
return client.post(url, contentType, content, accept);
case MANAGED:
return ManagedWebAccess.getAccessor().post(url, content, contentType, accept, newHeaders());
return ManagedWebAccess.getAccessor().post(getServerTypes(), url, content, contentType, accept, newHeaders());
case PROHIBITED:
throw new IOException("Access to the internet is not allowed by local security policy");
default:
@ -137,7 +137,7 @@ public class ManagedWebAccessor extends ManagedWebAccessorBase<ManagedWebAccesso
SimpleHTTPClient client = setupClient(url);
return client.put(url, contentType, content, accept);
case MANAGED:
return ManagedWebAccess.getAccessor().put(url, content, contentType, accept, newHeaders());
return ManagedWebAccess.getAccessor().put(getServerTypes(), url, content, contentType, accept, newHeaders());
case PROHIBITED:
throw new IOException("Access to the internet is not allowed by local security policy");
default:

View File

@ -8,6 +8,9 @@ import java.util.List;
import java.util.Map;
public abstract class ManagedWebAccessorBase<B extends ManagedWebAccessorBase<B>> {
@Getter
private final Iterable<String> serverTypes;
@Getter
private final String userAgent;
@Getter
@ -24,7 +27,8 @@ public abstract class ManagedWebAccessorBase<B extends ManagedWebAccessorBase<B>
@Getter
private final Map<String, String> headers = new HashMap<>();
public ManagedWebAccessorBase(String userAgent, List<ServerDetailsPOJO> serverAuthDetails) {
public ManagedWebAccessorBase(Iterable<String> serverTypes, String userAgent, List<ServerDetailsPOJO> serverAuthDetails) {
this.serverTypes = serverTypes;
this.userAgent = userAgent;
this.serverAuthDetails = serverAuthDetails;
}

View File

@ -2,34 +2,34 @@ package org.hl7.fhir.utilities.json;
import java.io.File;
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Copyright (c) 2011+, HL7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of HL7 nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
@ -37,6 +37,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;
import java.util.Stack;
@ -724,13 +725,13 @@ public class JsonTrackingParser {
}
public static JsonObject fetchJson(String source) throws IOException {
HTTPResult res = ManagedWebAccess.get(source+"?nocache=" + System.currentTimeMillis(), "application/json, application/fhir+json");
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), source+"?nocache=" + System.currentTimeMillis(), "application/json, application/fhir+json");
res.checkThrowException();
return parseJson(res.getContent());
}
public static JsonArray fetchJsonArray(String source) throws IOException {
HTTPResult res = ManagedWebAccess.get(source+"?nocache=" + System.currentTimeMillis(), "application/json, application/fhir+json");
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"),source+"?nocache=" + System.currentTimeMillis(), "application/json, application/fhir+json");
res.checkThrowException();
return parseJsonArray(res.getContent());
}

View File

@ -6,6 +6,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import org.hl7.fhir.utilities.TextFile;
@ -692,7 +693,7 @@ public class JsonParser {
private static byte[] fetch(String source) throws IOException {
String murl = source.contains("?") ? source+"&nocache=" + System.currentTimeMillis() : source+"?nocache=" + System.currentTimeMillis();
HTTPResult res = ManagedWebAccess.get(murl, "application/json, application/fhir+json");
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), murl, "application/json, application/fhir+json");
res.checkThrowException();
return res.getContent();
}

View File

@ -729,7 +729,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
private InputStream fetchFromUrlSpecific(String source, boolean optional) throws FHIRException {
try {
HTTPResult res = ManagedWebAccess.get(source);
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), source);
res.checkThrowException();
return new ByteArrayInputStream(res.getContent());
} catch (Exception e) {
@ -862,8 +862,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
}
private void loadFromBuildServer() throws IOException {
HTTPResult res = ManagedWebAccess.get("https://build.fhir.org/ig/qas.json?nocache=" + System.currentTimeMillis());
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), "https://build.fhir.org/ig/qas.json?nocache=" + System.currentTimeMillis());
res.checkThrowException();
buildInfo = (JsonArray) JsonParser.parse(TextFile.bytesToString(res.getContent()));

View File

@ -44,15 +44,7 @@ import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -1480,7 +1472,7 @@ public class NpmPackage {
}
public static NpmPackage fromUrl(String source) throws IOException {
HTTPResult res = ManagedWebAccess.get(source+"?nocache=" + System.currentTimeMillis());
HTTPResult res = ManagedWebAccess.get(Arrays.asList("npm-package", "fhir-package"), source+"?nocache=" + System.currentTimeMillis());
res.checkThrowException();
return fromPackage(new ByteArrayInputStream(res.getContent()));
}

View File

@ -8,11 +8,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.*;
import javax.annotation.Nullable;
@ -175,11 +171,13 @@ public class PackageClient {
}
private InputStream fetchUrl(String source, String accept) throws IOException {
ManagedWebAccessor webAccessor = ManagedWebAccess.accessor();
ManagedWebAccessor webAccessor = ManagedWebAccess.accessor(Arrays.asList("web"));
if (server.getAuthenticationMode() == HTTPAuthenticationMode.TOKEN) {
webAccessor.withToken(server.getToken());
} else if (server.getAuthenticationMode() == HTTPAuthenticationMode.BASIC) {
webAccessor.withBasicAuth(server.getUsername(), server.getPassword());
} else if (server.getAuthenticationMode() == HTTPAuthenticationMode.APIKEY) {
webAccessor.withApiKey(server.getApiKey());
}
HTTPResult res = webAccessor.get(source, accept);
res.checkThrowException();

View File

@ -7,7 +7,6 @@ import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.hl7.fhir.utilities.http.HTTPAuthenticationMode;
import org.hl7.fhir.utilities.http.SimpleHTTPClient;
import org.hl7.fhir.utilities.settings.FhirSettings;
import org.hl7.fhir.utilities.settings.ServerDetailsPOJO;
@ -27,10 +26,11 @@ public class PackageServer {
serverType = PackageServerType.FHIR;
}
@Getter
private String url;
@Getter
private HTTPAuthenticationMode authenticationMode;
private HTTPAuthenticationMode authenticationMode;
@Getter
private PackageServerType serverType;
@ -43,9 +43,11 @@ public class PackageServer {
@Getter
private String token;
public String getUrl() {
return url;
}
@Getter
private String apiKey;
public static final String PRIMARY_SERVER = "https://packages.fhir.org";
public static final String SECONDARY_SERVER = "https://packages2.fhir.org/packages";
@ -69,24 +71,54 @@ public class PackageServer {
return new PackageServer(pojo.getUrl())
.withAuthenticationMode(getModeFromPOJO(pojo))
.withServerType(
pojo.getServerType() != null && pojo.getServerType().equalsIgnoreCase("npm") ? PackageServerType.NPM : PackageServerType.FHIR
getPackageServerType(pojo.getType())
)
.withUsername(pojo.getUsername())
.withPassword(pojo.getPassword())
.withToken(pojo.getToken());
.withToken(pojo.getToken())
.withApiKey(pojo.getApikey());
}
private static boolean isPackageServer(String serverType) {
if (serverType == null) {
return false;
}
if (serverType.equals("fhir-package")) {
return true;
}
if (serverType.equals("npm-package")) {
return true;
}
return false;
}
private static PackageServerType getPackageServerType(String serverType) {
if (serverType == null) {
return null;
}
if (serverType.equals("fhir-package")) {
return PackageServerType.FHIR;
}
if (serverType.equals("npm-package")) {
return PackageServerType.NPM;
}
return null;
}
@Nullable
private static HTTPAuthenticationMode getModeFromPOJO(ServerDetailsPOJO pojo) {
if (pojo.getAuthenticationType().equalsIgnoreCase("basic")) return HTTPAuthenticationMode.BASIC;
if (pojo.getAuthenticationType().equalsIgnoreCase("token")) return HTTPAuthenticationMode.TOKEN;
if (pojo.getAuthenticationType().equalsIgnoreCase("apikey")) return HTTPAuthenticationMode.APIKEY;
return null;
}
public static List<PackageServer> getConfiguredServers() {
return FhirSettings.getPackageServers().stream().map(
PackageServer::getPackageServerFromPOJO
).collect(Collectors.toList());
return FhirSettings.getServers().stream()
.filter(serverDetailsPOJO -> isPackageServer(serverDetailsPOJO.getType()))
.map(PackageServer::getPackageServerFromPOJO)
.collect(Collectors.toList());
}
@Override
@ -101,6 +133,7 @@ public class PackageServer {
packageServer.username = this.username;
packageServer.password = this.password;
packageServer.token = this.token;
packageServer.apiKey = this.apiKey;
return packageServer;
}
@ -133,4 +166,10 @@ public class PackageServer {
packageServer.token = token;
return packageServer;
}
public PackageServer withApiKey(String apiKey) {
PackageServer packageServer = this.copy();
packageServer.apiKey = apiKey;
return packageServer;
}
}

View File

@ -222,25 +222,17 @@ public class FhirSettings {
public static boolean isIgnoreDefaultPackageServers() {
getInstance();
if (instance.fhirSettings.getPackageManagement() == null || instance.fhirSettings.getPackageManagement().getIgnoreDefaultServers() == null) {
if (instance.fhirSettings.getIgnoreDefaultPackageServers() == null) {
return false;
}
return instance.fhirSettings.getPackageManagement().getIgnoreDefaultServers();
return instance.fhirSettings.getIgnoreDefaultPackageServers();
}
public static List<ServerDetailsPOJO> getPackageServers() {
public static List<ServerDetailsPOJO> getServers() {
getInstance();
if (instance.fhirSettings.getPackageManagement() == null) {
if (instance.fhirSettings.getServers() == null) {
return Collections.emptyList();
}
return Arrays.asList(instance.fhirSettings.getPackageManagement().getServers().toArray(new ServerDetailsPOJO[]{}));
}
public static List<ServerDetailsPOJO> getTerminologyServers() {
getInstance();
if (instance.fhirSettings.getTerminologyServers() == null) {
return Collections.emptyList();
}
return Arrays.asList(instance.fhirSettings.getTerminologyServers().getServers().toArray(new ServerDetailsPOJO[]{}));
return Arrays.asList(instance.fhirSettings.getServers().toArray(new ServerDetailsPOJO[]{}));
}
}

View File

@ -1,5 +1,7 @@
package org.hl7.fhir.utilities.settings;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
@ -39,8 +41,9 @@ public class FhirSettingsPOJO {
private String txFhirDevelopment;
private String txFhirLocal;
private PackageManagementPOJO packageManagement;
private TerminologyServersPOJO terminologyServers;
private Boolean ignoreDefaultPackageServers;
private List<ServerDetailsPOJO> servers;
protected FhirSettingsPOJO() {
apiKeys = null;
@ -53,8 +56,6 @@ public class FhirSettingsPOJO {
txFhirProduction = TX_SERVER_PROD;
txFhirDevelopment = TX_SERVER_DEV;
txFhirLocal = TX_SERVER_LOCAL;
packageManagement = null;
terminologyServers = null;
servers = new ArrayList<>();
}
}

View File

@ -1,25 +0,0 @@
package org.hl7.fhir.utilities.settings;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.extern.jackson.Jacksonized;
@Data
@Builder
@Jacksonized
@AllArgsConstructor
public class PackageManagementPOJO {
private Boolean ignoreDefaultServers;
private List<ServerDetailsPOJO> servers;
protected PackageManagementPOJO() {
ignoreDefaultServers = false;
servers = new ArrayList<>();
}
}

View File

@ -10,14 +10,25 @@ import lombok.extern.jackson.Jacksonized;
@Jacksonized
@AllArgsConstructor
public class ServerDetailsPOJO {
String url;
// possible values: none, basic, token, apikey
String authenticationType;
// npm or fhir, because the FHIR npm usage varies a little bit from general NPM usage (change over time)
String serverType;
/**
* This helps clients use appropriate API endpoints for each server type.
* <p/>
* It can be of the following types:
* <ul>
* <li>web</li>
* <li>fhir</li>
* <li>npm-package</li>
* <li>fhir-package</li>
* </ul>
*/
String type;
String username;

View File

@ -1,22 +0,0 @@
package org.hl7.fhir.utilities.settings;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.extern.jackson.Jacksonized;
@Data
@Builder
@Jacksonized
@AllArgsConstructor
public class TerminologyServersPOJO {
private List<ServerDetailsPOJO> servers;
protected TerminologyServersPOJO() {
servers = new ArrayList<>();
}
}

View File

@ -164,7 +164,7 @@ public class ManagedWebAccessAuthTests {
return new ServerDetailsPOJO(
server.url("").toString(),
"basic",
"dummyServerType",
"fhir",
DUMMY_USERNAME,
DUMMY_PASSWORD,
null, null);
@ -183,7 +183,7 @@ public void testTokenAuthFromSettings() throws IOException, InterruptedException
return new ServerDetailsPOJO(
server.url("").toString(),
"token",
"dummyServerType",
"fhir",
null,
null,
DUMMY_TOKEN, null);
@ -202,7 +202,7 @@ public void testTokenAuthFromSettings() throws IOException, InterruptedException
return new ServerDetailsPOJO(
server.url("").toString(),
"apikey",
"dummyServerType",
"fhir",
null,
null,
null, DUMMY_API_KEY);

View File

@ -85,19 +85,19 @@ public class FhirSettingsTests implements ResourceLoaderTests {
assertEquals("dummy-temp-path", fhirSettings.getTempPath());
assertEquals("dummy-test-igs-path", fhirSettings.getTestIgsPath());
assertTrue(fhirSettings.getPackageManagement().getIgnoreDefaultServers());
assertTrue(fhirSettings.getIgnoreDefaultPackageServers());
List<ServerDetailsPOJO> packageServers = fhirSettings.getPackageManagement().getServers();
List<ServerDetailsPOJO> servers = fhirSettings.getServers();
assertEquals(2, packageServers.size());
assertEquals(2, servers.size());
assertEquals("http://dummy.org", packageServers.get(0).url);
assertEquals("npm", packageServers.get(0).serverType);
assertEquals("joe", packageServers.get(0).username);
assertEquals("swordfish", packageServers.get(0).password);
assertEquals("BASIC", packageServers.get(0).authenticationType);
assertEquals("http://dummy.org", servers.get(0).url);
assertEquals("npm-package", servers.get(0).type);
assertEquals("joe", servers.get(0).username);
assertEquals("swordfish", servers.get(0).password);
assertEquals("BASIC", servers.get(0).authenticationType);
assertEquals("http://dummy2.com", packageServers.get(1).url);
assertEquals("http://dummy2.com", servers.get(1).url);
}
}

View File

@ -2,30 +2,28 @@
"apiKeys": {
"dummy-api-key": "dummy-api-key-value"
},
"npmPath": "dummy-npm-path",
"npmPath": "dummy-npm-path",
"rubyPath": "dummy-ruby-path",
"fhirTestCasesPath": "dummy-fhir-test-cases-path",
"diffToolPath": "dummy-diff-tool-path",
"tempPath": "dummy-temp-path",
"testIgsPath": "dummy-test-igs-path",
"unusedField" : "unused",
"packageManagement" : {
"ignoreDefaultServers" : true,
"servers": [
{
"url": "http://dummy.org",
"serverType": "npm",
"authenticationType": "BASIC",
"username": "joe",
"password": "swordfish"
},
{
"url": "http://dummy2.com",
"goobledy-goo": 5
}
]
},
"unusedData" : {
"unusedDateField" : "unused-data"
"unusedField": "unused",
"ignoreDefaultPackageServers": true,
"servers": [
{
"url": "http://dummy.org",
"type": "npm-package",
"authenticationType": "BASIC",
"username": "joe",
"password": "swordfish"
},
{
"url": "http://dummy2.com",
"goobledy-goo": 5
}
],
"unusedData": {
"unusedDateField": "unused-data"
}
}

View File

@ -430,7 +430,7 @@ public class IgLoader implements IValidationEngineLoader {
private InputStream fetchFromUrlSpecific(String source, boolean optional) throws FHIRException, IOException {
try {
HTTPResult res = ManagedWebAccess.get(source + "?nocache=" + System.currentTimeMillis());
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), source + "?nocache=" + System.currentTimeMillis());
res.checkThrowException();
return new ByteArrayInputStream(res.getContent());
} catch (IOException e) {
@ -583,12 +583,12 @@ public class IgLoader implements IValidationEngineLoader {
private byte[] fetchFromUrlSpecific(String source, String contentType, boolean optional, List<String> errors) throws FHIRException, IOException {
try {
try {
// try with cache-busting option and then try withhout in case the server doesn't support that
HTTPResult res = ManagedWebAccess.get(source + "?nocache=" + System.currentTimeMillis(), contentType);
// try with cache-busting option and then try without in case the server doesn't support that
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"),source + "?nocache=" + System.currentTimeMillis(), contentType);
res.checkThrowException();
return res.getContent();
} catch (Exception e) {
HTTPResult res = ManagedWebAccess.get(source, contentType);
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), source, contentType);
res.checkThrowException();
return res.getContent();
}

View File

@ -8,13 +8,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -319,7 +313,7 @@ public class Scanner {
}
protected void download(String address, String filename) throws IOException {
HTTPResult res = ManagedWebAccess.get(address);
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), address);
res.checkThrowException();
TextFile.bytesToFile(res.getContent(), filename);
}

View File

@ -19,7 +19,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.fhir.ucum.UcumEssenceService;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
@ -72,12 +71,9 @@ import org.hl7.fhir.r5.utils.validation.IMessagingServices;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.AdditionalBindingPurpose;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor.CodedContentValidationAction;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.constants.BindingKind;
import org.hl7.fhir.r5.utils.validation.constants.CheckDisplayOption;
import org.hl7.fhir.r5.utils.validation.constants.CodedContentValidationPolicy;
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
import org.hl7.fhir.r5.utils.validation.constants.IdStatus;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
@ -942,7 +938,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
if (output.startsWith("http://")) {
ByteArrayOutputStream bs = new ByteArrayOutputStream();
handleOutputToStream(r, output, bs, version);
HTTPResult res = ManagedWebAccess.post(output, bs.toByteArray(), "application/fhir+xml", "application/fhir+xml");
HTTPResult res = ManagedWebAccess.post(Arrays.asList("web"), output, bs.toByteArray(), "application/fhir+xml", "application/fhir+xml");
res.checkThrowException();
} else {
FileOutputStream s = ManagedFileAccess.outStream(output);
@ -1099,7 +1095,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
@Override
public byte[] fetchRaw(IResourceValidator validator, String source) throws IOException {
HTTPResult res = ManagedWebAccess.get(source);
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), source);
res.checkThrowException();
return res.getContent();
}

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.validation.cli.utils;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.utilities.TextFile;
@ -25,7 +26,7 @@ public class ProfileLoader {
private static byte[] loadProfileFromUrl(String src) throws FHIRException {
try {
HTTPResult res = ManagedWebAccess.get(src + "?nocache=" + System.currentTimeMillis());
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), src + "?nocache=" + System.currentTimeMillis());
res.checkThrowException();
return res.getContent();
} catch (Exception e) {

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.validation.ipa;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -160,7 +161,7 @@ public class IPAValidator {
private Element makeRequest(ValidationNode vn, String url) {
try {
HTTPResult result = ManagedWebAccess.get(url, "application/fhir+json");
HTTPResult result = ManagedWebAccess.get(Arrays.asList("web"), url, "application/fhir+json");
if (result.getCode() >= 300) {
vn.getIssues().add(new ValidationMessage(Source.IPAValidator, IssueType.EXCEPTION, "http.request",
"HTTP Return code is "+result.getCode()+" "+result.getMessage(),

View File

@ -108,7 +108,7 @@ public class TxServiceTestHelper {
writeDiffToFileSystem( name, expectedResponse, actualResponse);
String diff = CompareUtilities.checkJsonSrcIsSame(id, expectedResponse, actualResponse, externals);
String diff = new CompareUtilities(externals).checkJsonSrcIsSame(id, expectedResponse, actualResponse);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(actualResponse, fp);
@ -182,7 +182,7 @@ public class TxServiceTestHelper {
writeDiffToFileSystem(name, expectedResponse, actualResponse);
String diff = CompareUtilities.checkJsonSrcIsSame(id, expectedResponse, actualResponse, externals);
String diff = new CompareUtilities(externals).checkJsonSrcIsSame(id, expectedResponse, actualResponse);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(actualResponse, fp);

View File

@ -19,8 +19,10 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -30,11 +32,13 @@ import org.hl7.fhir.convertors.txClient.TerminologyClientFactory;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r4b.context.TextClientLogger;
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.model.CapabilityStatement;
import org.hl7.fhir.r5.model.OperationOutcome;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.TerminologyCapabilities;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.terminologies.client.ITerminologyClient;
import org.hl7.fhir.r5.test.utils.CompareUtilities;
@ -65,6 +69,8 @@ public class TxTester {
private JsonObject externals;
private String software;
private List<String> fails = new ArrayList<>();
private CapabilityStatement cstmt;
private TerminologyCapabilities tc;
public TxTester(ITxTesterLoader loader, String server, boolean tight, JsonObject externals) {
@ -107,14 +113,14 @@ public class TxTester {
json.add("date", new SimpleDateFormat("EEE, MMM d, yyyy HH:mmZ", new Locale("en", "US")).format(Calendar.getInstance().getTime()) + timezone());
try {
JsonObject tests = loadTests();
ITerminologyClient tx = connectToServer(modes);
boolean ok = checkClient(tx);
tx = connectToServer(modes);
boolean ok = checkClient();
for (JsonObject suite : tests.getJsonObjects("suites")) {
if ((!suite.has("mode") || modes.contains(suite.asString("mode")))) {
if (suite.asBoolean("disabled")) {
// ok = true;
} else {
ok = runSuite(suite, tx, modes, filter, json.forceArray("suites")) && ok;
ok = runSuite(suite, modes, filter, json.forceArray("suites")) && ok;
}
}
}
@ -123,10 +129,10 @@ public class TxTester {
if (filter == null) {
String m = modes.isEmpty() ? "[none]" : CommaSeparatedStringBuilder.join(";", modes);
if (ok) {
System.out.println(software+" passed all HL7 terminology service tests (modes "+m+", tests v"+loadVersion()+", runner v"+VersionUtil.getBaseVersion()+")");
System.out.println(software+" passed all HL7 terminology service tests ("+Utilities.pluralize("mode", modes.size())+" "+m+", tests v"+loadVersion()+", runner v"+VersionUtil.getBaseVersion()+")");
return true;
} else {
System.out.println(software+" did not pass all HL7 terminology service tests (modes "+m+", tests v"+loadVersion()+", runner v"+VersionUtil.getBaseVersion()+")");
System.out.println(software+" did not pass all HL7 terminology service tests ("+Utilities.pluralize("mode", modes.size())+" "+m+", tests v"+loadVersion()+", runner v"+VersionUtil.getBaseVersion()+")");
System.out.println("Failed Tests: "+ CommaSeparatedStringBuilder.join(",", fails ));
return false;
}
@ -153,12 +159,12 @@ public class TxTester {
return offset;
}
private boolean checkClient(ITerminologyClient tx) {
CapabilityStatement cstmt = tx.getCapabilitiesStatementQuick();
private boolean checkClient() {
cstmt = tx.getCapabilitiesStatement();
if (cstmt.hasSoftware()) {
software = cstmt.getSoftware().getName()+" v"+cstmt.getSoftware().getVersion();
}
tx.getTerminologyCapabilities();
tc = tx.getTerminologyCapabilities();
return true;
}
@ -171,7 +177,7 @@ public class TxTester {
return processHistoryMarkdown(loader.loadContent("history.md"));
}
private String processHistoryMarkdown(byte[] content) throws IOException {
public static String processHistoryMarkdown(byte[] content) throws IOException {
DataInputStream in = new DataInputStream(new ByteArrayInputStream(content));
BufferedReader br = new BufferedReader(new InputStreamReader(in));
try {
@ -179,7 +185,7 @@ public class TxTester {
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
if (strLine.startsWith("## ")) {
return strLine.substring(3);
return strLine.substring(3).trim();
}
}
} finally {
@ -189,7 +195,7 @@ public class TxTester {
return "<1.6.0";
}
private ITerminologyClient connectToServer(List<String> modes) throws URISyntaxException {
private ITerminologyClient connectToServer(List<String> modes) throws URISyntaxException, IOException {
System.out.println("Connect to "+server);
software = server;
ITerminologyClient client = new TerminologyClientFactory(FhirPublication.R4).makeClient("Test-Server", server, "Tools/Java", null);
@ -201,18 +207,18 @@ public class TxTester {
error = null;
if (tx == null) {
tx = connectToServer(modes);
checkClient(tx);
checkClient();
}
List<Resource> setup = loadSetupResources(suite);
if (runTest(suite, test, tx, setup, modes, "*", null)) {
if (runTest(suite, test, setup, modes, "*", null)) {
return null;
} else {
return error;
}
}
private boolean runSuite(JsonObject suite, ITerminologyClient tx, List<String> modes, String filter, JsonArray output) throws FHIRFormatError, FileNotFoundException, IOException {
private boolean runSuite(JsonObject suite, List<String> modes, String filter, JsonArray output) throws FHIRFormatError, FileNotFoundException, IOException {
System.out.println("Group "+suite.asString("name"));
JsonObject outputS = new JsonObject();
if (output != null) {
@ -226,14 +232,14 @@ public class TxTester {
if (test.asBoolean("disabled")) {
ok = true;
} else {
ok = runTest(suite, test, tx, setup, modes, filter, outputS.forceArray("tests")) && ok;
ok = runTest(suite, test, setup, modes, filter, outputS.forceArray("tests")) && ok;
}
}
}
return ok;
}
private boolean runTest(JsonObject suite, JsonObject test, ITerminologyClient tx, List<Resource> setup, List<String> modes, String filter, JsonArray output) throws FHIRFormatError, DefinitionException, FileNotFoundException, FHIRException, IOException {
private boolean runTest(JsonObject suite, JsonObject test, List<Resource> setup, List<String> modes, String filter, JsonArray output) throws FHIRFormatError, DefinitionException, FileNotFoundException, FHIRException, IOException {
JsonObject outputT = new JsonObject();
if (output != null) {
output.add(outputT);
@ -253,7 +259,8 @@ public class TxTester {
}
}
Parameters req = (Parameters) loader.loadResource(chooseParam(test, "request", modes));
String reqFile = chooseParam(test, "request", modes);
Parameters req = reqFile == null ? null : (Parameters) loader.loadResource(reqFile);
String fn = chooseParam(test, "response", modes);
String resp = TextFile.bytesToString(loader.loadContent(fn));
@ -266,16 +273,20 @@ public class TxTester {
String lang = test.asString("Content-Language");
String msg = null;
if (test.asString("operation").equals("expand")) {
msg = expand(test.str("name"), tx, setup, req, resp, fp, lang, profile, ext, getResponseCode(test));
if (test.asString("operation").equals("metadata")) {
msg = metadata(test.str("name"), setup, resp, fp, lang, profile, ext);
} else if (test.asString("operation").equals("term-caps")) {
msg = termcaps(test.str("name"), setup, resp, fp, lang, profile, ext);
} else if (test.asString("operation").equals("expand")) {
msg = expand(test.str("name"), setup, req, resp, fp, lang, profile, ext, getResponseCode(test));
} else if (test.asString("operation").equals("validate-code")) {
msg = validate(test.str("name"),tx, setup, req, resp, fp, lang, profile, ext, getResponseCode(test));
msg = validate(test.str("name"), setup, req, resp, fp, lang, profile, ext, getResponseCode(test));
} else if (test.asString("operation").equals("cs-validate-code")) {
msg = validateCS(test.str("name"),tx, setup, req, resp, fp, lang, profile, ext, getResponseCode(test));
msg = validateCS(test.str("name"), setup, req, resp, fp, lang, profile, ext, getResponseCode(test));
} else if (test.asString("operation").equals("lookup")) {
msg = lookup(test.str("name"),tx, setup, req, resp, fp, lang, profile, ext, getResponseCode(test));
msg = lookup(test.str("name"), setup, req, resp, fp, lang, profile, ext, getResponseCode(test));
} else if (test.asString("operation").equals("translate")) {
msg = translate(test.str("name"),tx, setup, req, resp, fp, lang, profile, ext, getResponseCode(test));
msg = translate(test.str("name"), setup, req, resp, fp, lang, profile, ext, getResponseCode(test));
} else {
throw new Exception("Unknown Operation "+test.asString("operation"));
}
@ -311,6 +322,34 @@ public class TxTester {
}
}
private String metadata(String id, List<Resource> setup, String resp, String fp, String lang, Parameters profile, JsonObject ext) throws IOException {
CapabilityStatement cs = cstmt.copy();
TxTesterScrubbers.scrubCapStmt(cs, tight);
TxTesterSorters.sortCapStmt(cs);
String csj = new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).composeString(cs);
String diff = new CompareUtilities(ext, vars()).setPatternMode(true).checkJsonSrcIsSame(id, resp, csj, false);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(csj, fp);
}
return diff;
}
private String termcaps(String id, List<Resource> setup, String resp, String fp, String lang, Parameters profile, JsonObject ext) throws IOException {
TerminologyCapabilities cs = tc.copy();
TxTesterScrubbers.scrubTermCaps(cs, tight);
TxTesterSorters.sortTermCaps(cs);
String csj = new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).composeString(cs);
String diff = new CompareUtilities(ext, vars()).setPatternMode(true).checkJsonSrcIsSame(id, resp, csj, false);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(csj, fp);
}
return diff;
}
private String getResponseCode(JsonObject test) {
if (test.has("http-code")) {
return test.asString("http-code");
@ -340,7 +379,7 @@ public class TxTester {
return new URI(server).getHost();
}
private String lookup(String id, ITerminologyClient tx, List<Resource> setup, Parameters p, String resp, String fp, String lang, Parameters profile, JsonObject ext, String tcode) throws IOException {
private String lookup(String id, List<Resource> setup, Parameters p, String resp, String fp, String lang, Parameters profile, JsonObject ext, String tcode) throws IOException {
for (Resource r : setup) {
p.addParameter().setName("tx-resource").setResource(r);
}
@ -363,7 +402,7 @@ public class TxTester {
if (tcode != null && !httpCodeOk(tcode, code)) {
return "Response Code fail: should be '"+tcode+"' but is '"+code+"'";
}
String diff = CompareUtilities.checkJsonSrcIsSame(id, resp, pj, false, ext);
String diff = new CompareUtilities(ext, vars()).checkJsonSrcIsSame(id, resp, pj, false);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(pj, fp);
@ -371,7 +410,7 @@ public class TxTester {
return diff;
}
private String translate(String id, ITerminologyClient tx, List<Resource> setup, Parameters p, String resp, String fp, String lang, Parameters profile, JsonObject ext, String tcode) throws IOException {
private String translate(String id, List<Resource> setup, Parameters p, String resp, String fp, String lang, Parameters profile, JsonObject ext, String tcode) throws IOException {
for (Resource r : setup) {
p.addParameter().setName("tx-resource").setResource(r);
}
@ -394,7 +433,7 @@ public class TxTester {
if (tcode != null && !httpCodeOk(tcode, code)) {
return "Response Code fail: should be '"+tcode+"' but is '"+code+"'";
}
String diff = CompareUtilities.checkJsonSrcIsSame(id, resp, pj, false, ext);
String diff = new CompareUtilities(ext, vars()).checkJsonSrcIsSame(id, resp, pj, false);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(pj, fp);
@ -402,7 +441,7 @@ public class TxTester {
return diff;
}
private String expand(String id, ITerminologyClient tx, List<Resource> setup, Parameters p, String resp, String fp, String lang, Parameters profile, JsonObject ext, String tcode) throws IOException {
private String expand(String id, List<Resource> setup, Parameters p, String resp, String fp, String lang, Parameters profile, JsonObject ext, String tcode) throws IOException {
for (Resource r : setup) {
p.addParameter().setName("tx-resource").setResource(r);
}
@ -425,7 +464,7 @@ public class TxTester {
if (tcode != null && !httpCodeOk(tcode, code)) {
return "Response Code fail: should be '"+tcode+"' but is '"+code+"'";
}
String diff = CompareUtilities.checkJsonSrcIsSame(id, resp, vsj, false, ext);
String diff = new CompareUtilities(ext, vars()).checkJsonSrcIsSame(id, resp, vsj, false);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(vsj, fp);
@ -444,7 +483,7 @@ public class TxTester {
}
}
private String validate(String id, ITerminologyClient tx, List<Resource> setup, Parameters p, String resp, String fp, String lang, Parameters profile, JsonObject ext, String tcode) throws IOException {
private String validate(String id, List<Resource> setup, Parameters p, String resp, String fp, String lang, Parameters profile, JsonObject ext, String tcode) throws IOException {
for (Resource r : setup) {
p.addParameter().setName("tx-resource").setResource(r);
}
@ -468,7 +507,7 @@ public class TxTester {
if (tcode != null && !httpCodeOk(tcode, code)) {
return "Response Code fail: should be '"+tcode+"' but is '"+code+"'";
}
String diff = CompareUtilities.checkJsonSrcIsSame(id, resp, pj, false, ext);
String diff = new CompareUtilities(ext, vars()).checkJsonSrcIsSame(id, resp, pj, false);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(pj, fp);
@ -476,7 +515,7 @@ public class TxTester {
return diff;
}
private String validateCS(String id, ITerminologyClient tx, List<Resource> setup, Parameters p, String resp, String fp, String lang, Parameters profile, JsonObject ext, String tcode) throws IOException {
private String validateCS(String id, List<Resource> setup, Parameters p, String resp, String fp, String lang, Parameters profile, JsonObject ext, String tcode) throws IOException {
for (Resource r : setup) {
p.addParameter().setName("tx-resource").setResource(r);
}
@ -499,7 +538,7 @@ public class TxTester {
if (tcode != null && !httpCodeOk(tcode, code)) {
return "Response Code fail: should be '"+tcode+"' but is '"+code+"'";
}
String diff = CompareUtilities.checkJsonSrcIsSame(id, resp, pj, false, ext);
String diff = new CompareUtilities(ext, vars()).checkJsonSrcIsSame(id, resp, pj, false);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(pj, fp);
@ -508,6 +547,13 @@ public class TxTester {
}
private Map<String, String> vars() {
Map<String, String> vars = new HashMap<String, String>();
vars.put("version", tx.getActualVersion().toCode());
return vars;
}
private List<Resource> loadSetupResources(JsonObject suite) throws FHIRFormatError, FileNotFoundException, IOException {
List<Resource> res = new ArrayList<>();
for (String s : suite.getStrings("setup")) {

View File

@ -1,5 +1,7 @@
package org.hl7.fhir.validation.special;
import org.hl7.fhir.r5.model.CapabilityStatement;
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestComponent;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Element;
import org.hl7.fhir.r5.model.Extension;
@ -7,6 +9,7 @@ import org.hl7.fhir.r5.model.OperationOutcome;
import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.TerminologyCapabilities;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.ElementVisitor;
import org.hl7.fhir.r5.utils.ElementVisitor.ElementVisitorInstruction;
@ -98,4 +101,12 @@ public class TxTesterScrubbers {
}
}
public static void scrubCapStmt(CapabilityStatement cs, boolean tight) {
// nothing yet?
}
public static void scrubTermCaps(TerminologyCapabilities cs, boolean tight) {
// nothing yet?
}
}

View File

@ -8,18 +8,34 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.model.CanonicalType;
import org.hl7.fhir.r5.model.CapabilityStatement;
import org.hl7.fhir.r5.model.Extension;
import org.hl7.fhir.r5.model.OperationOutcome;
import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
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.TerminologyCapabilitiesCodeSystemVersionComponent;
import org.hl7.fhir.r5.model.TerminologyCapabilities.TerminologyCapabilitiesCodeSystemVersionFilterComponent;
import org.hl7.fhir.r5.model.TerminologyCapabilities.TerminologyCapabilitiesExpansionParameterComponent;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.TerminologyCapabilities;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestComponent;
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceOperationComponent;
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent;
import org.hl7.fhir.r5.model.CapabilityStatement.ResourceInteractionComponent;
import org.hl7.fhir.r5.model.CapabilityStatement.SystemInteractionComponent;
import org.hl7.fhir.r5.model.Enumerations.CommonLanguages;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.Enumeration;
import org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent;
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
@ -27,9 +43,11 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionPropertyComponent;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.json.JsonException;
import org.hl7.fhir.validation.special.TxTesterSorters.CodeTypeSorter;
public class TxTesterSorters {
public static void main(String[] args) throws JsonException, IOException {
Resource r = new JsonParser().parse(new FileInputStream(args[0]));
switch (r.fhirType()) {
@ -234,7 +252,205 @@ public class TxTesterSorters {
}
}
public static void sortCapStmt(CapabilityStatement cs) {
Collections.sort(cs.getFormat(), new CodeTypeSorter());
Collections.sort(cs.getInstantiates(), new CanonicalTypeSorter());
Collections.sort(cs.getImports(), new CanonicalTypeSorter());
Collections.sort(cs.getAcceptLanguage(), new CodeTypeSorter());
Collections.sort(cs.getRest(), new CSRestSorter());
for (CapabilityStatementRestComponent r : cs.getRest()) {
if (r.hasSecurity()) {
for (CodeableConcept cc : r.getSecurity().getService()) {
Collections.sort(cc.getCoding(), new CodingSorter());
}
Collections.sort(r.getSecurity().getService(), new CodeableConceptSorter());
}
Collections.sort(r.getResource(), new CSRestResourceSorter());
for (CapabilityStatementRestResourceComponent res : r.getResource()) {
Collections.sort(res.getSupportedProfile(), new CanonicalTypeSorter());
Collections.sort(res.getInteraction(), new CSRestResourceInteractionSorter());
Collections.sort(res.getSearchInclude(), new StringTypeSorter());
Collections.sort(res.getSearchRevInclude(), new StringTypeSorter());
Collections.sort(res.getSearchParam(), new SearchParamSorter());
Collections.sort(res.getOperation(), new CSRestResourceOperationSorter());
}
Collections.sort(r.getInteraction(), new CSRestInteractionSorter());
Collections.sort(r.getSearchParam(), new SearchParamSorter());
Collections.sort(r.getOperation(), new CSRestResourceOperationSorter());
Collections.sort(r.getCompartment(), new CanonicalTypeSorter());
}
}
public static class CodeTypeSorter implements Comparator<CodeType> {
@Override
public int compare(CodeType o1, CodeType o2) {
return o1.asStringValue().compareTo(o2.asStringValue());
}
}
public static class StringTypeSorter implements Comparator<StringType> {
@Override
public int compare(StringType o1, StringType o2) {
return o1.asStringValue().compareTo(o2.asStringValue());
}
}
public static class CanonicalTypeSorter implements Comparator<CanonicalType> {
@Override
public int compare(CanonicalType o1, CanonicalType o2) {
return o1.asStringValue().compareTo(o2.asStringValue());
}
}
public static class CodingSorter implements Comparator<Coding> {
@Override
public int compare(Coding c1, Coding c2) {
if (c1.getSystem().equals(c2.getSystem())) {
return c1.getCode().compareTo(c2.getCode());
} else {
return c1.getSystem().compareTo(c2.getSystem());
}
}
}
public static class CodeableConceptSorter implements Comparator<CodeableConcept> {
@Override
public int compare(CodeableConcept o1, CodeableConcept o2) {
if (o1.hasCoding() && o2.hasCoding()) {
Coding c1 = o1.getCodingFirstRep();
Coding c2 = o2.getCodingFirstRep();
if (c1.getSystem().equals(c2.getSystem())) {
return c1.getCode().compareTo(c2.getCode());
} else {
return c1.getSystem().compareTo(c2.getSystem());
}
} else {
return o1.getText().compareTo(o2.getText());
}
}
}
public static class CSRestSorter implements Comparator<CapabilityStatementRestComponent> {
@Override
public int compare(CapabilityStatementRestComponent o1, CapabilityStatementRestComponent o2) {
return o1.getMode().compareTo(o2.getMode());
}
}
public static class CSRestResourceSorter implements Comparator<CapabilityStatementRestResourceComponent> {
@Override
public int compare(CapabilityStatementRestResourceComponent o1, CapabilityStatementRestResourceComponent o2) {
return o1.getType().compareTo(o2.getType());
}
}
public static class CSRestResourceInteractionSorter implements Comparator<ResourceInteractionComponent> {
@Override
public int compare(ResourceInteractionComponent o1, ResourceInteractionComponent o2) {
return o1.getCode().toCode().compareTo(o2.getCode().toCode());
}
}
public static class CSRestInteractionSorter implements Comparator<SystemInteractionComponent> {
@Override
public int compare(SystemInteractionComponent o1, SystemInteractionComponent o2) {
return o1.getCode().compareTo(o2.getCode());
}
}
public static class SearchParamSorter implements Comparator<CapabilityStatementRestResourceSearchParamComponent> {
@Override
public int compare(CapabilityStatementRestResourceSearchParamComponent o1, CapabilityStatementRestResourceSearchParamComponent o2) {
return o1.getName().compareTo(o2.getName());
}
}
public static class CSRestResourceOperationSorter implements Comparator<CapabilityStatementRestResourceOperationComponent> {
@Override
public int compare(CapabilityStatementRestResourceOperationComponent o1, CapabilityStatementRestResourceOperationComponent o2) {
return o1.getName().compareTo(o2.getName());
}
}
public static void sortTermCaps(TerminologyCapabilities tc) {
Collections.sort(tc.getCodeSystem(), new TCCodeSystemSorter());
for (TerminologyCapabilitiesCodeSystemComponent t : tc.getCodeSystem()) {
Collections.sort(t.getVersion(), new TCCodeSystemVersionSorter());
for (TerminologyCapabilitiesCodeSystemVersionComponent v : t.getVersion()) {
Collections.sort(v.getLanguage(), new LanguageSorter());
Collections.sort(v.getProperty(), new CodeTypeSorter());
Collections.sort(v.getFilter(), new TCCodeSystemVersionFilterSorter());
}
}
Collections.sort(tc.getExpansion().getParameter(), new TCExpansionParameterSorter());
}
public static class LanguageSorter implements Comparator<Enumeration<CommonLanguages>> {
@Override
public int compare(Enumeration<CommonLanguages> o1, Enumeration<CommonLanguages> o2) {
return o1.asStringValue().compareTo(o2.asStringValue());
}
}
public static class TCCodeSystemSorter implements Comparator<TerminologyCapabilitiesCodeSystemComponent> {
@Override
public int compare(TerminologyCapabilitiesCodeSystemComponent o1, TerminologyCapabilitiesCodeSystemComponent o2) {
return o1.getUri().compareTo(o2.getUri());
}
}
public static class TCCodeSystemVersionSorter implements Comparator<TerminologyCapabilitiesCodeSystemVersionComponent> {
@Override
public int compare(TerminologyCapabilitiesCodeSystemVersionComponent o1, TerminologyCapabilitiesCodeSystemVersionComponent o2) {
return o1.getCode() == null || o2.getCode() == null ? 0 : o1.getCode().compareTo(o2.getCode());
}
}
public static class TCCodeSystemVersionFilterSorter implements Comparator<TerminologyCapabilitiesCodeSystemVersionFilterComponent> {
@Override
public int compare(TerminologyCapabilitiesCodeSystemVersionFilterComponent o1, TerminologyCapabilitiesCodeSystemVersionFilterComponent o2) {
return o1.getCode().compareTo(o2.getCode());
}
}
public static class TCExpansionParameterSorter implements Comparator<TerminologyCapabilitiesExpansionParameterComponent> {
@Override
public int compare(TerminologyCapabilitiesExpansionParameterComponent o1, TerminologyCapabilitiesExpansionParameterComponent o2) {
return o1.getName().compareTo(o2.getName());
}
}
}

View File

@ -245,7 +245,7 @@ public class ComparisonTests {
String en = Utilities.path("[tmp]", "comparison", Utilities.changeFileExt(name, ".expected.html"));
TextFile.stringToFile(expected, en);
String msg = CompareUtilities.checkXMLIsSame(id, en, an);
String msg = new CompareUtilities().checkXMLIsSame(id, en, an);
Assertions.assertTrue(msg == null, "Output does not match expected: "+msg);
}

View File

@ -20,7 +20,9 @@ import org.hl7.fhir.r5.model.Constants;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.test.utils.TestingUtilities;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtil;
import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
import org.hl7.fhir.utilities.json.JsonException;
import org.hl7.fhir.utilities.json.model.JsonObject;
import org.hl7.fhir.utilities.settings.FhirSettings;
import org.hl7.fhir.utilities.tests.TestConfig;
@ -81,6 +83,7 @@ public class LocalTerminologyServiceTests implements ITxTesterLoader {
for (String id : names) {
objects.add(new Object[]{id, examples.get(id)});
}
objects.add(new Object[]{"final", null});
return objects;
}
@ -90,6 +93,7 @@ public class LocalTerminologyServiceTests implements ITxTesterLoader {
private String version = "5.0.0";
private static TxTester tester;
private List<String> modes = new ArrayList<>();
private boolean error = false;
public LocalTerminologyServiceTests(String name, JsonObjectPair setup) {
this.setup = setup;
@ -107,17 +111,29 @@ public class LocalTerminologyServiceTests implements ITxTesterLoader {
logTestSkip("No local terminology server available.");
return;
}
if (SERVER != null) {
if (tester == null) {
tester = new TxTester(this, SERVER, true, externals);
if (setup == null) {
if (!error) {
System.out.println("tx.fhir.org passed all HL7 terminology service tests (mode 'tx.fhir.org', tests v"+loadVersion()+", runner v"+VersionUtil.getBaseVersion()+")");
}
String err = tester.executeTest(setup.suite, setup.test, modes);
Assertions.assertTrue(err == null, err);
Assertions.assertTrue(!error);
} else {
Assertions.assertTrue(true);
if (SERVER != null) {
if (tester == null) {
tester = new TxTester(this, SERVER, true, externals);
}
String err = tester.executeTest(setup.suite, setup.test, modes);
error = error || err != null;
Assertions.assertTrue(err == null, err);
} else {
Assertions.assertTrue(true);
}
}
}
private String loadVersion() throws JsonException, IOException {
return TxTester.processHistoryMarkdown(TestingUtilities.loadTestResourceBytes("tx", "history.md"));
}
private void logTestSkip(String reason) {
System.out.println("Skipping test: " + setup.suite.asString("name") + " " + setup.test.asString("name") + " reason: " + reason);
}

View File

@ -92,7 +92,8 @@ private static TxTestData testData;
if (setup.getSuite().asBoolean("disabled") || setup.getTest().asBoolean("disabled")) {
return;
}
Resource req = loadResource(setup.getTest().asString("request"));
String reqFile = setup.getTest().asString("request");
Resource req = reqFile == null ? null : loadResource(reqFile);
String fn = setup.getTest().has("response:tx.fhir.org") ? setup.getTest().asString("response:tx.fhir.org") : setup.getTest().asString("response");
String resp = TestingUtilities.loadTestResource("tx", fn);
String fp = Utilities.path("[tmp]", "tx", fn);
@ -114,7 +115,7 @@ private static TxTestData testData;
} else if (setup.getTest().asString("operation").equals("cs-validate-code")) {
String diff = TxServiceTestHelper.getDiffForValidation(setup.getTest().str("name"), engine.getContext(), setup.getTest().asString("name"), req, resp, setup.getTest().asString("Content-Language"), fp, ext, true);
assertNull(diff, diff);
} else if (Utilities.existsInList(setup.getTest().asString("operation"), "lookup", "translate")) {
} else if (Utilities.existsInList(setup.getTest().asString("operation"), "lookup", "translate", "metadata", "term-caps")) {
Assertions.assertTrue(true); // we don't test these for the internal server
} else {
Assertions.fail("Unknown Operation "+ setup.getTest().asString("operation"));
@ -140,7 +141,7 @@ private static TxTestData testData;
TxTesterSorters.sortValueSet(vse.getValueset());
TxTesterScrubbers.scrubVS(vse.getValueset(), false);
String vsj = new JsonParser().setOutputStyle(OutputStyle.PRETTY).composeString(vse.getValueset());
String diff = CompareUtilities.checkJsonSrcIsSame(id, resp, vsj, ext);
String diff = new CompareUtilities(ext).checkJsonSrcIsSame(id, resp, vsj);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(vsj, fp);
@ -189,7 +190,7 @@ private static TxTestData testData;
TxTesterScrubbers.scrubOO(oo, false);
String ooj = new JsonParser().setOutputStyle(OutputStyle.PRETTY).composeString(oo);
String diff = CompareUtilities.checkJsonSrcIsSame(id, resp, ooj, ext);
String diff = new CompareUtilities(ext).checkJsonSrcIsSame(id, resp, ooj);
if (diff != null) {
Utilities.createDirectory(Utilities.getDirectoryForFile(fp));
TextFile.stringToFile(ooj, fp);

View File

@ -121,11 +121,11 @@ public class StructureMappingTests {
fail(e.getMessage());
}
if (output.endsWith("json")) {
msg = CompareUtilities.checkJsonSrcIsSame(name, s.toString(), outputJson, null);
msg = new CompareUtilities().checkJsonSrcIsSame(name, s.toString(), outputJson);
} else {
TextFile.bytesToFile(s.toByteArray(), fileOutputRes);
TextFile.bytesToFile(outputJson.getBytes(), fileOutputResOrig);
msg = CompareUtilities.checkXMLIsSame(name, ManagedFileAccess.inStream(fileOutputResOrig), ManagedFileAccess.inStream(fileOutputRes));
msg = new CompareUtilities().checkXMLIsSame(name, ManagedFileAccess.inStream(fileOutputResOrig), ManagedFileAccess.inStream(fileOutputRes));
}
if (!Utilities.noString(msg)) {
System.out.print(s.toString());

View File

@ -8,17 +8,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.NotImplementedException;
@ -858,7 +849,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
@Override
public byte[] fetchRaw(IResourceValidator validator, String source) throws MalformedURLException, IOException {
HTTPResult res = ManagedWebAccess.get(source);
HTTPResult res = ManagedWebAccess.get(Arrays.asList("web"), source);
res.checkThrowException();
return res.getContent();
}