Add distinct FHIR version per IG parameter + tests

This commit is contained in:
dotasek 2022-04-07 17:30:50 -04:00
parent 489218da82
commit cb1d20afeb
4 changed files with 166 additions and 18 deletions

View File

@ -69,11 +69,37 @@ public class IgLoader {
this.isDebug = isDebug;
}
/**
*
* @param igs
* @param binaries
* @param src Source of the IG
*
* @param recursive
* @throws IOException
* @throws FHIRException
*
* @see IgLoader#loadIgSource(String, boolean, boolean) loadIgSource for detailed description of the src parameter
*/
public void loadIg(List<ImplementationGuide> igs,
Map<String, byte[]> binaries,
String src,
boolean recursive) throws IOException, FHIRException {
NpmPackage npm = src.matches(FilesystemPackageCacheManager.PACKAGE_VERSION_REGEX_OPT) && !new File(src).exists() ? getPackageCacheManager().loadPackage(src, null) : null;
final String explicitFhirVersion;
final String srcPackage;
if (src.startsWith("[") && src.indexOf(']', 1) > 1) {
explicitFhirVersion = src.substring(1,src.indexOf(']', 1));
srcPackage = src.substring(src.indexOf(']',1) + 1);
if (VersionUtilities.isSupportedVersion(explicitFhirVersion)) {
throw new FHIRException("Unsupported FHIR Version: " + explicitFhirVersion + " valid versions are " + VersionUtilities.listSupportedVersions());
}
} else {
explicitFhirVersion = null;
srcPackage = src;
}
NpmPackage npm = srcPackage.matches(FilesystemPackageCacheManager.PACKAGE_VERSION_REGEX_OPT) && !new File(srcPackage).exists() ? getPackageCacheManager().loadPackage(srcPackage, null) : null;
if (npm != null) {
for (String s : npm.dependencies()) {
if (!getContext().getLoadedPackages().contains(s)) {
@ -82,17 +108,17 @@ public class IgLoader {
}
}
}
System.out.print(" Load " + src);
if (!src.contains("#")) {
System.out.print(" Load " + srcPackage);
if (!srcPackage.contains("#")) {
System.out.print("#" + npm.version());
}
int count = getContext().loadFromPackage(npm, ValidatorUtils.loaderForVersion(npm.fhirVersion()));
System.out.println(" - " + count + " resources (" + getContext().clock().milestone() + ")");
} else {
System.out.print(" Load " + src);
System.out.print(" Load " + srcPackage);
String canonical = null;
int count = 0;
Map<String, byte[]> source = loadIgSource(src, recursive, true);
Map<String, byte[]> source = loadIgSource(srcPackage, recursive, true);
String version = Constants.VERSION;
if (getVersion() != null) {
version = getVersion();
@ -100,11 +126,8 @@ public class IgLoader {
if (source.containsKey("version.info")) {
version = readInfoVersion(source.get("version.info"));
}
if (src.endsWith("CareConnect-AllergyIntolerance-1.json")) {
version = "3.0.1";
} else if (src.endsWith("UKCoreAllergyIntolerance.json")) {
version = "4.0.1";
if (explicitFhirVersion != null) {
version = explicitFhirVersion;
}
for (Map.Entry<String, byte[]> t : source.entrySet()) {
@ -133,6 +156,18 @@ public class IgLoader {
}
}
/**
*
* @param source
* @param opName
* @param asIg
* @return
* @throws FHIRException
* @throws IOException
*
* * @see IgLoader#loadIgSource(String, boolean, boolean) loadIgSource for detailed description of the src parameter
*/
public Content loadContent(String source, String opName, boolean asIg) throws FHIRException, IOException {
Map<String, byte[]> s = loadIgSource(source, false, asIg);
Content res = new Content();
@ -157,18 +192,23 @@ public class IgLoader {
}
/**
* explore should be true if we're trying to load an -ig parameter, and false if we're loading source
*
* @param src can be one of the following:
* <br> - a canonical url for an ig - this will be converted to a package id and loaded into the cache
* <br> - a package id for an ig - this will be loaded into the cache
* <br> - a direct reference to a package ("package.tgz") - this will be extracted by the cache manager, but not put in the cache
* <br> - a folder containing resources - these will be loaded directly
* @param recursive if true and src resolves to a folder, recursively find and load IgSources from that directory
* @param explore should be true if we're trying to load an -ig parameter, and false if we're loading source
*
* @return
* @throws FHIRException
* @throws IOException
**/
*/
public Map<String, byte[]> loadIgSource(String src,
boolean recursive,
boolean explore) throws FHIRException, IOException {
// src can be one of the following:
// - a canonical url for an ig - this will be converted to a package id and loaded into the cache
// - a package id for an ig - this will be loaded into the cache
// - a direct reference to a package ("package.tgz") - this will be extracted by the cache manager, but not put in the cache
// - a folder containing resources - these will be loaded directly
//
if (Common.isNetworkPath(src)) {
String v = null;
if (src.contains("|")) {
@ -634,7 +674,7 @@ public class IgLoader {
return Utilities.existsInList(fn, EXEMPT_FILES);
}
private Resource loadFileWithErrorChecking(String version, Map.Entry<String, byte[]> t, String fn) {
protected Resource loadFileWithErrorChecking(String version, Map.Entry<String, byte[]> t, String fn) {
log("* load file: " + fn);
Resource r = null;
try {

View File

@ -266,6 +266,19 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
}
}
/**
*
* @param src
* @param recursive
* @param terminologyCachePath
* @param userAgent
* @param tt
* @param loggingService
* @throws FHIRException
* @throws IOException
*
* @see IgLoader#loadIgSource(String, boolean, boolean) loadIgSource for detailed description of the src parameter
*/
private void loadCoreDefinitions(String src, boolean recursive, String terminologyCachePath, String userAgent, TimeTracker tt, IWorkerContext.ILoggingService loggingService) throws FHIRException, IOException {
NpmPackage npm = getPcm().loadPackage(src, null);
if (npm != null) {

View File

@ -0,0 +1,95 @@
package org.hl7.fhir.validation;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.SimpleWorkerContext;
import org.hl7.fhir.r5.model.ImplementationGuide;
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
public class IgLoaderTests {
final static String DUMMY_PATH = Paths.get("src","test","resources", "igLoad", "my-dummy-ig.json").toAbsolutePath().toString();
@Mock
FilesystemPackageCacheManager filesystemPackageCacheManager;
@Mock
SimpleWorkerContext simpleWorkerContext;
@Mock
org.hl7.fhir.utilities.TimeTracker timeTracker;
private static Stream<Arguments> getTestIgLoadParams() {
return Stream.of(
Arguments.of(DUMMY_PATH, DUMMY_PATH, "4.0.1"),
Arguments.of("[3.0.1]" + DUMMY_PATH, DUMMY_PATH, "3.0.1"),
Arguments.of("[" + DUMMY_PATH, "[" + DUMMY_PATH, "4.0.1")
);
}
@ParameterizedTest
@MethodSource("getTestIgLoadParams")
public void testIgLoad(String packageString, String expectedPackageName, String expectedFhirVersion) throws IOException {
final byte[] dummyBytes = {};
final String dummyKey = "dummyKey";
final Map<String, byte[]> dummyMap = new HashMap<>();
dummyMap.put(dummyKey, dummyBytes);
IgLoader igLoader = Mockito.spy(new IgLoader(
filesystemPackageCacheManager,
simpleWorkerContext,
"4.0.1"
));
doReturn(dummyMap).when(igLoader).loadIgSource(expectedPackageName, false, true);
doReturn(timeTracker).when(simpleWorkerContext).clock();
List<ImplementationGuide> igs = Collections.emptyList();
igLoader.loadIg( igs,
Collections.emptyMap(),
packageString,
false);
Mockito.verify(igLoader, times(1)).loadResourceByVersion(expectedFhirVersion, dummyBytes, dummyKey);
}
@Test
public void testFailIfInvalidFHIRVersion() {
Exception exception = assertThrows(FHIRException.class, () -> {
IgLoader igLoader = Mockito.spy(new IgLoader(
filesystemPackageCacheManager,
simpleWorkerContext,
"4.0.1"
));
List<ImplementationGuide> igs = Collections.emptyList();
igLoader.loadIg(igs,
Collections.emptyMap(),
"[0.1.2]" + DUMMY_PATH,
false);
});
}
}