1 #include "otsdaq/FiniteStateMachine/FiniteStateMachine.h"
2 #include "otsdaq/MessageFacility/MessageFacility.h"
4 #include "otsdaq/Macros/CoutMacros.h"
12 #define __MF_SUBJECT__ "FSM"
13 #define mfSubject_ std::string("FSM-") + getStateMachineName()
15 const char FiniteStateMachine::FAILED_STATE =
'F';
16 const std::string FiniteStateMachine::FAILED_STATE_NAME =
"Failed";
17 const std::string FiniteStateMachine::ERROR_TRANSITION_NAME =
"Error";
18 const std::string FiniteStateMachine::INITIAL_STATE_NAME =
"Initial";
19 const std::string FiniteStateMachine::CONFIGURE_TRANSITION_NAME =
"Configure";
22 FiniteStateMachine::FiniteStateMachine(
const std::string& stateMachineName)
23 : stateEntranceTime_(0)
24 , inTransition_(false)
25 , provenanceState_(
'X')
26 , theErrorMessage_(
"")
27 , stateMachineName_(stateMachineName)
29 __GEN_COUT__ <<
"Constructing FiniteStateMachine" << __E__;
33 FiniteStateMachine::~FiniteStateMachine(
void) {}
36 toolbox::fsm::State FiniteStateMachine::getProvenanceState(
void)
38 return provenanceState_;
42 toolbox::fsm::State FiniteStateMachine::getTransitionFinalState(
43 const std::string& transition)
45 if(stateTransitionTable_[currentState_].find(transition) !=
46 stateTransitionTable_[currentState_].end())
47 return stateTransitionTable_[currentState_][transition];
50 if(transition == FiniteStateMachine::ERROR_TRANSITION_NAME)
52 __GEN_COUT__ << FiniteStateMachine::ERROR_TRANSITION_NAME <<
"'ing to "
53 << FiniteStateMachine::FAILED_STATE_NAME << __E__;
54 return stateTransitionTable_[FiniteStateMachine::FAILED_STATE]
55 [FiniteStateMachine::ERROR_TRANSITION_NAME];
57 __GEN_SS__ <<
"Cannot find transition name for transition '" << transition
58 <<
"' from current state '" << currentState_ <<
".'" << __E__;
59 __GEN_COUT__ << ss.str();
60 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
65 std::string FiniteStateMachine::getProvenanceStateName(
void)
67 return getStateName(getProvenanceState());
71 std::string FiniteStateMachine::getCurrentStateName(
void)
73 return getStateName(getCurrentState());
83 return stateEntranceTime_ ? (time(0) - stateEntranceTime_) : 0;
87 std::string FiniteStateMachine::getCurrentTransitionName(
const std::string& transition)
107 if(stateTransitionNameTable_.at(provenanceState_).find(currentTransition_) !=
108 stateTransitionNameTable_.at(provenanceState_).end())
109 return stateTransitionNameTable_.at(provenanceState_).at(currentTransition_);
112 if(currentTransition_ == FiniteStateMachine::ERROR_TRANSITION_NAME)
114 __GEN_COUT__ << FiniteStateMachine::ERROR_TRANSITION_NAME <<
"'ing to "
115 << FiniteStateMachine::FAILED_STATE_NAME << __E__;
116 return currentTransition_;
118 __GEN_SS__ <<
"Cannot find transition name from '" << getProvenanceStateName()
119 <<
"' for command: " << currentTransition_ <<
"...";
122 return currentTransition_;
126 if(stateTransitionNameTable_.at(currentState_).find(transition) !=
127 stateTransitionNameTable_.at(currentState_).end())
129 return stateTransitionNameTable_.at(currentState_).at(transition);
133 if(transition == FiniteStateMachine::ERROR_TRANSITION_NAME)
135 __GEN_COUT__ << FiniteStateMachine::ERROR_TRANSITION_NAME <<
"'ing to "
136 << FiniteStateMachine::FAILED_STATE_NAME << __E__;
139 std::stringstream ss;
140 ss <<
"Cannot find transition name from '" << getCurrentStateName()
141 <<
"' for command: " << transition <<
"...";
144 if(transition == FiniteStateMachine::CONFIGURE_TRANSITION_NAME &&
145 getCurrentStateName() == FiniteStateMachine::INITIAL_STATE_NAME)
146 __GEN_COUTT__ << ss.str();
148 __GEN_COUT_WARN__ << ss.str();
154 std::string FiniteStateMachine::getTransitionName(
const toolbox::fsm::State from,
155 const std::string& transition)
157 if(stateTransitionNameTable_[from].find(transition) !=
158 stateTransitionNameTable_[from].end())
160 return stateTransitionNameTable_[from][transition];
164 if(transition == FiniteStateMachine::ERROR_TRANSITION_NAME)
166 __GEN_COUT__ << FiniteStateMachine::ERROR_TRANSITION_NAME <<
"'ing to "
167 << FiniteStateMachine::FAILED_STATE_NAME << __E__;
170 std::ostringstream error;
171 error <<
"Cannot find transition name from '" << from
172 <<
"' for command: " << transition << __E__;
173 XCEPT_RAISE(toolbox::fsm::exception::Exception, error.str());
178 std::string FiniteStateMachine::getTransitionParameter(
const toolbox::fsm::State from,
179 const std::string& transition)
181 if(stateTransitionParameterTable_[from].find(transition) !=
182 stateTransitionParameterTable_[from].end())
184 return stateTransitionParameterTable_[from][transition];
190 std::string FiniteStateMachine::getTransitionFinalStateName(
const std::string& transition)
192 return getStateName(getTransitionFinalState(transition));
196 bool FiniteStateMachine::execTransition(
const std::string& transition)
198 const xoap::MessageReference message;
199 return execTransition(transition, message);
210 bool FiniteStateMachine::execTransition(
const std::string& transition,
211 const xoap::MessageReference& message)
213 __GEN_COUTV__(transition);
215 if(transition ==
"fail")
219 __GEN_COUT__ <<
"Currently in transition '" << currentTransition_
220 <<
"' executed from current state " << getProvenanceStateName()
221 <<
". Attempting to wait for the transition to complete."
227 if(getStateName(getCurrentState()) == FiniteStateMachine::FAILED_STATE_NAME)
229 __GEN_COUT_INFO__ <<
"Already failed. Current state: "
230 << getStateName(getCurrentState())
231 <<
" last state: " << getProvenanceStateName() << __E__;
234 __GEN_COUT_INFO__ <<
"Failing now!! Current state: "
235 << getStateName(getCurrentState())
236 <<
" last state: " << getProvenanceStateName() << __E__;
242 std::map<std::string, toolbox::fsm::State> transitions =
243 getTransitions(getCurrentState());
244 for(
const auto& transitionPair : transitions)
246 __GEN_COUT__ <<
"Taking any transition to indirect failure.. found '"
247 << transitionPair.first <<
"'" << __E__;
248 __GEN_COUT__ <<
"Taking fail transition from Current state: "
249 << getStateName(getCurrentState())
250 <<
" last state: " << getProvenanceStateName() << __E__;
251 toolbox::Event::Reference event(
252 new toolbox::Event(transitionPair.first,
this));
256 this->fireEvent(event);
258 catch(toolbox::fsm::exception::Exception& e)
260 std::ostringstream error;
261 error <<
"Transition " << transition
262 <<
" was not executed from current state "
263 << getStateName(getCurrentState())
264 <<
". There was an error: " << e.what();
265 __GEN_COUT_ERR__ << error.str() << __E__;
268 stateEntranceTime_ = time(0);
279 __GEN_COUT_WARN__ <<
"In transition, and received another transition: "
280 << transition <<
". Ignoring..." << __E__;
284 bool transitionSuccessful =
true;
285 provenanceState_ = getCurrentState();
287 std::map<std::string, toolbox::fsm::State> transitions =
288 getTransitions(getCurrentState());
289 if(transitions.find(transition) == transitions.end())
292 std::ostringstream error;
294 <<
" is not in the list of the transitions from current state "
295 << getStateName(getCurrentState());
296 __GEN_COUT_ERR__ << error.str() << __E__;
297 __GEN_COUTV__(getErrorMessage());
298 XCEPT_RAISE(toolbox::fsm::exception::Exception, error.str());
309 toolbox::Event::Reference event(
new toolbox::Event(transition,
this));
313 currentTransition_ = transition;
315 this->fireEvent(event);
317 catch(toolbox::fsm::exception::Exception& e)
320 transitionSuccessful =
false;
321 std::ostringstream error;
322 __GEN_SS__ <<
"Transition " << transition
323 <<
" was not executed from current state "
324 << getStateName(getCurrentState())
325 <<
". There was an error: " << e.what();
326 __GEN_COUT_ERR__ << ss.str() << __E__;
330 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
335 transitionSuccessful =
false;
336 __GEN_SS__ <<
"Transition " << transition
337 <<
" was not executed from current state "
338 << getStateName(getCurrentState()) <<
". There was an unknown error.";
343 catch(
const std::exception& e)
345 ss <<
"Exception message: " << e.what();
350 __GEN_COUT_ERR__ << ss.str() << __E__;
354 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
358 stateEntranceTime_ = time(0);
359 return transitionSuccessful;
363 bool FiniteStateMachine::isInTransition(
void) {
return inTransition_; }
366 void FiniteStateMachine::setErrorMessage(
const std::string& errMessage,
bool append)
369 theErrorMessage_ += errMessage;
371 theErrorMessage_ = errMessage;
375 const std::string& FiniteStateMachine::getErrorMessage()
const
377 return theErrorMessage_;
381 void FiniteStateMachine::setInitialState(toolbox::fsm::State state)
383 toolbox::fsm::FiniteStateMachine::setInitialState(state);
384 provenanceState_ = state;
385 stateEntranceTime_ = time(0);
volatile bool inTransition_
time_t getTimeInState(void) const
defines used also by OtsConfigurationWizardSupervisor