1 #include "otsdaq-core/CoreSupervisors/CoreSupervisorBase.h"
15 const std::string CoreSupervisorBase::WORK_LOOP_DONE =
"Done";
16 const std::string CoreSupervisorBase::WORK_LOOP_WORKING =
"Working";
19 CoreSupervisorBase::CoreSupervisorBase(xdaq::ApplicationStub * s)
20 throw (xdaq::exception::Exception)
21 : xdaq::Application (s)
23 , stateMachineWorkLoopManager_ (toolbox::task::bind(
this, &CoreSupervisorBase::stateMachineThread,
"StateMachine"))
24 , stateMachineSemaphore_ (toolbox::BSem::FULL)
26 , XDAQContextConfigurationName_ (theConfigurationManager_->__GET_CONFIG__(
XDAQContextConfiguration)->getConfigurationName())
27 , supervisorConfigurationPath_ (
"INITIALIZED INSIDE THE CONTRUCTOR BECAUSE IT NEEDS supervisorContextUID_ and supervisorApplicationUID_")
28 , supervisorContextUID_ (
"INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
29 , supervisorApplicationUID_ (
"INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
30 , supervisorClass_ (getApplicationDescriptor()->getClassName())
31 , supervisorClassNoNamespace_ (supervisorClass_.substr(supervisorClass_.find_last_of(
":")+1, supervisorClass_.length()-supervisorClass_.find_last_of(
":")))
32 , theRemoteWebUsers_ (
this)
33 , LOCK_REQUIRED_ (
false)
34 , USER_PERMISSIONS_THRESHOLD_ (1)
36 INIT_MF(
"CoreSupervisorBase");
38 __COUT__ <<
"Begin!" << std::endl;
40 xgi::bind (
this, &CoreSupervisorBase::DefaultWrapper,
"Default" );
41 xgi::bind (
this, &CoreSupervisorBase::requestWrapper,
"Request");
42 xgi::bind (
this, &CoreSupervisorBase::stateMachineXgiHandler,
"StateMachineXgiHandler");
44 xoap::bind(
this, &CoreSupervisorBase::stateMachineStateRequest,
"StateMachineStateRequest", XDAQ_NS_URI );
45 xoap::bind(
this, &CoreSupervisorBase::stateMachineErrorMessageRequest,
"StateMachineErrorMessageRequest", XDAQ_NS_URI );
47 xoap::bind(
this, &CoreSupervisorBase::workLoopStatusRequestWrapper,
"WorkLoopStatusRequest", XDAQ_NS_URI );
52 getApplicationContext()->getContextDescriptor()->getURL());
56 __COUT_ERR__ <<
"XDAQ Supervisor could not access it's configuration through the Configuration Context Group." <<
57 " The XDAQContextConfigurationName = " << XDAQContextConfigurationName_ <<
58 ". The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
65 getApplicationContext()->getContextDescriptor()->getURL(),
66 getApplicationDescriptor()->getLocalId()
71 __COUT_ERR__ <<
"XDAQ Supervisor could not access it's configuration through the Configuration Application Group."
72 <<
" The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
75 supervisorConfigurationPath_ =
"/" + supervisorContextUID_ +
"/LinkToApplicationConfiguration/" + supervisorApplicationUID_ +
"/LinkToSupervisorConfiguration";
77 setStateMachineName(supervisorApplicationUID_);
79 allSupervisorInfo_.init(getApplicationContext());
80 __COUT__ <<
"Name = " << allSupervisorInfo_.getSupervisorInfo(
this).getName();
83 __COUT__ <<
"Initializing..." << std::endl;
85 setSupervisorPropertyDefaults();
90 __COUT__ <<
"Looking for " <<
91 supervisorContextUID_ <<
"/" << supervisorApplicationUID_ <<
92 " supervisor security settings..." << __E__;
95 supervisorContextUID_, supervisorApplicationUID_);
98 auto children = appNode.getNode(
"LinkToPropertyConfiguration").getChildren();
100 for(
auto& child:children)
102 if(child.second.getNode(
"Status").getValue<
bool>() ==
false)
continue;
104 auto propertyName = child.second.getNode(
"PropertyName");
106 if(propertyName.getValue() ==
107 supervisorProperties_.fieldRequireLock)
109 LOCK_REQUIRED_ = child.second.getNode(
"PropertyValue").getValue<
bool>();
110 __COUTV__(LOCK_REQUIRED_);
112 else if(propertyName.getValue() ==
113 supervisorProperties_.fieldUserPermissionsThreshold)
115 USER_PERMISSIONS_THRESHOLD_ = child.second.getNode(
"PropertyValue").getValue<uint8_t>();
116 __COUTV__(USER_PERMISSIONS_THRESHOLD_);
122 __COUT__ <<
"No supervisor security settings found, going with defaults." << __E__;
128 CoreSupervisorBase::~CoreSupervisorBase(
void)
136 void CoreSupervisorBase::setSupervisorPropertyDefaults(
void)
140 __COUT__ <<
"Using base class property defaults..." << std::endl;
142 LOCK_REQUIRED_ =
false;
143 USER_PERMISSIONS_THRESHOLD_ = 1;
144 USER_GROUPS_ALLOWED_ =
"";
145 USER_GROUPS_DISALLOWED_ =
"";
147 __COUTV__(LOCK_REQUIRED_);
148 __COUTV__(USER_PERMISSIONS_THRESHOLD_);
149 __COUTV__(USER_GROUPS_ALLOWED_);
150 __COUTV__(USER_GROUPS_DISALLOWED_);
154 void CoreSupervisorBase::destroy(
void)
156 __COUT__ <<
"Destroying..." << std::endl;
157 for(
auto& it: theStateMachineImplementation_)
159 theStateMachineImplementation_.clear();
164 void CoreSupervisorBase::DefaultWrapper(xgi::Input * in, xgi::Output * out )
165 throw (xgi::exception::Exception)
167 return Default(in,out);
171 void CoreSupervisorBase::Default(xgi::Input * in, xgi::Output * out )
172 throw (xgi::exception::Exception)
174 __COUT__<<
"Supervisor class " << supervisorClass_ << std::endl;
176 std::stringstream pagess;
177 pagess <<
"/WebPath/html/" <<
178 supervisorClassNoNamespace_ <<
".html?urn=" <<
179 this->getApplicationDescriptor()->getLocalId();
181 __COUT__<<
"Default page = " << pagess.str() << std::endl;
183 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='" <<
185 "'></frameset></html>";
190 void CoreSupervisorBase::requestWrapper(xgi::Input * in, xgi::Output * out )
191 throw (xgi::exception::Exception)
193 return request(in,out);
197 void CoreSupervisorBase::request(xgi::Input * in, xgi::Output * out )
198 throw (xgi::exception::Exception)
218 void CoreSupervisorBase::stateMachineXgiHandler(xgi::Input * in, xgi::Output * out )
219 throw (xgi::exception::Exception)
223 void CoreSupervisorBase::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out )
224 throw (xgi::exception::Exception)
228 xoap::MessageReference CoreSupervisorBase::stateMachineXoapHandler(xoap::MessageReference message )
229 throw (xoap::exception::Exception)
231 __COUT__<<
"Soap Handler!" << std::endl;
232 stateMachineWorkLoopManager_.removeProcessedRequests();
233 stateMachineWorkLoopManager_.processRequest(message);
234 __COUT__<<
"Done - Soap Handler!" << std::endl;
239 xoap::MessageReference CoreSupervisorBase::stateMachineResultXoapHandler(xoap::MessageReference message )
240 throw (xoap::exception::Exception)
242 __COUT__<<
"Soap Handler!" << std::endl;
245 __COUT__<<
"Done - Soap Handler!" << std::endl;
251 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequestWrapper(xoap::MessageReference message)
252 throw (xoap::exception::Exception)
255 return workLoopStatusRequest(message);
259 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequest(xoap::MessageReference message)
260 throw (xoap::exception::Exception)
263 return SOAPUtilities::makeSOAPMessageReference(CoreSupervisorBase::WORK_LOOP_DONE);
267 bool CoreSupervisorBase::stateMachineThread(toolbox::task::WorkLoop* workLoop)
269 stateMachineSemaphore_.take();
270 __COUT__<<
"Re-sending message..." << SOAPUtilities::translate(stateMachineWorkLoopManager_.getMessage(workLoop)).getCommand() << std::endl;
271 std::string reply = send(this->getApplicationDescriptor(),stateMachineWorkLoopManager_.getMessage(workLoop));
272 stateMachineWorkLoopManager_.report(workLoop, reply, 100,
true);
273 __COUT__<<
"Done with message" << std::endl;
274 stateMachineSemaphore_.give();
280 xoap::MessageReference CoreSupervisorBase::stateMachineStateRequest(xoap::MessageReference message)
281 throw (xoap::exception::Exception)
283 __COUT__<<
"theStateMachine_.getCurrentStateName() = " << theStateMachine_.getCurrentStateName() << std::endl;
284 return SOAPUtilities::makeSOAPMessageReference(theStateMachine_.getCurrentStateName());
288 xoap::MessageReference CoreSupervisorBase::stateMachineErrorMessageRequest(xoap::MessageReference message)
289 throw (xoap::exception::Exception)
291 __COUT__<<
"theStateMachine_.getErrorMessage() = " << theStateMachine_.getErrorMessage() << std::endl;
294 retParameters.addParameter(
"ErrorMessage",theStateMachine_.getErrorMessage());
295 return SOAPUtilities::makeSOAPMessageReference(
"stateMachineErrorMessageRequestReply",retParameters);
299 void CoreSupervisorBase::stateInitial(toolbox::fsm::FiniteStateMachine& fsm)
300 throw (toolbox::fsm::exception::Exception)
302 __COUT__ <<
"CoreSupervisorBase::stateInitial" << std::endl;
306 void CoreSupervisorBase::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
307 throw (toolbox::fsm::exception::Exception)
309 __COUT__ <<
"CoreSupervisorBase::stateHalted" << std::endl;
313 void CoreSupervisorBase::stateRunning(toolbox::fsm::FiniteStateMachine& fsm)
314 throw (toolbox::fsm::exception::Exception)
316 __COUT__ <<
"CoreSupervisorBase::stateRunning" << std::endl;
320 void CoreSupervisorBase::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm)
321 throw (toolbox::fsm::exception::Exception)
323 __COUT__ <<
"CoreSupervisorBase::stateConfigured" << std::endl;
327 void CoreSupervisorBase::statePaused(toolbox::fsm::FiniteStateMachine& fsm)
328 throw (toolbox::fsm::exception::Exception)
330 __COUT__ <<
"CoreSupervisorBase::statePaused" << std::endl;
334 void CoreSupervisorBase::inError (toolbox::fsm::FiniteStateMachine & fsm)
335 throw (toolbox::fsm::exception::Exception)
337 __COUT__<<
"Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
342 void CoreSupervisorBase::enteringError (toolbox::Event::Reference e)
343 throw (toolbox::fsm::exception::Exception)
345 __COUT__<<
"Fsm current state: " << theStateMachine_.getCurrentStateName()
346 <<
"\n\nError Message: " <<
347 theStateMachine_.getErrorMessage() << std::endl;
348 toolbox::fsm::FailedEvent& failedEvent =
dynamic_cast<toolbox::fsm::FailedEvent&
>(*e);
349 std::ostringstream error;
350 error <<
"Failure performing transition from "
351 << failedEvent.getFromState()
353 << failedEvent.getToState()
354 <<
" exception: " << failedEvent.getException().what();
355 __COUT_ERR__<< error.str() << std::endl;
361 void CoreSupervisorBase::transitionConfiguring(toolbox::Event::Reference e)
362 throw (toolbox::fsm::exception::Exception)
364 __COUT__ <<
"transitionConfiguring" << std::endl;
367 SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
368 getParameters().getValue(
"ConfigurationGroupName"),
370 getParameters().getValue(
"ConfigurationGroupKey")));
372 __COUT__ <<
"Configuration group name: " << theGroup.first <<
" key: " <<
373 theGroup.second << std::endl;
375 theConfigurationManager_->loadConfigurationGroup(
377 theGroup.second,
true);
384 for(
auto& it: theStateMachineImplementation_)
387 catch(
const std::runtime_error& e)
389 __SS__ <<
"Error was caught while configuring: " << e.what() << std::endl;
390 __COUT_ERR__ <<
"\n" << ss.str();
391 theStateMachine_.setErrorMessage(ss.str());
392 throw toolbox::fsm::exception::Exception(
395 "CoreSupervisorBase::transitionConfiguring" ,
406 void CoreSupervisorBase::transitionHalting(toolbox::Event::Reference e)
407 throw (toolbox::fsm::exception::Exception)
409 __COUT__ <<
"transitionHalting" << std::endl;
411 for(
auto& it: theStateMachineImplementation_)
417 catch(
const std::runtime_error& e)
420 if(theStateMachine_.getProvenanceStateName() ==
421 RunControlStateMachine::FAILED_STATE_NAME)
423 __COUT_INFO__ <<
"Error was caught while halting (but ignoring because previous state was '" <<
424 RunControlStateMachine::FAILED_STATE_NAME <<
"'): " << e.what() << std::endl;
428 __SS__ <<
"Error was caught while halting: " << e.what() << std::endl;
429 __COUT_ERR__ <<
"\n" << ss.str();
430 theStateMachine_.setErrorMessage(ss.str());
431 throw toolbox::fsm::exception::Exception(
434 "CoreSupervisorBase::transitionHalting" ,
444 void CoreSupervisorBase::transitionInitializing(toolbox::Event::Reference e)
445 throw (toolbox::fsm::exception::Exception)
447 __COUT__ <<
"transitionInitializing" << std::endl;
454 void CoreSupervisorBase::transitionPausing(toolbox::Event::Reference e)
455 throw (toolbox::fsm::exception::Exception)
457 __COUT__ <<
"transitionPausing" << std::endl;
461 for(
auto& it: theStateMachineImplementation_)
464 catch(
const std::runtime_error& e)
466 __SS__ <<
"Error was caught while pausing: " << e.what() << std::endl;
467 __COUT_ERR__ <<
"\n" << ss.str();
468 theStateMachine_.setErrorMessage(ss.str());
469 throw toolbox::fsm::exception::Exception(
472 "CoreSupervisorBase::transitionPausing" ,
480 void CoreSupervisorBase::transitionResuming(toolbox::Event::Reference e)
481 throw (toolbox::fsm::exception::Exception)
486 __COUT__ <<
"transitionResuming" << std::endl;
490 for(
auto& it: theStateMachineImplementation_)
493 catch(
const std::runtime_error& e)
495 __SS__ <<
"Error was caught while resuming: " << e.what() << std::endl;
496 __COUT_ERR__ <<
"\n" << ss.str();
497 theStateMachine_.setErrorMessage(ss.str());
498 throw toolbox::fsm::exception::Exception(
501 "CoreSupervisorBase::transitionResuming" ,
509 void CoreSupervisorBase::transitionStarting(toolbox::Event::Reference e)
510 throw (toolbox::fsm::exception::Exception)
515 __COUT__ <<
"transitionStarting" << std::endl;
519 for(
auto& it: theStateMachineImplementation_)
520 it->start(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue(
"RunNumber"));
522 catch(
const std::runtime_error& e)
524 __SS__ <<
"Error was caught while starting: " << e.what() << std::endl;
525 __COUT_ERR__ <<
"\n" << ss.str();
526 theStateMachine_.setErrorMessage(ss.str());
527 throw toolbox::fsm::exception::Exception(
530 "CoreSupervisorBase::transitionStarting" ,
538 void CoreSupervisorBase::transitionStopping(toolbox::Event::Reference e)
539 throw (toolbox::fsm::exception::Exception)
541 __COUT__ <<
"transitionStopping" << std::endl;
545 for(
auto& it: theStateMachineImplementation_)
548 catch(
const std::runtime_error& e)
550 __SS__ <<
"Error was caught while pausing: " << e.what() << std::endl;
551 __COUT_ERR__ <<
"\n" << ss.str();
552 theStateMachine_.setErrorMessage(ss.str());
553 throw toolbox::fsm::exception::Exception(
556 "CoreSupervisorBase::transitionStopping" ,