Merge remote-tracking branch 'origin/master'

This commit is contained in:
Grahame Grieve 2022-06-24 14:02:24 +02:00
commit e0005ecb09
7 changed files with 156 additions and 52 deletions

View File

@ -171,10 +171,13 @@ public class FHIRToolingClient {
public TerminologyCapabilities getTerminologyCapabilities() { public TerminologyCapabilities getTerminologyCapabilities() {
TerminologyCapabilities capabilities = null; TerminologyCapabilities capabilities = null;
try {
capabilities = getCapabilities(resourceAddress.resolveMetadataTxCaps(), capabilities = getCapabilities(resourceAddress.resolveMetadataTxCaps(),
"TerminologyCapabilities", "TerminologyCapabilities",
"Error fetching the server's terminology capabilities"); "Error fetching the server's terminology capabilities");
} catch (ClassCastException e) {
throw new FHIRException("Unexpected response format for Terminology Capability metadata", e);
}
return capabilities; return capabilities;
} }

View File

@ -32,8 +32,7 @@ import okhttp3.Headers;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.internal.http2.Header; import okhttp3.internal.http2.Header;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
class FHIRToolingClientTest { class FHIRToolingClientTest {
@ -162,6 +161,20 @@ class FHIRToolingClientTest {
checkHeaders(argumentCaptorValue); checkHeaders(argumentCaptorValue);
} }
@Test
void getTerminologyCapabilitiesNotSupported() throws IOException {
Mockito.when(mockClient.issueGetResourceRequest(Mockito.any(URI.class), Mockito.anyString(),
Mockito.any(Headers.class), Mockito.eq("TerminologyCapabilities"), Mockito.anyLong()))
.thenReturn(new ResourceRequest<>(new CapabilityStatement(), 200, "location"));
ArgumentCaptor<Headers> headersArgumentCaptor = ArgumentCaptor.forClass(Headers.class);
toolingClient.setClientHeaders(getHeaders());
Exception exception = assertThrows(FHIRException.class, () -> {
toolingClient.getTerminologyCapabilities();
});
assertEquals(exception.getCause().getClass(), ClassCastException.class);
}
@Test @Test
void getTerminologyCapabilitiesFailsForJSON() throws IOException { void getTerminologyCapabilitiesFailsForJSON() throws IOException {
Mockito.when(mockClient.issueGetResourceRequest(Mockito.any(URI.class), Mockito.anyString(), Mockito.when(mockClient.issueGetResourceRequest(Mockito.any(URI.class), Mockito.anyString(),

View File

@ -0,0 +1,29 @@
package org.hl7.fhir.utilities;
import java.util.concurrent.TimeUnit;
public class DurationUtil {
public static String presentDuration(long duration) {
duration = duration / 1000000;
String res = ""; // ;
long days = TimeUnit.MILLISECONDS.toDays(duration);
long hours = TimeUnit.MILLISECONDS.toHours(duration) -
TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
long millis = TimeUnit.MILLISECONDS.toMillis(duration) -
TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration));
if (days > 0)
res = String.format("%dd %02d:%02d:%02d.%03d", days, hours, minutes, seconds, millis);
else if (hours > 0)
res = String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, millis);
else //
res = String.format("%02d:%02d.%03d", minutes, seconds, millis);
// else
// res = String.format("%02d.%04d", seconds, millis);
return res;
}
}

View File

@ -1,11 +1,7 @@
package org.hl7.fhir.utilities; package org.hl7.fhir.utilities;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.hl7.fhir.utilities.TimeTracker.Counter;
public class TimeTracker { public class TimeTracker {
@ -72,29 +68,29 @@ public class TimeTracker {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (Counter c : records) { for (Counter c : records) {
if (c.count == 1) { if (c.count == 1) {
b.append(c.name+": "+Utilities.presentDuration(c.length)); b.append(c.name+": "+ DurationUtil.presentDuration(c.length));
} }
} }
for (Counter c : records) { for (Counter c : records) {
if (c.count > 1) { if (c.count > 1) {
b.append(c.name+": "+Utilities.presentDuration(c.length)+" (#"+c.count+")"); b.append(c.name+": "+ DurationUtil.presentDuration(c.length)+" (#"+c.count+")");
} }
} }
return "Times: "+b.toString(); return "Times: "+b.toString();
} }
public String clock() { public String clock() {
return Utilities.presentDuration(System.nanoTime() - globalStart); return DurationUtil.presentDuration(System.nanoTime() - globalStart);
} }
public String instant() { public String instant() {
return Utilities.presentDuration(System.nanoTime() - globalStart); return DurationUtil.presentDuration(System.nanoTime() - globalStart);
} }
public String milestone() { public String milestone() {
long start = milestone == 0 ? globalStart : milestone ; long start = milestone == 0 ? globalStart : milestone ;
milestone = System.nanoTime(); milestone = System.nanoTime();
return Utilities.presentDuration(milestone - start); return DurationUtil.presentDuration(milestone - start);
} }
} }

View File

@ -22,14 +22,12 @@ import java.nio.file.StandardCopyOption;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
@ -92,7 +90,7 @@ public class Utilities {
* *
* @param word the word that is to be pluralized. * @param word the word that is to be pluralized.
* @return the pluralized form of the word, or the word itself if it could not be pluralized * @return the pluralized form of the word, or the word itself if it could not be pluralized
* @see #singularize(Object) * @see Inflector#singularize(Object)
*/ */
public static String pluralizeMe(String word) { public static String pluralizeMe(String word) {
Inflector inf = new Inflector(); Inflector inf = new Inflector();
@ -1424,30 +1422,6 @@ public class Utilities {
return byteArrays; return byteArrays;
} }
public static String presentDuration(long duration) {
duration = duration / 1000000;
String res = ""; // ;
long days = TimeUnit.MILLISECONDS.toDays(duration);
long hours = TimeUnit.MILLISECONDS.toHours(duration) -
TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) -
TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
long millis = TimeUnit.MILLISECONDS.toMillis(duration) -
TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(duration));
if (days > 0)
res = String.format("%dd %02d:%02d:%02d.%04d", days, hours, minutes, seconds, millis);
else if (hours > 0)
res = String.format("%02d:%02d:%02d.%04d", hours, minutes, seconds, millis);
else //
res = String.format("%02d:%02d.%04d", minutes, seconds, millis);
// else
// res = String.format("%02d.%04d", seconds, millis);
return res;
}
public static void unzip(InputStream zip, Path target) throws IOException { public static void unzip(InputStream zip, Path target) throws IOException {
try (ZipInputStream zis = new ZipInputStream(zip)) { try (ZipInputStream zis = new ZipInputStream(zip)) {
ZipEntry zipEntry = zis.getNextEntry(); ZipEntry zipEntry = zis.getNextEntry();

View File

@ -0,0 +1,44 @@
package org.hl7.fhir.utilities;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class DurationUtilTest {
public static Stream<Arguments> data() throws ParserConfigurationException, SAXException, IOException {
List<Arguments> objects = new ArrayList<>();
objects.add(Arguments.of("PT0.001S", "00:00.001"));
objects.add(Arguments.of("PT0.012S", "00:00.012"));
objects.add(Arguments.of("PT0.123S", "00:00.123"));
objects.add(Arguments.of("PT0.999S", "00:00.999"));
objects.add(Arguments.of("PT1.001S", "00:01.001"));
objects.add(Arguments.of("PT1M1.001S", "01:01.001"));
objects.add(Arguments.of("PT59M1.001S", "59:01.001"));
objects.add(Arguments.of("PT1H1M1.001S", "01:01:01.001"));
objects.add(Arguments.of("PT23H1M1.001S", "23:01:01.001"));
objects.add(Arguments.of("P1DT23H1M1.001S", "1d 23:01:01.001"));
objects.add(Arguments.of("P12DT23H1M1.001S", "12d 23:01:01.001"));
return objects.stream();
}
@ParameterizedTest
@MethodSource("data")
public void testPresentDuration(String iso8601String, String expectedPresentation) {
assertEquals(expectedPresentation, DurationUtil.presentDuration(Duration.parse(iso8601String).toNanos()));
}
}

View File

@ -13,6 +13,9 @@ schematron checking is performed, then some additional checks are performed.
If requested, instances will also be verified against the appropriate schema W3C If requested, instances will also be verified against the appropriate schema W3C
XML Schema, JSON schema or ShEx, as appropriate XML Schema, JSON schema or ShEx, as appropriate
Default Usage
=============
Usage: java -jar [validator].jar (parameters) Usage: java -jar [validator].jar (parameters)
The following parameters are supported: The following parameters are supported:
@ -111,9 +114,11 @@ proxy
Parameters can appear in any order Parameters can appear in any order
Alternatively, you can use the validator to execute a transformation as Transforms
described by a structure map. To do this, you must provide some additional ==========
parameters:
You can use the validator to execute a transformation as described by a
structure map. To do this, you must provide some additional parameters:
-transform [map] -transform [map]
@ -124,24 +129,33 @@ Any other dependency maps have to be loaded through an -ig reference
-transform uses the parameters -defn, -txserver, -ig (at least one with the map -transform uses the parameters -defn, -txserver, -ig (at least one with the map
files), and -output files), and -output
Alternatively, you can use the validator to generate narrative for a resource. Narratives
To do this, you must provide a specific parameter: ==========
You can use the validator to generate narrative for a resource. To do this, you
must provide a specific parameter:
-narrative -narrative
-narrative requires the parameters -defn, -txserver, -source, and -output. ig -narrative requires the parameters -defn, -txserver, -source, and -output. ig
and profile may be used and profile may be used
Alternatively, you can use the validator to convert a resource or logical model. Conversion
To do this, you must provide a specific parameter: ==========
You can use the validator to convert a resource or logical model. To do this,
you must provide a specific parameter:
-convert -convert
-convert requires the parameters -source and -output. ig may be used to provide -convert requires the parameters -source and -output. ig may be used to provide
a logical model a logical model
Alternatively, you can use the validator to evaluate a FHIRPath expression on a FHIRPath
resource or logical model. To do this, you must provide a specific parameter: ========
You can use the validator to evaluate a FHIRPath expression on a resource or
logical model. To do this, you must provide a specific parameter:
-fhirpath [FHIRPath] -fhirpath [FHIRPath]
@ -150,10 +164,41 @@ resource or logical model. To do this, you must provide a specific parameter:
-fhirpath requires the parameters -source. ig may be used to provide a logical -fhirpath requires the parameters -source. ig may be used to provide a logical
model model
Finally, you can use the validator to generate a snapshot for a profile. Snapshots
To do this, you must provide a specific parameter: =========
You can use the validator to generate a snapshot for a profile. To do this, you
must provide a specific parameter:
-snapshot -snapshot
-snapshot requires the parameters -defn, -txserver, -source, and -output. ig may -snapshot requires the parameters -defn, -txserver, -source, and -output. ig may
be used to provide necessary base profiles be used to provide necessary base profiles
Tests
=====
The validator can be run in test mode, which executes all JUnit tests for the
FHIR core library against a set of test cases in a local directory. To do this,
you must provide a specific parameter with a directory value:
-test [directory]
The directory must follow the same conventions as the reference test cases found
at https://github.com/FHIR/fhir-test-cases. This mode must also be executed with
the Java property java.locale.providers set to COMPAT as below:
java -Djava.locale.providers=COMPAT -jar validator_cli.jar -tests
./my/path/to/fhir-test-cases
This parameter is compatible with -txCache, -test-modules, and
-test-classname-filter parameters.
The following test-specific parameters can be used to limit which tests are run:
-test-modules [module-names] A comma delimited list of Java module names for
which to run JUnit tests. By default, all modules are used to run tests.
Example: -test-modules org.hl7.fhir.dstu2,org.hl7.fhir.dstu2016may
-test-classname-filter [regex] A regex filter applied to test Java class names
for selecting which JUnit tests to run. By default, all tests are run.
Example: -test-classname-filter .*ShexGeneratorTests