From 6d2634b7d1f493a0993c267c28aaa5bf3b405865 Mon Sep 17 00:00:00 2001
From: Reiner Jung <reiner.jung@email.uni-kiel.de>
Date: Wed, 27 Jul 2022 14:45:46 +0200
Subject: [PATCH] Added missing class file

---
 .gitignore                                    |  1 -
 .../moobench/tools/results/LogWriter.java     | 47 ++++++++++
 .../moobench/tools/results/MainLogReader.java | 86 ++++++++++++++++++
 .../tools/results/MakeWindowStage.java        | 28 ++++++
 .../tools/results/MappingFileReader.java      | 20 +++++
 .../tools/results/MergeDataStage.java         | 87 +++++++++++++++++++
 .../tools/results/ReadCsvFileSource.java      | 41 +++++++++
 .../java/moobench/tools/results/Settings.java | 46 ++++++++++
 .../results/SpecialArrayElementStage.java     | 23 +++++
 .../tools/results/TeetimeConfiguration.java   | 40 +++++++++
 10 files changed, 418 insertions(+), 1 deletion(-)
 create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/LogWriter.java
 create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/MainLogReader.java
 create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/MakeWindowStage.java
 create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/MappingFileReader.java
 create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/MergeDataStage.java
 create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/ReadCsvFileSource.java
 create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/Settings.java
 create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/SpecialArrayElementStage.java
 create mode 100644 tools/compile-results/src/main/java/moobench/tools/results/TeetimeConfiguration.java

diff --git a/.gitignore b/.gitignore
index dab7b95..fa3c4b8 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 0000000..cce1495
--- /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 0000000..f22e2ae
--- /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 0000000..3f79088
--- /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 0000000..30e3de1
--- /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 0000000..85cd673
--- /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 0000000..44376a1
--- /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 0000000..cc70b50
--- /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 0000000..0579d99
--- /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 0000000..123691e
--- /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());
+	}
+}
-- 
GitLab