diff --git a/src/main/java/kieker/analysis/stage/graphoutput/DotGraphWriter.java b/src/main/java/kieker/analysis/stage/graphoutput/DotGraphWriter.java index a12c98342c5ce63e9a5df2fe57baca219fc15994..118c137fa0cf589382257cc54541cb813abebbb9 100644 --- a/src/main/java/kieker/analysis/stage/graphoutput/DotGraphWriter.java +++ b/src/main/java/kieker/analysis/stage/graphoutput/DotGraphWriter.java @@ -12,11 +12,12 @@ import com.tinkerpop.blueprints.Edge; import com.tinkerpop.blueprints.Graph; import com.tinkerpop.blueprints.Vertex; +import kieker.analysis.trace.traversal.NamedGraph; import kieker.tools.traceAnalysis.filter.visualization.util.dot.DotFactory; import teetime.framework.AbstractConsumerStage; -public class DotGraphWriter extends AbstractConsumerStage<Graph> { +public class DotGraphWriter extends AbstractConsumerStage<NamedGraph> { private final String outputDir; @@ -25,8 +26,8 @@ public class DotGraphWriter extends AbstractConsumerStage<Graph> { } @Override - protected void execute(final Graph graph) { - String dotGraph = createDotGraph(graph); + protected void execute(final NamedGraph graph) { + String dotGraph = createDotGraph(graph.getGraph()); try { writeDotGraphFile(dotGraph); diff --git a/src/main/java/kieker/analysis/stage/graphoutput/GraphBuilder.java b/src/main/java/kieker/analysis/stage/graphoutput/GraphBuilder.java index dac7685dc5bca8f1b84846197d1ed3dd61ecf084..ebe75b99b374177169c54fbb63385f9f822dbf74 100644 --- a/src/main/java/kieker/analysis/stage/graphoutput/GraphBuilder.java +++ b/src/main/java/kieker/analysis/stage/graphoutput/GraphBuilder.java @@ -4,22 +4,24 @@ import com.tinkerpop.blueprints.Graph; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.impls.tg.TinkerGraph; +import kieker.analysis.trace.traversal.NamedGraph; import kieker.analysis.traceanalysisdomain.AbstractOperationCall; import kieker.analysis.traceanalysisdomain.AbstractTrace; import teetime.stage.basic.AbstractTransformation; //TODO: really necessary to have 2 type parameters? -public class GraphBuilder<T extends AbstractTrace<C>, C extends AbstractOperationCall<C>> extends AbstractTransformation<T, Graph> { +public class GraphBuilder<T extends AbstractTrace<C>, C extends AbstractOperationCall<C>> extends AbstractTransformation<T, NamedGraph> { @Override protected void execute(final T trace) { Graph graph = new TinkerGraph(); + String graphName = String.valueOf(trace.getRootOperationCall().hashCode()); transformOperationCallsRecurive(graph, trace.getRootOperationCall(), null); - this.getOutputPort().send(graph); + this.getOutputPort().send(new NamedGraph(graphName, graphName, graph)); } private void transformOperationCallsRecurive(final Graph graph, final C operationCall, final Vertex parentVertex) { diff --git a/src/main/java/kieker/analysis/stage/graphoutput/GraphMLWriter.java b/src/main/java/kieker/analysis/stage/graphoutput/GraphMLWriter.java index cf286f7ffe1e2a48eeac7d2293424d71cf449197..09f1cfb52ae72b025ae3ff1a16ae7f668de1d7fd 100644 --- a/src/main/java/kieker/analysis/stage/graphoutput/GraphMLWriter.java +++ b/src/main/java/kieker/analysis/stage/graphoutput/GraphMLWriter.java @@ -2,11 +2,11 @@ package kieker.analysis.stage.graphoutput; import java.io.IOException; -import com.tinkerpop.blueprints.Graph; +import kieker.analysis.trace.traversal.NamedGraph; import teetime.framework.AbstractConsumerStage; -public class GraphMLWriter extends AbstractConsumerStage<Graph> { +public class GraphMLWriter extends AbstractConsumerStage<NamedGraph> { private final String outputDir; @@ -15,18 +15,17 @@ public class GraphMLWriter extends AbstractConsumerStage<Graph> { } @Override - protected void execute(final Graph graph) { + protected void execute(final NamedGraph graph) { String outputFile = outputDir + "/traces.xml"; - com.tinkerpop.blueprints.util.io.graphml.GraphMLWriter writer = new com.tinkerpop.blueprints.util.io.graphml.GraphMLWriter(graph); + com.tinkerpop.blueprints.util.io.graphml.GraphMLWriter writer = new com.tinkerpop.blueprints.util.io.graphml.GraphMLWriter(graph.getGraph()); writer.setNormalize(true); try { writer.outputGraph(outputFile); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + throw new IllegalStateException(e); } } diff --git a/src/main/java/kieker/analysis/stage/tracediagnosis/TraceAggregationComposite.java b/src/main/java/kieker/analysis/stage/tracediagnosis/TraceAggregationComposite.java index c8f354799d20b942ebefc5af92336bdf1b7892e3..df478bec689e540671497a8fc80934fd5596b6b5 100644 --- a/src/main/java/kieker/analysis/stage/tracediagnosis/TraceAggregationComposite.java +++ b/src/main/java/kieker/analysis/stage/tracediagnosis/TraceAggregationComposite.java @@ -18,12 +18,10 @@ package kieker.analysis.stage.tracediagnosis; import java.util.List; -import com.tinkerpop.blueprints.Graph; - import kieker.analysis.stage.graphoutput.DotGraphWriter; -import kieker.analysis.stage.graphoutput.GraphBuilder; import kieker.analysis.stage.graphoutput.GraphMLWriter; -import kieker.analysis.traceanalysisdomain.AggregatedOperationCall; +import kieker.analysis.trace.traversal.AggrTraceTraverserStage; +import kieker.analysis.trace.traversal.NamedGraph; import kieker.analysis.traceanalysisdomain.AggregatedTrace; import kieker.analysis.traceanalysisdomain.Trace; @@ -57,17 +55,15 @@ public final class TraceAggregationComposite extends AbstractCompositeStage { String graphFilesOutputDir = "example/event monitoring log/output"; // TODO Temp hard coded final Distributor<AggregatedTrace> distributor = new Distributor<>(new CopyByReferenceStrategy()); - // DotGraphWriterOld<AggregatedTrace, AggregatedOperationCall> callDotGraphWriter = new DotGraphWriterOld<>(); TODO Remove - GraphBuilder<AggregatedTrace, AggregatedOperationCall> aggregatedTraceGraphBuilder = new GraphBuilder<>(); - final Distributor<Graph> graphDistributor = new Distributor<>(new CopyByReferenceStrategy()); + AggrTraceTraverserStage aggrTraceTraverser = new AggrTraceTraverserStage(); + final Distributor<NamedGraph> graphDistributor = new Distributor<>(new CopyByReferenceStrategy()); GraphMLWriter graphMLWriter = new GraphMLWriter(graphFilesOutputDir); DotGraphWriter dotGraphWriter = new DotGraphWriter(graphFilesOutputDir); super.connectPorts(this.statisticsDecorator.getOutputPort(), distributor.getInputPort()); super.connectPorts(distributor.getNewOutputPort(), this.tracesCollector.getInputPort()); - // super.connectPorts(distributor.getNewOutputPort(), callDotGraphWriter.getInputPort()); TODO Remove - super.connectPorts(distributor.getNewOutputPort(), aggregatedTraceGraphBuilder.getInputPort()); - super.connectPorts(aggregatedTraceGraphBuilder.getOutputPort(), graphDistributor.getInputPort()); + super.connectPorts(distributor.getNewOutputPort(), aggrTraceTraverser.getInputPort()); + super.connectPorts(aggrTraceTraverser.getOutputPort(), graphDistributor.getInputPort()); super.connectPorts(graphDistributor.getNewOutputPort(), graphMLWriter.getInputPort()); super.connectPorts(graphDistributor.getNewOutputPort(), dotGraphWriter.getInputPort()); diff --git a/src/main/java/kieker/analysis/trace/traversal/AggrTrace2Blueprint.java b/src/main/java/kieker/analysis/trace/traversal/AggrTrace2Blueprint.java new file mode 100644 index 0000000000000000000000000000000000000000..c7a4306a14133be868a7ce535e02487ffa167c92 --- /dev/null +++ b/src/main/java/kieker/analysis/trace/traversal/AggrTrace2Blueprint.java @@ -0,0 +1,41 @@ +package kieker.analysis.trace.traversal; + +import com.tinkerpop.blueprints.Graph; +import com.tinkerpop.blueprints.Vertex; +import com.tinkerpop.blueprints.impls.tg.TinkerGraph; + +import kieker.analysis.traceanalysisdomain.AggregatedOperationCall; + +public class AggrTrace2Blueprint extends OperationCallVisitor<AggregatedOperationCall> { + + private final Graph graph; + + public AggrTrace2Blueprint() { + super(); + this.graph = new TinkerGraph(); + } + + @Override + public void visit(final AggregatedOperationCall operationCall) { + + Vertex vertex = graph.addVertex(operationCall.hashCode()); + + vertex.setProperty("label", operationCall.getOperation()); + // TODO maybe more properties? + + AggregatedOperationCall parentCall = operationCall.getParent(); + + if (parentCall != null) { + Vertex parentVertex = graph.getVertex(operationCall.getParent().hashCode()); + if (parentVertex != null) { + graph.addEdge(null, parentVertex, vertex, ""); + } + } + + } + + public Graph getGraph() { + return graph; + } + +} diff --git a/src/main/java/kieker/analysis/trace/traversal/AggrTraceTraverserStage.java b/src/main/java/kieker/analysis/trace/traversal/AggrTraceTraverserStage.java new file mode 100644 index 0000000000000000000000000000000000000000..61247db17cdd7ddd2e931eb723fa4f15ed43f93b --- /dev/null +++ b/src/main/java/kieker/analysis/trace/traversal/AggrTraceTraverserStage.java @@ -0,0 +1,26 @@ +package kieker.analysis.trace.traversal; + +import kieker.analysis.traceanalysisdomain.AggregatedOperationCall; +import kieker.analysis.traceanalysisdomain.AggregatedTrace; + +import teetime.stage.basic.AbstractTransformation; + +public class AggrTraceTraverserStage extends AbstractTransformation<AggregatedTrace, NamedGraph> { + + @Override + protected void execute(final AggregatedTrace trace) { + + AggrTrace2Blueprint aggrTrace2Blueprint = new AggrTrace2Blueprint(); + + TraceTraverser<AggregatedTrace, AggregatedOperationCall> traverser = new TraceTraverser<>(aggrTrace2Blueprint); + + traverser.traverse(trace); + + String name = String.valueOf(trace.hashCode()); + + NamedGraph graph = new NamedGraph(name, name, aggrTrace2Blueprint.getGraph()); + + this.getOutputPort().send(graph); + } + +} diff --git a/src/main/java/kieker/analysis/trace/traversal/NamedGraph.java b/src/main/java/kieker/analysis/trace/traversal/NamedGraph.java new file mode 100644 index 0000000000000000000000000000000000000000..8337e119e4f1dfa937e019ee7daed5dd16d53e95 --- /dev/null +++ b/src/main/java/kieker/analysis/trace/traversal/NamedGraph.java @@ -0,0 +1,43 @@ +package kieker.analysis.trace.traversal; + +import com.tinkerpop.blueprints.Graph; + +public class NamedGraph { + + private String name; + + private String fileName; + + private Graph graph; + + public NamedGraph(final String name, final String fileName, final Graph graph) { + this.name = name; + this.fileName = fileName; + this.graph = graph; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(final String fileName) { + this.fileName = fileName; + } + + public Graph getGraph() { + return graph; + } + + public void setGraph(final Graph graph) { + this.graph = graph; + } + +} diff --git a/src/main/java/kieker/analysis/trace/traversal/OperationCallVisitor.java b/src/main/java/kieker/analysis/trace/traversal/OperationCallVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..50864506dbef67885bf4a2d20e14a4fff36f1f6c --- /dev/null +++ b/src/main/java/kieker/analysis/trace/traversal/OperationCallVisitor.java @@ -0,0 +1,9 @@ +package kieker.analysis.trace.traversal; + +import kieker.analysis.traceanalysisdomain.AbstractOperationCall; + +public abstract class OperationCallVisitor<C extends AbstractOperationCall<C>> { + + public abstract void visit(C operationCall); + +} diff --git a/src/main/java/kieker/analysis/trace/traversal/TraceToBlueprint.java b/src/main/java/kieker/analysis/trace/traversal/TraceToBlueprint.java new file mode 100644 index 0000000000000000000000000000000000000000..526e3b7e90c03fc3c983bf017fba8eb5d8d07dc8 --- /dev/null +++ b/src/main/java/kieker/analysis/trace/traversal/TraceToBlueprint.java @@ -0,0 +1,41 @@ +package kieker.analysis.trace.traversal; + +import com.tinkerpop.blueprints.Graph; +import com.tinkerpop.blueprints.Vertex; +import com.tinkerpop.blueprints.impls.tg.TinkerGraph; + +import kieker.analysis.traceanalysisdomain.OperationCall; + +public class TraceToBlueprint extends OperationCallVisitor<OperationCall> { + + private final Graph graph; + + public TraceToBlueprint() { + super(); + this.graph = new TinkerGraph(); + } + + @Override + public void visit(final OperationCall operationCall) { + + Vertex vertex = graph.addVertex(operationCall.hashCode()); + + vertex.setProperty("label", operationCall.getOperation()); + // TODO maybe more properties? + + OperationCall parentCall = operationCall.getParent(); + + if (parentCall != null) { + Vertex parentVertex = graph.getVertex(operationCall.getParent().hashCode()); + if (parentVertex != null) { + graph.addEdge(null, parentVertex, vertex, ""); + } + } + + } + + public Graph getGraph() { + return graph; + } + +} diff --git a/src/main/java/kieker/analysis/trace/traversal/TraceTraverser.java b/src/main/java/kieker/analysis/trace/traversal/TraceTraverser.java new file mode 100644 index 0000000000000000000000000000000000000000..989f5a744a2255418dbe93740b31c55012a161e0 --- /dev/null +++ b/src/main/java/kieker/analysis/trace/traversal/TraceTraverser.java @@ -0,0 +1,57 @@ +package kieker.analysis.trace.traversal; + +import java.util.ArrayList; +import java.util.List; + +import kieker.analysis.traceanalysisdomain.AbstractOperationCall; +import kieker.analysis.traceanalysisdomain.AbstractTrace; + +public class TraceTraverser<T extends AbstractTrace<C>, C extends AbstractOperationCall<C>> { + + private List<OperationCallVisitor<C>> visitors; + + public TraceTraverser() { + super(); + this.visitors = new ArrayList<>(); + } + + public TraceTraverser(final OperationCallVisitor<C> visitor) { + this(); + visitors.add(visitor); + } + + public TraceTraverser(final List<OperationCallVisitor<C>> visitors) { + super(); + this.visitors = visitors; + } + + public void traverse(final T trace) { + handleOperationCallsRecursively(trace.getRootOperationCall()); + } + + private void handleOperationCallsRecursively(final C operationCall) { + handleOperationCall(operationCall); + for (C childOperationCall : operationCall.getChildren()) { + handleOperationCallsRecursively(childOperationCall); + } + } + + private void handleOperationCall(final C operationCall) { + for (OperationCallVisitor<C> visitor : visitors) { + visitor.visit(operationCall); + } + } + + public List<OperationCallVisitor<C>> getVisitors() { + return visitors; + } + + public void setVisitors(final List<OperationCallVisitor<C>> visitors) { + this.visitors = visitors; + } + + public void addVisitor(final OperationCallVisitor<C> visitor) { + visitors.add(visitor); + } + +} diff --git a/src/main/java/kieker/analysis/trace/traversal/TraceTraverserStage.java b/src/main/java/kieker/analysis/trace/traversal/TraceTraverserStage.java new file mode 100644 index 0000000000000000000000000000000000000000..950a9a04782bfbaa05c2ea78df324909c266b96b --- /dev/null +++ b/src/main/java/kieker/analysis/trace/traversal/TraceTraverserStage.java @@ -0,0 +1,26 @@ +package kieker.analysis.trace.traversal; + +import kieker.analysis.traceanalysisdomain.OperationCall; +import kieker.analysis.traceanalysisdomain.Trace; + +import teetime.stage.basic.AbstractTransformation; + +public class TraceTraverserStage extends AbstractTransformation<Trace, NamedGraph> { + + @Override + protected void execute(final Trace trace) { + + TraceToBlueprint traceToBlueprint = new TraceToBlueprint(); + + TraceTraverser<Trace, OperationCall> traverser = new TraceTraverser<>(traceToBlueprint); + + traverser.traverse(trace); + + String name = String.valueOf(trace.hashCode()); + + NamedGraph graph = new NamedGraph(name, name, traceToBlueprint.getGraph()); + + this.getOutputPort().send(graph); + } + +}