Merge pull request #1443 from hapifhir/do-20230921-shc-validation-service
SHC Validation
This commit is contained in:
commit
7698ee4b7f
|
@ -50,9 +50,9 @@ public class FmlParser extends ParserBase {
|
|||
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||
String text = TextFile.streamToString(stream);
|
||||
List<ValidatedFragment> result = new ArrayList<>();
|
||||
ValidatedFragment ctxt = new ValidatedFragment("focus", "fml", content);
|
||||
ctxt.setElement(parse(ctxt.getErrors(), text));
|
||||
result.add(ctxt);
|
||||
ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "fml", content, false);
|
||||
focusFragment.setElement(parse(focusFragment.getErrors(), text));
|
||||
result.add(focusFragment);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ public class JsonParser extends ParserBase {
|
|||
public List<ValidatedFragment> parse(InputStream inStream) throws IOException, FHIRException {
|
||||
// long start = System.currentTimeMillis();
|
||||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
ValidatedFragment ctxt = new ValidatedFragment("focus", "json", content);
|
||||
ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "json", content, false);
|
||||
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||
|
||||
|
@ -135,17 +135,17 @@ public class JsonParser extends ParserBase {
|
|||
try {
|
||||
obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true);
|
||||
} catch (Exception e) {
|
||||
logError(ctxt.getErrors(), ValidationMessage.NO_RULE_DATE, -1, -1,context.formatMessage(I18nConstants.DOCUMENT), IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_, e.getMessage()), IssueSeverity.FATAL);
|
||||
logError(focusFragment.getErrors(), ValidationMessage.NO_RULE_DATE, -1, -1,context.formatMessage(I18nConstants.DOCUMENT), IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_, e.getMessage()), IssueSeverity.FATAL);
|
||||
}
|
||||
} else {
|
||||
obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true);
|
||||
}
|
||||
|
||||
if (obj != null) {
|
||||
ctxt.setElement(parse(ctxt.getErrors(), obj));
|
||||
focusFragment.setElement(parse(focusFragment.getErrors(), obj));
|
||||
}
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
res.add(ctxt);
|
||||
res.add(focusFragment);
|
||||
|
||||
// long t =System.currentTimeMillis()-start;
|
||||
// System.out.println("json parser: "+(t)+"ms, "+(content.length/1024)+"kb "+(t == 0 ? "" : " @ "+(content.length / t)+"kb/s"));
|
||||
|
|
|
@ -83,7 +83,7 @@ public class SHCParser extends ParserBase {
|
|||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
ValidatedFragment shc = new ValidatedFragment("shc", "txt", content);
|
||||
ValidatedFragment shc = new ValidatedFragment("shc", "txt", content, false);
|
||||
res.add(shc);
|
||||
|
||||
String src = TextFile.streamToString(stream).trim();
|
||||
|
@ -121,7 +121,7 @@ public class SHCParser extends ParserBase {
|
|||
return res;
|
||||
}
|
||||
|
||||
ValidatedFragment bnd = new ValidatedFragment("payload", "json", jwt.payloadSrc);
|
||||
ValidatedFragment bnd = new ValidatedFragment("payload", "json", jwt.payloadSrc, true);
|
||||
res.add(bnd);
|
||||
checkNamedProperties(shc.getErrors(), jwt.getPayload(), prefix+"payload", "iss", "nbf", "vc");
|
||||
checkProperty(shc.getErrors(), jwt.getPayload(), prefix+"payload", "iss", true, "String");
|
||||
|
|
|
@ -280,7 +280,7 @@ public class SHLParser extends ParserBase {
|
|||
}
|
||||
|
||||
private ValidatedFragment addNamedElement(List<ValidatedFragment> res, String name, String type, byte[] content) {
|
||||
ValidatedFragment result = new ValidatedFragment(name, type, content);
|
||||
ValidatedFragment result = new ValidatedFragment(name, type, content, true);
|
||||
res.add(result);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ public class TurtleParser extends ParserBase {
|
|||
@Override
|
||||
public List<ValidatedFragment> parse(InputStream inStream) throws IOException, FHIRException {
|
||||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
ValidatedFragment ctxt = new ValidatedFragment("focus", "ttl", content);
|
||||
ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "ttl", content, false);
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||
|
||||
Turtle src = new Turtle();
|
||||
|
@ -91,16 +91,16 @@ public class TurtleParser extends ParserBase {
|
|||
try {
|
||||
src.parse(TextFile.streamToString(stream));
|
||||
} catch (Exception e) {
|
||||
logError(ctxt.getErrors(), ValidationMessage.NO_RULE_DATE, -1, -1, "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_TURTLE_, e.getMessage()), IssueSeverity.FATAL);
|
||||
logError(focusFragment.getErrors(), ValidationMessage.NO_RULE_DATE, -1, -1, "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_TURTLE_, e.getMessage()), IssueSeverity.FATAL);
|
||||
return null;
|
||||
}
|
||||
ctxt.setElement(parse(ctxt.getErrors(), src));
|
||||
focusFragment.setElement(parse(focusFragment.getErrors(), src));
|
||||
} else {
|
||||
src.parse(TextFile.streamToString(stream));
|
||||
ctxt.setElement(parse(ctxt.getErrors(), src));
|
||||
focusFragment.setElement(parse(focusFragment.getErrors(), src));
|
||||
}
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
res.add(ctxt);
|
||||
res.add(focusFragment);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,63 +3,55 @@ package org.hl7.fhir.r5.elementmodel;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
|
||||
public class ValidatedFragment {
|
||||
|
||||
@Getter
|
||||
private String name;
|
||||
|
||||
@Getter @Setter
|
||||
private String elementPath;
|
||||
|
||||
@Getter
|
||||
private String extension;
|
||||
|
||||
@Getter @Setter
|
||||
private Element element;
|
||||
|
||||
@Getter @Setter
|
||||
private byte[] content;
|
||||
|
||||
@Getter
|
||||
private final boolean isDerivedContent;
|
||||
public final static String FOCUS_NAME = "focus";
|
||||
|
||||
@Getter
|
||||
private List<ValidationMessage> errors = new ArrayList<>();
|
||||
|
||||
public ValidatedFragment(String name, String extension, Element element, byte[] content) {
|
||||
|
||||
public ValidatedFragment(String name, String extension, Element element, byte[] content, boolean isDerivedContent) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.element = element;
|
||||
this.content = content;
|
||||
this.extension = extension;
|
||||
this.isDerivedContent = isDerivedContent;
|
||||
}
|
||||
|
||||
public ValidatedFragment(String name, String extension, byte[] content) {
|
||||
public ValidatedFragment(String name, String extension, byte[] content, boolean isDerivedContent) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
this.extension = extension;
|
||||
this.isDerivedContent = isDerivedContent;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Element getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public List<ValidationMessage> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
public void setElement(Element element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return name+"."+extension;
|
||||
}
|
||||
|
||||
public String getElementPath() {
|
||||
return elementPath;
|
||||
}
|
||||
|
||||
public void setElementPath(String elementPath) {
|
||||
this.elementPath = elementPath;
|
||||
}
|
||||
|
||||
public String path() {
|
||||
return elementPath == null ? name : elementPath;
|
||||
}
|
||||
|
|
|
@ -465,7 +465,7 @@ public class VerticalBarParser extends ParserBase {
|
|||
while (!reader.isFinished()) // && (getOptions().getSegmentLimit() == 0 || getOptions().getSegmentLimit() > message.getSegments().size()))
|
||||
readSegment(message, reader);
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
res.add(new ValidatedFragment("focus", "hl7", message, content));
|
||||
res.add(new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "hl7", message, content, false));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ public class XmlParser extends ParserBase {
|
|||
public List<ValidatedFragment> parse(InputStream inStream) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||
|
||||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
ValidatedFragment context = new ValidatedFragment("focus", "xml", content);
|
||||
ValidatedFragment focusFragment = new ValidatedFragment(ValidatedFragment.FOCUS_NAME, "xml", content, false);
|
||||
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||
Document doc = null;
|
||||
|
@ -137,7 +137,7 @@ public class XmlParser extends ParserBase {
|
|||
// if we can, we'll inspect the header/encoding ourselves
|
||||
|
||||
stream.mark(1024);
|
||||
version = checkHeader(context.getErrors(), stream);
|
||||
version = checkHeader(focusFragment.getErrors(), stream);
|
||||
stream.reset();
|
||||
|
||||
// use a slower parser that keeps location data
|
||||
|
@ -171,17 +171,17 @@ public class XmlParser extends ParserBase {
|
|||
if (e.getMessage().contains("lineNumber:") && e.getMessage().contains("columnNumber:")) {
|
||||
int line = Utilities.parseInt(extractVal(e.getMessage(), "lineNumber"), 0);
|
||||
int col = Utilities.parseInt(extractVal(e.getMessage(), "columnNumber"), 0);
|
||||
logError(context.getErrors(), ValidationMessage.NO_RULE_DATE, line, col, "(xml)", IssueType.INVALID, e.getMessage().substring(e.getMessage().lastIndexOf(";")+1).trim(), IssueSeverity.FATAL);
|
||||
logError(focusFragment.getErrors(), ValidationMessage.NO_RULE_DATE, line, col, "(xml)", IssueType.INVALID, e.getMessage().substring(e.getMessage().lastIndexOf(";")+1).trim(), IssueSeverity.FATAL);
|
||||
} else {
|
||||
logError(context.getErrors(), ValidationMessage.NO_RULE_DATE, 0, 0, "(xml)", IssueType.INVALID, e.getMessage(), IssueSeverity.FATAL);
|
||||
logError(focusFragment.getErrors(), ValidationMessage.NO_RULE_DATE, 0, 0, "(xml)", IssueType.INVALID, e.getMessage(), IssueSeverity.FATAL);
|
||||
}
|
||||
doc = null;
|
||||
}
|
||||
if (doc != null) {
|
||||
context.setElement(parse(context.getErrors(), doc));
|
||||
focusFragment.setElement(parse(focusFragment.getErrors(), doc));
|
||||
}
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
res.add(context);
|
||||
res.add(focusFragment);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,12 +32,8 @@ import org.hl7.fhir.r5.context.IWorkerContext;
|
|||
import org.hl7.fhir.r5.context.IWorkerContextManager;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
import org.hl7.fhir.r5.context.SystemOutLoggingService;
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
import org.hl7.fhir.r5.elementmodel.*;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||
import org.hl7.fhir.r5.elementmodel.ObjectConverter;
|
||||
import org.hl7.fhir.r5.elementmodel.ParserBase;
|
||||
import org.hl7.fhir.r5.elementmodel.SHCParser;
|
||||
import org.hl7.fhir.r5.formats.FormatUtilities;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
|
@ -635,6 +631,13 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
return results.getEntryFirstRep().getResource();
|
||||
}
|
||||
|
||||
|
||||
public List<ValidatedFragment> validateAsFragments(byte[] source, FhirFormat cntType, List<String> profiles, List<ValidationMessage> messages) throws FHIRException, IOException, EOperationOutcome {
|
||||
InstanceValidator validator = getValidator(cntType);
|
||||
validator.validate(null, messages, new ByteArrayInputStream(source), cntType, asSdList(profiles));
|
||||
return validator.validatedContent;
|
||||
}
|
||||
|
||||
public OperationOutcome validate(byte[] source, FhirFormat cntType, List<String> profiles, List<ValidationMessage> messages) throws FHIRException, IOException, EOperationOutcome {
|
||||
InstanceValidator validator = getValidator(cntType);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.hl7.fhir.r5.elementmodel.Element;
|
|||
import org.hl7.fhir.r5.elementmodel.LanguageUtils;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||
import org.hl7.fhir.r5.elementmodel.ValidatedFragment;
|
||||
import org.hl7.fhir.r5.formats.IParser;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
|
@ -61,10 +62,7 @@ import org.hl7.fhir.utilities.i18n.XLIFFProducer;
|
|||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
import org.hl7.fhir.validation.IgLoader;
|
||||
import org.hl7.fhir.validation.ValidationEngine;
|
||||
import org.hl7.fhir.validation.ValidationRecord;
|
||||
import org.hl7.fhir.validation.ValidatorUtils;
|
||||
import org.hl7.fhir.validation.*;
|
||||
import org.hl7.fhir.validation.ValidatorUtils.SourceFile;
|
||||
import org.hl7.fhir.validation.cli.model.CliContext;
|
||||
import org.hl7.fhir.validation.cli.model.FileInfo;
|
||||
|
@ -114,13 +112,43 @@ public class ValidationService {
|
|||
|
||||
ValidationResponse response = new ValidationResponse().setSessionId(sessionId);
|
||||
|
||||
for (FileInfo fp : request.getFilesToValidate()) {
|
||||
for (FileInfo fileToValidate : request.getFilesToValidate()) {
|
||||
if (fileToValidate.getFileType() == null) {
|
||||
Manager.FhirFormat format = ResourceChecker.checkIsResource(validator.getContext(),
|
||||
false,
|
||||
fileToValidate.getFileContent().getBytes(),
|
||||
fileToValidate.getFileName(),
|
||||
false);
|
||||
fileToValidate.setFileType(format.getExtension());
|
||||
}
|
||||
|
||||
List<ValidationMessage> messages = new ArrayList<>();
|
||||
validator.validate(fp.getFileContent().getBytes(), Manager.FhirFormat.getFhirFormat(fp.getFileType()),
|
||||
|
||||
List<ValidatedFragment> validatedFragments = validator.validateAsFragments(fileToValidate.getFileContent().getBytes(), Manager.FhirFormat.getFhirFormat(fileToValidate.getFileType()),
|
||||
request.getCliContext().getProfiles(), messages);
|
||||
ValidationOutcome outcome = new ValidationOutcome().setFileInfo(fp);
|
||||
messages.forEach(outcome::addMessage);
|
||||
response.addOutcome(outcome);
|
||||
|
||||
if (validatedFragments.size() == 1 && !validatedFragments.get(0).isDerivedContent()) {
|
||||
ValidatedFragment validatedFragment = validatedFragments.get(0);
|
||||
ValidationOutcome outcome = new ValidationOutcome();
|
||||
FileInfo fileInfo = new FileInfo(
|
||||
fileToValidate.getFileName(),
|
||||
new String(validatedFragment.getContent()),
|
||||
validatedFragment.getExtension());
|
||||
outcome.setMessages(validatedFragment.getErrors());
|
||||
outcome.setFileInfo(fileInfo);
|
||||
response.addOutcome(outcome);
|
||||
} else {
|
||||
for (ValidatedFragment validatedFragment : validatedFragments) {
|
||||
ValidationOutcome outcome = new ValidationOutcome();
|
||||
FileInfo fileInfo = new FileInfo(
|
||||
validatedFragment.getFilename(),
|
||||
new String(validatedFragment.getContent()),
|
||||
validatedFragment.getExtension());
|
||||
outcome.setMessages(validatedFragment.getErrors());
|
||||
outcome.setFileInfo(fileInfo);
|
||||
response.addOutcome(outcome);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println(" Max Memory: "+Runtime.getRuntime().maxMemory());
|
||||
return response;
|
||||
|
|
Loading…
Reference in New Issue