00001 #include "otsdaq-core/Supervisor/Supervisor.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00004 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
00005 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h"
00006 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
00007 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
00008
00009 #include "otsdaq-core/WorkLoopManager/WorkLoopManager.h"
00010 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
00011 #include "otsdaq-core/ConfigurationInterface/ConfigurationManagerRW.h"
00012 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
00013 #include <cgicc/HTMLClasses.h>
00014 #include <cgicc/HTTPCookie.h>
00015 #include <cgicc/HTMLDoctype.h>
00016 #include <cgicc/HTTPHeader.h>
00017 #include <xgi/Utils.h>
00018
00019 #include <xoap/Method.h>
00020 #include <xdaq/NamespaceURI.h>
00021 #include <toolbox/task/WorkLoopFactory.h>
00022 #include <toolbox/fsm/FailedEvent.h>
00023
00024 #include <fstream>
00025 #include <thread>
00026 #include <chrono>
00027 #include <sys/stat.h>
00028
00029 using namespace ots;
00030
00031
00032 #define ICON_FILE_NAME std::string(getenv("SERVICE_DATA_PATH")) + "/OtsWizardData/iconList.dat"
00033 #define RUN_NUMBER_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/RunNumber/"
00034 #define RUN_NUMBER_FILE_NAME "NextRunNumber.txt"
00035 #define FSM_LAST_GROUP_ALIAS_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/RunControlData/"
00036 #define FSM_LAST_GROUP_ALIAS_FILE_START std::string("FSMLastGroupAlias-")
00037 #define FSM_USERS_PREFERENCES_FILETYPE "pref"
00038
00039
00040 #undef __MF_SUBJECT__
00041 #define __MF_SUBJECT__ "GatewaySupervisor"
00042
00043
00044 XDAQ_INSTANTIATOR_IMPL(Supervisor)
00045
00046
00047
00048 Supervisor::Supervisor(xdaq::ApplicationStub * s) throw (xdaq::exception::Exception)
00049 :xdaq::Application (s)
00050 ,SOAPMessenger (this)
00051 ,RunControlStateMachine ("Supervisor")
00052 ,outputDir_ ("")
00053 ,theConfigurationManager_ (new ConfigurationManager)
00054
00055 ,stateMachineWorkLoopManager_ (toolbox::task::bind(this, &Supervisor::stateMachineThread,"StateMachine"))
00056 ,stateMachineSemaphore_ (toolbox::BSem::FULL)
00057 ,infoRequestWorkLoopManager_ (toolbox::task::bind(this, &Supervisor::infoRequestThread, "InfoRequest"))
00058 ,infoRequestSemaphore_ (toolbox::BSem::FULL)
00059 ,activeStateMachineName_ ("")
00060 ,theIterator_ (this)
00061 ,counterTest_ (0)
00062 {
00063 INIT_MF("Supervisor");
00064 __COUT__ << std::endl;
00065
00066
00067 mkdir((FSM_LAST_GROUP_ALIAS_PATH).c_str(), 0755);
00068 mkdir((RUN_NUMBER_PATH).c_str(), 0755);
00069
00070 securityType_ = theWebUsers_.getSecurity();
00071
00072 __COUT__ << "Security: " << securityType_ << std::endl;
00073
00074 xgi::bind(this, &Supervisor::Default, "Default");
00075 xgi::bind(this, &Supervisor::loginRequest, "LoginRequest");
00076 xgi::bind(this, &Supervisor::request, "Request");
00077 xgi::bind(this, &Supervisor::stateMachineXgiHandler, "StateMachineXgiHandler");
00078 xgi::bind(this, &Supervisor::infoRequestHandler, "InfoRequestHandler");
00079 xgi::bind(this, &Supervisor::infoRequestResultHandler, "InfoRequestResultHandler");
00080 xgi::bind(this, &Supervisor::tooltipRequest, "TooltipRequest");
00081
00082 xoap::bind(this, &Supervisor::supervisorCookieCheck, "SupervisorCookieCheck", XDAQ_NS_URI);
00083 xoap::bind(this, &Supervisor::supervisorGetActiveUsers, "SupervisorGetActiveUsers", XDAQ_NS_URI);
00084 xoap::bind(this, &Supervisor::supervisorSystemMessage, "SupervisorSystemMessage", XDAQ_NS_URI);
00085 xoap::bind(this, &Supervisor::supervisorGetUserInfo, "SupervisorGetUserInfo", XDAQ_NS_URI);
00086 xoap::bind(this, &Supervisor::supervisorSystemLogbookEntry, "SupervisorSystemLogbookEntry", XDAQ_NS_URI);
00087 xoap::bind(this, &Supervisor::supervisorLastConfigGroupRequest, "SupervisorLastConfigGroupRequest", XDAQ_NS_URI);
00088
00089
00090
00091
00092
00093
00094
00095 init();
00096
00097
00098
00099 }
00100
00101
00102
00103 Supervisor::~Supervisor(void)
00104 {
00105 delete theConfigurationManager_;
00106 makeSystemLogbookEntry("ots halted.");
00107 }
00108
00109
00110 void Supervisor::init(void)
00111 {
00112
00113 theSupervisorDescriptorInfo_.init(getApplicationContext());
00114 theSupervisorsInfo_.init(theSupervisorDescriptorInfo_);
00115
00116 supervisorGuiHasBeenLoaded_ = false;
00117
00118 const XDAQContextConfiguration* contextConfiguration = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration);
00119
00120 supervisorContextUID_ = contextConfiguration->getContextUID(
00121 getApplicationContext()->getContextDescriptor()->getURL()
00122 );
00123 __COUT__ << "Context UID:" << supervisorContextUID_ << std::endl;
00124
00125 supervisorApplicationUID_ = contextConfiguration->getApplicationUID(
00126 getApplicationContext()->getContextDescriptor()->getURL(),
00127 getApplicationDescriptor()->getLocalId()
00128 );
00129
00130 __COUT__ << "Application UID:" << supervisorApplicationUID_ << std::endl;
00131
00132 ConfigurationTree configLinkNode = theConfigurationManager_->getSupervisorConfigurationNode(
00133 supervisorContextUID_, supervisorApplicationUID_);
00134
00135
00136
00137
00138 std::string supervisorUID;
00139 if(!configLinkNode.isDisconnected())
00140 supervisorUID = configLinkNode.getValue();
00141 else
00142 supervisorUID = ViewColumnInfo::DATATYPE_LINK_DEFAULT;
00143
00144 __COUT__ << "Supervisor UID:" << supervisorUID << std::endl;
00145 }
00146
00147
00148 void Supervisor::URLDisplayThread(Supervisor *supervisorPtr)
00149 {
00150 INIT_MF("Supervisor");
00151
00152
00153 int i = 0;
00154 for (; i < 5; ++i)
00155 {
00156 std::this_thread::sleep_for (std::chrono::seconds(2));
00157 std:: cout << __COUT_HDR_FL__ << "\n*********************************************************************" << std::endl;
00158 std:: cout << __COUT_HDR_FL__ << "\n\n"
00159 << supervisorPtr->getApplicationContext()->getContextDescriptor()->getURL()
00160
00161 << "/urn:xdaq-application:lid="
00162 << supervisorPtr->getApplicationDescriptor()->getLocalId() << "/"
00163 << "\n" << std::endl;
00164 std:: cout << __COUT_HDR_FL__ << "\n*********************************************************************" << std::endl;
00165 }
00166 }
00167
00168
00169
00170
00171
00173 void Supervisor::makeSystemLogbookEntry(std::string entryText)
00174 {
00175 __COUT__ << "Making System Logbook Entry: " << entryText << std::endl;
00176
00177
00178 if(!theSupervisorDescriptorInfo_.getLogbookDescriptor())
00179 {
00180 __COUT__ << "Just kidding... Logbook Descriptor not found." << std:: endl;
00181 return;
00182 }
00183
00184
00185 {
00186 std::string replace[] =
00187 {"\"", "'", "&", "<", ">", "\n", " "};
00188 std::string with[] =
00189 {"%22","%27", "%26", "%3C", "%3E", "%0A%0D", "%20%20"};
00190
00191 int numOfKeys = 7;
00192
00193 size_t f;
00194 for(int i=0;i<numOfKeys;++i)
00195 {
00196 while((f=entryText.find(replace[i])) != std::string::npos)
00197 {
00198 entryText = entryText.substr(0,f) + with[i] + entryText.substr(f+replace[i].length());
00199
00200 }
00201 }
00202 }
00203
00204
00205 SOAPParameters parameters("EntryText",entryText);
00206
00207
00208
00209 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(theSupervisorDescriptorInfo_.getLogbookDescriptor(), "MakeSystemLogbookEntry",parameters);
00210
00211 SOAPParameters retParameters("Status");
00212
00213
00214 receive(retMsg, retParameters);
00215
00216 __COUT__ << "Returned Status: " << retParameters.getValue("Status") << std::endl;
00217
00218 }
00219
00220
00221 void Supervisor::Default(xgi::Input* in, xgi::Output* out)
00222 throw (xgi::exception::Exception)
00223 {
00224
00225 if (!supervisorGuiHasBeenLoaded_ && (supervisorGuiHasBeenLoaded_ = true))
00226 makeSystemLogbookEntry("ots started.");
00227
00228 *out <<
00229 "<!DOCTYPE HTML><html lang='en'><head><title>ots</title>" <<
00230
00231
00232 "<link rel='apple-touch-icon' sizes='57x57' href='/WebPath/images/otsdaqIcons/apple-icon-57x57.png'>\
00233 <link rel='apple-touch-icon' sizes='60x60' href='/WebPath/images/otsdaqIcons/apple-icon-60x60.png'>\
00234 <link rel='apple-touch-icon' sizes='72x72' href='/WebPath/images/otsdaqIcons/apple-icon-72x72.png'>\
00235 <link rel='apple-touch-icon' sizes='76x76' href='/WebPath/images/otsdaqIcons/apple-icon-76x76.png'>\
00236 <link rel='apple-touch-icon' sizes='114x114' href='/WebPath/images/otsdaqIcons/apple-icon-114x114.png'>\
00237 <link rel='apple-touch-icon' sizes='120x120' href='/WebPath/images/otsdaqIcons/apple-icon-120x120.png'>\
00238 <link rel='apple-touch-icon' sizes='144x144' href='/WebPath/images/otsdaqIcons/apple-icon-144x144.png'>\
00239 <link rel='apple-touch-icon' sizes='152x152' href='/WebPath/images/otsdaqIcons/apple-icon-152x152.png'>\
00240 <link rel='apple-touch-icon' sizes='180x180' href='/WebPath/images/otsdaqIcons/apple-icon-180x180.png'>\
00241 <link rel='icon' type='image/png' sizes='192x192' href='/WebPath/images/otsdaqIcons/android-icon-192x192.png'>\
00242 <link rel='icon' type='image/png' sizes='32x32' href='/WebPath/images/otsdaqIcons/favicon-32x32.png'>\
00243 <link rel='icon' type='image/png' sizes='96x96' href='/WebPath/images/otsdaqIcons/favicon-96x96.png'>\
00244 <link rel='icon' type='image/png' sizes='16x16' href='/WebPath/images/otsdaqIcons/favicon-16x16.png'>\
00245 <link rel='manifest' href='/WebPath/images/otsdaqIcons/manifest.json'>\
00246 <meta name='msapplication-TileColor' content='#ffffff'>\
00247 <meta name='msapplication-TileImage' content='/ms-icon-144x144.png'>\
00248 <meta name='theme-color' content='#ffffff'>" <<
00249
00250 "</head>" <<
00251 "<frameset col='100%' row='100%'>" <<
00252 "<frame src='/WebPath/html/Supervisor.html?urn=" <<
00253 this->getApplicationDescriptor()->getLocalId() << "=securityType=" <<
00254 securityType_ << "'></frameset></html>";
00255 }
00256
00257
00258
00259
00260 void Supervisor::stateMachineXgiHandler(xgi::Input* in, xgi::Output* out)
00261 throw (xgi::exception::Exception)
00262 {
00263
00264 if(VERBOSE_MUTEX) __COUT__ << "Waiting for FSM access" << std::endl;
00265 std::lock_guard<std::mutex> lock(stateMachineAccessMutex_);
00266 if(VERBOSE_MUTEX) __COUT__ << "Have FSM access" << std::endl;
00267
00268 cgicc::Cgicc cgi(in);
00269
00270 uint8_t userPermissions;
00271 uint64_t uid;
00272 std::string userWithLock;
00273 std::string cookieCode = CgiDataUtilities::postData(cgi, "CookieCode");
00274 if (!theWebUsers_.cookieCodeIsActiveForRequest(cookieCode, &userPermissions,
00275 &uid, "0", 1, &userWithLock))
00276 {
00277 *out << cookieCode;
00278 return;
00279 }
00280
00281 std::string command = CgiDataUtilities::getData(cgi, "StateMachine");
00282
00283
00284 std::string username = "";
00285 username = theWebUsers_.getUsersUsername(uid);
00286 if (userWithLock != "" && userWithLock != username)
00287 {
00288 *out << WebUsers::REQ_USER_LOCKOUT_RESPONSE;
00289 __COUT__ << "User " << username << " is locked out. " << userWithLock << " has lock." << std::endl;
00290 return;
00291 }
00292
00293
00294 HttpXmlDocument xmldoc(cookieCode);
00295 std::string fsmName = CgiDataUtilities::getData(cgi, "fsmName");
00296 std::string fsmWindowName = CgiDataUtilities::getData(cgi, "fsmWindowName");
00297 fsmWindowName = CgiDataUtilities::decodeURIComponent(fsmWindowName);
00298 std::string currentState = theStateMachine_.getCurrentStateName();
00299
00300
00301 if (theStateMachine_.isInTransition())
00302 {
00303 __SS__ << "Error - Can not accept request because the State Machine is already in transition!" << std::endl;
00304 __COUT_ERR__ << "\n" << ss.str();
00305
00306 xmldoc.addTextElementToData("state_tranisition_attempted", "0");
00307 xmldoc.addTextElementToData("state_tranisition_attempted_err",
00308 ss.str());
00309 xmldoc.outputXmlDocument((std::ostringstream*) out, false, true);
00310 return;
00311 }
00312
00313 __COUT__ << "Check for Handled by theIterator_" << std::endl;
00314
00315
00316 if((activeStateMachineWindowName_ == "" ||
00317 activeStateMachineWindowName_ == "iterator") &&
00318 theIterator_.handleCommandRequest(xmldoc,command,fsmWindowName))
00319 {
00320 __COUT__ << "Handled by theIterator_" << std::endl;
00321 xmldoc.outputXmlDocument((std::ostringstream*) out, false);
00322 return;
00323 }
00324
00325
00327
00328
00329
00330
00331
00332 if(activeStateMachineName_ != "" &&
00333 activeStateMachineName_ != fsmName)
00334 {
00335 __COUT__ << "currentState = " <<
00336 currentState << std::endl;
00337 if(currentState != "Halted" &&
00338 currentState != "Initial")
00339 {
00340
00341
00342 __SS__ << "Error - Can not accept request because the State Machine " <<
00343 "with window name '" <<
00344 activeStateMachineWindowName_ << "' (UID: " <<
00345 activeStateMachineName_ << ") "
00346 "is currently " <<
00347 "in control of State Machine progress. ";
00348 ss << "\n\nIn order for this State Machine with window name '" <<
00349 fsmWindowName << "' (UID: " << fsmName << ") "
00350 "to control progress, please transition to Halted using the active " <<
00351 "State Machine '" << activeStateMachineWindowName_ << ".'" << std::endl;
00352 __COUT_ERR__ << "\n" << ss.str();
00353
00354 xmldoc.addTextElementToData("state_tranisition_attempted", "0");
00355 xmldoc.addTextElementToData("state_tranisition_attempted_err",
00356 ss.str());
00357 xmldoc.outputXmlDocument((std::ostringstream*) out, false, true);
00358 return;
00359 }
00360 else
00361 {
00362 activeStateMachineName_ = "";
00363 activeStateMachineWindowName_ = "";
00364 }
00365 }
00366
00367
00368
00369
00370
00371
00372 std::vector<std::string> parameters;
00373 if(command == "Configure")
00374 parameters.push_back(CgiDataUtilities::postData(cgi, "ConfigurationAlias"));
00375 attemptStateMachineTransition(&xmldoc,out,command,fsmName,fsmWindowName,
00376 username,parameters);
00377 }
00378
00379 std::string Supervisor::attemptStateMachineTransition(
00380 HttpXmlDocument* xmldoc, std::ostringstream* out,
00381 const std::string& command,
00382 const std::string& fsmName, const std::string& fsmWindowName,
00383 const std::string& username,
00384 const std::vector<std::string>& commandParameters)
00385 {
00386 std::string errorStr = "";
00387
00388 std::string currentState = theStateMachine_.getCurrentStateName();
00389 __COUT__ << "State Machine command = " << command << std::endl;
00390 __COUT__ << "fsmName = " << fsmName << std::endl;
00391 __COUT__ << "fsmWindowName = " << fsmWindowName << std::endl;
00392 __COUT__ << "activeStateMachineName_ = " << activeStateMachineName_ << std::endl;
00393
00394 SOAPParameters parameters;
00395 if (command == "Configure")
00396 {
00397 if(currentState != "Halted")
00398 {
00399 __SS__ << "Error - Can only transition to Configured if the current " <<
00400 "state is Halted. Perhaps your state machine is out of sync." <<
00401 std::endl;
00402 __COUT_ERR__ << "\n" << ss.str();
00403 errorStr = ss.str();
00404
00405 if(xmldoc) xmldoc->addTextElementToData("state_tranisition_attempted", "0");
00406 if(xmldoc) xmldoc->addTextElementToData("state_tranisition_attempted_err",
00407 ss.str());
00408 if(out) xmldoc->outputXmlDocument((std::ostringstream*) out, false, true);
00409
00410 return errorStr;
00411 }
00412
00413
00414
00415 if(!commandParameters.size())
00416 {
00417 __SS__ << "Error - Can only transition to Configured if a Configuration Alias parameter is provided." <<
00418 std::endl;
00419 __COUT_ERR__ << "\n" << ss.str();
00420 errorStr = ss.str();
00421
00422 if(xmldoc) xmldoc->addTextElementToData("state_tranisition_attempted", "0");
00423 if(xmldoc) xmldoc->addTextElementToData("state_tranisition_attempted_err",
00424 ss.str());
00425 if(out) xmldoc->outputXmlDocument((std::ostringstream*) out, false, true);
00426
00427 return errorStr;
00428 }
00429
00430 parameters.addParameter("ConfigurationAlias",
00431 commandParameters[0]);
00432
00433 std::string configurationAlias = parameters.getValue("ConfigurationAlias");
00434 __COUT__ << "Configure --> Name: ConfigurationAlias Value: " <<
00435 configurationAlias << std::endl;
00436
00437
00438 std::string fn = FSM_LAST_GROUP_ALIAS_PATH + FSM_LAST_GROUP_ALIAS_FILE_START +
00439 username + "." + FSM_USERS_PREFERENCES_FILETYPE;
00440
00441 __COUT__ << "Save FSM preferences: " << fn << std::endl;
00442 FILE *fp = fopen(fn.c_str(),"w");
00443 if(!fp)
00444 {
00445 __SS__ << ("Could not open file: " + fn) << std::endl;
00446 __COUT_ERR__ << ss.str();
00447 throw std::runtime_error(ss.str());
00448 }
00449 fprintf(fp,"FSM_last_configuration_alias %s",configurationAlias.c_str());
00450 fclose(fp);
00451
00452 activeStateMachineName_ = fsmName;
00453 activeStateMachineWindowName_ = fsmWindowName;
00454 }
00455 else if (command == "Start")
00456 {
00457 if(currentState != "Configured")
00458 {
00459 __SS__ << "Error - Can only transition to Configured if the current " <<
00460 "state is Halted. Perhaps your state machine is out of sync. " <<
00461 "(Likely the server was restarted or another user changed the state)" <<
00462 std::endl;
00463 __COUT_ERR__ << "\n" << ss.str();
00464 errorStr = ss.str();
00465
00466 if(xmldoc) xmldoc->addTextElementToData("state_tranisition_attempted", "0");
00467 if(xmldoc) xmldoc->addTextElementToData("state_tranisition_attempted_err",
00468 ss.str());
00469 if(out) xmldoc->outputXmlDocument((std::ostringstream*) out, false, true);
00470
00471 return errorStr;
00472 }
00473
00474 unsigned int runNumber = getNextRunNumber();
00475 parameters.addParameter("RunNumber", runNumber);
00476 setNextRunNumber(++runNumber);
00477 }
00478
00479 xoap::MessageReference message = SOAPUtilities::makeSOAPMessageReference(
00480 command, parameters);
00481
00482 xoap::MessageReference reply = stateMachineXoapHandler(message);
00483
00484
00485
00486 if(xmldoc) xmldoc->addTextElementToData("state_tranisition_attempted", "1");
00487 if(out) xmldoc->outputXmlDocument((std::ostringstream*) out, false);
00488 __COUT__ << "FSM state transition launched!" << std::endl;
00489
00490 return errorStr;
00491 }
00492
00493
00494 void Supervisor::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out)
00495 throw (xgi::exception::Exception)
00496 {
00497 cgicc::Cgicc cgi(in);
00498 __COUT__ << "Xgi Request!" << std::endl;
00499
00500 uint8_t userPermissions;
00501 std::string cookieCode = CgiDataUtilities::postData(cgi, "CookieCode");
00502 if (!theWebUsers_.cookieCodeIsActiveForRequest(cookieCode,
00503 &userPermissions))
00504 {
00505 *out << cookieCode;
00506 return;
00507 }
00508
00509 HttpXmlDocument xmldoc(cookieCode);
00510
00511 std::string command = CgiDataUtilities::getData(cgi, "StateMachine");
00512
00513 SOAPParameters parameters;
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 xoap::MessageReference message = SOAPUtilities::makeSOAPMessageReference(
00533 CgiDataUtilities::getData(cgi, "StateMachine"), parameters);
00534
00535 xoap::MessageReference reply = stateMachineResultXoapHandler(message);
00536
00537
00538
00539 __COUT__ << "Done - Xgi Request!" << std::endl;
00540 }
00541
00542
00543 xoap::MessageReference Supervisor::stateMachineXoapHandler(xoap::MessageReference message)
00544 throw (xoap::exception::Exception)
00545 {
00546 __COUT__ << "Soap Handler!" << std::endl;
00547 stateMachineWorkLoopManager_.removeProcessedRequests();
00548 stateMachineWorkLoopManager_.processRequest(message);
00549 __COUT__ << "Done - Soap Handler!" << std::endl;
00550 return message;
00551 }
00552
00553
00554 xoap::MessageReference Supervisor::stateMachineResultXoapHandler(
00555 xoap::MessageReference message)
00556 throw (xoap::exception::Exception)
00557 {
00558 __COUT__ << "Soap Handler!" << std::endl;
00559
00560
00561 __COUT__ << "Done - Soap Handler!" << std::endl;
00562 return message;
00563 }
00564
00565
00566 bool Supervisor::stateMachineThread(toolbox::task::WorkLoop* workLoop)
00567 {
00568 stateMachineSemaphore_.take();
00569 __COUT__ << "Re-sending message..." << SOAPUtilities::translate( stateMachineWorkLoopManager_.getMessage(workLoop)).getCommand() << std::endl;
00570 std::string reply = send(
00571 theSupervisorDescriptorInfo_.getSupervisorDescriptor(),
00572 stateMachineWorkLoopManager_.getMessage(workLoop));
00573 stateMachineWorkLoopManager_.report(workLoop, reply, 100, true);
00574
00575 __COUT__ << "Done with message. Reply = " << reply << std::endl;
00576 stateMachineSemaphore_.give();
00577
00578 if(reply == "Fault")
00579 {
00580 __SS__ << "Failure to send Workloop transition command! Unrecognized transition name." << std::endl;
00581 __COUT_ERR__ << ss.str();
00582 __MOUT_ERR__ << ss.str();
00583 }
00584 return false;
00585
00586 }
00587
00588
00589
00590
00591
00592
00593 void Supervisor::infoRequestHandler(xgi::Input* in, xgi::Output* out)
00594 throw (xgi::exception::Exception)
00595 {
00596 __COUT__ << "Starting to Request!" << std::endl;
00597 cgicc::Cgicc cgi(in);
00598
00599
00600
00601
00602 std::string cookieCode = CgiDataUtilities::postData(cgi, "CookieCode");
00603 uint8_t userPermissions;
00604 if (!theWebUsers_.cookieCodeIsActiveForRequest(cookieCode, &userPermissions))
00605 {
00606 *out << cookieCode;
00607 return;
00608 }
00609
00610
00611 HttpXmlDocument xmldoc(cookieCode);
00612
00613
00614
00615
00616
00617 HttpXmlDocument tmpDoc = infoRequestWorkLoopManager_.processRequest(cgi);
00618
00619 xmldoc.copyDataChildren(tmpDoc);
00620
00621 xmldoc.outputXmlDocument((std::ostringstream*) out, false);
00622 }
00623
00624
00625 void Supervisor::infoRequestResultHandler(xgi::Input* in, xgi::Output* out)
00626 throw (xgi::exception::Exception)
00627 {
00628 __COUT__ << "Starting ask!" << std::endl;
00629 cgicc::Cgicc cgi(in);
00630
00631
00632
00633
00634 std::string cookieCode = CgiDataUtilities::postData(cgi, "CookieCode");
00635 uint8_t userPermissions;
00636 if (!theWebUsers_.cookieCodeIsActiveForRequest(cookieCode, &userPermissions))
00637 {
00638 *out << cookieCode;
00639 return;
00640 }
00641
00642
00643 HttpXmlDocument xmldoc(cookieCode);
00644
00645 infoRequestWorkLoopManager_.getRequestResult(cgi, xmldoc);
00646
00647
00648 xmldoc.outputXmlDocument((std::ostringstream*) out, false);
00649
00650 __COUT__ << "Done asking!" << std::endl;
00651 }
00652
00653
00654 bool Supervisor::infoRequestThread(toolbox::task::WorkLoop* workLoop)
00655 {
00656
00657
00658
00659 infoRequestSemaphore_.take();
00660
00661 vectorTest_.clear();
00662
00663 for (unsigned long long i = 0; i < 100000000; i++)
00664 {
00665 counterTest_ += 2;
00666 vectorTest_.push_back(counterTest_);
00667 }
00668
00669 infoRequestWorkLoopManager_.report(workLoop,
00670 "RESULT: This is the best result ever", 50, false);
00671 std::string workLoopName = workLoop->getName();
00672 __COUT__ << workLoopName << " test: " << counterTest_
00673 << " vector size: " << vectorTest_.size() << std::endl;
00674 wait(400, "InfoRequestThread ----- locked");
00675 infoRequestSemaphore_.give();
00676
00677 wait(200, "InfoRequestThread");
00678
00679 infoRequestSemaphore_.take();
00680
00681 vectorTest_.clear();
00682
00683 for (unsigned long long i = 0; i < 100000000; i++)
00684 {
00685 counterTest_ += 2;
00686 vectorTest_.push_back(counterTest_);
00687 }
00688
00689 wait(400, "InfoRequestThread ----- locked");
00690 __COUT__ << workLoopName << " test: " << counterTest_ << " vector size: " << vectorTest_.size() << std::endl;
00691 infoRequestSemaphore_.give();
00692
00693
00694 infoRequestWorkLoopManager_.report(workLoop,
00695 theStateMachine_.getCurrentStateName(), 100, true);
00696
00697 return false;
00698
00699 }
00700
00701
00702 void Supervisor::stateInitial(toolbox::fsm::FiniteStateMachine & fsm)
00703 throw (toolbox::fsm::exception::Exception)
00704 {
00705 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
00706
00707
00708 }
00709
00710
00711 void Supervisor::statePaused(toolbox::fsm::FiniteStateMachine & fsm)
00712 throw (toolbox::fsm::exception::Exception)
00713 {
00714 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 }
00728
00729
00730 void Supervisor::stateRunning(toolbox::fsm::FiniteStateMachine & fsm)
00731 throw (toolbox::fsm::exception::Exception)
00732 {
00733
00734 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 }
00748
00749
00750 void Supervisor::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
00751 throw (toolbox::fsm::exception::Exception)
00752 {
00753 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
00754 __COUT__ << "Fsm is in transition? " << (theStateMachine_.isInTransition()?"yes":"no") << std::endl;
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 }
00778
00779
00780 void Supervisor::stateConfigured(toolbox::fsm::FiniteStateMachine & fsm)
00781 throw (toolbox::fsm::exception::Exception)
00782 {
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 }
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 void Supervisor::inError(toolbox::fsm::FiniteStateMachine & fsm)
00850 throw (toolbox::fsm::exception::Exception)
00851 {
00852 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
00853
00854 }
00855
00856
00857 void Supervisor::enteringError(toolbox::Event::Reference e)
00858 throw (toolbox::fsm::exception::Exception)
00859 {
00860 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
00861
00862
00863 toolbox::fsm::FailedEvent& failedEvent = dynamic_cast<toolbox::fsm::FailedEvent&> (*e);
00864 __SS__ << "\nFailure performing transition from " << failedEvent.getFromState() << "-" <<
00865 theStateMachine_.getStateName(failedEvent.getFromState()) <<
00866 " to " << failedEvent.getToState() << "-" <<
00867 theStateMachine_.getStateName(failedEvent.getToState()) <<
00868 ".\n\nException:\n" << failedEvent.getException().what() << std::endl;
00869 __COUT_ERR__ << "\n" << ss.str();
00870
00871 theStateMachine_.setErrorMessage(ss.str());
00872
00873
00874
00875
00876
00877
00878 }
00879
00883
00884 void Supervisor::getSupervisorsStatus(void)
00885 throw (toolbox::fsm::exception::Exception)
00886 {
00887 theSupervisorsInfo_.getSupervisorInfo().setStatus(
00888 theStateMachine_.getCurrentStateName());
00889
00890 try
00891 {
00892 for (auto& it : theSupervisorDescriptorInfo_.getFEDescriptors())
00893 {
00894 try
00895 {
00896 std::string state = send(it.second,
00897 "StateMachineStateRequest");
00898
00899 theSupervisorsInfo_.getFESupervisorInfo(it.first).setStatus(
00900 state);
00901
00902 __COUT__ << "FESupervisor instance " << it.first << " is in FSM state " <<
00903 state << std::endl;
00904 __COUT__ << "Look! Here's a FEW! @@@" << std::endl;
00905 }
00906 catch (xdaq::exception::Exception& e)
00907 {
00908 __COUT_WARN__ << "Could not retrieve status from FESupervisor instance " <<
00909 it.first << "." << std::endl;
00910 }
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 for (auto& it : theSupervisorDescriptorInfo_.getARTDAQFEDataManagerDescriptors())
00931 {
00932 try
00933 {
00934 std::string state = send(it.second,
00935 "StateMachineStateRequest");
00936 theSupervisorsInfo_.getARTDAQFEDataManagerSupervisorInfo(it.first).setStatus(
00937 state);
00938 __COUT__ << "getARTDAQFEDataManagerDescriptors instance " << it.first << " is in FSM state " << state << std::endl;
00939 __COUT__ << "Look! Here's a FER! @@@" << std::endl;
00940 }
00941 catch (xdaq::exception::Exception& e)
00942 {
00943 __COUT_WARN__ << "Could not retrieve status from getARTDAQFEDataManagerDescriptors instance " <<
00944 it.first << "." << std::endl;
00945 }
00946 }
00947 for (auto& it : theSupervisorDescriptorInfo_.getARTDAQDataManagerDescriptors())
00948 {
00949 try
00950 {
00951 std::string state = send(it.second,
00952 "StateMachineStateRequest");
00953 theSupervisorsInfo_.getARTDAQDataManagerSupervisorInfo(it.first).setStatus(
00954 state);
00955 __COUT__ << "getARTDAQDataManagerSupervisorInfo instance " << it.first << " is in FSM state " << state << std::endl;
00956 __COUT__ << "Look! Here's a FER! @@@" << std::endl;
00957 }
00958 catch (xdaq::exception::Exception& e)
00959 {
00960 __COUT_WARN__ << "Could not retrieve status from getARTDAQDataManagerSupervisorInfo instance " <<
00961 it.first << "." << std::endl;
00962 }
00963 }
00964 }
00965 catch (xdaq::exception::Exception& e)
00966 {
00967 __COUT_WARN__ << "No FESupervisor found in the \"daq\" group in the Configuration XML file."
00968 << std::endl;
00969 }
00970
00971 }
00972
00973
00974 void Supervisor::transitionConfiguring(toolbox::Event::Reference e)
00975 throw (toolbox::fsm::exception::Exception)
00976 {
00977
00978
00979 theProgressBar_.step();
00980
00981 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
00982
00983 std::string systemAlias = SOAPUtilities::translate(
00984 theStateMachine_.getCurrentMessage()).getParameters().getValue("ConfigurationAlias");
00985
00986 __COUT__ << "Transition parameter: " << systemAlias << std::endl;
00987
00988 theProgressBar_.step();
00989
00990
00991 try
00992 {
00993 theConfigurationManager_->init();
00994 }
00995 catch(...)
00996 {
00997 __SS__ << "\nTransition to Configuring interrupted! " <<
00998 "The Configuration Manager could not be initialized." << std::endl;
00999
01000 __COUT_ERR__ << "\n" << ss.str();
01001 XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
01002 return;
01003 }
01004
01005 theProgressBar_.step();
01006
01007
01008 try
01009 {
01010 theConfigurationGroup_ = theConfigurationManager_->getConfigurationGroupFromAlias(systemAlias);
01011 }
01012 catch(...)
01013 {
01014 __COUT_INFO__ << "Exception occurred" << std::endl;
01015 }
01016
01017 theProgressBar_.step();
01018
01019 if(theConfigurationGroup_.second.isInvalid())
01020 {
01021 __SS__ << "\nTransition to Configuring interrupted! System Alias " <<
01022 systemAlias << " could not be translated to a group name and key." << std::endl;
01023
01024 __COUT_ERR__ << "\n" << ss.str();
01025 XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
01026 return;
01027 }
01028
01029 theProgressBar_.step();
01030
01031 __COUT__ << "Configuration group name: " << theConfigurationGroup_.first << " key: " <<
01032 theConfigurationGroup_.second << std::endl;
01033
01034
01035 {
01036 std::stringstream ss;
01037 ss << "Configuring '" << systemAlias << "' which translates to " <<
01038 theConfigurationGroup_.first << " (" << theConfigurationGroup_.second << ").";
01039 makeSystemLogbookEntry(ss.str());
01040 }
01041
01042 theProgressBar_.step();
01043
01044
01045 try
01046 {
01047 theConfigurationManager_->loadConfigurationGroup(theConfigurationGroup_.first, theConfigurationGroup_.second, true);
01048
01049
01050 ConfigurationManagerRW tmpCfgMgr("TheSupervisor");
01051 tmpCfgMgr.activateConfigurationGroup(theConfigurationGroup_.first, theConfigurationGroup_.second);
01052 }
01053 catch(...)
01054 {
01055 __SS__ << "\nTransition to Configuring interrupted! System Alias " <<
01056 systemAlias << " was translated to " << theConfigurationGroup_.first <<
01057 " (" << theConfigurationGroup_.second << ") but could not be loaded and initialized." << std::endl;
01058 ss << "\n\nTo debug this problem, try activating this group in the Configuration GUI " <<
01059 " and detailed errors will be shown." << std::endl;
01060 __COUT_ERR__ << "\n" << ss.str();
01061 XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
01062 return;
01063 }
01064
01065
01066 {
01067 ConfigurationTree configLinkNode = theConfigurationManager_->getSupervisorConfigurationNode(
01068 supervisorContextUID_, supervisorApplicationUID_);
01069 if(!configLinkNode.isDisconnected())
01070 {
01071
01072 try
01073 {
01074 bool dumpConfiguration = true;
01075 std::string dumpFilePath, dumpFileRadix, dumpFormat;
01076 try
01077 {
01078 ConfigurationTree fsmLinkNode = configLinkNode.getNode("LinkToStateMachineConfiguration").
01079 getNode(activeStateMachineName_);
01080 dumpConfiguration = fsmLinkNode.getNode("EnableConfigurationDumpOnConfigureTransition").
01081 getValue<bool>();
01082 dumpFilePath = fsmLinkNode.getNode("ConfigurationDumpOnConfigureFilePath").getValue<std::string>();
01083 dumpFileRadix = fsmLinkNode.getNode("ConfigurationDumpOnConfigureFileRadix").getValue<std::string>();
01084 dumpFormat = fsmLinkNode.getNode("ConfigurationDumpOnConfigureFormat").getValue<std::string>();
01085
01086 }
01087 catch(std::runtime_error &e)
01088 {
01089 __COUT_INFO__ << "FSM configuration dump Link disconnected." << std::endl;
01090 dumpConfiguration = false;
01091 }
01092
01093 if(dumpConfiguration)
01094 {
01095
01096 theConfigurationManager_->dumpActiveConfiguration(
01097 dumpFilePath +
01098 "/" +
01099 dumpFileRadix +
01100 "_" +
01101 std::to_string(time(0)) +
01102 ".dump",
01103 dumpFormat
01104 );
01105 }
01106
01107 }
01108 catch(std::runtime_error &e) {
01109 __SS__ << "\nTransition to Configuring interrupted! There was an error identified " <<
01110 "during the configuration dump attempt:\n\n " <<
01111 e.what() << std::endl;
01112 __COUT_ERR__ << "\n" << ss.str();
01113 XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
01114 return;
01115 }
01116 catch(...) {
01117 __SS__ << "\nTransition to Configuring interrupted! There was an error identified " <<
01118 "during the configuration dump attempt.\n\n " <<
01119 std::endl;
01120 __COUT_ERR__ << "\n" << ss.str();
01121 XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
01122 return;
01123 }
01124 }
01125 }
01126
01127 theProgressBar_.step();
01128 SOAPParameters parameters;
01129 parameters.addParameter("ConfigurationGroupName", theConfigurationGroup_.first);
01130 parameters.addParameter("ConfigurationGroupKey", theConfigurationGroup_.second.toString());
01131
01132
01133 xoap::MessageReference message = theStateMachine_.getCurrentMessage();
01134 SOAPUtilities::addParameters(message,parameters);
01135 broadcastMessage(message);
01136 theProgressBar_.step();
01137
01138
01139
01140
01141 saveGroupNameAndKey(theConfigurationGroup_,FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE);
01142
01143 __COUT__ << "Done" << std::endl;
01144 theProgressBar_.complete();
01145 }
01146
01147
01148 void Supervisor::transitionHalting(toolbox::Event::Reference e)
01149 throw (toolbox::fsm::exception::Exception)
01150 {
01151 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
01152
01153 makeSystemLogbookEntry("Run halting.");
01154
01155 broadcastMessage(theStateMachine_.getCurrentMessage());
01156 }
01157
01158
01159 void Supervisor::transitionInitializing(toolbox::Event::Reference e)
01160 throw (toolbox::fsm::exception::Exception)
01161 {
01162 __COUT__ << theStateMachine_.getCurrentStateName() << std::endl;
01163
01164
01165 getSupervisorsStatus();
01166
01167 if(!broadcastMessage(theStateMachine_.getCurrentMessage()))
01168 {
01169 __COUT__ << "I can't Initialize the supervisors!" << std::endl;
01170 }
01171
01172 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
01173 __COUT__ << "Fsm current transition: " << theStateMachine_.getCurrentTransitionName(e->type()) << std::endl;
01174 __COUT__ << "Fsm final state: " << theStateMachine_.getTransitionFinalStateName(e->type()) << std::endl;
01175 }
01176
01177
01178 void Supervisor::transitionPausing(toolbox::Event::Reference e)
01179 throw (toolbox::fsm::exception::Exception)
01180 {
01181 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
01182
01183 makeSystemLogbookEntry("Run pausing.");
01184
01185 broadcastMessage(theStateMachine_.getCurrentMessage());
01186 }
01187
01188
01189 void Supervisor::transitionResuming(toolbox::Event::Reference e)
01190 throw (toolbox::fsm::exception::Exception)
01191 {
01192 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
01193
01194 makeSystemLogbookEntry("Run resuming.");
01195
01196 broadcastMessage(theStateMachine_.getCurrentMessage());
01197 }
01198
01199
01200 void Supervisor::transitionStarting(toolbox::Event::Reference e)
01201 throw (toolbox::fsm::exception::Exception)
01202 {
01203 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
01204
01205 SOAPParameters parameters("RunNumber");
01206 receive(theStateMachine_.getCurrentMessage(), parameters);
01207
01208 std::string runNumber = parameters.getValue("RunNumber");
01209 __COUT__ << runNumber << std::endl;
01210
01211
01212 {
01213 ConfigurationTree configLinkNode = theConfigurationManager_->getSupervisorConfigurationNode(
01214 supervisorContextUID_, supervisorApplicationUID_);
01215 if(!configLinkNode.isDisconnected())
01216 {
01217 try
01218 {
01219 bool dumpConfiguration = true;
01220 std::string dumpFilePath, dumpFileRadix, dumpFormat;
01221 try
01222 {
01223 ConfigurationTree fsmLinkNode = configLinkNode.getNode("LinkToStateMachineConfiguration").
01224 getNode(activeStateMachineName_);
01225 dumpConfiguration = fsmLinkNode.getNode("EnableConfigurationDumpOnRunTransition").
01226 getValue<bool>();
01227 dumpFilePath = fsmLinkNode.getNode("ConfigurationDumpOnRunFilePath").getValue<std::string>();
01228 dumpFileRadix = fsmLinkNode.getNode("ConfigurationDumpOnRunFileRadix").getValue<std::string>();
01229 dumpFormat = fsmLinkNode.getNode("ConfigurationDumpOnRunFormat").getValue<std::string>();
01230 }
01231 catch(std::runtime_error &e)
01232 {
01233 __COUT_INFO__ << "FSM configuration dump Link disconnected." << std::endl;
01234 dumpConfiguration = false;
01235 }
01236
01237 if(dumpConfiguration)
01238 {
01239
01240 theConfigurationManager_->dumpActiveConfiguration(
01241 dumpFilePath +
01242 "/" +
01243 dumpFileRadix +
01244 "_Run" +
01245 runNumber +
01246 "_" +
01247 std::to_string(time(0)) +
01248 ".dump",
01249 dumpFormat
01250 );
01251 }
01252
01253 }
01254 catch(std::runtime_error &e) {
01255 __SS__ << "\nTransition to Running interrupted! There was an error identified " <<
01256 "during the configuration dump attempt:\n\n " <<
01257 e.what() << std::endl;
01258 __COUT_ERR__ << "\n" << ss.str();
01259 XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
01260 return;
01261 }
01262 catch(...) {
01263 __SS__ << "\nTransition to Running interrupted! There was an error identified " <<
01264 "during the configuration dump attempt.\n\n " <<
01265 std::endl;
01266 __COUT_ERR__ << "\n" << ss.str();
01267 XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
01268 return;
01269 }
01270 }
01271 }
01272
01273
01274 makeSystemLogbookEntry("Run " + runNumber + " starting.");
01275
01276 broadcastMessage(theStateMachine_.getCurrentMessage());
01277
01278
01279 saveGroupNameAndKey(theConfigurationGroup_,FSM_LAST_STARTED_GROUP_ALIAS_FILE);
01280 }
01281
01282
01283 void Supervisor::transitionStopping(toolbox::Event::Reference e)
01284 throw (toolbox::fsm::exception::Exception)
01285 {
01286 __COUT__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
01287
01288 makeSystemLogbookEntry("Run stopping.");
01289
01290 broadcastMessage(theStateMachine_.getCurrentMessage());
01291 }
01292
01296
01297
01298 bool Supervisor::broadcastMessage(xoap::MessageReference message)
01299 throw (toolbox::fsm::exception::Exception)
01300 {
01301 std::string command = SOAPUtilities::translate(message).getCommand();
01302 bool proceed = true;
01303 std::string reply;
01304
01305
01306
01307 for(auto& it: theSupervisorDescriptorInfo_.getFEDescriptors())
01308 {
01309 RunControlStateMachine::theProgressBar_.step();
01310 __COUT__ << "Sending message to FESupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01311 __COUT__ << "Sending message to FESupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01312 __COUT__ << "Sending message to FESupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01313 __COUT__ << "Sending message to FESupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01314 __COUT__ << "Sending message to FESupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01315
01316 try
01317 {
01318 reply = send(it.second, message);
01319 }
01320 catch(const xdaq::exception::Exception &e)
01321 {
01322
01323 __SS__ << "Can NOT " << command << " FESupervisors, instance = " << it.first << ".\n\n" <<
01324 "Xoap failure. Did the target Supervisor crash? Try restarting re-initializing or restarting otsdaq." << std::endl;
01325 __COUT_ERR__ << ss.str();
01326 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01327 proceed = false;
01328 }
01329
01330 if (reply != command + "Done")
01331 {
01332
01333
01334 __SS__ << "Can NOT " << command << " FESupervisor, instance = " << it.first << ".\n\n" <<
01335 reply;
01336 __COUT_ERR__ << ss.str() << std::endl;
01337
01338 __COUT__ << "Getting error message..." << std::endl;
01339 xoap::MessageReference errorMessage = sendWithSOAPReply(it.second, SOAPUtilities::makeSOAPMessageReference("StateMachineErrorMessageRequest"));
01340 SOAPParameters parameters;
01341 parameters.addParameter("ErrorMessage");
01342 SOAPMessenger::receive(errorMessage, parameters);
01343 __COUT_ERR__ << "errorMessage = " << parameters.getValue("ErrorMessage") << std::endl;
01344 ss << "\n\nError Message: " << parameters.getValue("ErrorMessage") << std::endl;
01345 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01346 proceed = false;
01347
01348 }
01349 else
01350 {
01351 __COUT__ << "FESupervisor supervisor " << (it.first) << " was " << command << "'d correctly!" << std::endl;
01352 }
01353 }
01354
01355 for(auto& it: theSupervisorDescriptorInfo_.getDTCDescriptors())
01356 {
01357 RunControlStateMachine::theProgressBar_.step();
01358 __COUT__ << "Sending message to DTCSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01359 __COUT__ << "Sending message to DTCSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01360 __COUT__ << "Sending message to DTCSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01361 __COUT__ << "Sending message to DTCSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01362 __COUT__ << "Sending message to DTCSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01363
01364 try
01365 {
01366 reply = send(it.second, message);
01367 }
01368 catch(const xdaq::exception::Exception &e)
01369 {
01370
01371 __SS__ << "Can NOT " << command << " DTCSupervisors, instance = " << it.first << ".\n\n" <<
01372 "Xoap failure. Did the target Supervisor crash? Try restarting re-initializing or restarting otsdaq." << std::endl;
01373 __COUT_ERR__ << ss.str();
01374 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01375 proceed = false;
01376 }
01377
01378 if (reply != command + "Response")
01379 {
01380
01381
01382 __SS__ << "Can NOT " << command << " DTCSupervisor, instance = " << it.first << ".\n\n" <<
01383 reply;
01384 __COUT_ERR__ << ss.str() << std::endl;
01385
01386
01387
01388
01389 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01390 proceed = false;
01391
01392 }
01393 else
01394 {
01395 __COUT__ << "DTCSupervisor supervisor " << (it.first) << " was " << command << "'d correctly!" << std::endl;
01396 }
01397 }
01398
01399
01400 for(auto& it: theSupervisorDescriptorInfo_.getDataManagerDescriptors())
01401 {
01402 RunControlStateMachine::theProgressBar_.step();
01403 __COUT__ << "Sending message to DataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01404 __COUT__ << "Sending message to DataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01405 __COUT__ << "Sending message to DataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01406 __COUT__ << "Sending message to DataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01407 __COUT__ << "Sending message to DataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01408
01409 try
01410 {
01411 reply = send(it.second, message);
01412 }
01413 catch(const xdaq::exception::Exception &e)
01414 {
01415
01416 __SS__ << "Can NOT " << command << " DataManagerSupervisors, instance = " << it.first << ".\n\n" <<
01417 "Xoap failure. Did the target Supervisor crash? Try restarting re-initializing or restarting otsdaq." << std::endl;
01418 __COUT_ERR__ << ss.str();
01419 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01420 proceed = false;
01421 }
01422
01423 if (reply != command + "Done")
01424 {
01425 __SS__ << "Can NOT " << command << " DataManagerSupervisor, instance = " << it.first << ".\n\n" <<
01426 reply;
01427 __COUT_ERR__ << ss.str() << std::endl;
01428 __COUT__ << "Getting error message..." << std::endl;
01429 xoap::MessageReference errorMessage = sendWithSOAPReply(it.second, SOAPUtilities::makeSOAPMessageReference("StateMachineErrorMessageRequest"));
01430 SOAPParameters parameters;
01431 parameters.addParameter("ErrorMessage");
01432 SOAPMessenger::receive(errorMessage, parameters);
01433 __COUT_ERR__ << "errorMessage = " << parameters.getValue("ErrorMessage") << std::endl;
01434 ss << "\n\nError Message: " << parameters.getValue("ErrorMessage") << std::endl;
01435 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01436 proceed = false;
01437 }
01438 else
01439 {
01440 __COUT__ << "DataManagerSupervisor " << (it.first) << " was " << command << "'d correctly!" << std::endl;
01441 }
01442 }
01443
01444
01445 for (auto& it: theSupervisorDescriptorInfo_.getFEDataManagerDescriptors())
01446 {
01447 RunControlStateMachine::theProgressBar_.step();
01448 __COUT__ << "Sending message to FEDataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01449 __COUT__ << "Sending message to FEDataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01450 __COUT__ << "Sending message to FEDataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01451 __COUT__ << "Sending message to FEDataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01452 __COUT__ << "Sending message to FEDataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01453
01454 try
01455 {
01456 reply = send(it.second, message);
01457 }
01458 catch(const xdaq::exception::Exception &e)
01459 {
01460
01461 __SS__ << "Can NOT " << command << " FEDataManagerSupervisors, instance = " << it.first << ".\n\n" <<
01462 "Xoap failure. Did the target Supervisor crash? Try restarting re-initializing or restarting otsdaq." << std::endl;
01463 __COUT_ERR__ << ss.str();
01464 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01465 proceed = false;
01466 }
01467
01468 if (reply != command + "Done")
01469 {
01470 __SS__ << "Can NOT " << command << " FEDataManagerSupervisor, instance = " << it.first << ".\n\n" <<
01471 reply;
01472 __COUT_ERR__ << ss.str() << std::endl;
01473 __COUT__ << "Getting error message..." << std::endl;
01474 xoap::MessageReference errorMessage = sendWithSOAPReply(it.second, SOAPUtilities::makeSOAPMessageReference("StateMachineErrorMessageRequest"));
01475 SOAPParameters parameters;
01476 parameters.addParameter("ErrorMessage");
01477 SOAPMessenger::receive(errorMessage, parameters);
01478 __COUT_ERR__ << "errorMessage = " << parameters.getValue("ErrorMessage") << std::endl;
01479 ss << "\n\nError Message: " << parameters.getValue("ErrorMessage") << std::endl;
01480 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01481 proceed = false;
01482 }
01483 else
01484 {
01485 __COUT__ << "FEDataManagerSupervisor " << (it.first) << " was " << command << "'d correctly!" << std::endl;
01486 }
01487 }
01488
01489
01490 for(auto& it: theSupervisorDescriptorInfo_.getVisualDescriptors())
01491 {
01492 RunControlStateMachine::theProgressBar_.step();
01493 __COUT__ << "Sending message to VisualSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01494 __COUT__ << "Sending message to VisualSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01495 __COUT__ << "Sending message to VisualSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01496 __COUT__ << "Sending message to VisualSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01497 __COUT__ << "Sending message to VisualSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01498
01499
01500 try
01501 {
01502 reply = send(it.second, message);
01503 }
01504 catch(const xdaq::exception::Exception &e)
01505 {
01506
01507 __SS__ << "Can NOT " << command << " VisualSupervisor, instance = " << it.first << ".\n\n" <<
01508 "Xoap failure. Did the target Supervisor crash? Try restarting re-initializing or restarting otsdaq." << std::endl;
01509 __COUT_ERR__ << ss.str();
01510 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01511 proceed = false;
01512 }
01513
01514
01515 if (reply != command + "Done")
01516 {
01517 __SS__ << "Can NOT " << command << " VisualSupervisor, instance = " << it.first << ".\n\n" <<
01518 reply;
01519 __COUT_ERR__ << ss.str() << std::endl;
01520 __COUT__ << "Getting error message..." << std::endl;
01521 xoap::MessageReference errorMessage = sendWithSOAPReply(it.second, SOAPUtilities::makeSOAPMessageReference("StateMachineErrorMessageRequest"));
01522 SOAPParameters parameters;
01523 parameters.addParameter("ErrorMessage");
01524 SOAPMessenger::receive(errorMessage, parameters);
01525 __COUT_ERR__ << "errorMessage = " << parameters.getValue("ErrorMessage") << std::endl;
01526 ss << "\n\nError Message: " << parameters.getValue("ErrorMessage") << std::endl;
01527 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01528 proceed = false;
01529 }
01530 else
01531 {
01532 __COUT__ << "VisualSupervisor supervisor " << (it.first) << " was " << command << "'d correctly!" << std::endl;
01533 }
01534 }
01535
01536
01537
01538
01539
01540 bool artdaqRestarted = false;
01541 bool artdaqWasRestarted = false;
01542
01543 RunControlStateMachine::theProgressBar_.step();
01544 if(command == "Halt" || command == "Initialize")
01545 {
01546
01547
01548
01549
01550
01551
01552 {
01553
01554 __COUT__ << "Extracting target context hostnames... " << std::endl;
01555 std::vector<std::string> hostnames;
01556 try
01557 {
01558 theConfigurationManager_->init();
01559
01560 const XDAQContextConfiguration* contextConfiguration = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration);
01561
01562 auto contexts = contextConfiguration->getContexts();
01563 unsigned int i,j;
01564 for(const auto& context: contexts)
01565 {
01566 if(!context.status_) continue;
01567
01568
01569 j=0;
01570 for(i=0;i<context.address_.size();++i)
01571 if(context.address_[i] == '/')
01572 j = i+1;
01573 hostnames.push_back(context.address_.substr(j));
01574 __COUT__ << "hostname = " << hostnames.back() << std::endl;
01575 }
01576 }
01577 catch(...)
01578 {
01579 __SS__ << "\nTransition to Configuring interrupted! " <<
01580 "The Configuration Manager could not be initialized." << std::endl;
01581
01582 __COUT_ERR__ << "\n" << ss.str();
01583
01584 XCEPT_RAISE (toolbox::fsm::exception::Exception, ss.str());
01585 }
01586
01587 for(const auto& hostname: hostnames)
01588 {
01589 std::string fn = (std::string(getenv("SERVICE_DATA_PATH")) +
01590 "/StartOTS_action_" + hostname + ".cmd");
01591 FILE* fp = fopen(fn.c_str(),"w");
01592 if(fp)
01593 {
01594 fprintf(fp,"RESET_MPI");
01595 fclose(fp);
01596 }
01597 else
01598 __COUT_ERR__ << "Unable to open command file: " << fn << std::endl;
01599 }
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610 }
01611
01612 artdaqRestarted = true;
01613
01614 SOAPParameters parameters;
01615 message = SOAPUtilities::makeSOAPMessageReference(
01616 "Initialize", parameters);
01617 command = SOAPUtilities::translate(message).getCommand();
01618 __COUT__ << "command now is " << command << std::endl;
01619 }
01620 RunControlStateMachine::theProgressBar_.step();
01621
01622
01623 int MAX_ARTDAQ_RESTARTS = 10;
01624 int ARTDAQ_RESTART_DELAY = 2;
01625 int artdaqRestartCount = 0;
01626 bool preArtdaqProceed = proceed;
01627
01628 ARTDAQ_RETRY:
01629 if(artdaqWasRestarted)
01630 {
01631 ++artdaqRestartCount;
01632 proceed = preArtdaqProceed;
01633 if(artdaqRestartCount < MAX_ARTDAQ_RESTARTS)
01634 artdaqWasRestarted = false;
01635 for(int i=0;i<ARTDAQ_RESTART_DELAY;++i)
01636 {
01637 sleep(1);
01638 __COUT_INFO__ << "Waiting on artdaq reboot... " << i << " for " << artdaqRestartCount << "x" << std::endl;
01639 }
01640 }
01641
01642
01643 for(auto& it: theSupervisorDescriptorInfo_.getARTDAQFEDataManagerDescriptors())
01644 {
01645 RunControlStateMachine::theProgressBar_.step();
01646 __COUT__ << "Sending message to ARTDAQFEDataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01647 __COUT__ << "Sending message to ARTDAQFEDataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01648 __COUT__ << "Sending message to ARTDAQFEDataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01649 __COUT__ << "Sending message to ARTDAQFEDataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01650 __COUT__ << "Sending message to ARTDAQFEDataManagerSupervisors: " << it.second->getLocalId() << " : " << command << std::endl;
01651
01652 try
01653 {
01654 reply = send(it.second, message);
01655 if (reply != command + "Done")
01656 {
01657 __SS__ << "Can NOT " << command << " ARTDAQFEDataManagerSupervisor, instance = " << it.first << ".\n\n" <<
01658 reply;
01659 __COUT_ERR__ << ss.str() << std::endl;
01660 __COUT__ << "Getting error message..." << std::endl;
01661 xoap::MessageReference errorMessage = sendWithSOAPReply(it.second, SOAPUtilities::makeSOAPMessageReference("StateMachineErrorMessageRequest"));
01662 SOAPParameters parameters;
01663 parameters.addParameter("ErrorMessage");
01664 SOAPMessenger::receive(errorMessage, parameters);
01665 __COUT_ERR__ << "errorMessage = " << parameters.getValue("ErrorMessage") << std::endl;
01666 ss << "\n\nError Message: " << parameters.getValue("ErrorMessage") << std::endl;
01667 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01668 proceed = false;
01669 }
01670 else
01671 {
01672 __COUT__ << "ARTDAQFEDataManagerSupervisors supervisor " << (it.first) << " was " << command << "'d correctly!" << std::endl;
01673 }
01674 }
01675 catch(const xdaq::exception::Exception &e)
01676 {
01677 if(artdaqRestarted && !artdaqWasRestarted)
01678 {
01679 artdaqWasRestarted = true;
01680 goto ARTDAQ_RETRY;
01681 }
01682 else
01683 {
01684
01685 __SS__ << "Can NOT " << command << " ARTDAQFEDataManagerSupervisor, instance = " << it.first << ".\n\n" <<
01686 "Xoap failure. Did the target Supervisor crash? Try restarting re-initializing or restarting otsdaq." << std::endl;
01687 __COUT_ERR__ << ss.str();
01688 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01689 proceed = false;
01690 }
01691 }
01692 catch(const toolbox::fsm::exception::Exception &e)
01693 {
01694 if(artdaqRestarted && !artdaqWasRestarted)
01695 {
01696 artdaqWasRestarted = true;
01697 goto ARTDAQ_RETRY;
01698 }
01699 else
01700 throw;
01701 }
01702 }
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712 for(auto& it: theSupervisorDescriptorInfo_.getARTDAQDataManagerDescriptors())
01713 {
01714 RunControlStateMachine::theProgressBar_.step();
01715 __COUT__ << "Sending message to ARTDAQDataManagerSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01716 __COUT__ << "Sending message to ARTDAQDataManagerSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01717 __COUT__ << "Sending message to ARTDAQDataManagerSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01718 __COUT__ << "Sending message to ARTDAQDataManagerSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01719 __COUT__ << "Sending message to ARTDAQDataManagerSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01720 try
01721 {
01722 reply = send(it.second, message);
01723 if (reply != command + "Done")
01724 {
01725 __SS__ << "Can NOT " << command << " ARTDAQDataManagerSupervisor, instance = " << it.first << ".\n\n" <<
01726 reply;
01727 __COUT_ERR__ << ss.str() << std::endl;
01728 __COUT__ << "Getting error message..." << std::endl;
01729 xoap::MessageReference errorMessage = sendWithSOAPReply(it.second, SOAPUtilities::makeSOAPMessageReference("StateMachineErrorMessageRequest"));
01730 SOAPParameters parameters;
01731 parameters.addParameter("ErrorMessage");
01732 SOAPMessenger::receive(errorMessage, parameters);
01733 __COUT_ERR__ << "errorMessage = " << parameters.getValue("ErrorMessage") << std::endl;
01734 ss << "\n\nError Message: " << parameters.getValue("ErrorMessage") << std::endl;
01735 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01736 proceed = false;
01737 }
01738 else
01739 {
01740 __COUT__ << "ARTDAQDataManagerSupervisor supervisor " << (it.first) << " was " << command << "'d correctly!" << std::endl;
01741 }
01742 }
01743 catch(const xdaq::exception::Exception &e)
01744 {
01745 if(artdaqRestarted && !artdaqWasRestarted)
01746 {
01747 artdaqWasRestarted = true;
01748 goto ARTDAQ_RETRY;
01749 }
01750 else
01751 {
01752
01753 __SS__ << "Can NOT " << command << " ARTDAQDataManagerSupervisor, instance = " << it.first << ".\n\n" <<
01754 "Xoap failure. Did the target Supervisor crash? Try restarting re-initializing or restarting otsdaq." << std::endl;
01755 __COUT_ERR__ << ss.str();
01756 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01757 proceed = false;
01758 }
01759 }
01760 catch(const toolbox::fsm::exception::Exception &e)
01761 {
01762 if(artdaqRestarted && !artdaqWasRestarted)
01763 {
01764 artdaqWasRestarted = true;
01765 goto ARTDAQ_RETRY;
01766 }
01767 else
01768 throw;
01769 }
01770 }
01771
01772
01773 for(auto& it: theSupervisorDescriptorInfo_.getARTDAQBuilderDescriptors())
01774 {
01775 RunControlStateMachine::theProgressBar_.step();
01776 __COUT__ << "Sending message to ARTDAQBuilderSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01777 __COUT__ << "Sending message to ARTDAQBuilderSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01778 __COUT__ << "Sending message to ARTDAQBuilderSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01779 __COUT__ << "Sending message to ARTDAQBuilderSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01780 __COUT__ << "Sending message to ARTDAQBuilderSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01781
01782 try
01783 {
01784 reply = send(it.second, message);
01785 if (reply != command + "Done")
01786 {
01787 __SS__ << "Can NOT " << command << " ARTDAQBuilderSupervisor, instance = " << it.first << ".\n\n" <<
01788 reply;
01789 __COUT_ERR__ << ss.str() << std::endl;
01790 __COUT__ << "Getting error message..." << std::endl;
01791 xoap::MessageReference errorMessage = sendWithSOAPReply(it.second, SOAPUtilities::makeSOAPMessageReference("StateMachineErrorMessageRequest"));
01792 SOAPParameters parameters;
01793 parameters.addParameter("ErrorMessage");
01794 SOAPMessenger::receive(errorMessage, parameters);
01795 __COUT_ERR__ << "errorMessage = " << parameters.getValue("ErrorMessage") << std::endl;
01796 ss << "\n\nError Message: " << parameters.getValue("ErrorMessage") << std::endl;
01797 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01798 proceed = false;
01799 }
01800 else
01801 {
01802 __COUT__ << "ARTDAQBuilderSupervisor supervisor " << (it.first) << " was " << command << "'d correctly!" << std::endl;
01803 }
01804 }
01805 catch(const xdaq::exception::Exception &e)
01806 {
01807 if(artdaqRestarted && !artdaqWasRestarted)
01808 {
01809 artdaqWasRestarted = true;
01810 goto ARTDAQ_RETRY;
01811 }
01812 else
01813 {
01814
01815 __SS__ << "Can NOT " << command << " ARTDAQBuilderSupervisor, instance = " << it.first << ".\n\n" <<
01816 "Xoap failure. Did the target Supervisor crash? Try restarting re-initializing or restarting otsdaq." << std::endl;
01817 __COUT_ERR__ << ss.str();
01818 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01819 proceed = false;
01820 }
01821 }
01822 catch(const toolbox::fsm::exception::Exception &e)
01823 {
01824 if(artdaqRestarted && !artdaqWasRestarted)
01825 {
01826 artdaqWasRestarted = true;
01827 goto ARTDAQ_RETRY;
01828 }
01829 else
01830 throw;
01831 }
01832 }
01833
01834
01835 for(auto& it: theSupervisorDescriptorInfo_.getARTDAQAggregatorDescriptors())
01836 {
01837 RunControlStateMachine::theProgressBar_.step();
01838 __COUT__ << "Sending message to ARTDAQAggregatorSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01839 __COUT__ << "Sending message to ARTDAQAggregatorSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01840 __COUT__ << "Sending message to ARTDAQAggregatorSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01841 __COUT__ << "Sending message to ARTDAQAggregatorSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01842 __COUT__ << "Sending message to ARTDAQAggregatorSupervisor: " << it.second->getLocalId() << " : " << command << std::endl;
01843
01844 try
01845 {
01846 reply = send(it.second, message);
01847 if (reply != command + "Done")
01848 {
01849 __SS__ << "Can NOT " << command << " ARTDAQAggregatorSupervisor, instance = " << it.first << ".\n\n" <<
01850 reply;
01851 __COUT_ERR__ << ss.str() << std::endl;
01852 __COUT__ << "Getting error message..." << std::endl;
01853 xoap::MessageReference errorMessage = sendWithSOAPReply(it.second, SOAPUtilities::makeSOAPMessageReference("StateMachineErrorMessageRequest"));
01854 SOAPParameters parameters;
01855 parameters.addParameter("ErrorMessage");
01856 SOAPMessenger::receive(errorMessage, parameters);
01857 __COUT_ERR__ << "errorMessage = " << parameters.getValue("ErrorMessage") << std::endl;
01858 ss << "\n\nError Message: " << parameters.getValue("ErrorMessage") << std::endl;
01859 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01860 proceed = false;
01861 }
01862 else
01863 {
01864 __COUT__ << "ARTDAQAggregatorSupervisor supervisor " << (it.first) << " was " << command << "'d correctly!" << std::endl;
01865 }
01866 }
01867 catch(const xdaq::exception::Exception &e)
01868 {
01869 if(artdaqRestarted && !artdaqWasRestarted)
01870 {
01871 artdaqWasRestarted = true;
01872 goto ARTDAQ_RETRY;
01873 }
01874 else
01875 {
01876
01877 __SS__ << "Can NOT " << command << " ARTDAQAggregatorSupervisor, instance = " << it.first << ".\n\n" <<
01878 "Xoap failure. Did the target Supervisor crash? Try restarting re-initializing or restarting otsdaq." << std::endl;
01879 __COUT_ERR__ << ss.str();
01880 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
01881 proceed = false;
01882 }
01883 }
01884 catch(const toolbox::fsm::exception::Exception &e)
01885 {
01886 if(artdaqRestarted && !artdaqWasRestarted)
01887 {
01888 artdaqWasRestarted = true;
01889 goto ARTDAQ_RETRY;
01890 }
01891 else
01892 throw;
01893 }
01894 }
01895
01896 return proceed;
01897 }
01898
01899
01900 void Supervisor::wait(int milliseconds, std::string who) const
01901 {
01902 for (int s = 1; s <= milliseconds; s++)
01903 {
01904 usleep(1000);
01905
01906 if (s % 100 == 0)
01907 __COUT__ << s << " msecs " << who << std::endl;
01908 }
01909 }
01910
01911
01912
01913
01914
01915
01916 void Supervisor::loginRequest(xgi::Input * in, xgi::Output * out)
01917 throw (xgi::exception::Exception)
01918 {
01919 cgicc::Cgicc cgi(in);
01920 std::string Command = CgiDataUtilities::getData(cgi, "RequestType");
01921 __COUT__ << "*** Login RequestType = " << Command << std::endl;
01922
01923
01924
01925
01926
01927
01928
01929
01930 std::vector<std::string> loggedOutUsernames;
01931 theWebUsers_.cleanupExpiredEntries(&loggedOutUsernames);
01932 for (unsigned int i = 0; i < loggedOutUsernames.size(); ++i)
01933 makeSystemLogbookEntry(loggedOutUsernames[i] + " login timed out.");
01934
01935 if (Command == "sessionId")
01936 {
01937
01938
01939
01940
01941
01942 std::string uuid = CgiDataUtilities::postData(cgi, "uuid");
01943
01944 std::string sid = theWebUsers_.createNewLoginSession(uuid);
01945
01946 __COUT__ << "uuid = " << uuid << std::endl;
01947 __COUT__ << "SessionId = " << sid.substr(0, 10) << std::endl;
01948 *out << sid;
01949 }
01950 else if (Command == "checkCookie")
01951 {
01952 uint64_t uid;
01953 std::string uuid;
01954 std::string jumbledUser;
01955 std::string cookieCode;
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965 uuid = CgiDataUtilities::postData(cgi, "uuid");
01966 jumbledUser = CgiDataUtilities::postData(cgi, "ju");
01967 cookieCode = CgiDataUtilities::postData(cgi, "cc");
01968
01969 __COUT__ << "uuid = " << uuid << std::endl;
01970 __COUT__ << "Cookie Code = " << cookieCode.substr(0, 10) << std::endl;
01971 __COUT__ << "jumbledUser = " << jumbledUser.substr(0, 10) << std::endl;
01972
01973
01974 uid = theWebUsers_.isCookieCodeActiveForLogin(uuid, cookieCode,
01975 jumbledUser);
01976
01977 if (uid == theWebUsers_.NOT_FOUND_IN_DATABASE)
01978 {
01979 __COUT__ << "cookieCode invalid" << std::endl;
01980 jumbledUser = "";
01981 cookieCode = "0";
01982 }
01983 else
01984 __COUT__ << "cookieCode is good." << std::endl;
01985
01986
01987 HttpXmlDocument xmldoc(cookieCode, jumbledUser);
01988
01989 theWebUsers_.insertSettingsForUser(uid, &xmldoc);
01990
01991 xmldoc.outputXmlDocument((std::ostringstream*) out);
01992
01993 }
01994 else if (Command == "login")
01995 {
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005 std::string uuid = CgiDataUtilities::postData(cgi, "uuid");
02006 std::string newAccountCode = CgiDataUtilities::postData(cgi, "nac");
02007 std::string jumbledUser = CgiDataUtilities::postData(cgi, "ju");
02008 std::string jumbledPw = CgiDataUtilities::postData(cgi, "jp");
02009
02010 __COUT__ << "jumbledUser = " << jumbledUser.substr(0, 10) << std::endl;
02011 __COUT__ << "jumbledPw = " << jumbledPw.substr(0, 10) << std::endl;
02012 __COUT__ << "uuid = " << uuid << std::endl;
02013 __COUT__ << "nac =-" << newAccountCode << "-" << std::endl;
02014
02015 uint64_t uid = theWebUsers_.attemptActiveSession(uuid, jumbledUser,
02016 jumbledPw, newAccountCode);
02017
02018
02019 if (uid == theWebUsers_.NOT_FOUND_IN_DATABASE)
02020 {
02021 __COUT__ << "cookieCode invalid" << std::endl;
02022 jumbledUser = "";
02023 if (newAccountCode != "1")
02024 newAccountCode = "0";
02025 }
02026
02027 __COUT__ << "new cookieCode = " << newAccountCode.substr(0, 10) << std::endl;
02028
02029 HttpXmlDocument xmldoc(newAccountCode, jumbledUser);
02030
02031 theWebUsers_.insertSettingsForUser(uid, &xmldoc);
02032
02033
02034
02035 if (uid != theWebUsers_.NOT_FOUND_IN_DATABASE)
02036 {
02037 uint64_t asCnt = theWebUsers_.getActiveSessionCountForUser(uid) - 1;
02038 char asStr[20];
02039 sprintf(asStr, "%lu", asCnt);
02040 xmldoc.addTextElementToData("user_active_session_count", asStr);
02041 }
02042
02043 xmldoc.outputXmlDocument((std::ostringstream*) out);
02044
02045
02046 makeSystemLogbookEntry(
02047 theWebUsers_.getUsersUsername(uid) + " logged in.");
02048 }
02049 else if (Command == "cert")
02050 {
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060 std::string uuid = CgiDataUtilities::postData(cgi, "uuid");
02061 std::string jumbledEmail = cgicc::form_urldecode(CgiDataUtilities::getData(cgi, "httpsUser"));
02062 std::string username = "";
02063 std::string cookieCode = "";
02064
02065 __COUT__ << "CERTIFICATE LOGIN REUEST RECEVIED!!!" << std::endl;
02066 __COUT__ << "jumbledEmail = " << jumbledEmail << std::endl;
02067 __COUT__ << "uuid = " << uuid << std::endl;
02068
02069 uint64_t uid = theWebUsers_.attemptActiveSessionWithCert(uuid, jumbledEmail,
02070 cookieCode, username);
02071
02072
02073 if (uid == theWebUsers_.NOT_FOUND_IN_DATABASE)
02074 {
02075 __COUT__ << "cookieCode invalid" << std::endl;
02076 jumbledEmail = "";
02077 if (cookieCode != "1")
02078 cookieCode = "0";
02079 }
02080
02081 __COUT__ << "new cookieCode = " << cookieCode.substr(0, 10) << std::endl;
02082
02083 HttpXmlDocument xmldoc(cookieCode, jumbledEmail);
02084
02085 theWebUsers_.insertSettingsForUser(uid, &xmldoc);
02086
02087
02088
02089 if (uid != theWebUsers_.NOT_FOUND_IN_DATABASE)
02090 {
02091 uint64_t asCnt = theWebUsers_.getActiveSessionCountForUser(uid) - 1;
02092 char asStr[20];
02093 sprintf(asStr, "%lu", asCnt);
02094 xmldoc.addTextElementToData("user_active_session_count", asStr);
02095 }
02096
02097 xmldoc.outputXmlDocument((std::ostringstream*) out);
02098
02099
02100 makeSystemLogbookEntry(
02101 theWebUsers_.getUsersUsername(uid) + " logged in.");
02102 }
02103 else if (Command == "logout")
02104 {
02105 std::string cookieCode = CgiDataUtilities::postData(cgi, "CookieCode");
02106 std::string logoutOthers = CgiDataUtilities::postData(cgi,
02107 "LogoutOthers");
02108
02109 __COUT__ << "Cookie Code = " << cookieCode.substr(0, 10) << std::endl;
02110 __COUT__ << "logoutOthers = " << logoutOthers << std::endl;
02111
02112 uint64_t uid;
02113 if (theWebUsers_.cookieCodeLogout(cookieCode, logoutOthers == "1", &uid)
02114 != theWebUsers_.NOT_FOUND_IN_DATABASE)
02115 {
02116
02117
02118 if (!theWebUsers_.isUserIdActive(uid))
02119 makeSystemLogbookEntry(
02120 theWebUsers_.getUsersUsername(uid) + " logged out.");
02121 }
02122 }
02123 else
02124 {
02125 __COUT__ << __LINE__ << "\tInvalid Command" << std::endl;
02126 *out << "0";
02127 }
02128 }
02129
02130
02131 void Supervisor::tooltipRequest(xgi::Input * in, xgi::Output * out)
02132 throw (xgi::exception::Exception)
02133 {
02134 cgicc::Cgicc cgi(in);
02135
02136 std::string Command = CgiDataUtilities::getData(cgi, "RequestType");
02137 __COUT__ << "Tooltip RequestType = " << Command << std::endl;
02138
02139
02140
02141
02142
02143 std::string cookieCode = CgiDataUtilities::postData(cgi, "CookieCode");
02144 uint8_t userPermissions;
02145 uint64_t uid;
02146
02147 if (!theWebUsers_.cookieCodeIsActiveForRequest(cookieCode, &userPermissions,
02148 &uid, "0", false))
02149 {
02150 *out << cookieCode;
02151 return;
02152 }
02153
02154
02155
02156 HttpXmlDocument xmldoc(cookieCode);
02157
02158 if(Command == "check")
02159 {
02160 WebUsers::tooltipCheckForUsername(
02161 theWebUsers_.getUsersUsername(uid),
02162 &xmldoc,
02163 CgiDataUtilities::getData(cgi, "srcFile"),
02164 CgiDataUtilities::getData(cgi, "srcFunc"),
02165 CgiDataUtilities::getData(cgi, "srcId"));
02166 }
02167 else if(Command == "setNeverShow")
02168 {
02169 WebUsers::tooltipSetNeverShowForUsername(
02170 theWebUsers_.getUsersUsername(uid),
02171 &xmldoc,
02172 CgiDataUtilities::getData(cgi, "srcFile"),
02173 CgiDataUtilities::getData(cgi, "srcFunc"),
02174 CgiDataUtilities::getData(cgi, "srcId"),
02175 CgiDataUtilities::getData(cgi, "doNeverShow") == "1"?true:false,
02176 CgiDataUtilities::getData(cgi, "temporarySilence") == "1"?true:false);
02177
02178 }
02179 else
02180 __COUT__ << "Command Request, " << Command << ", not recognized." << std::endl;
02181
02182 xmldoc.outputXmlDocument((std::ostringstream*) out, false, true);
02183 }
02184
02185
02186 void Supervisor::request(xgi::Input * in, xgi::Output * out)
02187 throw (xgi::exception::Exception)
02188 {
02189
02190 if(VERBOSE_MUTEX) __COUT__ << "Waiting for FSM access" << std::endl;
02191 std::lock_guard<std::mutex> lock(stateMachineAccessMutex_);
02192 if(VERBOSE_MUTEX) __COUT__ << "Have FSM access" << std::endl;
02193
02194 cgicc::Cgicc cgi(in);
02195
02196 std::string Command = CgiDataUtilities::getData(cgi, "RequestType");
02197
02198
02199
02200
02201
02202
02203 std::string cookieCode = CgiDataUtilities::postData(cgi, "CookieCode");
02204 uint8_t userPermissions;
02205 uint64_t uid;
02206 std::string userWithLock;
02207 bool refreshCookie = Command != "getSystemMessages" &&
02208 Command != "getCurrentState" &&
02209 Command != "gatewayLaunchOTS" &&
02210 Command != "gatewayLaunchWiz";
02211
02212 if (!theWebUsers_.cookieCodeIsActiveForRequest(cookieCode, &userPermissions,
02213 &uid, "0",
02214 refreshCookie,
02215 &userWithLock))
02216 {
02217 *out << cookieCode;
02218 return;
02219 }
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245 HttpXmlDocument xmldoc(cookieCode);
02246
02247 if (Command == "getSettings")
02248 {
02249 std::string accounts = CgiDataUtilities::getData(cgi, "accounts");
02250
02251 __COUT__ << "Get Settings Request" << std::endl;
02252 __COUT__ << "accounts = " << accounts << std::endl;
02253 theWebUsers_.insertSettingsForUser(uid, &xmldoc, accounts == "1");
02254 }
02255 else if (Command == "setSettings")
02256 {
02257 std::string bgcolor = CgiDataUtilities::postData(cgi, "bgcolor");
02258 std::string dbcolor = CgiDataUtilities::postData(cgi, "dbcolor");
02259 std::string wincolor = CgiDataUtilities::postData(cgi, "wincolor");
02260 std::string layout = CgiDataUtilities::postData(cgi, "layout");
02261 std::string syslayout = CgiDataUtilities::postData(cgi, "syslayout");
02262
02263 __COUT__ << "Set Settings Request" << std::endl;
02264 __COUT__ << "bgcolor = " << bgcolor << std::endl;
02265 __COUT__ << "dbcolor = " << dbcolor << std::endl;
02266 __COUT__ << "wincolor = " << wincolor << std::endl;
02267 __COUT__ << "layout = " << layout << std::endl;
02268 __COUT__ << "syslayout = " << syslayout << std::endl;
02269 theWebUsers_.changeSettingsForUser(uid, bgcolor, dbcolor, wincolor,
02270 layout, syslayout);
02271 theWebUsers_.insertSettingsForUser(uid, &xmldoc, true);
02272 }
02273 else if (Command == "accountSettings")
02274 {
02275 std::string type = CgiDataUtilities::postData(cgi, "type");
02276 int type_int = -1;
02277
02278 if (type == "updateAccount")
02279 type_int = 0;
02280 else if (type == "createAccount")
02281 type_int = 1;
02282 else if (type == "deleteAccount")
02283 type_int = 2;
02284
02285 std::string username = CgiDataUtilities::postData(cgi, "username");
02286 std::string displayname = CgiDataUtilities::postData(cgi,
02287 "displayname");
02288 std::string email = CgiDataUtilities::postData(cgi, "useremail");
02289 std::string permissions = CgiDataUtilities::postData(cgi,
02290 "permissions");
02291 std::string accounts = CgiDataUtilities::getData(cgi, "accounts");
02292
02293 __COUT__ << "accountSettings Request" << std::endl;
02294 __COUT__ << "type = " << type << " - " << type_int << std::endl;
02295 __COUT__ << "username = " << username << std::endl;
02296 __COUT__ << "useremail = " << email << std::endl;
02297 __COUT__ << "displayname = " << displayname << std::endl;
02298 __COUT__ << "permissions = " << permissions << std::endl;
02299
02300 theWebUsers_.modifyAccountSettings(uid, type_int, username, displayname,email,
02301 permissions);
02302
02303 __COUT__ << "accounts = " << accounts << std::endl;
02304
02305 theWebUsers_.insertSettingsForUser(uid, &xmldoc, accounts == "1");
02306 }
02307 else if(Command == "stateMatchinePreferences")
02308 {
02309 std::string set = CgiDataUtilities::getData(cgi, "set");
02310 const std::string DEFAULT_FSM_VIEW = "Default_FSM_View";
02311 if(set == "1")
02312 theWebUsers_.setGenericPreference(uid, DEFAULT_FSM_VIEW,
02313 CgiDataUtilities::getData(cgi, DEFAULT_FSM_VIEW));
02314 else
02315 theWebUsers_.getGenericPreference(uid, DEFAULT_FSM_VIEW, &xmldoc);
02316 }
02317 else if(Command == "getAliasList")
02318 {
02319 std::string username = theWebUsers_.getUsersUsername(uid);
02320 std::string fsmName = CgiDataUtilities::getData(cgi, "fsmName");
02321 __COUT__ << "fsmName = " << fsmName << std::endl;
02322
02323 std::string stateMachineAliasFilter = "*";
02324
02325 std::map<std::string ,
02326 std::pair<std::string , ConfigurationGroupKey> > aliasMap =
02327 theConfigurationManager_->getGroupAliasesConfiguration();
02328
02329
02330
02331 ConfigurationTree configLinkNode = theConfigurationManager_->getSupervisorConfigurationNode(
02332 supervisorContextUID_, supervisorApplicationUID_);
02333
02334 if(!configLinkNode.isDisconnected())
02335 {
02336 try
02337 {
02338 ConfigurationTree fsmLinkNode = configLinkNode.getNode("LinkToStateMachineConfiguration");
02339 if(!fsmLinkNode.isDisconnected())
02340 stateMachineAliasFilter =
02341 fsmLinkNode.getNode(fsmName + "/SystemAliasFilter").getValue<std::string>();
02342 else
02343 __COUT_INFO__ << "FSM Link disconnected." << std::endl;
02344 }
02345 catch(std::runtime_error &e) { __COUT_INFO__ << e.what() << std::endl; }
02346 catch(...) { __COUT_ERR__ << "Unknown error. Should never happen." << std::endl; }
02347 }
02348 else
02349 __COUT_INFO__ << "FSM Link disconnected." << std::endl;
02350
02351 __COUT__ << "stateMachineAliasFilter = " << stateMachineAliasFilter << std::endl;
02352
02353
02354
02355
02356
02357 {
02358 bool invertFilter = stateMachineAliasFilter.size() && stateMachineAliasFilter[0] == '!';
02359 std::vector<std::string> filterArr;
02360
02361 size_t i = 0;
02362 if(invertFilter) ++i;
02363 size_t f;
02364 std::string tmp;
02365 while((f = stateMachineAliasFilter.find('*',i)) != std::string::npos)
02366 {
02367 tmp = stateMachineAliasFilter.substr(i,f-i);
02368 i = f+1;
02369 filterArr.push_back(tmp);
02370
02371
02372
02373 }
02374 if(i <= stateMachineAliasFilter.size())
02375 {
02376 tmp = stateMachineAliasFilter.substr(i);
02377 filterArr.push_back(tmp);
02378
02379 }
02380
02381
02382 bool filterMatch;
02383
02384
02385 for(auto& aliasMapPair : aliasMap)
02386 {
02387
02388
02389 filterMatch = true;
02390
02391 if(filterArr.size() == 1)
02392 {
02393 if(filterArr[0] != "" &&
02394 filterArr[0] != "*" &&
02395 aliasMapPair.first != filterArr[0])
02396 filterMatch = false;
02397 }
02398 else
02399 {
02400 i = -1;
02401 for(f=0;f<filterArr.size();++f)
02402 {
02403 if(!filterArr[f].size()) continue;
02404
02405 if(f == 0)
02406 {
02407 if((i = aliasMapPair.first.find(filterArr[f])) != 0)
02408 {
02409 filterMatch = false;
02410 break;
02411 }
02412 }
02413 else if(f == filterArr.size()-1)
02414 {
02415 if(aliasMapPair.first.rfind(filterArr[f]) !=
02416 aliasMapPair.first.size() - filterArr[f].size())
02417 {
02418 filterMatch = false;
02419 break;
02420 }
02421 }
02422 else if((i = aliasMapPair.first.find(filterArr[f])) ==
02423 std::string::npos)
02424 {
02425 filterMatch = false;
02426 break;
02427 }
02428 }
02429 }
02430
02431 if(invertFilter) filterMatch = !filterMatch;
02432
02433
02434
02435 if(!filterMatch) continue;
02436
02437 xmldoc.addTextElementToData("config_alias", aliasMapPair.first);
02438 xmldoc.addTextElementToData("config_key",
02439 ConfigurationGroupKey::getFullGroupString(aliasMapPair.second.first,
02440 aliasMapPair.second.second).c_str());
02441
02442 std::string groupComment, groupAuthor, groupCreationTime;
02443 try
02444 {
02445 theConfigurationManager_->loadConfigurationGroup(
02446 aliasMapPair.second.first,aliasMapPair.second.second,
02447 false,0,0,
02448 &groupComment, &groupAuthor, &groupCreationTime, false );
02449
02450 xmldoc.addTextElementToData("config_comment", groupComment);
02451 xmldoc.addTextElementToData("config_author", groupAuthor);
02452 xmldoc.addTextElementToData("config_create_time", groupCreationTime);
02453 }
02454 catch(...)
02455 {
02456 __COUT_WARN__ << "Failed to load group metadata." << std::endl;
02457 }
02458 }
02459 }
02460
02461
02462 std::string fn = FSM_LAST_GROUP_ALIAS_PATH + FSM_LAST_GROUP_ALIAS_FILE_START +
02463 username + "." + FSM_USERS_PREFERENCES_FILETYPE;
02464 __COUT__ << "Load preferences: " << fn << std::endl;
02465 FILE *fp = fopen(fn.c_str(),"r");
02466 if(fp)
02467 {
02468 char tmpLastAlias[500];
02469 fscanf(fp,"%*s %s",tmpLastAlias);
02470 __COUT__ << "tmpLastAlias: " << tmpLastAlias << std::endl;
02471
02472 xmldoc.addTextElementToData("UserLastConfigAlias",tmpLastAlias);
02473 fclose(fp);
02474 }
02475 }
02476 else if (Command == "getFecList")
02477 {
02478 xmldoc.addTextElementToData("fec_list", "");
02479
02480 for (unsigned int i = 0; i< theSupervisorDescriptorInfo_.getFEDescriptors().size(); ++i)
02481 {
02482 xmldoc.addTextElementToParent("fec_url",
02483 theSupervisorDescriptorInfo_.getFEURL(i), "fec_list");
02484 xmldoc.addTextElementToParent(
02485 "fec_urn",
02486 theSupervisorDescriptorInfo_.getFEDescriptor(i)->getURN(),
02487 "fec_list");
02488 }
02489 }
02490 else if (Command == "getSystemMessages")
02491 {
02492 xmldoc.addTextElementToData("systemMessages",
02493 theSysMessenger_.getSysMsg(
02494 theWebUsers_.getUsersDisplayName(uid)));
02495
02496 xmldoc.addTextElementToData("username_with_lock",
02497 theWebUsers_.getUserWithLock());
02498
02499
02500 }
02501 else if (Command == "setUserWithLock")
02502 {
02503 std::string username = CgiDataUtilities::postData(cgi, "username");
02504 std::string lock = CgiDataUtilities::postData(cgi, "lock");
02505 std::string accounts = CgiDataUtilities::getData(cgi, "accounts");
02506
02507 __COUT__ << Command << std::endl;
02508 __COUT__ << "username " << username << std::endl;
02509 __COUT__ << "lock " << lock << std::endl;
02510 __COUT__ << "accounts " << accounts << std::endl;
02511 __COUT__ << "uid " << uid << std::endl;
02512
02513 std::string tmpUserWithLock = theWebUsers_.getUserWithLock();
02514 if(!theWebUsers_.setUserWithLock(uid, lock == "1", username))
02515 xmldoc.addTextElementToData("server_alert",
02516 std::string("Set user lock action failed. You must have valid permissions and ") +
02517 "locking user must be currently logged in.");
02518
02519 theWebUsers_.insertSettingsForUser(uid, &xmldoc, accounts == "1");
02520
02521 if (tmpUserWithLock != theWebUsers_.getUserWithLock())
02522 theSysMessenger_.addSysMsg("*", theWebUsers_.getUserWithLock()
02523 == "" ? tmpUserWithLock + " has unlocked ots."
02524 : theWebUsers_.getUserWithLock()
02525 + " has locked ots.");
02526 }
02527 else if (Command == "getStateMachine")
02528 {
02529
02530 std::vector<toolbox::fsm::State> states;
02531 states = theStateMachine_.getStates();
02532 char stateStr[2];
02533 stateStr[1] = '\0';
02534 std::string transName;
02535 std::string transParameter;
02536
02537
02538 for (unsigned int i = 0; i < states.size(); ++i)
02539 {
02540 stateStr[0] = states[i];
02541 DOMElement* stateParent = xmldoc.addTextElementToData("state", stateStr);
02542
02543 xmldoc.addTextElementToParent("state_name", theStateMachine_.getStateName(states[i]), stateParent);
02544
02545
02546
02547
02548 std::map<std::string, toolbox::fsm::State, std::less<std::string> >
02549 trans = theStateMachine_.getTransitions(states[i]);
02550 std::set<std::string> actionNames = theStateMachine_.getInputs(states[i]);
02551
02552 std::map<std::string, toolbox::fsm::State, std::less<std::string> >::iterator it =
02553 trans.begin();
02554 std::set<std::string>::iterator ait = actionNames.begin();
02555
02556
02557
02558
02559
02560
02561
02562 for (; it != trans.end() && ait != actionNames.end(); ++it, ++ait)
02563 {
02564 stateStr[0] = it->second;
02565
02566 if(stateStr[0] == 'R')
02567 {
02568
02569 xmldoc.addTextElementToParent("state_transition", stateStr, stateParent);
02570
02571
02572
02573 xmldoc.addTextElementToParent("state_transition_action", *ait, stateParent);
02574
02575 transName = theStateMachine_.getTransitionName(states[i], *ait);
02576
02577
02578 xmldoc.addTextElementToParent("state_transition_name",
02579 transName, stateParent);
02580 transParameter = theStateMachine_.getTransitionParameter(states[i], *ait);
02581
02582
02583 xmldoc.addTextElementToParent("state_transition_parameter", transParameter, stateParent);
02584 break;
02585 }
02586 else if(stateStr[0] == 'C')
02587 {
02588
02589 xmldoc.addTextElementToParent("state_transition", stateStr, stateParent);
02590
02591
02592
02593 xmldoc.addTextElementToParent("state_transition_action", *ait, stateParent);
02594
02595 transName = theStateMachine_.getTransitionName(states[i], *ait);
02596
02597
02598 xmldoc.addTextElementToParent("state_transition_name",
02599 transName, stateParent);
02600 transParameter = theStateMachine_.getTransitionParameter(states[i], *ait);
02601
02602
02603 xmldoc.addTextElementToParent("state_transition_parameter", transParameter, stateParent);
02604 break;
02605 }
02606 }
02607
02608
02609 it = trans.begin();
02610 ait = actionNames.begin();
02611
02612
02613 for (; it != trans.end() && ait != actionNames.end(); ++it, ++ait)
02614 {
02615
02616
02617 stateStr[0] = it->second;
02618
02619 if(stateStr[0] == 'R')
02620 continue;
02621 else if(stateStr[0] == 'C')
02622 continue;
02623
02624 xmldoc.addTextElementToParent("state_transition", stateStr, stateParent);
02625
02626
02627
02628 xmldoc.addTextElementToParent("state_transition_action", *ait, stateParent);
02629
02630 transName = theStateMachine_.getTransitionName(states[i], *ait);
02631
02632
02633 xmldoc.addTextElementToParent("state_transition_name",
02634 transName, stateParent);
02635 transParameter = theStateMachine_.getTransitionParameter(states[i], *ait);
02636
02637
02638 xmldoc.addTextElementToParent("state_transition_parameter", transParameter, stateParent);
02639 }
02640 }
02641
02642 }
02643 else if (Command == "getStateMachineNames")
02644 {
02645
02646 ConfigurationTree configLinkNode = theConfigurationManager_->getSupervisorConfigurationNode(
02647 supervisorContextUID_, supervisorApplicationUID_);
02648
02649 try
02650 {
02651 auto fsmNodes = configLinkNode.getNode(
02652 "LinkToStateMachineConfiguration").getChildren();
02653 for(const auto& fsmNode:fsmNodes)
02654 xmldoc.addTextElementToData("stateMachineName", fsmNode.first);
02655 }
02656 catch(...)
02657 {
02658 __COUT__ << "Caught exception, assuming no valid FSM names." << std::endl;
02659 xmldoc.addTextElementToData("stateMachineName", "");
02660 }
02661 }
02662 else if (Command == "getIterationPlanStatus")
02663 {
02664
02665 theIterator_.handleCommandRequest(xmldoc,Command,"");
02666 }
02667 else if (Command == "getCurrentState")
02668 {
02669 xmldoc.addTextElementToData("current_state", theStateMachine_.getCurrentStateName());
02670 xmldoc.addTextElementToData("in_transition", theStateMachine_.isInTransition() ? "1" : "0");
02671 if (theStateMachine_.isInTransition())
02672 xmldoc.addTextElementToData("transition_progress", theProgressBar_.readPercentageString());
02673 else
02674 xmldoc.addTextElementToData("transition_progress", "100");
02675
02676
02677 char tmp[20];
02678 sprintf(tmp,"%lu",theStateMachine_.getTimeInState());
02679 xmldoc.addTextElementToData("time_in_state", tmp);
02680
02681
02682
02683
02684
02685
02687
02688 std::string fsmName = CgiDataUtilities::getData(cgi, "fsmName");
02689
02690
02691
02692
02693
02694
02695
02696 if(!theStateMachine_.isInTransition())
02697 {
02698 std::string stateMachineRunAlias = "Run";
02699
02700
02701 ConfigurationTree configLinkNode = theConfigurationManager_->getSupervisorConfigurationNode(
02702 supervisorContextUID_, supervisorApplicationUID_);
02703
02704 if(!configLinkNode.isDisconnected())
02705 {
02706 try
02707 {
02708 ConfigurationTree fsmLinkNode = configLinkNode.getNode("LinkToStateMachineConfiguration");
02709 if(!fsmLinkNode.isDisconnected())
02710 stateMachineRunAlias =
02711 fsmLinkNode.getNode(fsmName + "/RunDisplayAlias").getValue<std::string>();
02712
02713
02714 }
02715 catch(std::runtime_error &e)
02716 {
02717
02718
02719
02720
02721 }
02722 catch(...) {
02723 __COUT_ERR__ << "Unknown error. Should never happen." << std::endl;
02724
02725 __COUT_INFO__ << "No state machine Run alias. Ignoring and assuming alias of '" <<
02726 stateMachineRunAlias << ".'" << std::endl;
02727 }
02728 }
02729
02730
02731
02732
02733
02734 xmldoc.addTextElementToData("stateMachineRunAlias", stateMachineRunAlias);
02735
02736
02738
02739
02740 if(theStateMachine_.getCurrentStateName() == "Running" ||
02741 theStateMachine_.getCurrentStateName() == "Paused")
02742 sprintf(tmp,"Current %s Number: %u",stateMachineRunAlias.c_str(),getNextRunNumber(activeStateMachineName_)-1);
02743 else
02744 sprintf(tmp,"Next %s Number: %u",stateMachineRunAlias.c_str(),getNextRunNumber(fsmName));
02745 xmldoc.addTextElementToData("run_number", tmp);
02746 }
02747 }
02748 else if(Command == "getErrorInStateMatchine")
02749 {
02750 xmldoc.addTextElementToData("FSM_Error", theStateMachine_.getErrorMessage());
02751 }
02752 else if(Command == "getDesktopIcons")
02753 {
02754
02755 std::string iconFileName = ICON_FILE_NAME;
02756 std::ifstream iconFile;
02757 std::string iconList = "";
02758 std::string line;
02759 iconFile.open(iconFileName.c_str());
02760
02761 if(!iconFile)
02762 {
02763 __COUT__ << "Error opening file: "<< iconFileName << std::endl;
02764 system("pause");
02765 return;
02766 }
02767 if(iconFile.is_open())
02768 {
02769 __COUT__ << "Getting Desktop Icons - opened file: " << iconFileName << std::endl;
02770 while(std::getline(iconFile, line))
02771 {
02772 iconList = line;
02773 }
02774
02775
02776
02777 iconFile.close();
02778 }
02779 xmldoc.addTextElementToData("iconList", iconList);
02780
02781 }
02782 else if(Command == "gatewayLaunchOTS" || Command == "gatewayLaunchWiz")
02783 {
02784
02785
02786 if(userPermissions != 255)
02787 {
02788 __COUT__ << "Insufficient Permissions" << std::endl;
02789 }
02790 else
02791 {
02792 __COUT_WARN__ << Command << " command received! " << std::endl;
02793 __MOUT_WARN__ << Command << " command received! " << std::endl;
02794
02795
02796
02797 theWebUsers_.saveActiveSessions();
02798
02799
02800 __COUT_INFO__ << "Launching... " << std::endl;
02801
02802
02803 __COUT__ << "Extracting target context hostnames... " << std::endl;
02804 std::vector<std::string> hostnames;
02805 try
02806 {
02807 theConfigurationManager_->init();
02808
02809 const XDAQContextConfiguration* contextConfiguration = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration);
02810
02811 auto contexts = contextConfiguration->getContexts();
02812 unsigned int i,j;
02813 for(const auto& context: contexts)
02814 {
02815 if(!context.status_) continue;
02816
02817
02818 j=0;
02819 for(i=0;i<context.address_.size();++i)
02820 if(context.address_[i] == '/')
02821 j = i+1;
02822 hostnames.push_back(context.address_.substr(j));
02823 __COUT__ << "hostname = " << hostnames.back() << std::endl;
02824 }
02825 }
02826 catch(...)
02827 {
02828 __SS__ << "\nRelaunch of otsdaq interrupted! " <<
02829 "The Configuration Manager could not be initialized." << std::endl;
02830
02831 __COUT_ERR__ << "\n" << ss.str();
02832 return;
02833 }
02834
02835 for(const auto& hostname: hostnames)
02836 {
02837 std::string fn = (std::string(getenv("SERVICE_DATA_PATH")) +
02838 "/StartOTS_action_" + hostname + ".cmd");
02839 FILE* fp = fopen(fn.c_str(),"w");
02840 if(fp)
02841 {
02842 if(Command == "gatewayLaunchOTS")
02843 fprintf(fp,"LAUNCH_OTS");
02844 else if(Command == "gatewayLaunchWiz")
02845 fprintf(fp,"LAUNCH_WIZ");
02846
02847 fclose(fp);
02848 }
02849 else
02850 __COUT_ERR__ << "Unable to open command file: " << fn << std::endl;
02851 }
02852 }
02853 }
02854 else if(Command == "resetUserTooltips")
02855 {
02856 WebUsers::resetAllUserTooltips(theWebUsers_.getUsersUsername(uid));
02857 }
02858 else
02859 __COUT__ << "Command Request, " << Command << ", not recognized." << std::endl;
02860
02861
02862
02863
02864 xmldoc.outputXmlDocument((std::ostringstream*) out, false, true);
02865
02866
02867 }
02868
02869
02870
02871
02872 xoap::MessageReference Supervisor::supervisorGetUserInfo(
02873 xoap::MessageReference message)
02874 throw (xoap::exception::Exception)
02875 {
02876 SOAPParameters parameters;
02877 parameters.addParameter("CookieCode");
02878 receive(message, parameters);
02879 std::string cookieCode = parameters.getValue("CookieCode");
02880
02881 std::string username, displayName;
02882 uint64_t activeSessionIndex;
02883
02884 theWebUsers_.getUserInfoForCookie(cookieCode, &username, &displayName,
02885 &activeSessionIndex);
02886
02887
02888
02889
02890
02891 SOAPParameters retParameters;
02892 retParameters.addParameter("Username", username);
02893 retParameters.addParameter("DisplayName", displayName);
02894 char tmpStr[100];
02895 sprintf(tmpStr, "%lu", activeSessionIndex);
02896 retParameters.addParameter("ActiveSessionIndex", tmpStr);
02897
02898 return SOAPUtilities::makeSOAPMessageReference("UserInfoResponse",
02899 retParameters);
02900 }
02901
02902
02903
02904
02905 xoap::MessageReference Supervisor::supervisorCookieCheck(xoap::MessageReference message)
02906 throw (xoap::exception::Exception)
02907 {
02908
02909
02910
02911 SOAPParameters parameters;
02912 parameters.addParameter("CookieCode");
02913 parameters.addParameter("RefreshOption");
02914 receive(message, parameters);
02915 std::string cookieCode = parameters.getValue("CookieCode");
02916 std::string refreshOption = parameters.getValue("RefreshOption");
02917
02918
02919
02920 uint8_t userPermissions = 0;
02921 std::string userWithLock = "";
02922 theWebUsers_.cookieCodeIsActiveForRequest(cookieCode, &userPermissions, 0,
02923 "0", refreshOption == "1", &userWithLock);
02924
02925
02926
02927
02928 SOAPParameters retParameters;
02929 retParameters.addParameter("CookieCode", cookieCode);
02930 char tmp[5];
02931 sprintf(tmp, "%d", userPermissions);
02932 retParameters.addParameter("Permissions", tmp);
02933 retParameters.addParameter("UserWithLock", userWithLock);
02934
02935
02936
02937 return SOAPUtilities::makeSOAPMessageReference("CookieResponse",
02938 retParameters);
02939 }
02940
02941
02942
02943
02944 xoap::MessageReference Supervisor::supervisorGetActiveUsers(
02945 xoap::MessageReference message)
02946 throw (xoap::exception::Exception)
02947 {
02948 __COUT__ << std::endl;
02949
02950 SOAPParameters
02951 parameters("UserList", theWebUsers_.getActiveUsersString());
02952 return SOAPUtilities::makeSOAPMessageReference("ActiveUserResponse",
02953 parameters);
02954 }
02955
02956
02957
02958
02959
02960 xoap::MessageReference Supervisor::supervisorSystemMessage(
02961 xoap::MessageReference message)
02962 throw (xoap::exception::Exception)
02963 {
02964 SOAPParameters parameters;
02965 parameters.addParameter("ToUser");
02966 parameters.addParameter("Message");
02967 receive(message, parameters);
02968
02969 __COUT__ << "toUser: " << parameters.getValue("ToUser").substr(
02970 0, 10) << ", message: " << parameters.getValue("Message").substr(0,
02971 10) << std::endl;
02972
02973 theSysMessenger_.addSysMsg(parameters.getValue("ToUser"),
02974 parameters.getValue("Message"));
02975 return SOAPUtilities::makeSOAPMessageReference("SystemMessageResponse");
02976 }
02977
02978
02979
02980
02981
02982 xoap::MessageReference Supervisor::supervisorSystemLogbookEntry(
02983 xoap::MessageReference message)
02984 throw (xoap::exception::Exception)
02985 {
02986 SOAPParameters parameters;
02987 parameters.addParameter("EntryText");
02988 receive(message, parameters);
02989
02990 __COUT__ << "EntryText: " << parameters.getValue("EntryText").substr(
02991 0, 10) << std::endl;
02992
02993 makeSystemLogbookEntry(parameters.getValue("EntryText"));
02994
02995 return SOAPUtilities::makeSOAPMessageReference("SystemLogbookResponse");
02996 }
02997
02998
02999
03000
03001
03002
03003 xoap::MessageReference Supervisor::supervisorLastConfigGroupRequest(
03004 xoap::MessageReference message)
03005 throw (xoap::exception::Exception)
03006 {
03007 SOAPParameters parameters;
03008 parameters.addParameter("ActionOfLastGroup");
03009 receive(message, parameters);
03010
03011 return Supervisor::lastConfigGroupRequestHandler(parameters);
03012 }
03013
03014
03015
03016
03017
03018
03019
03020 xoap::MessageReference Supervisor::lastConfigGroupRequestHandler(
03021 const SOAPParameters ¶meters)
03022 {
03023 std::string action = parameters.getValue("ActionOfLastGroup");
03024 __COUT__ << "ActionOfLastGroup: " << action.substr(
03025 0, 10) << std::endl;
03026
03027 std::string fileName = "";
03028 if(action == "Configured")
03029 fileName = FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE;
03030 else if(action == "Started")
03031 fileName = FSM_LAST_STARTED_GROUP_ALIAS_FILE;
03032 else
03033 {
03034 __COUT_ERR__ << "Invalid last group action requested." << std::endl;
03035 return SOAPUtilities::makeSOAPMessageReference("LastConfigGroupResponseFailure");
03036 }
03037 std::string timeString;
03038 std::pair<std::string , ConfigurationGroupKey> theGroup =
03039 loadGroupNameAndKey(fileName,timeString);
03040
03041
03042 SOAPParameters retParameters;
03043 retParameters.addParameter("GroupName", theGroup.first);
03044 retParameters.addParameter("GroupKey", theGroup.second.toString());
03045 retParameters.addParameter("GroupAction", action);
03046 retParameters.addParameter("GroupActionTime", timeString);
03047
03048
03049 return SOAPUtilities::makeSOAPMessageReference("LastConfigGroupResponse",
03050 retParameters);
03051 }
03052
03053
03054
03055
03056
03057
03058
03059
03060 unsigned int Supervisor::getNextRunNumber(const std::string &fsmNameIn)
03061 {
03062 std::string runNumberFileName = RUN_NUMBER_PATH + "/";
03063 std::string fsmName = fsmNameIn == ""?activeStateMachineName_:fsmNameIn;
03064
03065 for(unsigned int i=0;i<fsmName.size();++i)
03066 if( (fsmName[i] >= 'a' && fsmName[i] <= 'z') ||
03067 (fsmName[i] >= 'A' && fsmName[i] <= 'Z') ||
03068 (fsmName[i] >= '0' && fsmName[i] <= '9'))
03069 runNumberFileName += fsmName[i];
03070 runNumberFileName += RUN_NUMBER_FILE_NAME;
03071
03072
03073 std::ifstream runNumberFile(runNumberFileName.c_str());
03074 if (!runNumberFile.is_open())
03075 {
03076 __COUT__ << "Can't open file: " << runNumberFileName << std::endl;
03077
03078 __COUT__ << "Creating file and setting Run Number to 1: " << runNumberFileName << std::endl;
03079 FILE *fp = fopen(runNumberFileName.c_str(),"w");
03080 fprintf(fp,"1");
03081 fclose(fp);
03082
03083 runNumberFile.open(runNumberFileName.c_str());
03084 if(!runNumberFile.is_open())
03085 {
03086 __SS__ << "Error. Can't create file: " << runNumberFileName << std::endl;
03087 __COUT_ERR__ << ss.str();
03088 throw std::runtime_error(ss.str());
03089 }
03090 }
03091 std::string runNumberString;
03092 runNumberFile >> runNumberString;
03093 runNumberFile.close();
03094 return atoi(runNumberString.c_str());
03095 }
03096
03097
03098 bool Supervisor::setNextRunNumber(unsigned int runNumber, const std::string &fsmNameIn)
03099 {
03100 std::string runNumberFileName = RUN_NUMBER_PATH + "/";
03101 std::string fsmName = fsmNameIn == ""?activeStateMachineName_:fsmNameIn;
03102
03103 for(unsigned int i=0;i<fsmName.size();++i)
03104 if( (fsmName[i] >= 'a' && fsmName[i] <= 'z') ||
03105 (fsmName[i] >= 'A' && fsmName[i] <= 'Z') ||
03106 (fsmName[i] >= '0' && fsmName[i] <= '9'))
03107 runNumberFileName += fsmName[i];
03108 runNumberFileName += RUN_NUMBER_FILE_NAME;
03109 __COUT__ << "runNumberFileName: " << runNumberFileName << std::endl;
03110
03111 std::ofstream runNumberFile(runNumberFileName.c_str());
03112 if (!runNumberFile.is_open())
03113 {
03114 __SS__ << "Can't open file: " << runNumberFileName << std::endl;
03115 __COUT__ << ss.str();
03116 throw std::runtime_error(ss.str());
03117 }
03118 std::stringstream runNumberStream;
03119 runNumberStream << runNumber;
03120 runNumberFile << runNumberStream.str().c_str();
03121 runNumberFile.close();
03122 return true;
03123 }
03124
03125
03126
03127
03128
03129
03130
03131 std::pair<std::string ,
03132 ConfigurationGroupKey> Supervisor::loadGroupNameAndKey(const std::string &fileName,
03133 std::string &returnedTimeString)
03134 {
03135 std::string fullPath = FSM_LAST_GROUP_ALIAS_PATH + "/" + fileName;
03136
03137 FILE *groupFile = fopen(fullPath.c_str(),"r");
03138 if (!groupFile)
03139 {
03140 __COUT__ << "Can't open file: " << fullPath << std::endl;
03141
03142 __COUT__ << "Returning empty groupName and key -1" << std::endl;
03143
03144 return std::pair<std::string ,
03145 ConfigurationGroupKey>("",ConfigurationGroupKey());
03146 }
03147
03148 char line[500];
03149
03150 std::pair<std::string ,
03151 ConfigurationGroupKey> theGroup;
03152
03153 fgets(line,500,groupFile);
03154 theGroup.first = line;
03155
03156 fgets(line,500,groupFile);
03157 int key;
03158 sscanf(line,"%d",&key);
03159 theGroup.second = key;
03160
03161 fgets(line,500,groupFile);
03162 time_t timestamp;
03163 sscanf(line,"%ld",×tamp);
03164 struct tm tmstruct;
03165 ::localtime_r(×tamp, &tmstruct);
03166 ::strftime(line, 30, "%c %Z", &tmstruct);
03167 returnedTimeString = line;
03168 fclose(groupFile);
03169
03170
03171 __COUT__ << "theGroup.first= " << theGroup.first <<
03172 " theGroup.second= " << theGroup.second << std::endl;
03173
03174 return theGroup;
03175 }
03176
03177
03178 void Supervisor::saveGroupNameAndKey(const std::pair<std::string ,
03179 ConfigurationGroupKey> &theGroup,
03180 const std::string &fileName)
03181 {
03182 std::string fullPath = FSM_LAST_GROUP_ALIAS_PATH + "/" + fileName;
03183
03184 std::ofstream groupFile(fullPath.c_str());
03185 if (!groupFile.is_open())
03186 {
03187 __SS__ << "Error. Can't open file: " << fullPath << std::endl;
03188 __COUT_ERR__ << "\n" << ss.str();
03189 throw std::runtime_error(ss.str());
03190 }
03191 std::stringstream outss;
03192 outss << theGroup.first << "\n" << theGroup.second << "\n" << time(0);
03193 groupFile << outss.str().c_str();
03194 groupFile.close();
03195 }
03196
03197
03198
03200
03201
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230