use of org.jenkinsci.plugins.workflow.graph.BlockStartNode in project workflow-cps-plugin by jenkinsci.
the class CpsFlowExecution method initializeStorage.
@SuppressFBWarnings(value = "IS2_INCONSISTENT_SYNC", justification = "Storage does not actually NEED to be synchronized but the rest does.")
protected synchronized void initializeStorage() throws IOException {
// Maybe storage didn't get to persist properly or files were deleted.
boolean storageErrors = false;
try {
storage = createStorage();
heads = new TreeMap<Integer, FlowHead>();
for (Map.Entry<Integer, String> entry : headsSerial.entrySet()) {
FlowHead h = new FlowHead(this, entry.getKey());
FlowNode n = storage.getNode(entry.getValue());
if (n != null) {
h.setForDeserialize(storage.getNode(entry.getValue()));
heads.put(h.getId(), h);
} else {
storageErrors = true;
break;
}
}
headsSerial = null;
if (!storageErrors) {
// Same for startNodes:
storageErrors = false;
startNodes = new Stack<BlockStartNode>();
for (String id : startNodesSerial) {
FlowNode node = storage.getNode(id);
if (node != null) {
startNodes.add((BlockStartNode) storage.getNode(id));
} else {
// TODO if possible, consider trying to close out unterminated blocks using heads, to keep existing graph history
storageErrors = true;
break;
}
}
}
startNodesSerial = null;
} catch (IOException ioe) {
LOGGER.log(Level.WARNING, "Error initializing storage and loading nodes", ioe);
storageErrors = true;
}
if (storageErrors) {
//
// Avoid overwriting data
this.storageDir = (this.storageDir != null) ? this.storageDir + "-fallback" : "workflow-fallback";
// Empty storage
this.storage = createStorage();
// Need to find a way to mimic up the heads and fail cleanly, far enough to let the canResume do its thing
rebuildEmptyGraph();
}
}
use of org.jenkinsci.plugins.workflow.graph.BlockStartNode in project workflow-cps-plugin by jenkinsci.
the class CpsFlowExecution method rebuildEmptyGraph.
/**
* Handle failures where we can't load heads.
*/
private void rebuildEmptyGraph() {
synchronized (this) {
// something went catastrophically wrong and there's no live head. fake one
if (this.startNodes == null) {
this.startNodes = new Stack<BlockStartNode>();
}
this.heads.clear();
this.startNodes.clear();
FlowHead head = new FlowHead(this);
heads.put(head.getId(), head);
try {
FlowStartNode start = new FlowStartNode(this, iotaStr());
startNodes.push(start);
head.newStartNode(start);
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Failed to persist", e);
}
persistedClean = false;
startNodesSerial = null;
headsSerial = null;
}
}
use of org.jenkinsci.plugins.workflow.graph.BlockStartNode in project workflow-job-plugin by jenkinsci.
the class GraphVizAction method writeDot.
private void writeDot(PrintWriter w) throws IOException {
try {
w.println("digraph G {");
FlowGraphWalker walker = new FlowGraphWalker(run.getExecution());
for (FlowNode n : walker) {
for (FlowNode p : n.getParents()) {
w.printf("%s -> %s%n", p.getId(), n.getId());
}
if (n instanceof BlockStartNode) {
BlockStartNode sn = (BlockStartNode) n;
w.printf("%s [shape=trapezium]%n", n.getId());
} else if (n instanceof BlockEndNode) {
BlockEndNode sn = (BlockEndNode) n;
w.printf("%s [shape=invtrapezium]%n", n.getId());
w.printf("%s -> %s [style=dotted]%n", sn.getStartNode().getId(), n.getId());
}
w.printf("%s [label=\"%s: %s\"]%n", n.getId(), n.getId(), n.getDisplayName());
}
w.println("}");
} finally {
w.close();
}
}
use of org.jenkinsci.plugins.workflow.graph.BlockStartNode in project blueocean-plugin by jenkinsci.
the class GraphDumpAction method doIndex.
public HttpResponse doIndex() throws IOException {
JSONArray response = new JSONArray();
FlowGraphWalker walker = new FlowGraphWalker(run.getExecution());
for (FlowNode node : walker) {
JSONObject outputNode = new JSONObject();
outputNode.put("id", node.getId());
outputNode.put("name", node.getDisplayName());
outputNode.put("functionName", node.getDisplayFunctionName());
outputNode.put("className", node.getClass().getName());
outputNode.put("enclosingId", node.getEnclosingId());
outputNode.put("isBegin", node instanceof BlockStartNode);
outputNode.put("isEnd", node instanceof BlockEndNode);
outputNode.put("isStepNode", node instanceof StepNode);
if (node instanceof StepNode) {
StepNode sn = (StepNode) node;
StepDescriptor descriptor = sn.getDescriptor();
if (descriptor != null) {
JSONObject outputDescriptor = new JSONObject();
outputDescriptor.put("getDisplayName", descriptor.getDisplayName());
outputDescriptor.put("getFunctionName", descriptor.getFunctionName());
outputNode.put("stepDescriptor", outputDescriptor);
}
}
JSONArray parents = new JSONArray();
for (FlowNode parent : node.getParents()) {
parents.add(parent.getId());
}
outputNode.put("parents", parents);
if (node instanceof BlockStartNode) {
BlockStartNode startNode = (BlockStartNode) node;
final BlockEndNode endNode = startNode.getEndNode();
outputNode.put("endNodeId", endNode == null ? null : endNode.getId());
} else if (node instanceof BlockEndNode) {
BlockEndNode endNode = (BlockEndNode) node;
outputNode.put("startNodeId", endNode.getStartNode().getId());
}
JSONArray actions = new JSONArray();
for (Action action : node.getAllActions()) {
JSONObject outputAction = new JSONObject();
outputAction.put("className", action.getClass().getName());
outputAction.put("displayName", action.getDisplayName());
actions.add(outputAction);
}
outputNode.put("actions", actions);
response.add(outputNode);
}
return HttpResponses.okJSON(response);
}
Aggregations