mirror of
https://github.com/itplr-kosit/validator.git
synced 2026-05-26 01:05:38 +00:00
Improve memory effeciency (#22)
#20 Use s9api only for internal processing; Improve memory effeciency
This commit is contained in:
parent
aacbce522b
commit
34d79d5e2c
26 changed files with 326 additions and 202 deletions
|
|
@ -19,24 +19,29 @@
|
|||
|
||||
package de.kosit.validationtool.cmd;
|
||||
|
||||
import de.kosit.validationtool.cmd.assertions.AssertionType;
|
||||
import de.kosit.validationtool.cmd.assertions.Assertions;
|
||||
import de.kosit.validationtool.impl.model.Result;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.saxon.s9api.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import de.kosit.validationtool.cmd.assertions.AssertionType;
|
||||
import de.kosit.validationtool.cmd.assertions.Assertions;
|
||||
import de.kosit.validationtool.impl.model.Result;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
|
||||
import net.sf.saxon.s9api.Processor;
|
||||
import net.sf.saxon.s9api.SaxonApiException;
|
||||
import net.sf.saxon.s9api.XPathCompiler;
|
||||
import net.sf.saxon.s9api.XPathSelector;
|
||||
import net.sf.saxon.s9api.XdmNode;
|
||||
|
||||
/**
|
||||
* Überprüft den Report mittels bereitgestellter Assertions. Diese {@link CheckAction} dient der Überprüfung der von der
|
||||
* KoSIT bereitgestellten Prüfszenarien und den darin enthaltenen Artefakten.
|
||||
|
|
@ -64,7 +69,7 @@ public class CheckAssertionAction implements CheckAction {
|
|||
final List<AssertionType> toCheck = findAssertions(results.getName());
|
||||
final List<String> errors = new ArrayList<>();
|
||||
if (toCheck != null && !toCheck.isEmpty()) {
|
||||
final XdmNode node = loadDocument(results.getReport());
|
||||
final XdmNode node = results.getReport();
|
||||
toCheck.forEach(a -> {
|
||||
if (!check(node, a)) {
|
||||
log.error("Assertion mismatch: {}", a.getValue());
|
||||
|
|
@ -86,15 +91,6 @@ public class CheckAssertionAction implements CheckAction {
|
|||
return getMapped().entrySet().stream().filter(e -> matches(e.getKey(), name)).map(Map.Entry::getValue).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
private XdmNode loadDocument(Document d) {
|
||||
DocumentBuilder documentBuilder = getProcessor().newDocumentBuilder();
|
||||
try {
|
||||
return documentBuilder.build(new DOMSource(d));
|
||||
} catch (SaxonApiException e) {
|
||||
log.error("Can not load result document. Therefore can not run defined assertions", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean check(XdmNode document, AssertionType assertion) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ public class CommandLineApplication {
|
|||
private static final Option CHECK_ASSERTIONS = Option.builder("c").longOpt("check-assertions").hasArg()
|
||||
.desc("Check the result using defined assertions").argName("assertions-file").build();
|
||||
|
||||
private static final Option PRINT_MEM_STATS = Option.builder("m").longOpt("memory-stats").desc("Prints some memory stats").build();
|
||||
|
||||
private CommandLineApplication() {
|
||||
// main class -> hide constructor
|
||||
}
|
||||
|
|
@ -151,6 +153,9 @@ public class CommandLineApplication {
|
|||
Assertions assertions = loadAssertions(cmd.getOptionValue(CHECK_ASSERTIONS.getOpt()));
|
||||
check.getCheckSteps().add(new CheckAssertionAction(assertions, ObjectFactory.createProcessor()));
|
||||
}
|
||||
if (cmd.hasOption(PRINT_MEM_STATS.getOpt())) {
|
||||
check.getCheckSteps().add(new PrintMemoryStats());
|
||||
}
|
||||
|
||||
log.info("Setup completed in {}ms\n", System.currentTimeMillis() - start);
|
||||
|
||||
|
|
@ -226,7 +231,7 @@ public class CommandLineApplication {
|
|||
try {
|
||||
return Files.list(d).filter(path -> path.toString().endsWith(".xml")).collect(Collectors.toList());
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("IOException while liste directory content. Can not determine test targets.", e);
|
||||
throw new IllegalStateException("IOException while list directory content. Can not determine test targets.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -293,6 +298,7 @@ public class CommandLineApplication {
|
|||
options.addOption(EXTRACT_HTML);
|
||||
options.addOption(DEBUG);
|
||||
options.addOption(CHECK_ASSERTIONS);
|
||||
options.addOption(PRINT_MEM_STATS);
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,15 +23,19 @@ import java.nio.file.Path;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import de.kosit.validationtool.impl.ContentRepository;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
|
||||
import net.sf.saxon.s9api.*;
|
||||
import net.sf.saxon.s9api.QName;
|
||||
import net.sf.saxon.s9api.SaxonApiException;
|
||||
import net.sf.saxon.s9api.Serializer;
|
||||
import net.sf.saxon.s9api.XPathExecutable;
|
||||
import net.sf.saxon.s9api.XPathSelector;
|
||||
import net.sf.saxon.s9api.XdmItem;
|
||||
import net.sf.saxon.s9api.XdmNode;
|
||||
|
||||
/**
|
||||
* Extrahiert HTML-Dokumente aus dem Report und persistiert diese im konfigurierten Ausgabe-Verzeichnis.
|
||||
|
|
@ -54,9 +58,7 @@ public class ExtractHtmlContentAction implements CheckAction {
|
|||
public void check(Bag results) {
|
||||
try {
|
||||
final XPathSelector selector = getSelector();
|
||||
DocumentBuilder documentBuilder = repository.getProcessor().newDocumentBuilder();
|
||||
|
||||
final XdmNode xdmSource = documentBuilder.build(new DOMSource(results.getReport()));
|
||||
final XdmNode xdmSource = results.getReport();
|
||||
selector.setContextItem(xdmSource);
|
||||
selector.forEach(m -> print(results.getName(), m));
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import de.kosit.validationtool.api.Input;
|
|||
import de.kosit.validationtool.impl.DefaultCheck;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
|
||||
import net.sf.saxon.s9api.XdmNode;
|
||||
|
||||
/**
|
||||
* Simple Erweiterung der Klasse {@link DefaultCheck} um das Ergebnis der Assertion-Prüfung auszwerten und auszugeben.
|
||||
* Diese Klasse stellt keine fachlicher Erweiterung des eigentlichen Prüfvorganges dar!
|
||||
|
|
@ -54,16 +56,17 @@ class InternalCheck extends DefaultCheck {
|
|||
* @param input die Prüflinge
|
||||
* @return false wenn es Assertion-Fehler gibt, sonst true
|
||||
*/
|
||||
void checkInput(Input input) {
|
||||
public XdmNode checkInput(Input input) {
|
||||
CheckAction.Bag bag = new CheckAction.Bag(input, createReport());
|
||||
runCheckInternal(bag);
|
||||
XdmNode result = runCheckInternal(bag);
|
||||
if (bag.getAssertionResult() != null) {
|
||||
checkAssertions += bag.getAssertionResult().getObject();
|
||||
failedAssertions += bag.getAssertionResult().getErrors().size();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean printAndEvaluate() {
|
||||
boolean printAndEvaluate() {
|
||||
if (failedAssertions > 0) {
|
||||
log.error("Assertion check failed.\n\nAssertions run: {}, Assertions failed: {}\n", checkAssertions, failedAssertions);
|
||||
} else if (checkAssertions > 0) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Licensed to the Koordinierungsstelle für IT-Standards (KoSIT) under
|
||||
* one or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. KoSIT licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package de.kosit.validationtool.cmd;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
*
|
||||
* Prints some memory usage information for debugging purposes.
|
||||
*
|
||||
* @author Andreas Penski
|
||||
*/
|
||||
@Slf4j
|
||||
public class PrintMemoryStats implements de.kosit.validationtool.impl.tasks.CheckAction {
|
||||
|
||||
private static final int BYTES_PER_K = 1024;
|
||||
|
||||
@Override
|
||||
public void check(final Bag results) {
|
||||
final Runtime runtime = Runtime.getRuntime();
|
||||
long maxMemory = runtime.maxMemory();
|
||||
long allocatedMemory = runtime.totalMemory();
|
||||
long freeMemory = runtime.freeMemory();
|
||||
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
final String freeStr = format.format(freeMemory / BYTES_PER_K);
|
||||
final String allocStr = format.format(allocatedMemory / BYTES_PER_K);
|
||||
final String maxStr = format.format(maxMemory / BYTES_PER_K);
|
||||
final String totalFreeStr = format.format((freeMemory + (maxMemory - allocatedMemory)) / BYTES_PER_K);
|
||||
log.info("free memory: {}MB; allocated memory: {}MB", freeStr, allocStr);
|
||||
log.info("max memory: {}MB; total free memory: {}MB", maxStr, totalFreeStr);
|
||||
}
|
||||
}
|
||||
|
|
@ -21,18 +21,14 @@ package de.kosit.validationtool.cmd;
|
|||
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import de.kosit.validationtool.impl.ObjectFactory;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
|
||||
import net.sf.saxon.s9api.SaxonApiException;
|
||||
import net.sf.saxon.s9api.Serializer;
|
||||
|
||||
/**
|
||||
* Gibt das Ergebnis-Document auf std-out aus.
|
||||
*
|
||||
|
|
@ -44,13 +40,11 @@ public class PrintReportAction implements CheckAction {
|
|||
@Override
|
||||
public void check(Bag results) {
|
||||
try {
|
||||
Transformer transformer = ObjectFactory.createTransformer(true);
|
||||
final StringWriter writer = new StringWriter();
|
||||
Result output = new StreamResult(writer);
|
||||
Source input = new DOMSource(results.getReport());
|
||||
transformer.transform(input, output);
|
||||
final Serializer serializer = ObjectFactory.createProcessor().newSerializer(writer);
|
||||
serializer.serializeNode(results.getReport());
|
||||
System.out.print(writer.toString());
|
||||
} catch (TransformerException e) {
|
||||
} catch (SaxonApiException e) {
|
||||
log.error("Error while printing result to stdout", e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,18 +19,16 @@
|
|||
|
||||
package de.kosit.validationtool.cmd;
|
||||
|
||||
import de.kosit.validationtool.impl.ObjectFactory;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.xml.transform.Result;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.nio.file.Path;
|
||||
import de.kosit.validationtool.impl.ObjectFactory;
|
||||
import de.kosit.validationtool.impl.tasks.CheckAction;
|
||||
|
||||
import net.sf.saxon.s9api.SaxonApiException;
|
||||
import net.sf.saxon.s9api.Serializer;
|
||||
|
||||
/**
|
||||
* Schreibt das Prüfergebnis als XML-Dokument an eine definierte Stelle.
|
||||
|
|
@ -48,11 +46,9 @@ public class SerializeReportAction implements CheckAction {
|
|||
final Path file = outputDirectory.resolve(results.getName() + "-report.xml");
|
||||
try {
|
||||
log.info("Serializing result to {}", file.toAbsolutePath());
|
||||
Transformer transformer = ObjectFactory.createTransformer(true);
|
||||
Result output = new StreamResult(file.toFile());
|
||||
Source input = new DOMSource(results.getReport());
|
||||
transformer.transform(input, output);
|
||||
} catch (TransformerException e) {
|
||||
final Serializer serializer = ObjectFactory.createProcessor().newSerializer(file.toFile());
|
||||
serializer.serializeNode(results.getReport());
|
||||
} catch (SaxonApiException e) {
|
||||
log.error("Can not serialize result report to {}", file.toAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue