/** * Execute a workflow item, returns true if the item succeeds. This method will throw an exception * if the workflow item fails and the Workflow is has keepgoing==false. * * @param failedMap List to add any messages if the item fails * @param c index of the WF item * @param cmd WF item descriptor * @return true if the execution succeeds, false otherwise */ protected StepExecutionResult executeWFItem( final StepExecutionContext executionContext, final Map<Integer, StepExecutionResult> failedMap, final int c, final StepExecutionItem cmd) { if (null != executionContext.getExecutionListener()) { executionContext .getExecutionListener() .log(Constants.DEBUG_LEVEL, c + ": Workflow step executing: " + cmd); } StepExecutionResult result; try { result = framework .getExecutionService() .executeStep( ExecutionContextImpl.builder(executionContext).stepNumber(c).build(), cmd); if (!result.isSuccess()) { failedMap.put(c, result); } } catch (StepException e) { result = StepExecutionResultImpl.wrapStepException(e); failedMap.put(c, result); } if (null != executionContext.getExecutionListener()) { executionContext .getExecutionListener() .log(Constants.DEBUG_LEVEL, c + ": Workflow step finished, result: " + result); } return result; }
public DispatcherResult dispatch( final ExecutionContext context, final ExecutionItem item, final Dispatchable toDispatch) throws DispatcherException { final NodesSelector nodesSelector = context.getNodeSelector(); INodeSet nodes = null; try { nodes = framework.filterAuthorizedNodes( context.getFrameworkProject(), new HashSet<String>(Arrays.asList("read", "run")), framework.filterNodeSet( nodesSelector, context.getFrameworkProject(), context.getNodesFile())); } catch (NodeFileParserException e) { throw new DispatcherException(e); } if (nodes.getNodes().size() < 1) { throw new DispatcherException("No nodes matched"); } boolean keepgoing = context.isKeepgoing(); context .getExecutionListener() .log(4, "preparing for sequential execution on " + nodes.getNodes().size() + " nodes"); final HashSet<String> nodeNames = new HashSet<String>(nodes.getNodeNames()); final HashMap<String, Object> failures = new HashMap<String, Object>(); FailedNodesListener failedListener = context.getExecutionListener().getFailedNodesListener(); if (null != failedListener) { failedListener.matchedNodes(nodeNames); } boolean interrupted = false; final Thread thread = Thread.currentThread(); boolean success = true; final HashMap<String, StatusResult> resultMap = new HashMap<String, StatusResult>(); final Collection<INodeEntry> nodes1 = nodes.getNodes(); // reorder based on configured rank property and order final String rankProperty = null != context.getNodeRankAttribute() ? context.getNodeRankAttribute() : "nodename"; final boolean rankAscending = context.isNodeRankOrderAscending(); final INodeEntryComparator comparator = new INodeEntryComparator(rankProperty); final TreeSet<INodeEntry> orderedNodes = new TreeSet<INodeEntry>(rankAscending ? comparator : Collections.reverseOrder(comparator)); orderedNodes.addAll(nodes1); for (final Object node1 : orderedNodes) { if (thread.isInterrupted() || thread instanceof ExecutionServiceThread && ((ExecutionServiceThread) thread).isAborted()) { interrupted = true; break; } final INodeEntry node = (INodeEntry) node1; context .getExecutionListener() .log( Constants.DEBUG_LEVEL, "Executing command on node: " + node.getNodename() + ", " + node.toString()); try { if (thread.isInterrupted() || thread instanceof ExecutionServiceThread && ((ExecutionServiceThread) thread).isAborted()) { interrupted = true; break; } final StatusResult result; final ExecutionContext interimcontext = new ExecutionContextImpl.Builder(context) .nodeSelector(SelectorUtils.singleNode(node.getNodename())) .build(); if (null != item) { result = framework.getExecutionService().interpretCommand(interimcontext, item, node); } else { result = toDispatch.dispatch(interimcontext, node); } if (null != result) { resultMap.put(node.getNodename(), result); } if (null == result || !result.isSuccess()) { success = false; // context.getExecutionListener().log(Constants.ERR_LEVEL, // "Failed execution for node " + node.getNodename() + ": " + // result); if (null != result) { failures.put(node.getNodename(), result); } else { failures.put(node.getNodename(), "Failed execution, result was null"); } if (!keepgoing) { break; } } else { nodeNames.remove(node.getNodename()); } } catch (Throwable e) { success = false; failures.put( node.getNodename(), "Error dispatching command to the node: " + e.getMessage()); context .getExecutionListener() .log( Constants.ERR_LEVEL, "Failed dispatching to node " + node.getNodename() + ": " + e.getMessage()); final StringWriter stringWriter = new StringWriter(); e.printStackTrace(new PrintWriter(stringWriter)); context .getExecutionListener() .log( Constants.DEBUG_LEVEL, "Failed dispatching to node " + node.getNodename() + ": " + stringWriter.toString()); if (!keepgoing) { if (failures.size() > 0 && null != failedListener) { // tell listener of failed node list failedListener.nodesFailed(failures); } throw new DispatcherException( "Failed dispatching to node " + node.getNodename() + ": " + e.getMessage(), e, node); } } } if (keepgoing && nodeNames.size() > 0) { if (null != failedListener) { // tell listener of failed node list failedListener.nodesFailed(failures); } // now fail // XXX: needs to change from exception throw new NodesetFailureException(failures); } else if (null != failedListener && failures.isEmpty() && !interrupted) { failedListener.nodesSucceeded(); } if (interrupted) { throw new DispatcherException("Node dispatch interrupted"); } final boolean status = success; return new DispatcherResult() { public Map<String, ? extends StatusResult> getResults() { return resultMap; } public boolean isSuccess() { return status; } @Override public String toString() { return "DispatcherResult{" + "status=" + isSuccess() + ", " + "results=" + getResults() + "}"; } }; }