private StepStateChange createStepStateChange(ExecutionState executionState, Map metadata) {
    INodeEntry currentNode = stepContext.getCurrentNode();

    return StateUtils.stepStateChange(
        StateUtils.stepState(executionState, metadata),
        null != currentNode ? currentNode.getNodename() : null);
  }
  /**
   * Convert map of step execution results keyed by step number, to a collection of step execution
   * results keyed by node name
   */
  protected Map<String, Collection<StepExecutionResult>> convertFailures(
      final Map<Integer, StepExecutionResult> failedMap) {

    final Map<String, Collection<StepExecutionResult>> failures =
        new HashMap<String, Collection<StepExecutionResult>>();
    for (final Map.Entry<Integer, StepExecutionResult> entry : failedMap.entrySet()) {
      final StepExecutionResult o = entry.getValue();

      if (NodeDispatchStepExecutor.isWrappedDispatcherResult(o)) {
        // indicates dispatcher returned node results
        final DispatcherResult dispatcherResult =
            NodeDispatchStepExecutor.extractDispatcherResult(o);

        for (final String s : dispatcherResult.getResults().keySet()) {
          final NodeStepResult interpreterResult = dispatcherResult.getResults().get(s);
          if (!failures.containsKey(s)) {
            failures.put(s, new ArrayList<StepExecutionResult>());
          }
          failures.get(s).add(interpreterResult);
        }
      } else if (NodeDispatchStepExecutor.isWrappedDispatcherException(o)) {
        DispatcherException e = NodeDispatchStepExecutor.extractDispatcherException(o);
        final INodeEntry node = e.getNode();
        if (null != node) {
          // dispatch failed for a specific node
          final String key = node.getNodename();
          if (!failures.containsKey(key)) {
            failures.put(key, new ArrayList<StepExecutionResult>());
          }
          failures.get(key).add(e.getResultMap().get(node.getNodename()));
        } else {
          // dispatch failed for a set of nodes
          for (final String s : e.getResultMap().keySet()) {
            final NodeStepResult interpreterResult = e.getResultMap().get(s);
            if (!failures.containsKey(s)) {
              failures.put(s, new ArrayList<StepExecutionResult>());
            }
            failures.get(s).add(interpreterResult);
          }
        }
      }
    }
    return failures;
  }
 private List<String> getNodeNames(StepExecutionContext executionContext) {
   List<INodeEntry> orderedNodes =
       INodeEntryComparator.rankOrderedNodes(
           executionContext.getNodes(),
           executionContext.getNodeRankAttribute(),
           executionContext.isNodeRankOrderAscending());
   List<String> names = new ArrayList<String>();
   for (INodeEntry orderedNode : orderedNodes) {
     names.add(orderedNode.getNodename());
   }
   return names;
 }
  @Test
  public void testConvert() throws Exception {

    Node puppetNode = new Node();
    puppetNode.setName(NODE_NAME);

    List<Node> puppetNodes = new ArrayList<>();
    puppetNodes.add(puppetNode);

    PuppetNodesToRundeckConverter sut = new PuppetNodesToRundeckConverter(USERNAME);

    INodeSet rundeckNodes = sut.convert(puppetNodes);

    INodeEntry rundeckNode = rundeckNodes.getNode(NODE_NAME);

    assertThat(rundeckNode.getNodename(), is(NODE_NAME));
    assertThat(rundeckNode.getHostname(), is(NODE_NAME));
    assertThat(rundeckNode.getUsername(), is(USERNAME));
  }
 public void beginWorkflowExecution(
     StepExecutionContext executionContext, WorkflowExecutionItem item) {
   StepContextId currentStep = stepContext.getCurrentStep();
   INodeEntry currentNode = stepContext.getCurrentNode();
   if (null != currentNode && null != currentStep) {
     // if already node context, begin a parameterized sub workflow
     // change step context to include node name parameter for the step id
     HashMap<String, String> params = new HashMap<String, String>();
     params.put("node", currentNode.getNodename());
     stepContext.beginStepContext(
         StateUtils.stepContextId(
             currentStep.getStep(), !currentStep.getAspect().isMain(), params));
   }
   stepContext.beginContext();
   List<Pair<StepContextId, INodeEntry>> currentContext = stepContext.getCurrentContextPairs();
   List<String> names = getNodeNames(executionContext);
   if (null == currentContext) {
     notifyAllWorkflowState(ExecutionState.RUNNING, new Date(), names);
   } else {
     notifyAllSubWorkflowState(createIdentifier(), ExecutionState.RUNNING, new Date(), names);
   }
 }
  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()
            + "}";
      }
    };
  }
 private StepStateChange createStepStateChange(
     StepExecutionResult result, INodeEntry currentNode) {
   return StateUtils.stepStateChange(
       StateUtils.stepState(resultState(result), resultMetadata(result), resultMessage(result)),
       null != currentNode ? currentNode.getNodename() : null);
 }