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