diff --git a/.gitignore b/.gitignore index dab7b95353ecc3addd50c5a1e3c914cc637743ac..fa3c4b8ed98cc0b71fa4fd6355f9a88805c51450 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ **/build/** **/bin/** frameworks/log_* -results/ frameworks/Kieker/benchmark/ frameworks/Kieker/data/ frameworks/Kieker/MooBench.jar diff --git a/tools/compile-results/src/main/java/moobench/tools/results/LogWriter.java b/tools/compile-results/src/main/java/moobench/tools/results/LogWriter.java new file mode 100644 index 0000000000000000000000000000000000000000..cce1495031ebb4cf3d231afec6ee0367fa25de21 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/LogWriter.java @@ -0,0 +1,47 @@ +package moobench.tools.results; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import teetime.framework.AbstractConsumerStage; + +public class LogWriter extends AbstractConsumerStage<List<Map<String,JsonNode>>> { + + private Path logJson; + + public LogWriter(Path logJson) { + this.logJson = logJson; + } + + @Override + protected void execute(List<Map<String,JsonNode>> list) throws Exception { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode node = mapper.createObjectNode(); + ArrayNode arrayNode = node.putArray("results"); + + for(Map<String, JsonNode> map : list) { + ObjectNode objectNode = mapper.createObjectNode(); + for (Entry<String, JsonNode> entry : map.entrySet()) { + JsonNode value = entry.getValue(); + if (value.isDouble()) + objectNode.put(entry.getKey(), value.asDouble()); + else if (value.isInt()) + objectNode.put(entry.getKey(), value.asInt()); + else + this.logger.warn("property {} is of type {}", entry.getKey(), value.getNodeType().toString()); + } + arrayNode.add(objectNode); + } + + mapper.writeValue(Files.newBufferedWriter(logJson), node); + } + +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/MainLogReader.java b/tools/compile-results/src/main/java/moobench/tools/results/MainLogReader.java new file mode 100644 index 0000000000000000000000000000000000000000..f22e2aecebc783488b302b8290d9473edc689e0c --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/MainLogReader.java @@ -0,0 +1,86 @@ +/** + * + */ +package moobench.tools.results; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import teetime.framework.AbstractProducerStage; + +/** + * @author reiner + * + */ +public class MainLogReader extends AbstractProducerStage<List<Map<String,JsonNode>>> { + + private static final String RESULTS_LABEL = "results"; + + private final Path mainLogJson; + + public MainLogReader(Path mainLogJson) { + this.mainLogJson = mainLogJson; + } + + @Override + protected void execute() throws JsonProcessingException, IOException { + List<Map<String,JsonNode>> result = new ArrayList<Map<String,JsonNode>>(); + JsonNode node; + if (Files.exists(mainLogJson)) { + node = readJsonFile(); + } else { + node = readJsonString(); + } + + JsonNode resultsNode = node.get(RESULTS_LABEL); + if ((resultsNode instanceof ArrayNode)) { + ArrayNode arrayNode = (ArrayNode)resultsNode; + Iterator<JsonNode> iterator = arrayNode.elements(); + while (iterator.hasNext()) { + JsonNode element = iterator.next(); + if (element instanceof ObjectNode) { + ObjectNode objectNode = (ObjectNode)element; + + Iterator<Entry<String, JsonNode>> elementIterator = objectNode.fields(); + Map<String,JsonNode> row = new HashMap<>(); + while (elementIterator.hasNext()) { + Entry<String, JsonNode> parameter = elementIterator.next(); + row.put(parameter.getKey(), parameter.getValue()); + } + result.add(row); + } + } + } + + this.outputPort.send(result); + this.workCompleted(); + } + + + + private JsonNode readJsonString() throws JsonMappingException, JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + String value = "{ \"results\" : [] }"; + return mapper.readTree(value); + } + + private JsonNode readJsonFile() throws JsonProcessingException, IOException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readTree(Files.newInputStream(mainLogJson)); + } + +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/MakeWindowStage.java b/tools/compile-results/src/main/java/moobench/tools/results/MakeWindowStage.java new file mode 100644 index 0000000000000000000000000000000000000000..3f79088a75eeb9eca797b1862080150a2e828a70 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/MakeWindowStage.java @@ -0,0 +1,28 @@ +package moobench.tools.results; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.databind.JsonNode; + +import teetime.stage.basic.AbstractFilter; + +public class MakeWindowStage extends AbstractFilter<List<Map<String, JsonNode>>> { + + private Integer window; + + public MakeWindowStage(Integer window) { + this.window = window; + } + + @Override + protected void execute(List<Map<String, JsonNode>> list) throws Exception { + List<Map<String, JsonNode>> newList = new ArrayList<Map<String, JsonNode>>(); + for (int i=list.size()-window-1;i < list.size();i++) { + newList.add(list.get(i)); + } + this.outputPort.send(newList); + } + +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/MappingFileReader.java b/tools/compile-results/src/main/java/moobench/tools/results/MappingFileReader.java new file mode 100644 index 0000000000000000000000000000000000000000..30e3de105393d6f6a5f6403ca055c24f5baaa72a --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/MappingFileReader.java @@ -0,0 +1,20 @@ +package moobench.tools.results; + +import java.nio.file.Path; +import java.util.Map; + +import teetime.framework.AbstractProducerStage; + +public class MappingFileReader extends AbstractProducerStage<Map<String,String>> { + + public MappingFileReader(Path mappingFile) { + // TODO Auto-generated constructor stub + } + + @Override + protected void execute() throws Exception { + // TODO Auto-generated method stub + this.workCompleted(); + } + +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/MergeDataStage.java b/tools/compile-results/src/main/java/moobench/tools/results/MergeDataStage.java new file mode 100644 index 0000000000000000000000000000000000000000..85cd673c0cd9be0f43ca6b5596adf663eee10aa8 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/MergeDataStage.java @@ -0,0 +1,87 @@ +package moobench.tools.results; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import teetime.framework.AbstractStage; +import teetime.framework.InputPort; +import teetime.framework.OutputPort; + +public class MergeDataStage extends AbstractStage { + + private static final String BUILD_LABEL = "build"; + + private final InputPort<Map<String, String>> mappingInputPort = this.createInputPort(); + private final InputPort<List<Map<String, JsonNode>>> mainLogInputPort = this.createInputPort(); + private final InputPort<Map<String, JsonNode>> newDataInputPort = this.createInputPort(); + + private final OutputPort<List<Map<String, JsonNode>>> outputPort = this.createOutputPort(); + + private List<Map<String, JsonNode>> mainLog; + private List<Map<String, JsonNode>> bufferLog = new ArrayList<>(); + private Map<String, String> mapping; + + + @Override + protected void execute() throws Exception { + List<Map<String, JsonNode>> log = this.mainLogInputPort.receive(); + if (log != null) { + mainLog = log; + } + Map<String, String> newMapping = this.mappingInputPort.receive(); + if (newMapping != null) { + mapping = newMapping; + } + Map<String, JsonNode> newData = this.newDataInputPort.receive(); + if (newData != null) { + bufferLog.add(newData); + } + } + + @Override + protected void onTerminating() { + moveNewData(); + this.outputPort.send(mainLog); + super.onTerminating(); + } + + private void moveNewData() { + int last = mainLog.size()-1; + int build = mainLog.get(last).get(BUILD_LABEL).asInt() + 1; + + Map<String,JsonNode> node = new HashMap<>(); + node.put(BUILD_LABEL, new ObjectMapper().getNodeFactory().numberNode(build)); + + for (Map<String, JsonNode> data : bufferLog) { + for (Entry<String, JsonNode> entry : data.entrySet()) { + node.put(entry.getKey(), entry.getValue()); + } + } + bufferLog.clear(); + mainLog.add(node); + } + + + public InputPort<List<Map<String, JsonNode>>> getMainLogInputPort() { + return this.mainLogInputPort; + } + + public InputPort<Map<String,String>> getMappingInputPort() { + return this.mappingInputPort; + } + + public InputPort<Map<String,JsonNode>> getNewDataInputPort() { + return this.newDataInputPort ; + } + + public OutputPort<List<Map<String, JsonNode>>> getOutputPort() { + return this.outputPort; + } + +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/ReadCsvFileSource.java b/tools/compile-results/src/main/java/moobench/tools/results/ReadCsvFileSource.java new file mode 100644 index 0000000000000000000000000000000000000000..44376a1a0468531be74b493140261adcb63b51d4 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/ReadCsvFileSource.java @@ -0,0 +1,41 @@ +package moobench.tools.results; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.DoubleNode; + +import teetime.framework.AbstractConsumerStage; +import teetime.framework.OutputPort; + +public class ReadCsvFileSource extends AbstractConsumerStage<Path> { + + private final OutputPort<Map<String, JsonNode>> outputPort = this.createOutputPort(); + + @Override + protected void execute(Path path) throws Exception { + final CSVParser csvParser = new CSVParser(Files.newBufferedReader(path), + CSVFormat.DEFAULT.withHeader()); + List<String> header = csvParser.getHeaderNames(); + Map<String, JsonNode> recordMap = new HashMap<>(); + CSVRecord record = csvParser.getRecords().get(0); + for (int i=0;i<header.size();i++) { + String value = record.get(header.get(i)); + recordMap.put(header.get(i).trim(), new DoubleNode(Double.parseDouble(value))); + } + csvParser.close(); + this.outputPort.send(recordMap); + } + + public OutputPort<Map<String, JsonNode>> getOutputPort() { + return this.outputPort; + } +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/Settings.java b/tools/compile-results/src/main/java/moobench/tools/results/Settings.java new file mode 100644 index 0000000000000000000000000000000000000000..cc70b50120fdcf42c7fbc634100a9e9606ec83a4 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/Settings.java @@ -0,0 +1,46 @@ + +package moobench.tools.results; + +import java.nio.file.Path; +import java.util.List; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.converters.PathConverter; + +public class Settings { + + @Parameter(names= { "-l", "--main-log" }, required = true, converter = PathConverter.class, description = "Main log file") + private Path mainLogJson; + + @Parameter(names= { "-p", "--partial-log" }, required = true, converter = PathConverter.class, description = "Partial log file") + private Path partialLogJson; + + @Parameter(names= { "-d", "--result-data" }, variableArity = true, required = true, converter = PathConverter.class, description = "Collection of experiment data") + private List<Path> resultCsvPaths; + + @Parameter(names= { "-m", "--mapping-file" }, required = true, converter = PathConverter.class, description = "Experiment Result to log mapping") + private Path mappingFile; + + @Parameter(names= { "-w", "--window" }, required = true, description = "Time Window Size") + private Integer window; + + public Path getMainLogJson() { + return mainLogJson; + } + + public Path getPartialLogJson() { + return partialLogJson; + } + + public List<Path> getResultCsvPaths() { + return resultCsvPaths; + } + + public Path getMappingFile() { + return mappingFile; + } + + public Integer getWindow() { + return window; + } +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/SpecialArrayElementStage.java b/tools/compile-results/src/main/java/moobench/tools/results/SpecialArrayElementStage.java new file mode 100644 index 0000000000000000000000000000000000000000..0579d9997a48952474eacc23f8807150447364c2 --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/SpecialArrayElementStage.java @@ -0,0 +1,23 @@ +package moobench.tools.results; + +import java.nio.file.Path; +import java.util.List; + +import teetime.framework.AbstractProducerStage; + +public class SpecialArrayElementStage extends AbstractProducerStage<Path> { + + private List<Path> resultCsvPaths; + + public SpecialArrayElementStage(List<Path> resultCsvPaths) { + this.resultCsvPaths = resultCsvPaths; + } + + @Override + protected void execute() throws Exception { + for(Path path : resultCsvPaths) { + this.outputPort.send(path); + } + this.workCompleted(); + } +} diff --git a/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java b/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..123691eb2f33bce87a9f2b56c03f03932a372dfb --- /dev/null +++ b/tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java @@ -0,0 +1,40 @@ +package moobench.tools.results; + +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.databind.JsonNode; + +import teetime.framework.Configuration; +import teetime.stage.basic.distributor.Distributor; +import teetime.stage.basic.distributor.strategy.CopyByReferenceStrategy; + +public class TeetimeConfiguration extends Configuration { + + public TeetimeConfiguration(Settings settings) { + MainLogReader mainLogReader = new MainLogReader(settings.getMainLogJson()); + MappingFileReader mappingFileReader = new MappingFileReader(settings.getMappingFile()); + SpecialArrayElementStage arrayElementStage = new SpecialArrayElementStage(settings.getResultCsvPaths()); + ReadCsvFileSource readCsvFileSource = new ReadCsvFileSource(); + + MergeDataStage mergeDataStage = new MergeDataStage(); + mergeDataStage.declareActive(); + + Distributor<List<Map<String, JsonNode>>> distributor = new Distributor<>(new CopyByReferenceStrategy()); + + LogWriter mainLogWriter = new LogWriter(settings.getMainLogJson()); + MakeWindowStage makeWindowStage = new MakeWindowStage(settings.getWindow()); + LogWriter partialLogWriter = new LogWriter(settings.getPartialLogJson()); + + this.connectPorts(mainLogReader.getOutputPort(), mergeDataStage.getMainLogInputPort()); + this.connectPorts(mappingFileReader.getOutputPort(), mergeDataStage.getMappingInputPort()); + this.connectPorts(arrayElementStage.getOutputPort(), readCsvFileSource.getInputPort()); + this.connectPorts(readCsvFileSource.getOutputPort(), mergeDataStage.getNewDataInputPort()); + + this.connectPorts(mergeDataStage.getOutputPort(), distributor.getInputPort()); + + this.connectPorts(distributor.getNewOutputPort(), mainLogWriter.getInputPort()); + this.connectPorts(distributor.getNewOutputPort(), makeWindowStage.getInputPort()); + this.connectPorts(makeWindowStage.getOutputPort(), partialLogWriter.getInputPort()); + } +}