Created
September 26, 2014 22:25
-
-
Save mdaniel/1290c66822f7279f7e40 to your computer and use it in GitHub Desktop.
StormTopology to graphviz dot format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.radius.kafkastorm; | |
import java.io.ByteArrayInputStream; | |
import java.io.IOException; | |
import java.io.ObjectInputStream; | |
import java.util.Map; | |
import backtype.storm.generated.Bolt; | |
import backtype.storm.generated.ComponentObject; | |
import backtype.storm.generated.GlobalStreamId; | |
import backtype.storm.generated.Grouping; | |
import backtype.storm.generated.SpoutSpec; | |
import backtype.storm.generated.StormTopology; | |
/** | |
* Returns a <tt>graphviz</tt> compatible string representing the provided | |
* {@linkplain backtype.storm.generated.StormTopology}. | |
* It is accurate as of | |
* <a href="https://github.com/apache/storm/tree/v0.9.2-incubating">0.9.2-incubating</a>. | |
* This is the transliteration of <a href="https://github.com/schleyfox/storm-test/blob/master/src/clj/storm/test/visualization.clj" | |
* >visualization.clj</a>. | |
*/ | |
public class Visualization | |
{ | |
public static final String[] COLORS = new String[] { | |
"red", "orange", "yellow", "green", "blue", "indigo", "violet" | |
}; | |
public static String topologyToDot(StormTopology topo) { | |
final Map<String, SpoutSpec> spouts = topo.get_spouts(); | |
final Map<String, Bolt> bolts = topo.get_bolts(); | |
return String.format("digraph Topology {%n" + | |
"%s" + | |
"%s" + | |
"%s" + | |
"%n" + | |
"}%n", | |
labelSpouts(spouts), | |
labelBolts(bolts), | |
drawConnections(bolts)); | |
} | |
private static String labelSpouts(final Map<String, SpoutSpec> spouts) { | |
final StringBuilder sb = new StringBuilder(); | |
for (final String id : spouts.keySet()) { | |
final SpoutSpec spout = spouts.get(id); | |
sb.append(String.format( | |
" \"%s\" [%s,shape=box];%n", | |
id, labelNode(id, spout))); | |
} | |
return sb.toString(); | |
} | |
private static String labelBolts(final Map<String, Bolt> bolts) { | |
final StringBuilder sb = new StringBuilder(); | |
for (final String id : bolts.keySet()) { | |
final Bolt bolt = bolts.get(id); | |
sb.append(String.format( | |
" \"%s\" [%s];%n", | |
id, labelNode(id, bolt))); | |
} | |
return sb.toString(); | |
} | |
private static String labelNode(String id, Bolt b) { | |
return labelNode(id, b.get_bolt_object()); | |
} | |
private static String labelNode(String id, SpoutSpec s) { | |
return labelNode(id, s.get_spout_object()); | |
} | |
private static String labelNode(String id, ComponentObject co) { | |
final byte[] java_bytes = co.get_serialized_java(); | |
assert null != java_bytes; | |
final Object javaO; | |
try { | |
javaO = new ObjectInputStream(new ByteArrayInputStream(java_bytes)).readObject(); | |
} catch (IOException | ClassNotFoundException e) { | |
e.printStackTrace(System.err); | |
throw new RuntimeException(e); | |
} | |
return String.format("label=\"%s (%s)\"", id, | |
null == javaO ? "NULL": javaO.getClass().getName() | |
.replaceAll(".*\\.([^\\.]+)", "$1")); | |
} | |
private static String drawConnections(final Map<String, Bolt> bolts) { | |
final StringBuilder sb = new StringBuilder(); | |
for (final String id : bolts.keySet()) { | |
final Bolt bolt = bolts.get(id); | |
final Map<GlobalStreamId, Grouping> inputs = bolt.get_common().get_inputs(); | |
for (final GlobalStreamId from : inputs.keySet()) { | |
final Grouping grouping = inputs.get(from); | |
final String fromId = from.get_componentId(); | |
final String streamId = from.get_streamId(); | |
sb.append(String.format(" \"%s\" -> \"%s\" [%s%s];%n", | |
fromId, id, | |
"default".equals(streamId) | |
? "" | |
: String.format( | |
"color=%s,", | |
COLORS[new java.util.Random().nextInt(COLORS.length)]), | |
labelConnection(streamId, grouping))); | |
} | |
} | |
return sb.toString(); | |
} | |
private static String labelConnection(String streamId, Grouping grouping) { | |
final String fieldName = grouping.getSetField().getFieldName(); | |
final String groupingStr; | |
if ("fields".equals(fieldName)) { | |
groupingStr = String.valueOf(grouping.get_fields()); | |
} else { | |
groupingStr = fieldName; | |
} | |
final String streamName = "default".equals(streamId) | |
? "" | |
: String.format(" \\\"%s\\\"", streamId); | |
return String.format("label=\"%s%s\"", | |
groupingStr.replaceAll("\"", "\\\""), streamName); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment