00001 #include "otsdaq-core/FiniteStateMachine/RunControlStateMachine.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00004 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
00005 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
00006
00007 #include <toolbox/fsm/FailedEvent.h>
00008 #include <xoap/Method.h>
00009 #include <xdaq/NamespaceURI.h>
00010
00011 #include <iostream>
00012
00013 using namespace ots;
00014
00015 const std::string RunControlStateMachine::FAILED_STATE_NAME = "Failed";
00016
00017
00018 RunControlStateMachine::RunControlStateMachine(std::string name)
00019 : stateMachineName_(name)
00020 {
00021 theStateMachine_.addState('I', "Initial", this, &RunControlStateMachine::stateInitial);
00022 theStateMachine_.addState('H', "Halted", this, &RunControlStateMachine::stateHalted);
00023 theStateMachine_.addState('C', "Configured", this, &RunControlStateMachine::stateConfigured);
00024 theStateMachine_.addState('R', "Running", this, &RunControlStateMachine::stateRunning);
00025 theStateMachine_.addState('P', "Paused", this, &RunControlStateMachine::statePaused);
00026
00027
00028
00029
00030
00031
00032
00033 theStateMachine_.setStateName('F',RunControlStateMachine::FAILED_STATE_NAME);
00034 theStateMachine_.setFailedStateTransitionAction (this, &RunControlStateMachine::enteringError);
00035 theStateMachine_.setFailedStateTransitionChanged(this, &RunControlStateMachine::inError);
00036
00037
00038 theStateMachine_.addStateTransition('F', 'H', "Halt" , "Halting" , this, &RunControlStateMachine::transitionHalting);
00039
00040
00041
00042 theStateMachine_.addStateTransition('H', 'C', "Configure" , "Configuring" , "ConfigurationAlias", this, &RunControlStateMachine::transitionConfiguring);
00043
00044
00045 theStateMachine_.addStateTransition('I', 'H', "Initialize", "Initializing", this, &RunControlStateMachine::transitionInitializing);
00046 theStateMachine_.addStateTransition('H', 'H', "Halt" , "Halting" , this, &RunControlStateMachine::transitionHalting);
00047 theStateMachine_.addStateTransition('C', 'H', "Halt" , "Halting" , this, &RunControlStateMachine::transitionHalting);
00048 theStateMachine_.addStateTransition('R', 'H', "Abort" , "Aborting" , this, &RunControlStateMachine::transitionHalting);
00049 theStateMachine_.addStateTransition('P', 'H', "Abort" , "Aborting" , this, &RunControlStateMachine::transitionHalting);
00050
00051
00052 theStateMachine_.addStateTransition('R', 'P', "Pause" , "Pausing" , this, &RunControlStateMachine::transitionPausing);
00053 theStateMachine_.addStateTransition('P', 'R', "Resume" , "Resuming" , this, &RunControlStateMachine::transitionResuming);
00054 theStateMachine_.addStateTransition('C', 'R', "Start" , "Starting" , this, &RunControlStateMachine::transitionStarting);
00055 theStateMachine_.addStateTransition('R', 'C', "Stop" , "Stopping" , this, &RunControlStateMachine::transitionStopping);
00056 theStateMachine_.addStateTransition('P', 'C', "Stop" , "Stopping" , this, &RunControlStateMachine::transitionStopping);
00057
00058
00059
00060
00061 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Initialize", XDAQ_NS_URI);
00062 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Configure" , XDAQ_NS_URI);
00063 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Start" , XDAQ_NS_URI);
00064 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Stop" , XDAQ_NS_URI);
00065 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Pause" , XDAQ_NS_URI);
00066 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Resume" , XDAQ_NS_URI);
00067 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Halt" , XDAQ_NS_URI);
00068 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Abort" , XDAQ_NS_URI);
00069
00070
00071 reset();
00072 }
00073
00074
00075 RunControlStateMachine::~RunControlStateMachine(void)
00076 {
00077 }
00078
00079
00080 void RunControlStateMachine::reset(void)
00081 {
00082 __MOUT__ << stateMachineName_ << " is in transition?" << theStateMachine_.isInTransition() << std::endl;
00083 theStateMachine_.setInitialState('I');
00084 theStateMachine_.reset();
00085 __MOUT__ << stateMachineName_ << " is in transition?" << theStateMachine_.isInTransition() << std::endl;
00086 }
00087
00088
00089 xoap::MessageReference RunControlStateMachine::runControlMessageHandler(
00090 xoap::MessageReference message)
00091 throw (xoap::exception::Exception)
00092 {
00093 __MOUT__ << "Starting state for " << stateMachineName_ << " is " << theStateMachine_.getCurrentStateName() << std::endl;
00094 __MOUT__ << SOAPUtilities::translate(message) << std::endl;
00095 std::string command = SOAPUtilities::translate(message).getCommand();
00096
00097 theProgressBar_.reset(command,stateMachineName_);
00098 std::string result = command + "Done";
00099
00100
00101
00102 if(command == "Error" || command == "Fail")
00103 {
00104 __SS__ << command << " was received! Immediately throwing FSM exception." << std::endl;
00105 __MOUT_ERR__ << "\n" << ss.str();
00106 XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
00107 return SOAPUtilities::makeSOAPMessageReference(result);
00108 }
00109
00110
00111 try
00112 {
00113 theStateMachine_.execTransition(command,message);
00114
00115
00116 if(theStateMachine_.getCurrentStateName() == RunControlStateMachine::FAILED_STATE_NAME)
00117 {
00118 result = command + " " + RunControlStateMachine::FAILED_STATE_NAME + ": " + theStateMachine_.getErrorMessage();
00119 __MOUT_ERR__ << "Unexpected Failure state for " << stateMachineName_ << " is " << theStateMachine_.getCurrentStateName() << std::endl;
00120 __MOUT_ERR__ << "Error message was as follows: " << theStateMachine_.getErrorMessage() << std::endl;
00121 }
00122 }
00123 catch (toolbox::fsm::exception::Exception& e)
00124 {
00125 result = command + " " + RunControlStateMachine::FAILED_STATE_NAME + ": " + theStateMachine_.getErrorMessage();
00126 __SS__ << "Run Control Message Handling Failed: " << e.what() << std::endl;
00127 __MOUT_ERR__ << "\n" << ss.str();
00128 __MOUT_ERR__ << "Error message was as follows: " << theStateMachine_.getErrorMessage() << std::endl;
00129 }
00130
00131 theProgressBar_.complete();
00132 __MOUT__ << "Ending state for " << stateMachineName_ << " is " << theStateMachine_.getCurrentStateName() << std::endl;
00133 __MOUT__ << "result = " << result << std::endl;
00134 return SOAPUtilities::makeSOAPMessageReference(result);
00135 }
00136