diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/api/Verification.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/api/Verification.java index 5229c0b0b375e16791e5524dd5c07d41ae721724..cd369a791e94b406b0fcbdd2fc2d5ee025f22393 100644 --- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/api/Verification.java +++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/api/Verification.java @@ -1,6 +1,7 @@ package de.unikoblenz.fgbks.api; import de.unikoblenz.fgbks.core.dmn.verification.DmnVerificationService; +import de.unikoblenz.fgbks.core.dmn.verification.metrics.DmnVerificationMetricsService; import de.unikoblenz.fgbks.core.dmn.verification.result.VerifierResultSet; import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.ClassificationType; import de.unikoblenz.fgbks.core.dmn.verification.verifier.types.VerificationType; @@ -22,6 +23,8 @@ import javax.ws.rs.core.Response; public class Verification { @Inject protected DmnVerificationService dmnVerificationService; + @Inject + protected DmnVerificationMetricsService dmnVerificationMetricsService; /** * Method to generate all verifications for a dmn with all registered verifiers. @@ -94,4 +97,16 @@ public class Verification { dmnVerificationService.generateFromClassification(classificationName, payload)) .build(); } + + /** + * Method to get all registered classification types. + * + * @return a list of {@link ClassificationType} as a JSON String. + */ + @GET + @Path("/metrics") + @Produces(MediaType.APPLICATION_JSON) + public Response metrics() { + return Response.accepted(dmnVerificationMetricsService.getMetrics()).build(); + } } diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/DmnVerificationMetricsService.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/DmnVerificationMetricsService.java deleted file mode 100644 index 03d76c5ca9f833440bb2b6b1230ef5d998392379..0000000000000000000000000000000000000000 --- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/DmnVerificationMetricsService.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.unikoblenz.fgbks.core.dmn.verification; - -import de.unikoblenz.fgbks.core.dmn.verification.metrics.Metric; -import de.unikoblenz.fgbks.core.dmn.verification.verifier.types.VerificationType; -import java.util.HashMap; -import javax.enterprise.context.ApplicationScoped; - -@ApplicationScoped -public class DmnVerificationMetricsService { - - private HashMap<VerificationType, Metric> metrics; - -} diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/DmnVerificationService.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/DmnVerificationService.java index 0d9ad88f06190b295e894ce2ba1687dd00ac7eca..af7c8b125596951dffcf09526d741b055fd8b8ff 100644 --- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/DmnVerificationService.java +++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/DmnVerificationService.java @@ -1,11 +1,13 @@ package de.unikoblenz.fgbks.core.dmn.verification; import de.unikoblenz.fgbks.core.dmn.utils.DmnService; +import de.unikoblenz.fgbks.core.dmn.verification.metrics.DmnVerificationMetricsService; import de.unikoblenz.fgbks.core.dmn.verification.result.VerifierResult; import de.unikoblenz.fgbks.core.dmn.verification.result.VerifierResultSet; import de.unikoblenz.fgbks.core.dmn.verification.result.VerifierResultSet.Builder; import de.unikoblenz.fgbks.core.dmn.verification.verifier.AbstractVerifier; import de.unikoblenz.fgbks.core.dmn.verification.verifier.DmnVerifier; +import de.unikoblenz.fgbks.core.dmn.verification.verifier.Verifier; import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.Classification; import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.ClassificationType; import de.unikoblenz.fgbks.core.dmn.verification.verifier.config.AbstractDmnVerifierConfig; @@ -57,6 +59,8 @@ public class DmnVerificationService { private List<ClassificationType> verificationClassificationTypes; @Inject protected DmnService dmnService; + @Inject + protected DmnVerificationMetricsService dmnVerificationMetricsService; protected DmnVerificationService() { super(); @@ -182,12 +186,13 @@ public class DmnVerificationService { List<Future<VerifierResult>> results = new ArrayList<>(verifierClasses.size()); + List<Verifier> executedVerifier = new ArrayList<>(); for (Class<?> verifierClass : verifierClasses) { AbstractVerifier av = null; try { av = (AbstractVerifier) verifierClass.newInstance(); } catch (InstantiationException | IllegalAccessException e) { - e.printStackTrace(); + LOGGER.error(e.getMessage()); } if (av != null && (typeName == null || av.getVerificationType().getName().getValue().equals(typeName)) @@ -197,6 +202,8 @@ public class DmnVerificationService { .getName() .getValue() .equals(classificationName))) { + // add verifier to list + executedVerifier.add(av); // Create Configuration AbstractDmnVerifierConfig verifierConfig = configs.get(av.getClass().getAnnotation(DmnVerifier.class).verifierConfig()); @@ -205,7 +212,7 @@ public class DmnVerificationService { results.add(av.withConfiguration(verifierConfig).verify(executor)); } } - + // add all verifier results to the result Builder results.forEach( r -> { try { @@ -215,6 +222,12 @@ public class DmnVerificationService { } }); + // add execution times to metric statistics + executedVerifier.forEach( + v -> + dmnVerificationMetricsService.addExecutionTime( + v.getVerificationType(), v.getExecutionTime())); + return resultBuilder.build(); } } diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/metrics/DmnVerificationMetricsService.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/metrics/DmnVerificationMetricsService.java new file mode 100644 index 0000000000000000000000000000000000000000..8f4e215fc46405b91286b9a8ea94428caef92553 --- /dev/null +++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/metrics/DmnVerificationMetricsService.java @@ -0,0 +1,39 @@ +package de.unikoblenz.fgbks.core.dmn.verification.metrics; + +import de.unikoblenz.fgbks.core.dmn.verification.verifier.types.VerificationType; +import javax.enterprise.context.ApplicationScoped; + +/** + * Service class for adding statistics of execution time of {@link VerificationType}s with the + * function {@link DmnVerificationMetricsService#addExecutionTime}. The statistic metrics can be + * accessed with {@link DmnVerificationMetricsService#getMetrics()} to get a {@link MetricSet} + * object. + */ +@ApplicationScoped +public class DmnVerificationMetricsService { + + MetricSet metricSet; + + protected DmnVerificationMetricsService() { + metricSet = new MetricSet(); + } + + /** + * Get the current {@link Metric}s in a {@link MetricSet}. + * + * @return the {@link MetricSet} + */ + public MetricSet getMetrics() { + return metricSet; + } + + /** + * Add a execution time tho the given {@link VerificationType}. + * + * @param type the {@link VerificationType} + * @param timeInNs the time in ns + */ + public void addExecutionTime(VerificationType type, long timeInNs) { + metricSet.addExecutionTime(type, timeInNs); + } +} diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/metrics/Metric.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/metrics/Metric.java index 1442a37e6975ef533d52ed922316be58afac098c..805537cc26c259bb70c48b0a2036a5ab029b0e33 100644 --- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/metrics/Metric.java +++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/metrics/Metric.java @@ -1,32 +1,101 @@ package de.unikoblenz.fgbks.core.dmn.verification.metrics; +import com.fasterxml.jackson.annotation.JsonProperty; import de.unikoblenz.fgbks.core.dmn.verification.verifier.types.VerificationType; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import java.util.Objects; -public class Metric { +/** + * A metric instance give statistics about the execution of one verifier {@link VerificationType}). + */ +public class Metric implements Serializable { + public static final long NANO_SECONDS_PER_SECOND = 1_000_000L; VerificationType type; - private List<Integer> executionTimes; + private List<Long> executionTimes; - public Metric() { + /** + * Create a new metric instance + */ + public Metric(VerificationType type) { + this.type = type; this.executionTimes = new ArrayList<>(); } + /** + * Get the number of total executions. + * + * @return the number of executions + */ + @JsonProperty("amountOfExecutions") public int getAmountOfExecutions() { return executionTimes.size(); } + /** + * Get the average execution time in ns. + * + * @return the average execution time + */ + @JsonProperty("averageExecutionTime") public double getAverageExecutionTime() { - return executionTimes.stream().mapToInt(Integer::intValue).average().orElseGet(() -> 0); + return executionTimes.stream().mapToLong(Long::longValue).average().orElseGet(() -> 0); } - public int getTotalExecutionTime() { - return executionTimes.stream().mapToInt(Integer::intValue).sum(); + /** + * Get the average execution time in ns. + * + * @return the average execution time + */ + @JsonProperty("averageExecutionTimeInMs") + public double getAverageExecutionTimeInMs() { + return executionTimes.stream().mapToLong(Long::longValue).average().orElseGet(() -> 0) + / NANO_SECONDS_PER_SECOND; + } + + /** + * Get the total execution time in ns. + */ + @JsonProperty("totalExecutionTime") + public long getTotalExecutionTime() { + return executionTimes.stream().mapToLong(Long::longValue).sum(); + } + + /** + * Get the total execution time in ms. + * + * @return + */ + @JsonProperty("totalExecutionTimeInMs") + public long getTotalExecutionTimeInMs() { + return executionTimes.stream().mapToLong(Long::longValue).sum() / NANO_SECONDS_PER_SECOND; + } + + /** + * Add a new execution time. + * + * @param timeInMs the time in ns + */ + void addExecutionTime(long timeInMs) { + executionTimes.add(timeInMs); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Metric metric = (Metric) o; + return type.equals(metric.type); } @Override - public String toString() { - return super.toString(); + public int hashCode() { + return Objects.hash(type); } } diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java index 62c8e1fb96a9e2e0cad24b26f8dc307e3665f127..f0e4aea9d3036e69a42a490f5e3f40824bd71ead 100644 --- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java +++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java @@ -83,14 +83,14 @@ public abstract class AbstractVerifier implements Verifier { watch.start(); doVerification(); watch.stop(); - executionTime = watch.getTime(); + executionTime = watch.getNanoTime(); LOGGER.info( "Verification " + getVerificationType().getName() + " finished. " + "Time Elapsed: " + executionTime - + " ms"); + + " nano seconds"); return resultBuilder.withExecutionTime(executionTime).build(); } diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/AbstractVerificationType.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/AbstractVerificationType.java index 3967dc3740ee4f5941f0527d9f90e2236b394462..f81cf28f833dadc2d664222a13e79ac3c136114e 100644 --- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/AbstractVerificationType.java +++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/AbstractVerificationType.java @@ -2,6 +2,7 @@ package de.unikoblenz.fgbks.core.dmn.verification.verifier.types; import de.unikoblenz.fgbks.base.domain.Description; import de.unikoblenz.fgbks.base.domain.Name; +import java.util.Objects; public abstract class AbstractVerificationType implements VerificationType { @@ -22,4 +23,21 @@ public abstract class AbstractVerificationType implements VerificationType { public Description getDescription() { return description; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AbstractVerificationType that = (AbstractVerificationType) o; + return name.equals(that.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } }