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