Skip to content

Commit

Permalink
Merge pull request #157 from onc-healthit/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
ssavarala authored Sep 1, 2022
2 parents c34e95b + 729cc03 commit d4a1bd7
Show file tree
Hide file tree
Showing 19 changed files with 1,147 additions and 159 deletions.
1 change: 1 addition & 0 deletions .java-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.8
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
This document is meant to outline the steps to successfully configure and deploy the reference ccda application.

If you would like to get a test virtual machine up and running quickly, check out https://github.com/mieweb/vagrant-ccda-validator for a Vagrant build. Note: This is a 3rd-party option and is not directly supported by SITE/the ONC. It intends to pull, configure, and deploy the data from our codebase based on these instructions. Otherwise, please continue to follow the full instructions below to create a local, external, or customized instance of the validator.
If you would like to get a test virtual machine up and running quickly, check out https://github.com/mieweb/vagrant-ccda-validator for a Vagrant build or https://github.com/mieweb/docker-ccda-validator for a docker container. Note: These are 3rd-party options and are not directly supported by SITE/the ONC. They intend to pull, configure, and deploy the data from our codebase based on these instructions. Otherwise, please continue to follow the full instructions below to create a local, external, or customized instance of the validator.

**1. Assumptions**

Expand Down
30 changes: 10 additions & 20 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>org.sitenv</groupId>
<artifactId>referenceccdavalidator</artifactId>
<version>1.0.65</version>
<version>1.0.66</version>
<packaging>war</packaging>
<name>Reference CCDA Validator</name>

Expand All @@ -16,12 +16,12 @@
<content.validator.version>latestVersion</content.validator.version>
<!-- MDHT SITE properties -->
<mdht.models.groupid>mdht.openhealthtools.mdht.cda</mdht.models.groupid>
<mdht.models.version>3.0.0.20220126</mdht.models.version>
<mdht.models.version>3.0.0.20220825</mdht.models.version>
<ds4pcontent.groupId>mdht.hl7.ds4p</ds4pcontent.groupId>
<ds4pcontent.version>${mdht.models.version}</ds4pcontent.version>
<mdht.plugins.groupId>mdht.eclipse.mdht</mdht.plugins.groupId>
<mdht.plugins.version>3.0.0.202201250600</mdht.plugins.version>

<mdht.plugins.version>3.0.0.202208250500</mdht.plugins.version>
<logback.version>1.2.11</logback.version>
<!-- MDHT SNAPSHOT properties: Uncomment for local test -->
<!--
<mdht.models.groupid>org.openhealthtools.mdht.cda</mdht.models.groupid>
Expand Down Expand Up @@ -246,25 +246,15 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.0</version>
<scope>runtime</scope>
</dependency>

<!-- pull in logback-core and slf4j-api -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>runtime</scope>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.sitenv.referenceccda.controllers;

import org.apache.log4j.Logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sitenv.referenceccda.dto.ValidationResultsDto;
import org.sitenv.referenceccda.services.ReferenceCCDAValidationService;
import org.sitenv.referenceccda.services.VocabularyService;
Expand Down Expand Up @@ -32,70 +33,74 @@ public class ReferenceCCDAValidationController {

private static final String GITHUB_URL = "https://api.github.com/repos/onc-healthit/2015-certification-ccda-testdata/git/trees/master?recursive=1";
private static final String DEFAULT_SEVERITY_LEVEL = "INFO";
private static Logger logger = Logger.getLogger(ReferenceCCDAValidationController.class);
private static Logger logger = LoggerFactory.getLogger(ReferenceCCDAValidationController.class);

@RequestMapping(value = "/", headers = "content-type=multipart/*", method = RequestMethod.POST)
public ValidationResultsDto doValidation(
@RequestParam(value = "validationObjective", required = true) String validationObjective,
@RequestParam(value = "referenceFileName", required = true) String referenceFileName,
@RequestParam(value = "ccdaFile", required = true) MultipartFile ccdaFile,
@RequestParam(value = "curesUpdate", required = false) boolean curesUpdate,
@RequestParam(value = "curesUpdate", required = false) boolean curesUpdate,
@RequestParam(value = "svap2022", required = false) boolean svap2022,
@RequestParam(defaultValue = VocabularyConstants.Config.DEFAULT, required = false) String vocabularyConfig,
@RequestParam(defaultValue = DEFAULT_SEVERITY_LEVEL, required = false) String severityLevel) {

logger.info("severityLevel requestParam: " + severityLevel);
if ((severityLevel == null || severityLevel.equals("")) ||
(!severityLevel.equalsIgnoreCase(VocabularyConstants.SeverityLevel.INFO.name()) &&
!severityLevel.equalsIgnoreCase(VocabularyConstants.SeverityLevel.WARNING.name()) &&
!severityLevel.equalsIgnoreCase(VocabularyConstants.SeverityLevel.ERROR.name())) ) {

if ((severityLevel == null || severityLevel.equals(""))
|| (!severityLevel.equalsIgnoreCase(VocabularyConstants.SeverityLevel.INFO.name())
&& !severityLevel.equalsIgnoreCase(VocabularyConstants.SeverityLevel.WARNING.name())
&& !severityLevel.equalsIgnoreCase(VocabularyConstants.SeverityLevel.ERROR.name()))) {
severityLevel = DEFAULT_SEVERITY_LEVEL;
logger.info("severityLevel was set/overwritten to default: " + severityLevel);
}

SeverityLevel severityLevelEnum = SeverityLevel.valueOf(severityLevel.toUpperCase());
logger.info("Final severityLevelEnum.name() " + severityLevelEnum.name());


return referenceCcdaValidationService.validateCCDA(validationObjective, referenceFileName, ccdaFile, curesUpdate,
vocabularyConfig, severityLevelEnum);

logger.info("Final severityLevelEnum.name() " + severityLevelEnum.name());

return referenceCcdaValidationService.validateCCDA(validationObjective, referenceFileName, ccdaFile,
curesUpdate, svap2022, vocabularyConfig, severityLevelEnum);
}

@RequestMapping(value = "/getvaluesetsbyoids", method = RequestMethod.GET)
public List<VsacValueSet> getValuesetsByOids(@RequestParam(value = "oids", required = true) String[] valuesetOids){
public List<VsacValueSet> getValuesetsByOids(@RequestParam(value = "oids", required = true) String[] valuesetOids) {
return vocabularyService.getValuesetsByOids(Arrays.asList(valuesetOids));
}

@RequestMapping(value = "/getbycodeincodesystem", method = RequestMethod.GET)
public List<Code> getByCodeInCodeSystems(@RequestParam(value = "code", required = true)String code, @RequestParam(value = "codeSystems", required = true) String[] codeSystems){
public List<Code> getByCodeInCodeSystems(@RequestParam(value = "code", required = true) String code,
@RequestParam(value = "codeSystems", required = true) String[] codeSystems) {
return vocabularyService.getByCodeInCodesystems(code, Arrays.asList(codeSystems));
}

@RequestMapping(value = "/getbycodeinvaluesetoid", method = RequestMethod.GET)
public List<VsacValueSet> getByCodeInValuesetOid(@RequestParam(value = "code", required = true)String code, @RequestParam(value = "oids", required = true) String[] valuesetOids){
public List<VsacValueSet> getByCodeInValuesetOid(@RequestParam(value = "code", required = true) String code,
@RequestParam(value = "oids", required = true) String[] valuesetOids) {
return vocabularyService.getByCodeInValuesetOids(code, Arrays.asList(valuesetOids));
}

@RequestMapping(value = "/iscodeandisplaynameincodesystem", method = RequestMethod.GET)
public boolean isCodeAndDisplayNameFoundInCodeSystems(@RequestParam(value = "code", required = true)String code, @RequestParam(value = "displayName", required = true)String displayName, @RequestParam(value = "codeSystems", required = true) String[] codeSystems){
public boolean isCodeAndDisplayNameFoundInCodeSystems(@RequestParam(value = "code", required = true) String code,
@RequestParam(value = "displayName", required = true) String displayName,
@RequestParam(value = "codeSystems", required = true) String[] codeSystems) {
return vocabularyService.isCodeAndDisplayNameFoundInCodeSystems(code, displayName, Arrays.asList(codeSystems));
}

@RequestMapping(value = "/iscodeincodesystem", method = RequestMethod.GET)
public boolean isCodeFoundInCodeSystems(@RequestParam(value = "code", required = true)String code, @RequestParam(value = "codeSystems", required = true) String[] codeSystems){
public boolean isCodeFoundInCodeSystems(@RequestParam(value = "code", required = true) String code,
@RequestParam(value = "codeSystems", required = true) String[] codeSystems) {
return vocabularyService.isCodeFoundInCodesystems(code, Arrays.asList(codeSystems));
}

@RequestMapping(value = "/iscodeinvalueset", method = RequestMethod.GET)
public boolean isCodeFoundInValuesetOids(@RequestParam(value = "code", required = true)String code, @RequestParam(value = "valuesetOids", required = true) String[] valuesetOids){
public boolean isCodeFoundInValuesetOids(@RequestParam(value = "code", required = true) String code,
@RequestParam(value = "valuesetOids", required = true) String[] valuesetOids) {
return vocabularyService.isCodeFoundInValuesetOids(code, Arrays.asList(valuesetOids));
}

@Cacheable("messagetypeValidationObjectivesAndReferenceFilesMap")
@RequestMapping(value = "/senderreceivervalidationobjectivesandreferencefiles", method = RequestMethod.GET)
public Map<String, Map<String, List<String>>> getMapOfSenderAndRecieverValidationObjectivesWithReferenceFiles(){
public Map<String, Map<String, List<String>>> getMapOfSenderAndRecieverValidationObjectivesWithReferenceFiles() {
return vocabularyService.getMapOfSenderAndRecieverValidationObjectivesWithReferenceFiles();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sitenv.referenceccda.dto.ValidationResultsDto;
import org.sitenv.referenceccda.dto.ValidationResultsMetaData;
import org.sitenv.referenceccda.validators.RefCCDAValidationResult;
Expand All @@ -27,7 +28,7 @@

@Service
public class ReferenceCCDAValidationService {
private static Logger logger = Logger.getLogger(ReferenceCCDAValidationService.class);
private static Logger logger = LoggerFactory.getLogger(ReferenceCCDAValidationService.class);

private ReferenceCCDAValidator referenceCCDAValidator;
private VocabularyCCDAValidator vocabularyCCDAValidator;
Expand All @@ -54,29 +55,29 @@ public ReferenceCCDAValidationService(ReferenceCCDAValidator referenceCCDAValida

public ValidationResultsDto validateCCDA(String validationObjective, String referenceFileName,
MultipartFile ccdaFile) {
return validateCCDAImplementation(validationObjective, referenceFileName, ccdaFile,false,
return validateCCDAImplementation(validationObjective, referenceFileName, ccdaFile, false, false,
VocabularyConstants.Config.DEFAULT, SeverityLevel.INFO);
}

public ValidationResultsDto validateCCDA(String validationObjective, String referenceFileName,
MultipartFile ccdaFile, String vocabularyConfig) {
return validateCCDAImplementation(validationObjective, referenceFileName, ccdaFile, false, vocabularyConfig,
return validateCCDAImplementation(validationObjective, referenceFileName, ccdaFile, false, false, vocabularyConfig,
SeverityLevel.INFO);
}

public ValidationResultsDto validateCCDA(String validationObjective, String referenceFileName,
MultipartFile ccdaFile, boolean curesUpdate, String vocabularyConfig, SeverityLevel severityLevel) {
return validateCCDAImplementation(validationObjective, referenceFileName, ccdaFile, curesUpdate, vocabularyConfig,
MultipartFile ccdaFile, boolean curesUpdate, boolean svap2022, String vocabularyConfig, SeverityLevel severityLevel) {
return validateCCDAImplementation(validationObjective, referenceFileName, ccdaFile, curesUpdate, svap2022, vocabularyConfig,
severityLevel);
}

private ValidationResultsDto validateCCDAImplementation(String validationObjective, String referenceFileName,
MultipartFile ccdaFile, boolean curesUpdate, String vocabularyConfig, SeverityLevel severityLevel) {
MultipartFile ccdaFile, boolean curesUpdate, boolean svap2022, String vocabularyConfig, SeverityLevel severityLevel) {
ValidationResultsDto resultsDto = new ValidationResultsDto();
ValidationResultsMetaData resultsMetaData = new ValidationResultsMetaData();
List<RefCCDAValidationResult> validatorResults = new ArrayList<>();
try {
validatorResults = runValidators(validationObjective, referenceFileName, ccdaFile, curesUpdate, vocabularyConfig,
validatorResults = runValidators(validationObjective, referenceFileName, ccdaFile, curesUpdate, svap2022, vocabularyConfig,
severityLevel);
resultsMetaData = buildValidationMedata(validatorResults, validationObjective, severityLevel);
resultsMetaData.setCcdaFileName(ccdaFile.getOriginalFilename());
Expand Down Expand Up @@ -110,7 +111,7 @@ private static void processValidateCCDAException(ValidationResultsMetaData resul
}

private List<RefCCDAValidationResult> runValidators(String validationObjective, String referenceFileName,
MultipartFile ccdaFile, boolean curesUpdate, String vocabularyConfig, SeverityLevel severityLevel)
MultipartFile ccdaFile, boolean curesUpdate, boolean svap2022, String vocabularyConfig, SeverityLevel severityLevel)
throws SAXException, Exception {
List<RefCCDAValidationResult> validatorResults = new ArrayList<>();
InputStream ccdaFileInputStream = null;
Expand Down Expand Up @@ -148,7 +149,7 @@ private List<RefCCDAValidationResult> runValidators(String validationObjective,
}
if (objectiveAllowsContentValidation(validationObjective)) {
List<RefCCDAValidationResult> contentResults = doContentValidation(validationObjective,
referenceFileName, ccdaFileContents, curesUpdate, severityLevel);
referenceFileName, ccdaFileContents, curesUpdate, svap2022, severityLevel);
if (contentResults != null && !contentResults.isEmpty()) {
logger.info("Adding Content results");
validatorResults.addAll(contentResults);
Expand Down Expand Up @@ -212,9 +213,10 @@ private ArrayList<RefCCDAValidationResult> doVocabularyValidation(String validat
}

private List<RefCCDAValidationResult> doContentValidation(String validationObjective, String referenceFileName,
String ccdaFileContents, boolean curesUpdate, SeverityLevel severityLevel) throws SAXException {
String ccdaFileContents, boolean curesUpdate, boolean svap2022, SeverityLevel severityLevel)
throws SAXException {
logger.info("Attempting Content validation...");
return goldMatchingValidator.validateFile(validationObjective, referenceFileName, ccdaFileContents, curesUpdate, severityLevel);
return goldMatchingValidator.validateFile(validationObjective, referenceFileName, ccdaFileContents, curesUpdate, svap2022, severityLevel);
}

private ValidationResultsMetaData buildValidationMedata(List<RefCCDAValidationResult> validatorResults,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
import java.io.IOException;
import java.io.StringReader;

import org.apache.log4j.Logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

public abstract class BaseCCDAValidator {
public static final String UTF8_BOM = "\uFEFF";
private static Logger logger = Logger.getLogger(BaseCCDAValidator.class);
private static Logger logger = LoggerFactory.getLogger(BaseCCDAValidator.class);

protected static void trackXPathsInXML(XPathIndexer xpathIndexer, String xmlString) throws SAXException{
XMLReader parser = XMLReaderFactory.createXMLReader();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,24 @@ public ReferenceContentValidator(ContentValidatorService contentValidatorService
@Override
public ArrayList<RefCCDAValidationResult> validateFile(String validationObjective, String referenceFileName,
String ccdaFile) throws SAXException {
return validateFile(validationObjective, referenceFileName, ccdaFile, false, SeverityLevel.INFO);
return validateFile(validationObjective, referenceFileName, ccdaFile, false, false, SeverityLevel.INFO);
}

public ArrayList<RefCCDAValidationResult> validateFile(String validationObjective, String referenceFileName,
String ccdaFile, boolean curesUpdate, SeverityLevel severityLevel) throws SAXException {
String ccdaFile, boolean curesUpdate, boolean svap2022, SeverityLevel severityLevel) throws SAXException {
ArrayList<RefCCDAValidationResult> results = null;
if (ccdaFile != null) {
results = doValidation(validationObjective, referenceFileName, ccdaFile, curesUpdate, severityLevel);
results = doValidation(validationObjective, referenceFileName, ccdaFile, curesUpdate, svap2022, severityLevel);
}
return results;
}

private ArrayList<RefCCDAValidationResult> doValidation(String validationObjective, String referenceFileName,
String ccdaFile, boolean curesUpdate, SeverityLevel severityLevel) throws SAXException {
String ccdaFile, boolean curesUpdate, boolean svap2022, SeverityLevel severityLevel) throws SAXException {
org.sitenv.contentvalidator.dto.enums.SeverityLevel userSeverityLevelForContentValidation =
org.sitenv.contentvalidator.dto.enums.SeverityLevel.valueOf(severityLevel.name());
List<ContentValidationResult> validationResults = contentValidatorService.validate(validationObjective,
referenceFileName, ccdaFile, curesUpdate, userSeverityLevelForContentValidation);
referenceFileName, ccdaFile, curesUpdate, svap2022, userSeverityLevelForContentValidation);
ArrayList<RefCCDAValidationResult> results = new ArrayList<>();
for (ContentValidationResult result : validationResults) {
results.add(createValidationResult(result));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
Expand Down Expand Up @@ -61,7 +62,7 @@
@RequestScope
@Component
public class ReferenceCCDAValidator extends BaseCCDAValidator implements CCDAValidator {
private static Logger logger = Logger.getLogger(ReferenceCCDAValidator.class);
private static Logger logger = LoggerFactory.getLogger(ReferenceCCDAValidator.class);

private static final String IG_ISSUE_ID = "a.consol", MU_ISSUE_ID = "a.mu2con", DS4P_ISSUE_ID = "ds4p";
private static final boolean CAPTURE_VALIDATION_STATISTICS = true;
Expand Down
Loading

0 comments on commit d4a1bd7

Please sign in to comment.