CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/EventFilter/Utilities/src/StateMachine.cc

Go to the documentation of this file.
00001 
00002 //
00003 // StateMachine
00004 // ------------
00005 //
00006 //            03/06/2007 Philipp Schieferdecker <philipp.schieferdecker@cern.ch>
00008 
00009 
00010 #include "EventFilter/Utilities/interface/StateMachine.h"
00011 #include "EventFilter/Utilities/interface/FsmFailedEvent.h"
00012 #include "EventFilter/Utilities/interface/Exception.h"
00013 
00014 #include "toolbox/fsm/FailedEvent.h"
00015 
00016 #include "xoap/SOAPEnvelope.h"
00017 #include "xoap/SOAPBody.h"
00018 #include "xoap/domutils.h"
00019 
00020 #include "xcept/tools.h"
00021 
00022 #include <typeinfo>
00023 #include <string>
00024 #include <sstream>
00025 
00026 
00027 using namespace std;
00028 using namespace evf;
00029 
00030 
00032 // construction/destruction
00034 
00035 //______________________________________________________________________________
00036 StateMachine::StateMachine(xdaq::Application* app)
00037   : logger_(app->getApplicationLogger())
00038   , appInfoSpace_(app->getApplicationInfoSpace())
00039   , doStateNotification_(true)
00040   , workLoopConfiguring_(0)
00041   , workLoopEnabling_(0)
00042   , workLoopStopping_(0)
00043   , workLoopHalting_(0)
00044   , asConfiguring_(0)
00045   , asEnabling_(0)
00046   , asStopping_(0)
00047   , asHalting_(0)
00048   , rcmsStateNotifier_(app->getApplicationLogger(),
00049                        app->getApplicationDescriptor(),
00050                        app->getApplicationContext())
00051 {
00052   ostringstream oss;
00053   oss<<app->getApplicationDescriptor()->getClassName()
00054      <<app->getApplicationDescriptor()->getInstance();
00055   appNameAndInstance_ = oss.str();
00056 }
00057 
00058 
00059 //______________________________________________________________________________
00060 StateMachine::~StateMachine()
00061 {
00062 
00063 }
00064 
00065 
00067 // implementation of member functions
00069 
00070 //______________________________________________________________________________
00071 xoap::MessageReference StateMachine::commandCallback(xoap::MessageReference msg)
00072   throw (xoap::exception::Exception)
00073 {
00074   xoap::SOAPPart     part    =msg->getSOAPPart();
00075   xoap::SOAPEnvelope env     =part.getEnvelope();
00076   xoap::SOAPBody     body    =env.getBody();
00077   DOMNode           *node    =body.getDOMNode();
00078   DOMNodeList       *bodyList=node->getChildNodes();
00079   DOMNode           *command =0;
00080   string             commandName;
00081   
00082   for (unsigned int i=0;i<bodyList->getLength();i++) {
00083     command = bodyList->item(i);
00084     if(command->getNodeType() == DOMNode::ELEMENT_NODE) {
00085       commandName = xoap::XMLCh2String(command->getLocalName());
00086       break;
00087     }
00088   }
00089   
00090   if (commandName.empty()) {
00091     XCEPT_RAISE(xoap::exception::Exception,"Command not found.");
00092   }
00093   
00094   // fire appropriate event and create according response message
00095   try {
00096     toolbox::Event::Reference e(new toolbox::Event(commandName,this));
00097     fsm_.fireEvent(e);
00098     
00099     // response string
00100     xoap::MessageReference reply = xoap::createMessage();
00101     xoap::SOAPEnvelope envelope  = reply->getSOAPPart().getEnvelope();
00102     xoap::SOAPName responseName  = envelope.createName(commandName+"Response",
00103                                                        "xdaq",XDAQ_NS_URI);
00104     xoap::SOAPBodyElement responseElem =
00105       envelope.getBody().addBodyElement(responseName);
00106     
00107     // state string
00108     int               iState        = fsm_.getCurrentState();
00109     string            state         = fsm_.getStateName(iState);
00110     xoap::SOAPName    stateName     = envelope.createName("state",
00111                                                           "xdaq",XDAQ_NS_URI);
00112     xoap::SOAPElement stateElem     = responseElem.addChildElement(stateName);
00113     xoap::SOAPName    attributeName = envelope.createName("stateName",
00114                                                           "xdaq",XDAQ_NS_URI);
00115     stateElem.addAttribute(attributeName,state);
00116     
00117     return reply;
00118   }
00119   catch (toolbox::fsm::exception::Exception & e) {
00120     XCEPT_RETHROW(xoap::exception::Exception,"invalid command.",e);
00121   }     
00122 }
00123 
00124 
00125 //______________________________________________________________________________
00126 void StateMachine::stateChanged(toolbox::fsm::FiniteStateMachine & fsm) 
00127   throw (toolbox::fsm::exception::Exception)
00128 {
00129   stateName_   = fsm_.getStateName(fsm_.getCurrentState());
00130   string state = stateName_.toString();
00131   
00132   LOG4CPLUS_INFO(logger_,"New state is: "<<state);
00133   
00134   if (state=="configuring") {
00135     try {
00136       workLoopConfiguring_->submit(asConfiguring_);
00137     }
00138     catch (xdaq::exception::Exception& e) {
00139       LOG4CPLUS_ERROR(logger_,xcept::stdformat_exception_history(e));
00140     }
00141   }
00142   else if (state=="enabling") {
00143     try {
00144       workLoopEnabling_->submit(asEnabling_);
00145     }
00146     catch (xdaq::exception::Exception& e) {
00147       LOG4CPLUS_ERROR(logger_,xcept::stdformat_exception_history(e));
00148     }
00149   }
00150   else if (state=="stopping") {
00151     try {
00152       workLoopStopping_->submit(asStopping_);
00153     }
00154     catch (xdaq::exception::Exception& e) {
00155       LOG4CPLUS_ERROR(logger_,xcept::stdformat_exception_history(e));
00156     }
00157   }
00158   else if (state=="halting") {
00159     try {
00160       workLoopHalting_->submit(asHalting_);
00161     }
00162     catch (xdaq::exception::Exception& e) {
00163       LOG4CPLUS_ERROR(logger_,xcept::stdformat_exception_history(e));
00164     }
00165   }
00166   else if (state=="Halted"||state=="Ready"||state=="Enabled"||state=="Failed") {
00167     if(doStateNotification_)
00168       {
00169         try {
00170           rcmsStateNotifier_.stateChanged(state,appNameAndInstance_+
00171                                           " has reached target state " +
00172                                           state);
00173         }
00174         catch (xcept::Exception& e) {
00175           LOG4CPLUS_ERROR(logger_,"Failed to notify state change: "
00176                           <<xcept::stdformat_exception_history(e));
00177         }
00178       }
00179   }
00180 }
00181 
00182 
00183 //______________________________________________________________________________
00184 void StateMachine::failed(toolbox::Event::Reference e)
00185   throw (toolbox::fsm::exception::Exception)
00186 {
00187   if (typeid(*e) == typeid(toolbox::fsm::FailedEvent)) {
00188     toolbox::fsm::FailedEvent &fe=dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
00189     LOG4CPLUS_FATAL(logger_,"Failure occurred in transition from '"
00190                     <<fe.getFromState()<<"' to '"<<fe.getToState()
00191                     <<"', exception history: "
00192                     <<xcept::stdformat_exception_history(fe.getException()));
00193   }
00194   else if (typeid(*e) == typeid(evf::FsmFailedEvent)) {
00195     evf::FsmFailedEvent &fe=dynamic_cast<evf::FsmFailedEvent&>(*e);
00196     LOG4CPLUS_FATAL(logger_,"fsm failure occured: "<<fe.errorMessage());
00197   }
00198 }
00199 
00200 
00201 //______________________________________________________________________________
00202 void StateMachine::fireEvent(const string& evtType,void* originator)
00203 {
00204   toolbox::Event::Reference e(new toolbox::Event(evtType,originator));
00205   fsm_.fireEvent(e);
00206 }
00207 
00208 
00209 //______________________________________________________________________________
00210 void StateMachine::fireFailed(const string& errorMsg,void* originator)
00211 {
00212   toolbox::Event::Reference e(new evf::FsmFailedEvent(errorMsg,originator));
00213   fsm_.fireEvent(e);
00214 }
00215 
00216 
00217 //______________________________________________________________________________
00218 void StateMachine::findRcmsStateListener()
00219 {
00220   rcmsStateNotifier_.findRcmsStateListener(); //might not be needed
00221   rcmsStateNotifier_.subscribeToChangesInRcmsStateListener(appInfoSpace_); 
00222 }