00001 #include "otsdaq-core/CoreSupervisors/CoreSupervisorBase.h"
00002
00003
00004
00005
00006
00007
00008 #include <iostream>
00009
00010 using namespace ots;
00011
00012
00013
00014
00015 const std::string CoreSupervisorBase::WORK_LOOP_DONE = "Done";
00016 const std::string CoreSupervisorBase::WORK_LOOP_WORKING = "Working";
00017
00018
00019 CoreSupervisorBase::CoreSupervisorBase(xdaq::ApplicationStub * s)
00020 : xdaq::Application (s)
00021 , SOAPMessenger (this)
00022 , CorePropertySupervisorBase (this)
00023 , RunControlStateMachine (CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode()?
00024 CorePropertySupervisorBase::supervisorClassNoNamespace_:
00025 CorePropertySupervisorBase::supervisorClassNoNamespace_ + ":" + CorePropertySupervisorBase::supervisorApplicationUID_)
00026 , stateMachineWorkLoopManager_ (toolbox::task::bind(this, &CoreSupervisorBase::stateMachineThread, "StateMachine"))
00027 , stateMachineSemaphore_ (toolbox::BSem::FULL)
00028
00029
00030
00031 , theRemoteWebUsers_ (this)
00032
00033 {
00034 INIT_MF("CoreSupervisorBase");
00035
00036 __SUP_COUT__ << "Begin!" << std::endl;
00037
00038 xgi::bind (this, &CoreSupervisorBase::defaultPageWrapper, "Default" );
00039 xgi::bind (this, &CoreSupervisorBase::requestWrapper, "Request");
00040
00041 xgi::bind (this, &CoreSupervisorBase::stateMachineXgiHandler, "StateMachineXgiHandler");
00042
00043 xoap::bind(this, &CoreSupervisorBase::stateMachineStateRequest, "StateMachineStateRequest", XDAQ_NS_URI );
00044 xoap::bind(this, &CoreSupervisorBase::stateMachineErrorMessageRequest, "StateMachineErrorMessageRequest", XDAQ_NS_URI );
00045
00046 xoap::bind(this, &CoreSupervisorBase::workLoopStatusRequestWrapper, "WorkLoopStatusRequest", XDAQ_NS_URI );
00047
00048 return;
00049 }
00050
00051
00052 CoreSupervisorBase::~CoreSupervisorBase(void)
00053 {
00054 destroy();
00055 }
00056
00057
00058 void CoreSupervisorBase::destroy(void)
00059 {
00060 __SUP_COUT__ << "Destroying..." << std::endl;
00061 for(auto& it: theStateMachineImplementation_)
00062 delete it;
00063 theStateMachineImplementation_.clear();
00064 }
00065
00066
00067
00068 void CoreSupervisorBase::defaultPageWrapper(xgi::Input * in, xgi::Output * out )
00069 {
00070 return defaultPage(in,out);
00071 }
00072
00073
00074 void CoreSupervisorBase::defaultPage(xgi::Input * in, xgi::Output * out )
00075 {
00076 __SUP_COUT__<< "Supervisor class " << supervisorClass_ << std::endl;
00077
00078 std::stringstream pagess;
00079 pagess << "/WebPath/html/" <<
00080 supervisorClassNoNamespace_ << ".html?urn=" <<
00081 this->getApplicationDescriptor()->getLocalId();
00082
00083 __SUP_COUT__<< "Default page = " << pagess.str() << std::endl;
00084
00085 *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='" <<
00086 pagess.str() <<
00087 "'></frameset></html>";
00088 }
00089
00090
00091
00092
00093 void CoreSupervisorBase::requestWrapper(xgi::Input * in, xgi::Output * out )
00094
00095 {
00096
00097
00098 cgicc::Cgicc cgiIn(in);
00099 std::string requestType = CgiDataUtilities::getData(cgiIn,"RequestType");
00100
00101
00102
00103 HttpXmlDocument xmlOut;
00104 WebUsers::RequestUserInfo userInfo(requestType,
00105 CgiDataUtilities::getOrPostData(cgiIn,"CookieCode"));
00106
00107 CorePropertySupervisorBase::getRequestUserInfo(userInfo);
00108
00109 if(!theRemoteWebUsers_.xmlRequestToGateway(
00110 cgiIn,
00111 out,
00112 &xmlOut,
00113 CorePropertySupervisorBase::allSupervisorInfo_,
00114 userInfo))
00115 return;
00116
00117
00118
00119
00120
00121 if(!userInfo.automatedCommand_)
00122 __SUP_COUT__ << "requestType: " << requestType << __E__;
00123
00124 if(userInfo.NonXMLRequestType_)
00125 {
00126 nonXmlRequest(requestType,cgiIn,*out,userInfo);
00127 return;
00128 }
00129
00130
00131 request(requestType,cgiIn,xmlOut,userInfo);
00132
00133
00134 {
00135 unsigned int occurance = 0;
00136 std::string err = xmlOut.getMatchingValue("Error",occurance++);
00137 while(err != "")
00138 {
00139 __SUP_COUT_ERR__ << "'" << requestType << "' ERROR encountered: " << err << std::endl;
00140 __MOUT_ERR__ << "'" << requestType << "' ERROR encountered: " << err << std::endl;
00141 err = xmlOut.getMatchingValue("Error",occurance++);
00142 }
00143 }
00144
00145
00146
00147 xmlOut.outputXmlDocument((std::ostringstream*) out, false ,
00148 !userInfo.NoXmlWhiteSpace_);
00149
00150 }
00151
00152
00153
00154
00155
00156
00157 void CoreSupervisorBase::request(const std::string& requestType, cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut,
00158 const WebUsers::RequestUserInfo& userInfo)
00159 {
00160 __SUP_COUT__ << "This is the empty Core Supervisor request. Supervisors should override this function." << __E__;
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 }
00186
00187
00188
00189
00190
00191
00192 void CoreSupervisorBase::nonXmlRequest(const std::string& requestType, cgicc::Cgicc& cgiIn, std::ostream& out,
00193 const WebUsers::RequestUserInfo& userInfo)
00194 {
00195 __SUP_COUT__ << "This is the empty Core Supervisor non-xml request. Supervisors should override this function." << __E__;
00196 out << "This is the empty Core Supervisor non-xml request. Supervisors should override this function." << __E__;
00197 }
00198
00199
00200 void CoreSupervisorBase::stateMachineXgiHandler(xgi::Input * in, xgi::Output * out )
00201
00202 {}
00203
00204
00205 void CoreSupervisorBase::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out )
00206
00207 {}
00208
00209
00210 xoap::MessageReference CoreSupervisorBase::stateMachineXoapHandler(xoap::MessageReference message )
00211
00212 {
00213 __SUP_COUT__<< "Soap Handler!" << std::endl;
00214 stateMachineWorkLoopManager_.removeProcessedRequests();
00215 stateMachineWorkLoopManager_.processRequest(message);
00216 __SUP_COUT__<< "Done - Soap Handler!" << std::endl;
00217 return message;
00218 }
00219
00220
00221 xoap::MessageReference CoreSupervisorBase::stateMachineResultXoapHandler(xoap::MessageReference message )
00222
00223 {
00224 __SUP_COUT__<< "Soap Handler!" << std::endl;
00225
00226
00227 __SUP_COUT__<< "Done - Soap Handler!" << std::endl;
00228 return message;
00229 }
00230
00231
00232
00233 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequestWrapper(xoap::MessageReference message)
00234
00235 {
00236
00237 return workLoopStatusRequest(message);
00238 }
00239
00240
00241 xoap::MessageReference CoreSupervisorBase::workLoopStatusRequest(xoap::MessageReference message)
00242
00243 {
00244
00245 return SOAPUtilities::makeSOAPMessageReference(CoreSupervisorBase::WORK_LOOP_DONE);
00246 }
00247
00248
00249 bool CoreSupervisorBase::stateMachineThread(toolbox::task::WorkLoop* workLoop)
00250 {
00251 stateMachineSemaphore_.take();
00252 __SUP_COUT__<< "Re-sending message..." << SOAPUtilities::translate(stateMachineWorkLoopManager_.getMessage(workLoop)).getCommand() << std::endl;
00253 std::string reply = send(this->getApplicationDescriptor(),stateMachineWorkLoopManager_.getMessage(workLoop));
00254 stateMachineWorkLoopManager_.report(workLoop, reply, 100, true);
00255 __SUP_COUT__<< "Done with message" << std::endl;
00256 stateMachineSemaphore_.give();
00257 return false;
00258
00259 }
00260
00261
00262 xoap::MessageReference CoreSupervisorBase::stateMachineStateRequest(xoap::MessageReference message)
00263
00264 {
00265 __SUP_COUT__<< "theStateMachine_.getCurrentStateName() = " << theStateMachine_.getCurrentStateName() << std::endl;
00266 return SOAPUtilities::makeSOAPMessageReference(theStateMachine_.getCurrentStateName());
00267 }
00268
00269
00270 xoap::MessageReference CoreSupervisorBase::stateMachineErrorMessageRequest(xoap::MessageReference message)
00271
00272 {
00273 __SUP_COUT__<< "theStateMachine_.getErrorMessage() = " << theStateMachine_.getErrorMessage() << std::endl;
00274
00275 SOAPParameters retParameters;
00276 retParameters.addParameter("ErrorMessage",theStateMachine_.getErrorMessage());
00277 return SOAPUtilities::makeSOAPMessageReference("stateMachineErrorMessageRequestReply",retParameters);
00278 }
00279
00280
00281 void CoreSupervisorBase::stateInitial(toolbox::fsm::FiniteStateMachine& fsm)
00282
00283 {
00284 __SUP_COUT__ << "CoreSupervisorBase::stateInitial" << std::endl;
00285 }
00286
00287
00288 void CoreSupervisorBase::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
00289
00290 {
00291 __SUP_COUT__ << "CoreSupervisorBase::stateHalted" << std::endl;
00292 }
00293
00294
00295 void CoreSupervisorBase::stateRunning(toolbox::fsm::FiniteStateMachine& fsm)
00296
00297 {
00298 __SUP_COUT__ << "CoreSupervisorBase::stateRunning" << std::endl;
00299 }
00300
00301
00302 void CoreSupervisorBase::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm)
00303
00304 {
00305 __SUP_COUT__ << "CoreSupervisorBase::stateConfigured" << std::endl;
00306 }
00307
00308
00309 void CoreSupervisorBase::statePaused(toolbox::fsm::FiniteStateMachine& fsm)
00310
00311 {
00312 __SUP_COUT__ << "CoreSupervisorBase::statePaused" << std::endl;
00313 }
00314
00315
00316 void CoreSupervisorBase::inError (toolbox::fsm::FiniteStateMachine & fsm)
00317
00318 {
00319 __SUP_COUT__<< "Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
00320
00321 }
00322
00323
00324 void CoreSupervisorBase::enteringError (toolbox::Event::Reference e)
00325
00326 {
00327 __SUP_COUT__<< "Fsm current state: " << theStateMachine_.getCurrentStateName()
00328 << "\n\nError Message: " <<
00329 theStateMachine_.getErrorMessage() << std::endl;
00330 toolbox::fsm::FailedEvent& failedEvent = dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
00331 std::ostringstream error;
00332 error << "Failure performing transition from "
00333 << failedEvent.getFromState()
00334 << " to "
00335 << failedEvent.getToState()
00336 << " exception: " << failedEvent.getException().what();
00337 __SUP_COUT_ERR__<< error.str() << std::endl;
00338
00339
00340 }
00341
00342
00343 void CoreSupervisorBase::transitionConfiguring(toolbox::Event::Reference e)
00344
00345 {
00346 __SUP_COUT__ << "transitionConfiguring" << std::endl;
00347
00348 std::pair<std::string , ConfigurationGroupKey> theGroup(
00349 SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
00350 getParameters().getValue("ConfigurationGroupName"),
00351 ConfigurationGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
00352 getParameters().getValue("ConfigurationGroupKey")));
00353
00354 __SUP_COUT__ << "Configuration group name: " << theGroup.first << " key: " <<
00355 theGroup.second << std::endl;
00356
00357 theConfigurationManager_->loadConfigurationGroup(
00358 theGroup.first,
00359 theGroup.second, true);
00360
00361
00362
00363 try
00364 {
00365 for(auto& it: theStateMachineImplementation_)
00366 it->configure();
00367 }
00368 catch(const std::runtime_error& e)
00369 {
00370 __SUP_SS__ << "Error was caught while configuring: " << e.what() << std::endl;
00371 __SUP_COUT_ERR__ << "\n" << ss.str();
00372 theStateMachine_.setErrorMessage(ss.str());
00373 throw toolbox::fsm::exception::Exception(
00374 "Transition Error" ,
00375 ss.str() ,
00376 "CoreSupervisorBase::transitionConfiguring" ,
00377 __LINE__ ,
00378 __FUNCTION__
00379 );
00380 }
00381
00382 }
00383
00384
00385
00386
00387 void CoreSupervisorBase::transitionHalting(toolbox::Event::Reference e)
00388
00389 {
00390 __SUP_COUT__ << "transitionHalting" << std::endl;
00391
00392 for(auto& it: theStateMachineImplementation_)
00393 {
00394 try
00395 {
00396 it->halt();
00397 }
00398 catch(const std::runtime_error& e)
00399 {
00400
00401 if(theStateMachine_.getProvenanceStateName() ==
00402 RunControlStateMachine::FAILED_STATE_NAME)
00403 {
00404 __SUP_COUT_INFO__ << "Error was caught while halting (but ignoring because previous state was '" <<
00405 RunControlStateMachine::FAILED_STATE_NAME << "'): " << e.what() << std::endl;
00406 }
00407 else
00408 {
00409 __SUP_SS__ << "Error was caught while halting: " << e.what() << std::endl;
00410 __SUP_COUT_ERR__ << "\n" << ss.str();
00411 theStateMachine_.setErrorMessage(ss.str());
00412 throw toolbox::fsm::exception::Exception(
00413 "Transition Error" ,
00414 ss.str() ,
00415 "CoreSupervisorBase::transitionHalting" ,
00416 __LINE__ ,
00417 __FUNCTION__
00418 );
00419 }
00420 }
00421 }
00422 }
00423
00424
00425
00426
00427 void CoreSupervisorBase::transitionInitializing(toolbox::Event::Reference e)
00428
00429 {
00430 __SUP_COUT__ << "transitionInitializing" << std::endl;
00431
00432 CorePropertySupervisorBase::resetPropertiesAreSetup();
00433
00434
00435
00436
00437
00438
00439 }
00440
00441
00442 void CoreSupervisorBase::transitionPausing(toolbox::Event::Reference e)
00443
00444 {
00445 __SUP_COUT__ << "transitionPausing" << std::endl;
00446
00447 try
00448 {
00449 for(auto& it: theStateMachineImplementation_)
00450 it->pause();
00451 }
00452 catch(const std::runtime_error& e)
00453 {
00454 __SUP_SS__ << "Error was caught while pausing: " << e.what() << std::endl;
00455 __SUP_COUT_ERR__ << "\n" << ss.str();
00456 theStateMachine_.setErrorMessage(ss.str());
00457 throw toolbox::fsm::exception::Exception(
00458 "Transition Error" ,
00459 ss.str() ,
00460 "CoreSupervisorBase::transitionPausing" ,
00461 __LINE__ ,
00462 __FUNCTION__
00463 );
00464 }
00465 }
00466
00467
00468 void CoreSupervisorBase::transitionResuming(toolbox::Event::Reference e)
00469
00470 {
00471
00472
00473
00474 __SUP_COUT__ << "transitionResuming" << std::endl;
00475
00476 try
00477 {
00478 for(auto& it: theStateMachineImplementation_)
00479 it->resume();
00480 }
00481 catch(const std::runtime_error& e)
00482 {
00483 __SUP_SS__ << "Error was caught while resuming: " << e.what() << std::endl;
00484 __SUP_COUT_ERR__ << "\n" << ss.str();
00485 theStateMachine_.setErrorMessage(ss.str());
00486 throw toolbox::fsm::exception::Exception(
00487 "Transition Error" ,
00488 ss.str() ,
00489 "CoreSupervisorBase::transitionResuming" ,
00490 __LINE__ ,
00491 __FUNCTION__
00492 );
00493 }
00494 }
00495
00496
00497 void CoreSupervisorBase::transitionStarting(toolbox::Event::Reference e)
00498
00499 {
00500
00501
00502
00503 __SUP_COUT__ << "transitionStarting" << std::endl;
00504
00505 try
00506 {
00507 for(auto& it: theStateMachineImplementation_)
00508 it->start(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue("RunNumber"));
00509 }
00510 catch(const std::runtime_error& e)
00511 {
00512 __SUP_SS__ << "Error was caught while starting: " << e.what() << std::endl;
00513 __SUP_COUT_ERR__ << "\n" << ss.str();
00514 theStateMachine_.setErrorMessage(ss.str());
00515 throw toolbox::fsm::exception::Exception(
00516 "Transition Error" ,
00517 ss.str() ,
00518 "CoreSupervisorBase::transitionStarting" ,
00519 __LINE__ ,
00520 __FUNCTION__
00521 );
00522 }
00523 }
00524
00525
00526 void CoreSupervisorBase::transitionStopping(toolbox::Event::Reference e)
00527
00528 {
00529 __SUP_COUT__ << "transitionStopping" << std::endl;
00530
00531 try
00532 {
00533 for(auto& it: theStateMachineImplementation_)
00534 it->stop();
00535 }
00536 catch(const std::runtime_error& e)
00537 {
00538 __SUP_SS__ << "Error was caught while pausing: " << e.what() << std::endl;
00539 __SUP_COUT_ERR__ << "\n" << ss.str();
00540 theStateMachine_.setErrorMessage(ss.str());
00541 throw toolbox::fsm::exception::Exception(
00542 "Transition Error" ,
00543 ss.str() ,
00544 "CoreSupervisorBase::transitionStopping" ,
00545 __LINE__ ,
00546 __FUNCTION__
00547 );
00548 }
00549 }