Package com.dtolabs.rundeck.core.execution.dispatch

Source Code of com.dtolabs.rundeck.core.execution.dispatch.SequentialNodeDispatcher

/*
* Copyright 2011 DTO Solutions, Inc. (http://dtosolutions.com)
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

/*
* SequentialNodeDispatcher.java
*
* User: Greg Schueler <a href="mailto:greg@dtosolutions.com">greg@dtosolutions.com</a>
* Created: 3/22/11 11:54 AM
*
*/
package com.dtolabs.rundeck.core.execution.dispatch;

import com.dtolabs.rundeck.core.Constants;
import com.dtolabs.rundeck.core.common.Framework;
import com.dtolabs.rundeck.core.common.INodeEntry;
import com.dtolabs.rundeck.core.common.INodeSet;
import com.dtolabs.rundeck.core.execution.FailedNodesListener;
import com.dtolabs.rundeck.core.execution.ServiceThreadBase;
import com.dtolabs.rundeck.core.execution.workflow.StepExecutionContext;
import com.dtolabs.rundeck.core.execution.workflow.steps.node.NodeStepException;
import com.dtolabs.rundeck.core.execution.workflow.steps.node.NodeStepExecutionItem;
import com.dtolabs.rundeck.core.execution.workflow.steps.node.NodeStepResult;
import com.dtolabs.rundeck.core.execution.workflow.steps.node.NodeStepResultImpl;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;


/**
* SequentialNodeDispatcher is ...
*
* @author Greg Schueler <a href="mailto:greg@dtosolutions.com">greg@dtosolutions.com</a>
*/
public class SequentialNodeDispatcher implements NodeDispatcher {
    private Framework framework;

    public SequentialNodeDispatcher(Framework framework) {
        this.framework = framework;
    }

    public DispatcherResult dispatch(final StepExecutionContext context,
                                     final NodeStepExecutionItem item) throws
                                                                       DispatcherException {
        return dispatch(context, item, null);
    }

    public DispatcherResult dispatch(final StepExecutionContext context,
                                     final Dispatchable item) throws
                                                              DispatcherException {
        return dispatch(context, null, item);
    }

    public DispatcherResult dispatch(final StepExecutionContext context,
                                     final NodeStepExecutionItem item, final Dispatchable toDispatch) throws
                                                                                                      DispatcherException {

        INodeSet nodes = context.getNodes();
        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, NodeStepResult> failures = new HashMap<String, NodeStepResult>();
        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, NodeStepResult> resultMap = new HashMap<String, NodeStepResult>();
        final List<INodeEntry> nodes1 = INodeEntryComparator.rankOrderedNodes(nodes, context
                .getNodeRankAttribute(),
                context.isNodeRankOrderAscending());
        //reorder based on configured rank property and order

        NodeStepException caught = null;
        INodeEntry failedNode = null;
        for (final INodeEntry node : nodes1) {
            if (thread.isInterrupted()
                || thread instanceof ServiceThreadBase && ((ServiceThreadBase) thread).isAborted()) {
                interrupted = true;
                break;
            }
            context.getExecutionListener().log(Constants.DEBUG_LEVEL,
                                               "Executing command on node: " + node.getNodename() + ", "
                                               + node.toString());
            try {

                if (thread.isInterrupted()
                    || thread instanceof ServiceThreadBase && ((ServiceThreadBase) thread).isAborted()) {
                    interrupted = true;
                    break;
                }
                final NodeStepResult result;

                //execute the step or dispatchable
                if (null != item) {
                    result = framework.getExecutionService().executeNodeStep(context, item, node);
                } else {
                    result = toDispatch.dispatch(context, node);

                }
                resultMap.put(node.getNodename(), result);
                if (!result.isSuccess()) {
                    success = false;
//                    context.getExecutionListener().log(Constants.ERR_LEVEL,
//                        "Failed execution for node " + node.getNodename() + ": " + result);
                    failures.put(node.getNodename(), result);
                    if (!keepgoing) {
                        failedNode = node;
                        break;
                    }
                } else {
                    nodeNames.remove(node.getNodename());
                }
            } catch (NodeStepException e) {
                success = false;
                failures.put(node.getNodename(),
                             new NodeStepResultImpl(e, e.getFailureReason(), e.getMessage(), node)
                );
                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) {
                    failedNode = node;
                    caught = e;
                    break;
                }
            }
        }
        if (!keepgoing && failures.size() > 0 && null != failedListener) {
            //tell listener of failed node list
            failedListener.nodesFailed(failures);
        }
        if (!keepgoing && null != caught) {
            throw new DispatcherException(
                "Failed dispatching to node " + failedNode.getNodename() + ": " + caught.getMessage(), caught,
                failedNode);
        }
        if (keepgoing && nodeNames.size() > 0) {
            if (null != failedListener) {
                //tell listener of failed node list
                failedListener.nodesFailed(failures);
            }
            //now fail
            return new DispatcherResultImpl(failures, false);
        } else if (null != failedListener && failures.isEmpty() && !interrupted) {
            failedListener.nodesSucceeded();
        }
        if (interrupted) {
            throw new DispatcherException("Node dispatch interrupted");
        }

        final boolean status = success;
        return new DispatcherResultImpl(resultMap, status);
    }
}
TOP

Related Classes of com.dtolabs.rundeck.core.execution.dispatch.SequentialNodeDispatcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.