Go to the documentation of this file.00001
00002
00003
00004
00005
00006
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
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
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
00095 try {
00096 toolbox::Event::Reference e(new toolbox::Event(commandName,this));
00097 fsm_.fireEvent(e);
00098
00099
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
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();
00221 rcmsStateNotifier_.subscribeToChangesInRcmsStateListener(appInfoSpace_);
00222 }