| 
		| Source: ../../rtrmgr/task.hh |  
		|  |  
 |  | 
 
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// Copyright (c) 2001-2009 XORP, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, Version 2, June
// 1991 as published by the Free Software Foundation. Redistribution
// and/or modification of this program under the terms of any other
// version of the GNU General Public License is not permitted.
// 
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
// see the GNU General Public License, Version 2, a copy of which can be
// found in the XORP LICENSE.gpl file.
// 
// XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
// $XORP: xorp/rtrmgr/task.hh,v 1.44 2009/01/05 18:31:10 jtc Exp $
#ifndef __RTRMGR_TASK_HH__
#define __RTRMGR_TASK_HH__
#include <map>
#include <vector>
#include "libxorp/run_command.hh"
#include "libxorp/status_codes.h"
#include "libxipc/xrl_router.hh"
#include "unexpanded_program.hh"
#include "unexpanded_xrl.hh"
class MasterConfigTree;
class ModuleCommand;
class ModuleManager;
class Task;
class TaskManager;
class XorpClient;
class Validation {
public:
    typedef XorpCallback1<void, bool>::RefPtr CallBack;
    Validation(const string& module_name, bool verbose)
	: _module_name(module_name), _verbose(verbose) {};
    virtual ~Validation() {};
    virtual void validate(RunShellCommand::ExecId exec_id, CallBack cb) = 0;
protected:
    const string	_module_name;
    RunShellCommand::ExecId _exec_id;
    bool		_verbose;	 // Set to true if output is verbose
};
class DelayValidation : public Validation {
public:
    DelayValidation(const string& module_name, EventLoop& eventloop,
		    uint32_t ms, bool verbose);
    void validate(RunShellCommand::ExecId exec_id, CallBack cb);
private:
    void timer_expired();
    EventLoop&	_eventloop;
    CallBack	_cb;
    uint32_t	_delay_in_ms;
    XorpTimer	_timer;
};
class XrlStatusValidation : public Validation {
public:
    XrlStatusValidation(const string& module_name, const XrlAction& xrl_action,
			TaskManager& taskmgr);
    virtual ~XrlStatusValidation() {}
    void validate(RunShellCommand::ExecId exec_id, CallBack cb);
protected:
    void dummy_response();
    virtual void xrl_done(const XrlError& e, XrlArgs* xrl_args);
    virtual void handle_status_response(ProcessStatus status,
					const string& reason) = 0;
    EventLoop& eventloop();
    const XrlAction&	_xrl_action;
    TaskManager&	_task_manager;
    CallBack		_cb;
    XorpTimer		_retry_timer;
    uint32_t		_retries;
};
class ProgramStatusValidation : public Validation {
public:
    ProgramStatusValidation(const string& module_name,
			    const ProgramAction& program_action,
			    TaskManager& taskmgr);
    virtual ~ProgramStatusValidation();
    void validate(RunShellCommand::ExecId exec_id, CallBack cb);
protected:
    virtual void handle_status_response(bool success,
					const string& stdout_output,
					const string& stderr_output) = 0;
    EventLoop& eventloop();
    const ProgramAction& _program_action;
    TaskManager&	_task_manager;
    CallBack		_cb;
private:
    void stdout_cb(RunShellCommand* run_command, const string& output);
    void stderr_cb(RunShellCommand* run_command, const string& output);
    void done_cb(RunShellCommand* run_command, bool success,
		 const string& error_msg);
    void execute_done(bool success);
    RunShellCommand*	_run_command;
    string		_command_stdout;
    string		_command_stderr;
    XorpTimer		_delay_timer;
};
class XrlStatusStartupValidation : public XrlStatusValidation {
public:
    XrlStatusStartupValidation(const string& module_name,
			       const XrlAction& xrl_action,
			       TaskManager& taskmgr);
private:
    void handle_status_response(ProcessStatus status, const string& reason);
};
class ProgramStatusStartupValidation : public ProgramStatusValidation {
public:
    ProgramStatusStartupValidation(const string& module_name,
				   const ProgramAction& program_action,
				   TaskManager& taskmgr);
private:
    void handle_status_response(bool success,
				const string& stdout_output,
				const string& stderr_output);
};
class XrlStatusReadyValidation : public XrlStatusValidation {
public:
    XrlStatusReadyValidation(const string& module_name,
			     const XrlAction& xrl_action,
			     TaskManager& taskmgr);
private:
    void handle_status_response(ProcessStatus status, const string& reason);
};
class ProgramStatusReadyValidation : public ProgramStatusValidation {
public:
    ProgramStatusReadyValidation(const string& module_name,
				 const ProgramAction& program_action,
				 TaskManager& taskmgr);
private:
    void handle_status_response(bool success,
				const string& stdout_output,
				const string& stderr_output);
};
class XrlStatusConfigMeValidation : public XrlStatusValidation {
public:
    XrlStatusConfigMeValidation(const string& module_name,
				const XrlAction& xrl_action,
				TaskManager& taskmgr);
private:
    void handle_status_response(ProcessStatus status, const string& reason);
};
class ProgramStatusConfigMeValidation : public ProgramStatusValidation {
public:
    ProgramStatusConfigMeValidation(const string& module_name,
				    const ProgramAction& program_action,
				    TaskManager& taskmgr);
private:
    void handle_status_response(bool success,
				const string& stdout_output,
				const string& stderr_output);
};
class XrlStatusShutdownValidation : public XrlStatusValidation {
public:
    XrlStatusShutdownValidation(const string& module_name,
				const XrlAction& xrl_action,
				TaskManager& taskmgr);
private:
    void xrl_done(const XrlError& e, XrlArgs* xrl_args);
    void handle_status_response(ProcessStatus status, const string& reason);
};
class ProgramStatusShutdownValidation : public ProgramStatusValidation {
public:
    ProgramStatusShutdownValidation(const string& module_name,
				    const ProgramAction& program_action,
				    TaskManager& taskmgr);
private:
    void handle_status_response(bool success,
				const string& stdout_output,
				const string& stderr_output);
};
class Startup {
public:
    typedef XorpCallback1<void, bool>::RefPtr CallBack;
    Startup(const string& module_name, bool verbose);
    virtual ~Startup() {}
    virtual void startup(const RunShellCommand::ExecId& exec_id,
			 CallBack cb) = 0;
protected:
    const string _module_name;
    bool	_verbose;	 // Set to true if output is verbose
};
class XrlStartup : public Startup {
public:
    XrlStartup(const string& module_name, const XrlAction& xrl_action,
	       TaskManager& taskmgr);
    virtual ~XrlStartup() {}
    void startup(const RunShellCommand::ExecId& exec_id, CallBack cb);
    EventLoop& eventloop() const;
private:
    void dummy_response();
    void startup_done(const XrlError& err, XrlArgs* xrl_args);
    const XrlAction&	_xrl_action;
    TaskManager&	_task_manager;
    CallBack		_cb;
    XorpTimer		_dummy_timer;
};
class ProgramStartup : public Startup {
public:
    ProgramStartup(const string& module_name,
		   const ProgramAction& program_action,
		   TaskManager& taskmgr);
    virtual ~ProgramStartup();
    void startup(const RunShellCommand::ExecId& exec_id, CallBack cb);
    EventLoop& eventloop() const;
private:
    void stdout_cb(RunShellCommand* run_command, const string& output);
    void stderr_cb(RunShellCommand* run_command, const string& output);
    void done_cb(RunShellCommand* run_command, bool success,
		 const string& error_msg);
    void execute_done(bool success);
    const ProgramAction& _program_action;
    TaskManager&	_task_manager;
    CallBack		_cb;
    RunShellCommand*	_run_command;
    string		_command_stdout;
    string		_command_stderr;
    XorpTimer		_delay_timer;
};
class Shutdown {
public:
    typedef XorpCallback1<void, bool>::RefPtr CallBack;
    Shutdown(const string& module_name, bool verbose);
    virtual ~Shutdown() {}
    virtual void shutdown(const RunShellCommand::ExecId& exec_id,
			  CallBack cb) = 0;
protected:
    const string _module_name;
    bool	_verbose;	 // Set to true if output is verbose
};
class XrlShutdown : public Shutdown {
public:
    XrlShutdown(const string& module_name, const XrlAction& xrl_action,
		TaskManager& taskmgr);
    virtual ~XrlShutdown() {}
    void shutdown(const RunShellCommand::ExecId& exec_id, CallBack cb);
    EventLoop& eventloop() const;
private:
    void dummy_response();
    void shutdown_done(const XrlError& err, XrlArgs* xrl_args);
    const XrlAction&	_xrl_action;
    TaskManager&	_task_manager;
    CallBack		_cb;
    XorpTimer		_dummy_timer;
};
class ProgramShutdown : public Shutdown {
public:
    ProgramShutdown(const string& module_name,
		    const ProgramAction& program_action,
		    TaskManager& taskmgr);
    virtual ~ProgramShutdown();
    void shutdown(const RunShellCommand::ExecId& exec_id, CallBack cb);
    EventLoop& eventloop() const;
private:
    void stdout_cb(RunShellCommand* run_command, const string& output);
    void stderr_cb(RunShellCommand* run_command, const string& output);
    void done_cb(RunShellCommand* run_command, bool success,
		 const string& error_msg);
    void execute_done(bool success);
    const ProgramAction& _program_action;
    TaskManager&	_task_manager;
    CallBack		_cb;
    RunShellCommand*	_run_command;
    string		_command_stdout;
    string		_command_stderr;
    XorpTimer		_delay_timer;
};
class TaskBaseItem {
public:
    TaskBaseItem(Task& task) : _task(task) {}
    TaskBaseItem(const TaskBaseItem& them) : _task(them._task) {}
    virtual ~TaskBaseItem() {}
    virtual bool execute(string& errmsg) = 0;
    virtual void unschedule() = 0;
    Task& task() { return (_task); }
private:
    Task&	_task;
};
class TaskXrlItem : public TaskBaseItem {
public:
    TaskXrlItem(const UnexpandedXrl& uxrl, const XrlRouter::XrlCallback& cb,
		Task& task,
		uint32_t xrl_resend_count = TaskXrlItem::DEFAULT_RESEND_COUNT,
		int xrl_resend_delay_ms = TaskXrlItem::DEFAULT_RESEND_DELAY_MS);
    TaskXrlItem(const TaskXrlItem& them);
    bool execute(string& errmsg);
    void execute_done(const XrlError& err, XrlArgs* xrl_args);
    void resend();
    void unschedule();
private:
    static const uint32_t	DEFAULT_RESEND_COUNT;
    static const int		DEFAULT_RESEND_DELAY_MS;
    UnexpandedXrl		_unexpanded_xrl;
    XrlRouter::XrlCallback	_xrl_callback;
    uint32_t			_xrl_resend_count_limit;
    uint32_t			_xrl_resend_count;
    int				_xrl_resend_delay_ms;
    XorpTimer			_xrl_resend_timer;
    bool			_verbose;   // Set to true if output is verbose
};
class TaskProgramItem : public TaskBaseItem {
public:
    typedef XorpCallback4<void, bool, const string&, const string&, bool>::RefPtr ProgramCallback;
    TaskProgramItem(const UnexpandedProgram&		program,
		    TaskProgramItem::ProgramCallback	program_cb,
		    Task&				task);
    TaskProgramItem(const TaskProgramItem& them);
    ~TaskProgramItem();
    bool execute(string& errmsg);
    void execute_done(bool success);
    void unschedule();
private:
    void stdout_cb(RunShellCommand* run_command, const string& output);
    void stderr_cb(RunShellCommand* run_command, const string& output);
    void done_cb(RunShellCommand* run_command, bool success,
		 const string& error_msg);
    UnexpandedProgram		_unexpanded_program;
    RunShellCommand*		_run_command;
    string			_command_stdout;
    string			_command_stderr;
    TaskProgramItem::ProgramCallback _program_cb;
    XorpTimer			_delay_timer;
    bool			_verbose;   // Set to true if output is verbose
};
class Task {
public:
    typedef XorpCallback2<void, bool, string>::RefPtr CallBack;
    Task(const string& name, TaskManager& taskmgr);
    ~Task();
    void start_module(const string& mod_name, Validation* startup_validation,
		      Validation* config_validation, Startup* startup);
    void shutdown_module(const string& mod_name, Validation* validation,
			 Shutdown* shutdown);
    void add_xrl(const UnexpandedXrl& xrl, XrlRouter::XrlCallback& cb);
    void add_program(const UnexpandedProgram&		program,
		     TaskProgramItem::ProgramCallback	program_cb);
    void set_ready_validation(Validation* validation);
    Validation* ready_validation() const { return _ready_validation; }
    bool will_shutdown_module() const { return _stop_module; }
    void run(CallBack cb);
    void item_done(bool success, bool fatal, string errmsg); 
    bool do_exec() const;
    bool is_verification() const;
    XorpClient& xorp_client() const;
    /**
     * Get a reference to the ExecId object.
     * 
     * @return a reference to the ExecId object that is used
     * for setting the execution ID when running the task.
     */
    const RunShellCommand::ExecId& exec_id() const { return _exec_id; }
    /**
     * Set the execution ID for executing the task.
     * 
     * @param v the execution ID.
     */
    void set_exec_id(const RunShellCommand::ExecId& v) { _exec_id = v; }
    const string& name() const { return _name; }
    EventLoop& eventloop() const;
    bool verbose() const { return _verbose; }
protected:
    void step1_start();
    void step1_done(bool success);
    void step2_wait();
    void step2_done(bool success);
    void step2_2_wait();
    void step2_2_done(bool success);
    void step2_3_wait();
    void step2_3_done(bool success);
    void step3_config();
    void step3_done(bool success);
    void step4_wait();
    void step4_done(bool success);
    void step5_stop();
    void step5_done(bool success);
    void step6_wait();
    void step6_done(bool success);
    void step7_wait();
    void step7_kill();
    void step8_report();
    void task_fail(string errmsg, bool fatal);
private:
    string	_name;		// The name of the task
    TaskManager& _taskmgr;
    string	_module_name;	// The name of the module to start and stop
    bool	_start_module;
    bool	_stop_module;
    Validation*	_startup_validation; // The validation mechanism for the
                                     // module startup
    Validation* _config_validation;  // The validation mechanism for the
				     // module configuration
    Validation*	_ready_validation; // The validation mechanism for the module 
                                   // reconfiguration
    Validation*	_shutdown_validation;  // The validation mechanism for the 
                                       // module shutdown
    Startup*	_startup_method;
    Shutdown*	_shutdown_method;
    list<TaskBaseItem *> _task_items;
    bool	_config_done;	// True if we changed the module's config
    CallBack	_task_complete_cb; // The task completion callback
    XorpTimer	_wait_timer;
    RunShellCommand::ExecId _exec_id;
    bool	_verbose;	 // Set to true if output is verbose
};
class TaskManager {
    typedef XorpCallback2<void, bool, string>::RefPtr CallBack;
public:
    TaskManager(MasterConfigTree& config_tree, 
		ModuleManager& mmgr,
		XorpClient& xclient, bool global_do_exec,
		bool verbose);
    ~TaskManager();
    void set_do_exec(bool do_exec, bool is_verification);
    void reset();
    int add_module(const ModuleCommand& mod_cmd, string& error_msg);
    void add_xrl(const string& module_name, const UnexpandedXrl& xrl, 
		 XrlRouter::XrlCallback& cb);
    void add_program(const string&			module_name,
		     const UnexpandedProgram&		program,
		     TaskProgramItem::ProgramCallback	program_cb);
    void shutdown_module(const string& module_name);
    void run(CallBack cb);
    XorpClient& xorp_client() const { return _xorp_client; }
    ModuleManager& module_manager() const { return _module_manager; }
    MasterConfigTree& config_tree() const { return _config_tree; }
    bool do_exec() const { return _current_do_exec; }
    bool is_verification() const { return _is_verification; }
    bool verbose() const { return _verbose; }
    EventLoop& eventloop() const;
    /**
     * @short kill_process is used to kill a fatally wounded process
     *
     * kill_process is used to kill a fatally wounded process. This
     * does not politely ask the process to die, because if we get
     * here we can't communicate with the process using XRLs or any other
     * mechanism, so we just kill it outright.
     * 
     * @param module_name the module name of the process to be killed.  
     */
    void kill_process(const string& module_name);
    /**
     * Get a reference to the ExecId object.
     * 
     * @return a reference to the ExecId object that is used
     * for setting the execution ID when running the tasks.
     */
    const RunShellCommand::ExecId& exec_id() const { return _exec_id; }
    /**
     * Set the execution ID for executing the tasks.
     * 
     * @param v the execution ID.
     */
    void set_exec_id(const RunShellCommand::ExecId& v) { _exec_id = v; }
private:
    void reorder_tasks();
    void run_task();
    void task_done(bool success, string errmsg);
    void fail_tasklist_initialization(const string& errmsg);
    Task& find_task(const string& module_name);
    void null_callback();
    MasterConfigTree&   _config_tree;
    ModuleManager&	_module_manager;
    XorpClient&		_xorp_client;
    bool		_global_do_exec; // Set to false if we're never going
					// to execute anything because we're
					// in a debug mode
    bool		_current_do_exec;
    bool		_is_verification; // Set to true if current execution
					  // is for verification purpose
    bool		_verbose;	// Set to true if output is verbose
    // _tasks provides fast access to a Task by name
    map<string, Task*> _tasks;
    // _tasklist maintains the execution order
    list<Task*> _tasklist;
    // _shutdown_order maintains the shutdown ordering
    list<Task*> _shutdown_order;
    map<string, const ModuleCommand*> _module_commands;
    RunShellCommand::ExecId _exec_id;
    CallBack _completion_cb;
};
#endif // __RTRMGR_TASK_HH__
	
Generated by: pavlin on kobe.xorp.net on Wed Jan  7 19:11:12 2009, using kdoc 2.0a54+XORP.