Skip to content

Commit

Permalink
Group file creation bug resolved.
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Chicoine committed Dec 19, 2023
1 parent ac43428 commit d9570c8
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ca.uhn.fhir.context.FhirContext;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.cqframework.cql.cql2elm.CqlCompilerException;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource;
Expand Down Expand Up @@ -271,16 +272,13 @@ public void bundleResources(ArrayList<String> refreshedLibraryNames, String igPa


} catch (Exception e) {
PrintWriter pw = new PrintWriter(new StringWriter());
e.printStackTrace(pw);

String failMsg = "";
if (e.getMessage() != null) {
failMsg = e.getMessage();
} else {
failMsg = e.getClass().getName() ;
failMsg = e.getClass().getName() + ":\r\n" + ExceptionUtils.getStackTrace(e);
}
failedExceptionMessages.put(resourceSourcePath, failMsg + ":\r\n" + pw.toString());
failedExceptionMessages.put(resourceSourcePath, failMsg);
}

processedResources.add(resourceSourcePath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
Expand All @@ -38,137 +39,117 @@ public void refreshTestCases(String path, IOUtils.Encoding encoding, FhirContext
System.out.println("\r\n[Refreshing Tests]\r\n");


final Map<String, String> testCaseRefreshSuccessMap = new ConcurrentHashMap<>();
final Map<String, String> testCaseRefreshFailMap = new ConcurrentHashMap<>();
final Map<String, String> groupFileRefreshSuccessMap = new ConcurrentHashMap<>();
final Map<String, String> groupFileRefreshFailMap = new ConcurrentHashMap<>();
final Map<String, String> testCaseRefreshSuccessMap = new HashMap<>();
final Map<String, String> testCaseRefreshFailMap = new HashMap<>();
final Map<String, String> groupFileRefreshSuccessMap = new HashMap<>();
final Map<String, String> groupFileRefreshFailMap = new HashMap<>();


final List<Callable<Void>> testCaseRefreshTasks = new CopyOnWriteArrayList<>();
IFhirVersion version = fhirContext.getVersion();

final int totalTestFileCount = getTestFileCount(path);

//build list of tasks via for loop:
List<Callable<Void>> testGroupTasks = new ArrayList<>();
List<String> resourceTypeTestGroups = IOUtils.getDirectoryPaths(path, false);

for (String group : resourceTypeTestGroups) {
testGroupTasks.add(() -> {
List<String> testArtifactPaths = IOUtils.getDirectoryPaths(group, false);

//build list of tasks via for loop:
List<Callable<Void>> testArtifactTasks = new CopyOnWriteArrayList<>();
ExecutorService testArtifactExecutor = Executors.newCachedThreadPool();

for (String testArtifactPath : testArtifactPaths) {
testArtifactTasks.add(() -> {
List<String> testCasePaths = IOUtils.getDirectoryPaths(testArtifactPath, false);

org.hl7.fhir.r4.model.Group testGroup;
if (version.getVersion() == FhirVersionEnum.R4) {
testGroup = new org.hl7.fhir.r4.model.Group();
testGroup.setActive(true);
testGroup.setType(Group.GroupType.PERSON);
testGroup.setActual(true);
} else {
testGroup = null;
}

// For each test case we need to create a group
if (!testCasePaths.isEmpty()) {
String measureName = IOUtils.getMeasureTestDirectory(testCasePaths.get(0));
List<String> testArtifactPaths = IOUtils.getDirectoryPaths(group, false);

if (testGroup != null) {
testGroup.setId(measureName);
for (String testArtifactPath : testArtifactPaths) {
List<String> testCasePaths = IOUtils.getDirectoryPaths(testArtifactPath, false);

testGroup.addExtension("http://hl7.org/fhir/StructureDefinition/artifact-testArtifact",
new CanonicalType("http://ecqi.healthit.gov/ecqms/Measure/" + measureName));
}
org.hl7.fhir.r4.model.Group testGroup;
if (version.getVersion() == FhirVersionEnum.R4) {
testGroup = new org.hl7.fhir.r4.model.Group();
testGroup.setActive(true);
testGroup.setType(Group.GroupType.PERSON);
testGroup.setActual(true);
} else {
testGroup = null;
}

for (String testCasePath : testCasePaths) {
testCaseRefreshTasks.add(() -> {
try {
List<String> paths = IOUtils.getFilePaths(testCasePath, true);
List<IBaseResource> resources = IOUtils.readResources(paths, fhirContext);
ensureIds(testCasePath, resources);

// Loop through resources and any that are patients need to be added to the test Group
// Handle individual resources when they exist
for (IBaseResource resource : resources) {
if ((resource.fhirType().equalsIgnoreCase("Patient")) && (version.getVersion() == FhirVersionEnum.R4)) {
org.hl7.fhir.r4.model.Patient patient = (org.hl7.fhir.r4.model.Patient) resource;
if (testGroup != null) {
addPatientToGroupR4(testGroup, patient);
}
}
// For each test case we need to create a group
if (!testCasePaths.isEmpty()) {
String measureName = IOUtils.getMeasureTestDirectory(testCasePaths.get(0));

if (testGroup != null) {
testGroup.setId(measureName);

testGroup.addExtension("http://hl7.org/fhir/StructureDefinition/artifact-testArtifact",
new CanonicalType("http://ecqi.healthit.gov/ecqms/Measure/" + measureName));
}

for (String testCasePath : testCasePaths) {
try {
List<String> paths = IOUtils.getFilePaths(testCasePath, true);
List<IBaseResource> resources = IOUtils.readResources(paths, fhirContext);
ensureIds(testCasePath, resources);

// Loop through resources and any that are patients need to be added to the test Group
// Handle individual resources when they exist
for (IBaseResource resource : resources) {
if ((resource.fhirType().equalsIgnoreCase("Patient")) && (version.getVersion() == FhirVersionEnum.R4)) {
org.hl7.fhir.r4.model.Patient patient = (org.hl7.fhir.r4.model.Patient) resource;
if (testGroup != null) {
addPatientToGroupR4(testGroup, patient);
}
}

// Handle bundled resources when that is how they are provided
if ((resource.fhirType().equalsIgnoreCase("Bundle")) && (version.getVersion() == FhirVersionEnum.R4)) {
org.hl7.fhir.r4.model.Bundle bundle = (org.hl7.fhir.r4.model.Bundle) resource;
var bundleResources =
BundleUtils.getR4ResourcesFromBundle(bundle);
for (IBaseResource bundleResource : bundleResources) {
if (bundleResource.fhirType().equalsIgnoreCase("Patient")) {
org.hl7.fhir.r4.model.Patient patient = (org.hl7.fhir.r4.model.Patient) bundleResource;
if (testGroup != null) {
addPatientToGroupR4(testGroup, patient);
}
}
}
// Handle bundled resources when that is how they are provided
if ((resource.fhirType().equalsIgnoreCase("Bundle")) && (version.getVersion() == FhirVersionEnum.R4)) {
org.hl7.fhir.r4.model.Bundle bundle = (org.hl7.fhir.r4.model.Bundle) resource;
var bundleResources =
BundleUtils.getR4ResourcesFromBundle(bundle);
for (IBaseResource bundleResource : bundleResources) {
if (bundleResource.fhirType().equalsIgnoreCase("Patient")) {
org.hl7.fhir.r4.model.Patient patient = (org.hl7.fhir.r4.model.Patient) bundleResource;
if (testGroup != null) {
addPatientToGroupR4(testGroup, patient);
}
}

// If the resource is a transaction bundle then don't bundle it again otherwise do
String fileId = getId(FilenameUtils.getName(testCasePath));
Object bundle;
if ((resources.size() == 1) && (BundleUtils.resourceIsABundle(resources.get(0)))) {
bundle = processTestBundle(fileId, resources.get(0), fhirContext, testArtifactPath, testCasePath);
} else {
bundle = BundleUtils.bundleArtifacts(fileId, resources, fhirContext, false);
}
IOUtils.writeBundle(bundle, testArtifactPath, encoding, fhirContext);

} catch (Exception e) {
testCaseRefreshFailMap.put(testCasePath, e.getMessage());
}
}
}

// If the resource is a transaction bundle then don't bundle it again otherwise do
String fileId = getId(FilenameUtils.getName(testCasePath));
Object bundle;
if ((resources.size() == 1) && (BundleUtils.resourceIsABundle(resources.get(0)))) {
bundle = processTestBundle(fileId, resources.get(0), fhirContext, testArtifactPath, testCasePath);
} else {
bundle = BundleUtils.bundleArtifacts(fileId, resources, fhirContext, false);
}
IOUtils.writeBundle(bundle, testArtifactPath, encoding, fhirContext);

testCaseRefreshSuccessMap.put(testCasePath, "");
reportProgress((testCaseRefreshFailMap.size() + testCaseRefreshSuccessMap.size()), testCaseRefreshTasks.size());
//task requires return statement
return null;
});
}//end for (String testCasePath : testCasePaths) {

// Need to output the Group if it exists
if (testGroup != null) {
String groupFileName = "Group-" + measureName;
String groupFileIdentifier = testArtifactPath + separator + groupFileName;
} catch (Exception e) {
testCaseRefreshFailMap.put(testCasePath, e.getMessage());
}
testCaseRefreshSuccessMap.put(testCasePath, "");
reportProgress((testCaseRefreshSuccessMap.size() + testCaseRefreshFailMap.size()), totalTestFileCount);
}

try {
IOUtils.writeResource(testGroup, testArtifactPath, encoding, fhirContext, true,
groupFileName);
// Need to output the Group if it exists
if (testGroup != null) {
String groupFileName = "Group-" + measureName;
String groupFileIdentifier = testArtifactPath + separator + groupFileName;

groupFileRefreshSuccessMap.put(groupFileIdentifier, "");
try {
IOUtils.writeResource(testGroup, testArtifactPath, encoding, fhirContext, true,
groupFileName);

} catch (Exception e) {
groupFileRefreshSuccessMap.put(groupFileIdentifier, "");

groupFileRefreshFailMap.put(groupFileIdentifier, e.getMessage());
}
} catch (Exception e) {

}
groupFileRefreshFailMap.put(groupFileIdentifier, e.getMessage());
}
//task requires return statement
return null;
});
}//
ThreadUtils.executeTasks(testArtifactTasks, testArtifactExecutor);

//task requires return statement
return null;
});
}//end for (String group : resourceTypeTestGroups) {
ThreadUtils.executeTasks(testGroupTasks);
//Now with all possible tasks collected, progress can be reported instead of flooding the console.
ThreadUtils.executeTasks(testCaseRefreshTasks);
//ensure accurate progress at final stage:
reportProgress((testCaseRefreshFailMap.size() + testCaseRefreshSuccessMap.size()), testCaseRefreshTasks.size());

}
}
}

}

StringBuilder testCaseMessage = buildInformationMessage(testCaseRefreshFailMap, testCaseRefreshSuccessMap, "Test Case", "Refreshed", verboseMessaging);
if (!groupFileRefreshSuccessMap.isEmpty() || !groupFileRefreshFailMap.isEmpty()) {
Expand All @@ -177,13 +158,25 @@ public void refreshTestCases(String path, IOUtils.Encoding encoding, FhirContext
System.out.println(testCaseMessage);
}

private int getTestFileCount(String path) {
int counter = 0;
List<String> resourceTypeTestGroups = IOUtils.getDirectoryPaths(path, false);
for (String group : resourceTypeTestGroups) {
List<String> testArtifactPaths = IOUtils.getDirectoryPaths(group, false);
for (String testArtifactPath : testArtifactPaths) {
counter += IOUtils.getDirectoryPaths(testArtifactPath, false).size();
}
}
return counter;
}

/**
* Gives the user a nice report at the end of the refresh test case process (used to report group file status as well)
*
* @param failMap which items failed
* @param successMap which items succeeded
* @param type group file or test case
* @param successType created or refreshed
* @param failMap which items failed
* @param successMap which items succeeded
* @param type group file or test case
* @param successType created or refreshed
* @param verboseMessaging give the exception message if verboseMessaging is on
* @return built message for console
*/
Expand Down Expand Up @@ -281,7 +274,7 @@ public static String getId(String baseId) {
}

public static void bundleTestCases(String igPath, String contextResourceType, String libraryName, FhirContext fhirContext,
Map<String, IBaseResource> resources) throws Exception {
Map<String, IBaseResource> resources) throws Exception {
String igTestCasePath = FilenameUtils.concat(FilenameUtils.concat(FilenameUtils.concat(igPath, IGProcessor.TEST_CASE_PATH_ELEMENT), contextResourceType), libraryName);

// this is breaking for bundle of a bundle. Replace with individual resources
Expand Down

0 comments on commit d9570c8

Please sign in to comment.