1 #include "otsdaq/GatewaySupervisor/GatewaySupervisor.h"
2 #include "otsdaq/CgiDataUtilities/CgiDataUtilities.h"
3 #include "otsdaq/Macros/CoutMacros.h"
4 #include "otsdaq/MessageFacility/MessageFacility.h"
5 #include "otsdaq/SOAPUtilities/SOAPCommand.h"
6 #include "otsdaq/SOAPUtilities/SOAPUtilities.h"
7 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
9 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
10 #include "otsdaq/ConfigurationInterface/ConfigurationManagerRW.h"
11 #include "otsdaq/TablePlugins/XDAQContextTable.h"
12 #include "otsdaq/WorkLoopManager/WorkLoopManager.h"
14 #include "otsdaq/NetworkUtilities/TransceiverSocket.h"
17 #pragma GCC diagnostic push
18 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
19 #include <cgicc/HTMLClasses.h>
20 #include <cgicc/HTMLDoctype.h>
21 #include <cgicc/HTTPCookie.h>
22 #include <cgicc/HTTPHeader.h>
23 #include <xgi/Utils.h>
24 #pragma GCC diagnostic pop
26 #include <toolbox/fsm/FailedEvent.h>
27 #include <toolbox/task/WorkLoopFactory.h>
28 #include <xdaq/NamespaceURI.h>
29 #include <xoap/Method.h>
38 #define RUN_NUMBER_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/RunNumber/"
39 #define RUN_NUMBER_FILE_NAME "NextRunNumber.txt"
40 #define FSM_LAST_GROUP_ALIAS_FILE_START std::string("FSMLastGroupAlias-")
41 #define FSM_USERS_PREFERENCES_FILETYPE "pref"
45 #define __MF_SUBJECT__ "GatewaySupervisor"
53 : xdaq::Application(s)
57 , stateMachineWorkLoopManager_(toolbox::task::bind(this, &GatewaySupervisor::stateMachineThread, "StateMachine"))
58 , stateMachineSemaphore_(toolbox::BSem::FULL)
59 , activeStateMachineName_("")
61 , broadcastCommandMessageIndex_(0)
62 , broadcastIterationBreakpoint_(-1)
69 mkdir((std::string(__ENV__(
"SERVICE_DATA_PATH"))).c_str(), 0755);
72 mkdir((ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH).c_str(), 0755);
73 mkdir((RUN_NUMBER_PATH).c_str(), 0755);
75 securityType_ = GatewaySupervisor::theWebUsers_.getSecurity();
77 __COUT__ <<
"Security: " << securityType_ << __E__;
79 xgi::bind(
this, &GatewaySupervisor::Default,
"Default");
80 xgi::bind(
this, &GatewaySupervisor::loginRequest,
"LoginRequest");
81 xgi::bind(
this, &GatewaySupervisor::request,
"Request");
82 xgi::bind(
this, &GatewaySupervisor::stateMachineXgiHandler,
"StateMachineXgiHandler");
83 xgi::bind(
this, &GatewaySupervisor::stateMachineIterationBreakpoint,
"StateMachineIterationBreakpoint");
84 xgi::bind(
this, &GatewaySupervisor::tooltipRequest,
"TooltipRequest");
86 xoap::bind(
this, &GatewaySupervisor::supervisorCookieCheck,
"SupervisorCookieCheck", XDAQ_NS_URI);
87 xoap::bind(
this, &GatewaySupervisor::supervisorGetActiveUsers,
"SupervisorGetActiveUsers", XDAQ_NS_URI);
88 xoap::bind(
this, &GatewaySupervisor::supervisorSystemMessage,
"SupervisorSystemMessage", XDAQ_NS_URI);
89 xoap::bind(
this, &GatewaySupervisor::supervisorSystemLogbookEntry,
"SupervisorSystemLogbookEntry", XDAQ_NS_URI);
90 xoap::bind(
this, &GatewaySupervisor::supervisorLastTableGroupRequest,
"SupervisorLastTableGroupRequest", XDAQ_NS_URI);
101 GatewaySupervisor::~GatewaySupervisor(
void)
103 delete CorePropertySupervisorBase::theConfigurationManager_;
104 makeSystemLogbookEntry(
"ots halted.");
108 void GatewaySupervisor::indicateOtsAlive(
const CorePropertySupervisorBase* properties) { CorePropertySupervisorBase::indicateOtsAlive(properties); }
111 void GatewaySupervisor::init(
void)
113 supervisorGuiHasBeenLoaded_ =
false;
117 bool enableStateChanges =
false;
120 enableStateChanges = CorePropertySupervisorBase::getSupervisorTableNode().getNode(
"EnableStateChangesOverUDP").getValue<
bool>();
127 if(enableStateChanges)
129 __COUT__ <<
"Enabling state changes over UDP..." << __E__;
131 std::thread([](GatewaySupervisor* s) { GatewaySupervisor::StateChangerWorkLoop(s); },
this).detach();
134 __COUT__ <<
"State changes over UDP are disabled." << __E__;
139 bool checkAppStatus =
false;
142 checkAppStatus = CorePropertySupervisorBase::getSupervisorTableNode().getNode(
"EnableApplicationStatusMonitoring").getValue<
bool>();
151 __COUT__ <<
"Enabling App Status checking..." << __E__;
153 std::thread([](GatewaySupervisor* s) { GatewaySupervisor::AppStatusWorkLoop(s); },
this).detach();
156 __COUT__ <<
"App Status checking is disabled." << __E__;
164 void GatewaySupervisor::AppStatusWorkLoop(GatewaySupervisor* theSupervisor)
166 std::string status, progress, detail, appName;
177 for(
const auto& it : theSupervisor->allSupervisorInfo_.getAllSupervisorInfo())
179 auto appInfo = it.second;
180 appName = appInfo.getName();
189 if(appInfo.isGatewaySupervisor())
192 const std::string& err = theSupervisor->theStateMachine_.getErrorMessage();
193 status = err ==
"" ? (theSupervisor->theStateMachine_.isInTransition() ? theSupervisor->theStateMachine_.getProvenanceStateName()
194 : theSupervisor->theStateMachine_.getCurrentStateName())
195 : (theSupervisor->theStateMachine_.getCurrentStateName() ==
"Paused" ?
"Soft-Error:::" :
"Failed:::") + err;
196 progress = theSupervisor->theProgressBar_.readPercentageString();
200 detail = (theSupervisor->theStateMachine_.isInTransition()
201 ? theSupervisor->theStateMachine_.getCurrentTransitionName(theSupervisor->stateMachineLastCommandInput_)
213 appPointer.addParameter(
"ApplicationPointer");
215 xoap::MessageReference tempMessage = SOAPUtilities::makeSOAPMessageReference(
"ApplicationStatusRequest");
223 xoap::MessageReference statusMessage = theSupervisor->sendWithSOAPReply(appInfo.getDescriptor(), tempMessage);
231 parameters.addParameter(
"Status");
232 parameters.addParameter(
"Progress");
233 parameters.addParameter(
"Detail");
234 SOAPUtilities::receive(statusMessage, parameters);
236 status = parameters.getValue(
"Status");
238 status = SupervisorInfo::APP_STATUS_UNKNOWN;
240 progress = parameters.getValue(
"Progress");
244 detail = parameters.getValue(
"Detail");
246 catch(
const xdaq::exception::Exception& e)
249 status = SupervisorInfo::APP_STATUS_UNKNOWN;
251 detail =
"SOAP Message Error";
257 status = SupervisorInfo::APP_STATUS_UNKNOWN;
259 detail =
"Unknown SOAP Message Error";
270 std::istringstream ssProgress(progress);
271 ssProgress >> progressInteger;
273 theSupervisor->allSupervisorInfo_.setSupervisorStatus(appInfo, status, progressInteger, detail);
282 void GatewaySupervisor::StateChangerWorkLoop(GatewaySupervisor* theSupervisor)
284 ConfigurationTree configLinkNode = theSupervisor->CorePropertySupervisorBase::getSupervisorTableNode();
286 std::string ipAddressForStateChangesOverUDP = configLinkNode.getNode(
"IPAddressForStateChangesOverUDP").getValue<std::string>();
287 int portForStateChangesOverUDP = configLinkNode.getNode(
"PortForStateChangesOverUDP").getValue<
int>();
288 bool acknowledgementEnabled = configLinkNode.getNode(
"EnableAckForStateChangesOverUDP").getValue<
bool>();
297 portForStateChangesOverUDP);
305 __SS__ <<
"FATAL Console error. Could not initialize socket at ip '" << ipAddressForStateChangesOverUDP <<
"' and port " << portForStateChangesOverUDP
306 <<
". Perhaps it is already in use? Exiting State Changer "
307 "SOAPUtilities::receive loop."
309 __COUT__ << ss.str();
314 std::size_t commaPosition;
315 unsigned int commaCounter = 0;
316 std::size_t begin = 0;
318 std::string errorStr;
321 std::vector<std::string> parameters;
330 if(sock.receive(buffer, 0 , 1 ,
false ) != -1)
332 __COUT__ <<
"UDP State Changer packet received of size = " << buffer.size() << __E__;
334 size_t nCommas = std::count(buffer.begin(), buffer.end(),
',');
337 __SS__ <<
"Unrecognized State Machine command :-" << buffer
338 <<
"-. Format is FiniteStateMachineName,Command,Parameter(s). "
339 "Where Parameter(s) is/are optional."
341 __COUT_INFO__ << ss.str();
342 __MOUT_INFO__ << ss.str();
347 while((commaPosition = buffer.find(
',', begin)) != std::string::npos || commaCounter == nCommas)
349 if(commaCounter == nCommas)
350 commaPosition = buffer.size();
351 if(commaCounter == 0)
352 fsmName = buffer.substr(begin, commaPosition - begin);
353 else if(commaCounter == 1)
354 command = buffer.substr(begin, commaPosition - begin);
356 parameters.push_back(buffer.substr(begin, commaPosition - begin));
357 __COUT__ <<
"Word: " << buffer.substr(begin, commaPosition - begin) << __E__;
359 begin = commaPosition + 1;
369 if(theSupervisor->VERBOSE_MUTEX)
370 __COUT__ <<
"Waiting for FSM access" << __E__;
371 std::lock_guard<std::mutex> lock(theSupervisor->stateMachineAccessMutex_);
372 if(theSupervisor->VERBOSE_MUTEX)
373 __COUT__ <<
"Have FSM access" << __E__;
375 errorStr = theSupervisor->attemptStateMachineTransition(
376 0, 0, command, fsmName, WebUsers::DEFAULT_STATECHANGER_USERNAME , WebUsers::DEFAULT_STATECHANGER_USERNAME, parameters);
381 __SS__ <<
"UDP State Changer failed to execute command because of the "
384 __COUT_ERR__ << ss.str();
385 __MOUT_ERR__ << ss.str();
386 if(acknowledgementEnabled)
387 sock.acknowledge(errorStr,
true );
391 __SS__ <<
"Successfully executed state change command '" << command <<
".'" << __E__;
392 __COUT_INFO__ << ss.str();
393 __MOUT_INFO__ << ss.str();
394 if(acknowledgementEnabled)
395 sock.acknowledge(
"Done",
true );
409 void GatewaySupervisor::makeSystemLogbookEntry(std::string entryText)
411 __COUT__ <<
"Making System Logbook Entry: " << entryText << __E__;
413 SupervisorInfoMap logbookInfoMap = allSupervisorInfo_.getAllLogbookTypeSupervisorInfo();
415 if(logbookInfoMap.size() == 0)
417 __COUT__ <<
"No logbooks found! Here is entry: " << entryText << __E__;
422 __COUT__ <<
"Making logbook entry: " << entryText << __E__;
427 std::string replace[] = {
"\"",
"'",
"&",
"<",
">",
"\n",
" "};
428 std::string with[] = {
"%22",
"%27",
"%26",
"%3C",
"%3E",
"%0A%0D",
"%20%20"};
433 for(
int i = 0; i < numOfKeys; ++i)
435 while((f = entryText.find(replace[i])) != std::string::npos)
437 entryText = entryText.substr(0, f) + with[i] + entryText.substr(f + replace[i].length());
448 for(
auto& logbookInfo : logbookInfoMap)
452 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(logbookInfo.second.getDescriptor(),
"MakeSystemLogbookEntry", parameters);
457 SOAPUtilities::receive(retMsg, retParameters);
459 __COUT__ <<
"Returned Status: " << retParameters.getValue(
"Status") << __E__;
463 __COUT_ERR__ <<
"Failed to send logbook SOAP entry to " <<
464 logbookInfo.first <<
":" << logbookInfo.second.getContextName() <<
465 ":" << logbookInfo.second.getName() << __E__;
471 void GatewaySupervisor::Default(xgi::Input* , xgi::Output* out)
473 if(!supervisorGuiHasBeenLoaded_ && (supervisorGuiHasBeenLoaded_ =
true))
474 makeSystemLogbookEntry(
"ots started.");
476 *out <<
"<!DOCTYPE HTML><html lang='en'><head><title>ots</title>" << GatewaySupervisor::getIconHeaderString() <<
479 <<
"<frameset col='100%' row='100%'>"
480 <<
"<frame src='/WebPath/html/Desktop.html?urn=" << this->getApplicationDescriptor()->getLocalId() <<
"&securityType=" << securityType_
481 <<
"'></frameset></html>";
485 std::string GatewaySupervisor::getIconHeaderString(
void)
489 return "<link rel='apple-touch-icon' sizes='57x57' href='/WebPath/images/otsdaqIcons/apple-icon-57x57.png'>\
490 <link rel='apple-touch-icon' sizes='60x60' href='/WebPath/images/otsdaqIcons/apple-icon-60x60.png'>\
491 <link rel='apple-touch-icon' sizes='72x72' href='/WebPath/images/otsdaqIcons/apple-icon-72x72.png'>\
492 <link rel='apple-touch-icon' sizes='76x76' href='/WebPath/images/otsdaqIcons/apple-icon-76x76.png'>\
493 <link rel='apple-touch-icon' sizes='114x114' href='/WebPath/images/otsdaqIcons/apple-icon-114x114.png'>\
494 <link rel='apple-touch-icon' sizes='120x120' href='/WebPath/images/otsdaqIcons/apple-icon-120x120.png'>\
495 <link rel='apple-touch-icon' sizes='144x144' href='/WebPath/images/otsdaqIcons/apple-icon-144x144.png'>\
496 <link rel='apple-touch-icon' sizes='152x152' href='/WebPath/images/otsdaqIcons/apple-icon-152x152.png'>\
497 <link rel='apple-touch-icon' sizes='180x180' href='/WebPath/images/otsdaqIcons/apple-icon-180x180.png'>\
498 <link rel='icon' type='image/png' sizes='192x192' href='/WebPath/images/otsdaqIcons/android-icon-192x192.png'>\
499 <link rel='icon' type='image/png' sizes='144x144' href='/WebPath/images/otsdaqIcons/android-icon-144x144.png'>\
500 <link rel='icon' type='image/png' sizes='48x48' href='/WebPath/images/otsdaqIcons/android-icon-48x48.png'>\
501 <link rel='icon' type='image/png' sizes='72x72' href='/WebPath/images/otsdaqIcons/android-icon-72x72.png'>\
502 <link rel='icon' type='image/png' sizes='32x32' href='/WebPath/images/otsdaqIcons/favicon-32x32.png'>\
503 <link rel='icon' type='image/png' sizes='96x96' href='/WebPath/images/otsdaqIcons/favicon-96x96.png'>\
504 <link rel='icon' type='image/png' sizes='16x16' href='/WebPath/images/otsdaqIcons/favicon-16x16.png'>\
505 <link rel='manifest' href='/WebPath/images/otsdaqIcons/manifest.json'>\
506 <meta name='msapplication-TileColor' content='#ffffff'>\
507 <meta name='msapplication-TileImage' content='/WebPath/images/otsdaqIcons/ms-icon-144x144.png'>\
508 <meta name='theme-color' content='#ffffff'>";
516 void GatewaySupervisor::stateMachineIterationBreakpoint(xgi::Input* in, xgi::Output* out)
try
518 cgicc::Cgicc cgiIn(in);
520 std::string requestType = CgiDataUtilities::getData(cgiIn,
"Request");
525 CorePropertySupervisorBase::getRequestUserInfo(userInfo);
527 if(!theWebUsers_.xmlRequestOnGateway(cgiIn, out, &xmlOut, userInfo))
530 __COUTV__(requestType);
534 if(requestType ==
"get")
538 std::lock_guard<std::mutex> lock(broadcastIterationBreakpointMutex_);
539 v << broadcastIterationBreakpoint_;
542 xmlOut.addTextElementToData(
"iterationBreakpoint", v.str());
544 else if(requestType ==
"set")
546 unsigned int breakpointSetValue = CgiDataUtilities::getDataAsInt(cgiIn,
"breakpointSetValue");
547 __COUTV__(breakpointSetValue);
550 std::lock_guard<std::mutex> lock(broadcastIterationBreakpointMutex_);
551 broadcastIterationBreakpoint_ = breakpointSetValue;
556 v << breakpointSetValue;
557 xmlOut.addTextElementToData(
"iterationBreakpoint", v.str());
561 __SS__ <<
"Unknown iteration breakpoint request type = " << requestType << __E__;
565 catch(
const std::runtime_error& e)
567 __SS__ <<
"Error caught handling iteration breakpoint command: " << e.what() << __E__;
568 __COUT_ERR__ << ss.str();
569 xmlOut.addTextElementToData(
"Error", ss.str());
573 __SS__ <<
"Unknown error caught handling iteration breakpoint command." << __E__;
574 __COUT_ERR__ << ss.str();
575 xmlOut.addTextElementToData(
"Error", ss.str());
578 xmlOut.outputXmlDocument((std::ostringstream*)out,
false,
true);
581 catch(
const std::runtime_error& e)
583 __SS__ <<
"Error caught handling iteration breakpoint command: " << e.what() << __E__;
584 __COUT_ERR__ << ss.str();
588 __SS__ <<
"Unknown error caught handling iteration breakpoint command." << __E__;
589 __COUT_ERR__ << ss.str();
593 void GatewaySupervisor::stateMachineXgiHandler(xgi::Input* in, xgi::Output* out)
599 __COUT__ <<
"Waiting for FSM access" << __E__;
600 std::lock_guard<std::mutex> lock(stateMachineAccessMutex_);
602 __COUT__ <<
"Have FSM access" << __E__;
604 cgicc::Cgicc cgiIn(in);
606 std::string command = CgiDataUtilities::getData(cgiIn,
"StateMachine");
607 std::string requestType =
"StateMachine" + command;
612 CorePropertySupervisorBase::getRequestUserInfo(userInfo);
614 if(!theWebUsers_.xmlRequestOnGateway(cgiIn, out, &xmlOut, userInfo))
617 std::string fsmName = CgiDataUtilities::getData(cgiIn,
"fsmName");
618 std::string fsmWindowName = CgiDataUtilities::getData(cgiIn,
"fsmWindowName");
619 fsmWindowName = StringMacros::decodeURIComponent(fsmWindowName);
620 std::string currentState = theStateMachine_.getCurrentStateName();
622 __COUT__ <<
"Check for Handled by theIterator_" << __E__;
625 if((activeStateMachineWindowName_ ==
"" || activeStateMachineWindowName_ ==
"iterator") &&
626 theIterator_.handleCommandRequest(xmlOut, command, fsmWindowName))
628 __COUT__ <<
"Handled by theIterator_" << __E__;
629 xmlOut.outputXmlDocument((std::ostringstream*)out,
false);
634 if(theStateMachine_.isInTransition())
636 __SS__ <<
"Error - Can not accept request because the State Machine is already "
639 __COUT_ERR__ <<
"\n" << ss.str();
641 xmlOut.addTextElementToData(
"state_tranisition_attempted",
643 xmlOut.addTextElementToData(
"state_tranisition_attempted_err",
645 xmlOut.outputXmlDocument((std::ostringstream*)out,
false,
true);
655 if(activeStateMachineName_ !=
"" && activeStateMachineName_ != fsmName)
657 __COUT__ <<
"currentState = " << currentState << __E__;
658 if(currentState !=
"Halted" && currentState !=
"Initial")
662 __SS__ <<
"Error - Can not accept request because the State Machine "
663 <<
"with window name '" << activeStateMachineWindowName_ <<
"' (UID: " << activeStateMachineName_
666 <<
"in control of State Machine progress. ";
667 ss <<
"\n\nIn order for this State Machine with window name '" << fsmWindowName <<
"' (UID: " << fsmName
669 "to control progress, please transition to Halted using the active "
670 <<
"State Machine '" << activeStateMachineWindowName_ <<
".'" << __E__;
671 __COUT_ERR__ <<
"\n" << ss.str();
673 xmlOut.addTextElementToData(
"state_tranisition_attempted",
675 xmlOut.addTextElementToData(
"state_tranisition_attempted_err",
677 xmlOut.outputXmlDocument((std::ostringstream*)out,
false,
true);
682 activeStateMachineName_ =
"";
683 activeStateMachineWindowName_ =
"";
689 std::vector<std::string> parameters;
691 if(command ==
"Configure")
692 parameters.push_back(CgiDataUtilities::postData(cgiIn,
"ConfigurationAlias"));
694 attemptStateMachineTransition(&xmlOut, out, command, fsmName, fsmWindowName, userInfo.username_, parameters);
699 std::string GatewaySupervisor::attemptStateMachineTransition(
HttpXmlDocument* xmldoc,
700 std::ostringstream* out,
701 const std::string& command,
702 const std::string& fsmName,
703 const std::string& fsmWindowName,
704 const std::string& username,
705 const std::vector<std::string>& commandParameters)
707 std::string errorStr =
"";
709 std::string currentState = theStateMachine_.getCurrentStateName();
710 __COUT__ <<
"State Machine command = " << command << __E__;
711 __COUT__ <<
"fsmName = " << fsmName << __E__;
712 __COUT__ <<
"fsmWindowName = " << fsmWindowName << __E__;
713 __COUT__ <<
"activeStateMachineName_ = " << activeStateMachineName_ << __E__;
714 __COUT__ <<
"command = " << command << __E__;
715 __COUT__ <<
"commandParameters.size = " << commandParameters.size() << __E__;
718 if(command ==
"Configure")
720 if(currentState !=
"Halted")
722 __SS__ <<
"Error - Can only transition to Configured if the current "
723 <<
"state is Halted. Perhaps your state machine is out of sync." << __E__;
724 __COUT_ERR__ <<
"\n" << ss.str();
728 xmldoc->addTextElementToData(
"state_tranisition_attempted",
731 xmldoc->addTextElementToData(
"state_tranisition_attempted_err",
734 xmldoc->outputXmlDocument((std::ostringstream*)out,
false ,
true );
741 if(commandParameters.size() == 0)
743 __SS__ <<
"Error - Can only transition to Configured if a Configuration "
744 "Alias parameter is provided."
746 __COUT_ERR__ <<
"\n" << ss.str();
750 xmldoc->addTextElementToData(
"state_tranisition_attempted",
753 xmldoc->addTextElementToData(
"state_tranisition_attempted_err",
756 xmldoc->outputXmlDocument((std::ostringstream*)out,
false ,
true );
761 parameters.addParameter(
"ConfigurationAlias", commandParameters[0]);
763 std::string configurationAlias = parameters.getValue(
"ConfigurationAlias");
764 __COUT__ <<
"Configure --> Name: ConfigurationAlias Value: " << configurationAlias << __E__;
767 std::string fn = ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" +
768 FSM_LAST_GROUP_ALIAS_FILE_START +
769 username +
"." + FSM_USERS_PREFERENCES_FILETYPE;
771 __COUT__ <<
"Save FSM preferences: " << fn << __E__;
772 FILE* fp = fopen(fn.c_str(),
"w");
775 __SS__ << (
"Could not open file: " + fn) << __E__;
776 __COUT_ERR__ << ss.str();
779 fprintf(fp,
"FSM_last_configuration_alias %s", configurationAlias.c_str());
782 activeStateMachineName_ = fsmName;
783 activeStateMachineWindowName_ = fsmWindowName;
785 else if(command ==
"Start")
787 if(currentState !=
"Configured")
789 __SS__ <<
"Error - Can only transition to Configured if the current "
790 <<
"state is Halted. Perhaps your state machine is out of sync. "
791 <<
"(Likely the server was restarted or another user changed the state)" << __E__;
792 __COUT_ERR__ <<
"\n" << ss.str();
796 xmldoc->addTextElementToData(
"state_tranisition_attempted",
799 xmldoc->addTextElementToData(
"state_tranisition_attempted_err",
802 xmldoc->outputXmlDocument((std::ostringstream*)out,
false ,
true );
806 unsigned int runNumber;
807 if(commandParameters.size() == 0)
809 runNumber = getNextRunNumber();
810 setNextRunNumber(runNumber + 1);
814 runNumber = std::atoi(commandParameters[0].c_str());
816 parameters.addParameter(
"RunNumber", runNumber);
819 xoap::MessageReference message = SOAPUtilities::makeSOAPMessageReference(command, parameters);
821 xoap::MessageReference reply = stateMachineXoapHandler(message);
826 xmldoc->addTextElementToData(
"state_tranisition_attempted",
829 xmldoc->outputXmlDocument((std::ostringstream*)out,
false);
830 __COUT__ <<
"FSM state transition launched!" << __E__;
832 stateMachineLastCommandInput_ = command;
837 xoap::MessageReference GatewaySupervisor::stateMachineXoapHandler(xoap::MessageReference message)
840 __COUT__ <<
"Soap Handler!" << __E__;
841 stateMachineWorkLoopManager_.removeProcessedRequests();
842 stateMachineWorkLoopManager_.processRequest(message);
843 __COUT__ <<
"Done - Soap Handler!" << __E__;
853 bool GatewaySupervisor::stateMachineThread(toolbox::task::WorkLoop* workLoop)
855 stateMachineSemaphore_.take();
856 std::string command = SOAPUtilities::translate(stateMachineWorkLoopManager_.getMessage(workLoop)).getCommand();
858 __COUT__ <<
"Propagating command '" << command <<
"'..." << __E__;
860 std::string reply = send(allSupervisorInfo_.getGatewayDescriptor(), stateMachineWorkLoopManager_.getMessage(workLoop));
861 stateMachineWorkLoopManager_.report(workLoop, reply, 100,
true);
863 __COUT__ <<
"Done with command '" << command <<
".' Reply = " << reply << __E__;
864 stateMachineSemaphore_.give();
868 __SS__ <<
"Failure to send Workloop transition command '" << command <<
"!' An error response '" << reply <<
"' was received." << __E__;
869 __COUT_ERR__ << ss.str();
870 __MOUT_ERR__ << ss.str();
879 void GatewaySupervisor::stateInitial(toolbox::fsm::FiniteStateMachine& )
882 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
887 void GatewaySupervisor::statePaused(toolbox::fsm::FiniteStateMachine& )
890 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
895 void GatewaySupervisor::stateRunning(toolbox::fsm::FiniteStateMachine& )
897 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
902 void GatewaySupervisor::stateHalted(toolbox::fsm::FiniteStateMachine& )
905 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
906 __COUT__ <<
"Fsm is in transition? " << (theStateMachine_.isInTransition() ?
"yes" :
"no") << __E__;
910 void GatewaySupervisor::stateConfigured(toolbox::fsm::FiniteStateMachine& )
912 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
913 __COUT__ <<
"Fsm is in transition? " << (theStateMachine_.isInTransition() ?
"yes" :
"no") << __E__;
917 void GatewaySupervisor::inError(toolbox::fsm::FiniteStateMachine& )
920 __COUT__ <<
"Fsm current state: "
928 void GatewaySupervisor::enteringError(toolbox::Event::Reference e)
930 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
933 toolbox::fsm::FailedEvent& failedEvent =
dynamic_cast<toolbox::fsm::FailedEvent&
>(*e);
938 if(RunControlStateMachine::asyncFailureReceived_)
940 ss <<
"\nAn asynchronous failure was encountered."
941 <<
".\n\nException:\n"
942 << failedEvent.getException().what() << __E__;
943 RunControlStateMachine::asyncFailureReceived_ =
false;
947 ss <<
"\nFailure performing transition from " << failedEvent.getFromState() <<
"-" << theStateMachine_.getStateName(failedEvent.getFromState())
948 <<
" to " << failedEvent.getToState() <<
"-" << theStateMachine_.getStateName(failedEvent.getToState()) <<
".\n\nException:\n"
949 << failedEvent.getException().what() << __E__;
952 __COUT_ERR__ <<
"\n" << ss.str();
953 theStateMachine_.setErrorMessage(ss.str());
956 broadcastMessage(SOAPUtilities::makeSOAPMessageReference(
"Error"));
960 void GatewaySupervisor::checkForAsyncError()
962 if(RunControlStateMachine::asyncFailureReceived_)
964 __COUTV__(RunControlStateMachine::asyncFailureReceived_);
966 XCEPT_RAISE(toolbox::fsm::exception::Exception, RunControlStateMachine::getErrorMessage());
976 void GatewaySupervisor::transitionConfiguring(toolbox::Event::Reference)
978 checkForAsyncError();
980 RunControlStateMachine::theProgressBar_.step();
982 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
984 std::string systemAlias = SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue(
"ConfigurationAlias");
986 __COUT__ <<
"Transition parameter: " << systemAlias << __E__;
988 RunControlStateMachine::theProgressBar_.step();
992 CorePropertySupervisorBase::theConfigurationManager_->init();
996 __SS__ <<
"\nTransition to Configuring interrupted! "
997 <<
"The Configuration Manager could not be initialized." << __E__;
999 __COUT_ERR__ <<
"\n" << ss.str();
1000 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1004 RunControlStateMachine::theProgressBar_.step();
1009 theConfigurationTableGroup_ = CorePropertySupervisorBase::theConfigurationManager_->getTableGroupFromAlias(systemAlias);
1013 __COUT_INFO__ <<
"Exception occurred" << __E__;
1016 RunControlStateMachine::theProgressBar_.step();
1018 if(theConfigurationTableGroup_.second.isInvalid())
1020 __SS__ <<
"\nTransition to Configuring interrupted! System Alias " << systemAlias <<
" could not be translated to a group name and key." << __E__;
1022 __COUT_ERR__ <<
"\n" << ss.str();
1023 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1027 RunControlStateMachine::theProgressBar_.step();
1029 __COUT__ <<
"Configuration table group name: " << theConfigurationTableGroup_.first <<
" key: " << theConfigurationTableGroup_.second << __E__;
1033 std::stringstream ss;
1034 ss <<
"Configuring '" << systemAlias <<
"' which translates to " << theConfigurationTableGroup_.first <<
" (" << theConfigurationTableGroup_.second
1036 makeSystemLogbookEntry(ss.str());
1039 RunControlStateMachine::theProgressBar_.step();
1044 CorePropertySupervisorBase::theConfigurationManager_->loadTableGroup(
1045 theConfigurationTableGroup_.first, theConfigurationTableGroup_.second,
true );
1047 __COUT__ <<
"Done loading Configuration Alias." << __E__;
1051 tmpCfgMgr.activateTableGroup(theConfigurationTableGroup_.first, theConfigurationTableGroup_.second);
1053 __COUT__ <<
"Done activating Configuration Alias." << __E__;
1055 catch(
const std::runtime_error& e)
1057 __SS__ <<
"\nTransition to Configuring interrupted! System Alias " << systemAlias <<
" was translated to " << theConfigurationTableGroup_.first <<
" ("
1058 << theConfigurationTableGroup_.second <<
") but could not be loaded and initialized." << __E__;
1059 ss <<
"\n\nHere was the error: " << e.what() <<
"\n\nTo help debug this problem, try activating this group in the Configuration "
1061 <<
" and detailed errors will be shown." << __E__;
1062 __COUT_ERR__ <<
"\n" << ss.str();
1063 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1068 __SS__ <<
"\nTransition to Configuring interrupted! System Alias " << systemAlias <<
" was translated to " << theConfigurationTableGroup_.first <<
" ("
1069 << theConfigurationTableGroup_.second <<
") but could not be loaded and initialized." << __E__;
1070 ss <<
"\n\nTo help debug this problem, try activating this group in the Configuration "
1072 <<
" and detailed errors will be shown." << __E__;
1073 __COUT_ERR__ <<
"\n" << ss.str();
1074 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1082 CorePropertySupervisorBase::theConfigurationManager_->dumpMacroMakerModeFhicl();
1086 __COUT_ERR__ <<
"Failed to dump MacroMaker mode fhicl." << __E__;
1090 CorePropertySupervisorBase::theConfigurationManager_->getSupervisorTableNode(supervisorContextUID_, supervisorApplicationUID_);
1091 if(!configLinkNode.isDisconnected())
1095 bool dumpConfiguration =
true;
1096 std::string dumpFilePath, dumpFileRadix, dumpFormat;
1099 ConfigurationTree fsmLinkNode = configLinkNode.getNode(
"LinkToStateMachineTable").getNode(activeStateMachineName_);
1100 dumpConfiguration = fsmLinkNode.getNode(
"EnableConfigurationDumpOnConfigureTransition").getValue<
bool>();
1101 dumpFilePath = fsmLinkNode.getNode(
"ConfigurationDumpOnConfigureFilePath").getValue<std::string>();
1102 dumpFileRadix = fsmLinkNode.getNode(
"ConfigurationDumpOnConfigureFileRadix").getValue<std::string>();
1103 dumpFormat = fsmLinkNode.getNode(
"ConfigurationDumpOnConfigureFormat").getValue<std::string>();
1105 catch(std::runtime_error& e)
1107 __COUT_INFO__ <<
"FSM configuration dump Link disconnected." << __E__;
1108 dumpConfiguration =
false;
1111 if(dumpConfiguration)
1114 CorePropertySupervisorBase::theConfigurationManager_->dumpActiveConfiguration(
1115 dumpFilePath +
"/" + dumpFileRadix +
"_" + std::to_string(time(0)) +
".dump", dumpFormat);
1117 CorePropertySupervisorBase::theConfigurationManager_->dumpMacroMakerModeFhicl();
1120 catch(std::runtime_error& e)
1122 __SS__ <<
"\nTransition to Configuring interrupted! There was an error "
1124 <<
"during the configuration dump attempt:\n\n " << e.what() << __E__;
1125 __COUT_ERR__ <<
"\n" << ss.str();
1126 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1131 __SS__ <<
"\nTransition to Configuring interrupted! There was an error "
1133 <<
"during the configuration dump attempt.\n\n " << __E__;
1134 __COUT_ERR__ <<
"\n" << ss.str();
1135 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1141 RunControlStateMachine::theProgressBar_.step();
1143 parameters.addParameter(
"ConfigurationTableGroupName", theConfigurationTableGroup_.first);
1144 parameters.addParameter(
"ConfigurationTableGroupKey", theConfigurationTableGroup_.second.toString());
1148 __COUT__ <<
"Initializing Macro Maker." << __E__;
1149 xoap::MessageReference message = SOAPUtilities::makeSOAPMessageReference(
"FECommunication");
1152 parameters.addParameter(
"type",
"initFElist");
1153 parameters.addParameter(
"groupName", theConfigurationTableGroup_.first);
1154 parameters.addParameter(
"groupKey", theConfigurationTableGroup_.second.toString());
1155 SOAPUtilities::addParameters(message, parameters);
1157 __COUT__ <<
"Sending FE communication: " << SOAPUtilities::translate(message) << __E__;
1160 SOAPMessenger::send(CorePropertySupervisorBase::allSupervisorInfo_.getAllMacroMakerTypeSupervisorInfo().begin()->second.getDescriptor(), message);
1162 __COUT__ <<
"Macro Maker init reply: " << reply << __E__;
1163 if(reply ==
"Error")
1165 __SS__ <<
"\nTransition to Configuring interrupted! There was an error "
1166 "identified initializing Macro Maker.\n\n "
1168 __COUT_ERR__ <<
"\n" << ss.str();
1169 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1177 xoap::MessageReference message = theStateMachine_.getCurrentMessage();
1178 SOAPUtilities::addParameters(message, parameters);
1179 broadcastMessage(message);
1180 RunControlStateMachine::theProgressBar_.step();
1185 ConfigurationManager::saveGroupNameAndKey(theConfigurationTableGroup_, FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE);
1187 __COUT__ <<
"Done configuring." << __E__;
1188 RunControlStateMachine::theProgressBar_.complete();
1192 void GatewaySupervisor::transitionHalting(toolbox::Event::Reference )
1194 checkForAsyncError();
1196 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
1198 makeSystemLogbookEntry(
"Run halting.");
1200 broadcastMessage(theStateMachine_.getCurrentMessage());
1204 void GatewaySupervisor::transitionShuttingDown(toolbox::Event::Reference )
1206 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
1208 RunControlStateMachine::theProgressBar_.step();
1209 makeSystemLogbookEntry(
"System shutting down.");
1210 RunControlStateMachine::theProgressBar_.step();
1213 GatewaySupervisor::launchStartOTSCommand(
"OTS_APP_SHUTDOWN", CorePropertySupervisorBase::theConfigurationManager_);
1214 RunControlStateMachine::theProgressBar_.step();
1218 for(
int i = 0; i < 5; ++i)
1221 RunControlStateMachine::theProgressBar_.step();
1226 void GatewaySupervisor::transitionStartingUp(toolbox::Event::Reference )
1228 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
1230 RunControlStateMachine::theProgressBar_.step();
1231 makeSystemLogbookEntry(
"System starting up.");
1232 RunControlStateMachine::theProgressBar_.step();
1235 GatewaySupervisor::launchStartOTSCommand(
"OTS_APP_STARTUP", CorePropertySupervisorBase::theConfigurationManager_);
1236 RunControlStateMachine::theProgressBar_.step();
1240 for(
int i = 0; i < 10; ++i)
1243 RunControlStateMachine::theProgressBar_.step();
1249 void GatewaySupervisor::transitionInitializing(toolbox::Event::Reference e)
1252 __COUT__ << theStateMachine_.getCurrentStateName() << __E__;
1254 broadcastMessage(theStateMachine_.getCurrentMessage());
1256 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
1257 __COUT__ <<
"Fsm current transition: " << theStateMachine_.getCurrentTransitionName(e->type()) << __E__;
1258 __COUT__ <<
"Fsm final state: " << theStateMachine_.getTransitionFinalStateName(e->type()) << __E__;
1262 void GatewaySupervisor::transitionPausing(toolbox::Event::Reference )
1264 checkForAsyncError();
1266 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
1268 makeSystemLogbookEntry(
"Run pausing.");
1271 if(RunControlStateMachine::asyncSoftFailureReceived_)
1273 __COUT_ERR__ <<
"Broadcasting pause for async SOFT error!" << __E__;
1274 broadcastMessage(SOAPUtilities::makeSOAPMessageReference(
"Pause"));
1277 broadcastMessage(theStateMachine_.getCurrentMessage());
1281 void GatewaySupervisor::transitionResuming(toolbox::Event::Reference )
1283 if(RunControlStateMachine::asyncSoftFailureReceived_)
1286 __COUT_INFO__ <<
"Clearing async SOFT error!" << __E__;
1287 RunControlStateMachine::asyncSoftFailureReceived_ =
false;
1290 checkForAsyncError();
1292 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
1294 makeSystemLogbookEntry(
"Run resuming.");
1296 broadcastMessage(theStateMachine_.getCurrentMessage());
1300 void GatewaySupervisor::transitionStarting(toolbox::Event::Reference )
1302 if(RunControlStateMachine::asyncSoftFailureReceived_)
1305 __COUT_INFO__ <<
"Clearing async SOFT error!" << __E__;
1306 RunControlStateMachine::asyncSoftFailureReceived_ =
false;
1309 checkForAsyncError();
1311 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
1314 SOAPUtilities::receive(theStateMachine_.getCurrentMessage(), parameters);
1316 std::string runNumber = parameters.getValue(
"RunNumber");
1317 __COUTV__(runNumber);
1322 CorePropertySupervisorBase::theConfigurationManager_->getSupervisorTableNode(supervisorContextUID_, supervisorApplicationUID_);
1323 if(!configLinkNode.isDisconnected())
1327 bool dumpConfiguration =
true;
1328 std::string dumpFilePath, dumpFileRadix, dumpFormat;
1331 ConfigurationTree fsmLinkNode = configLinkNode.getNode(
"LinkToStateMachineTable").getNode(activeStateMachineName_);
1332 dumpConfiguration = fsmLinkNode.getNode(
"EnableConfigurationDumpOnRunTransition").getValue<
bool>();
1333 dumpFilePath = fsmLinkNode.getNode(
"ConfigurationDumpOnRunFilePath").getValue<std::string>();
1334 dumpFileRadix = fsmLinkNode.getNode(
"ConfigurationDumpOnRunFileRadix").getValue<std::string>();
1335 dumpFormat = fsmLinkNode.getNode(
"ConfigurationDumpOnRunFormat").getValue<std::string>();
1337 catch(std::runtime_error& e)
1339 __COUT_INFO__ <<
"FSM configuration dump Link disconnected." << __E__;
1340 dumpConfiguration =
false;
1343 if(dumpConfiguration)
1346 CorePropertySupervisorBase::theConfigurationManager_->dumpActiveConfiguration(
1347 dumpFilePath +
"/" + dumpFileRadix +
"_Run" + runNumber +
"_" + std::to_string(time(0)) +
".dump", dumpFormat);
1350 catch(std::runtime_error& e)
1352 __SS__ <<
"\nTransition to Running interrupted! There was an error "
1354 <<
"during the configuration dump attempt:\n\n " << e.what() << __E__;
1355 __COUT_ERR__ <<
"\n" << ss.str();
1356 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1361 __SS__ <<
"\nTransition to Running interrupted! There was an error "
1363 <<
"during the configuration dump attempt.\n\n " << __E__;
1364 __COUT_ERR__ <<
"\n" << ss.str();
1365 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1371 makeSystemLogbookEntry(
"Run " + runNumber +
" starting.");
1373 broadcastMessage(theStateMachine_.getCurrentMessage());
1376 ConfigurationManager::saveGroupNameAndKey(theConfigurationTableGroup_, FSM_LAST_STARTED_GROUP_ALIAS_FILE);
1380 void GatewaySupervisor::transitionStopping(toolbox::Event::Reference )
1382 checkForAsyncError();
1384 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
1386 makeSystemLogbookEntry(
"Run stopping.");
1388 broadcastMessage(theStateMachine_.getCurrentMessage());
1401 bool GatewaySupervisor::handleBroadcastMessageTarget(
const SupervisorInfo& appInfo,
1402 xoap::MessageReference message,
1403 const std::string& command,
1404 const unsigned int& iteration,
1406 unsigned int threadIndex)
1408 unsigned int subIteration = 0;
1409 bool subIterationsDone =
false;
1410 bool iterationsDone =
true;
1412 while(!subIterationsDone)
1414 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1415 <<
"Supervisor instance = '" << appInfo.getName() <<
"' [LID=" << appInfo.getId() <<
"] in Context '" << appInfo.getContextName()
1416 <<
"' [URL=" << appInfo.getURL() <<
"] Command = " << command << __E__;
1418 checkForAsyncError();
1420 subIterationsDone =
true;
1421 RunControlStateMachine::theProgressBar_.step();
1427 parameters.addParameter(
"subIterationIndex", subIteration);
1428 SOAPUtilities::addParameters(message, parameters);
1431 if(iteration || subIteration)
1432 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1433 <<
"Adding iteration parameters " << iteration <<
"." << subIteration << __E__;
1435 RunControlStateMachine::theProgressBar_.step();
1437 if(iteration == 0 && subIteration == 0)
1439 for(
unsigned int j = 0; j < 4; ++j)
1440 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1441 <<
"Sending message to Supervisor " << appInfo.getName() <<
" [LID=" << appInfo.getId() <<
"]: " << command << __E__;
1445 if(subIteration == 0)
1447 for(
unsigned int j = 0; j < 4; ++j)
1448 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1449 <<
"Sending message to Supervisor " << appInfo.getName() <<
" [LID=" << appInfo.getId() <<
"]: " << command
1450 <<
" (iteration: " << iteration <<
")" << __E__;
1454 for(
unsigned int j = 0; j < 4; ++j)
1455 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1456 <<
"Sending message to Supervisor " << appInfo.getName() <<
" [LID=" << appInfo.getId() <<
"]: " << command
1457 <<
" (iteration: " << iteration <<
", sub-iteration: " << subIteration <<
")" << __E__;
1465 std::lock_guard<std::mutex> lock(broadcastCommandMessageIndexMutex_);
1466 parameters.addParameter(
"commandId", broadcastCommandMessageIndex_++);
1468 SOAPUtilities::addParameters(message, parameters);
1471 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1472 <<
"Sending... \t" << SOAPUtilities::translate(message) << std::endl;
1476 reply = send(appInfo.getDescriptor(), message);
1478 catch(
const xdaq::exception::Exception& e)
1481 __SS__ <<
"Error! Gateway Supervisor can NOT " << command <<
" Supervisor instance = '" << appInfo.getName() <<
"' [LID=" << appInfo.getId()
1482 <<
"] in Context '" << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL() <<
"].\n\n"
1483 <<
"Xoap message failure. Did the target Supervisor crash? Try "
1484 "re-initializing or restarting otsdaq."
1486 __COUT_ERR__ << ss.str();
1487 __MOUT_ERR__ << ss.str();
1491 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1492 <<
"Try again.." << __E__;
1497 parameters.addParameter(
"retransmission",
"1");
1498 SOAPUtilities::addParameters(message, parameters);
1505 std::lock_guard<std::mutex> lock(broadcastCommandMessageIndexMutex_);
1506 parameters.addParameter(
"commandId", broadcastCommandMessageIndex_++);
1508 SOAPUtilities::addParameters(message, parameters);
1511 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1512 <<
"Re-Sending... " << SOAPUtilities::translate(message) << std::endl;
1514 reply = send(appInfo.getDescriptor(), message);
1516 catch(
const xdaq::exception::Exception& e)
1518 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1519 <<
"Second try failed.." << __E__;
1520 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1522 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1523 <<
"2nd try passed.." << __E__;
1526 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1527 <<
"Reply received = " << reply << __E__;
1529 if((reply != command +
"Done") && (reply != command +
"Response") && (reply != command +
"Iterate") && (reply != command +
"SubIterate"))
1531 __SS__ <<
"Error! Gateway Supervisor can NOT " << command <<
" Supervisor instance = '" << appInfo.getName() <<
"' [LID=" << appInfo.getId()
1532 <<
"] in Context '" << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL() <<
"].\n\n"
1534 __COUT_ERR__ << ss.str() << __E__;
1535 __MOUT_ERR__ << ss.str() << __E__;
1537 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1538 <<
"Getting error message..." << __E__;
1541 xoap::MessageReference errorMessage =
1542 sendWithSOAPReply(appInfo.getDescriptor(), SOAPUtilities::makeSOAPMessageReference(
"StateMachineErrorMessageRequest"));
1544 parameters.addParameter(
"ErrorMessage");
1545 SOAPUtilities::receive(errorMessage, parameters);
1547 std::string error = parameters.getValue(
"ErrorMessage");
1550 std::stringstream err;
1551 err <<
"Unknown error from Supervisor instance = '" << appInfo.getName() <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1552 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
1553 <<
"]. If the problem persists or is repeatable, please notify "
1558 __SS__ <<
"Received error from Supervisor instance = '" << appInfo.getName() <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1559 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL() <<
"].\n\n Error Message = " << error << __E__;
1561 __COUT_ERR__ << ss.str() << __E__;
1562 __MOUT_ERR__ << ss.str() << __E__;
1564 if(command ==
"Error")
1568 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1570 catch(
const xdaq::exception::Exception& e)
1573 __SS__ <<
"Error! Gateway Supervisor failed to read error message from "
1574 "Supervisor instance = '"
1575 << appInfo.getName() <<
"' [LID=" << appInfo.getId() <<
"] in Context '" << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
1577 <<
"Xoap message failure. Did the target Supervisor crash? Try "
1578 "re-initializing or restarting otsdaq."
1580 __COUT_ERR__ << ss.str();
1581 __MOUT_ERR__ << ss.str();
1582 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1585 else if(reply == command +
"Iterate")
1592 iterationsDone =
false;
1593 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1594 <<
"Supervisor instance = '" << appInfo.getName() <<
"' [LID=" << appInfo.getId() <<
"] in Context '" << appInfo.getContextName()
1595 <<
"' [URL=" << appInfo.getURL() <<
"] flagged for another iteration to " << command <<
"... (iteration: " << iteration <<
")" << __E__;
1598 else if(reply == command +
"SubIterate")
1605 subIterationsDone =
false;
1606 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1607 <<
"Supervisor instance = '" << appInfo.getName() <<
"' [LID=" << appInfo.getId() <<
"] in Context '" << appInfo.getContextName()
1608 <<
"' [URL=" << appInfo.getURL() <<
"] flagged for another sub-iteration to " << command <<
"... (iteration: " << iteration
1609 <<
", sub-iteration: " << subIteration <<
")" << __E__;
1613 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1614 <<
"Supervisor instance = '" << appInfo.getName() <<
"' [LID=" << appInfo.getId() <<
"] in Context '" << appInfo.getContextName()
1615 <<
"' [URL=" << appInfo.getURL() <<
"] was " << command <<
"'d correctly!" << __E__;
1619 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
1620 <<
"Completed sub-iteration: " << subIteration << __E__;
1625 return iterationsDone;
1633 void GatewaySupervisor::broadcastMessageThread(GatewaySupervisor* supervisorPtr, GatewaySupervisor::BroadcastThreadStruct* threadStruct)
1635 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
1636 <<
"starting..." << __E__;
1638 while(!threadStruct->exitThread_)
1644 std::lock_guard<std::mutex> lock(threadStruct->threadMutex);
1645 if(threadStruct->workToDo_)
1647 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
1648 <<
"starting work..." << __E__;
1652 if(supervisorPtr->handleBroadcastMessageTarget(threadStruct->getAppInfo(),
1653 threadStruct->getMessage(),
1654 threadStruct->getCommand(),
1655 threadStruct->getIteration(),
1656 threadStruct->getReply(),
1657 threadStruct->threadIndex_))
1658 threadStruct->getIterationsDone() =
true;
1660 catch(toolbox::fsm::exception::Exception
const& e)
1662 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
1663 <<
"going into error: " << e.what() << __E__;
1665 threadStruct->getReply() = e.what();
1666 threadStruct->error_ =
true;
1667 threadStruct->workToDo_ =
false;
1668 threadStruct->working_ =
false;
1672 if(!threadStruct->getIterationsDone())
1674 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
1675 <<
"flagged for another iteration." << __E__;
1678 std::lock_guard<std::mutex> lock(supervisorPtr->broadcastIterationsDoneMutex_);
1679 supervisorPtr->broadcastIterationsDone_ =
false;
1682 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
1683 <<
"done with work." << __E__;
1685 threadStruct->workToDo_ =
false;
1690 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
1691 <<
"exited." << __E__;
1692 threadStruct->working_ =
false;
1700 void GatewaySupervisor::broadcastMessage(xoap::MessageReference message)
1702 RunControlStateMachine::theProgressBar_.step();
1705 allSupervisorInfo_.setSupervisorStatus(
this, theStateMachine_.getCurrentStateName());
1707 std::string command = SOAPUtilities::translate(message).getCommand();
1710 broadcastIterationsDone_ =
false;
1713 std::vector<std::vector<const SupervisorInfo*>> orderedSupervisors;
1717 orderedSupervisors = allSupervisorInfo_.getOrderedSupervisorDescriptors(command);
1719 catch(
const std::runtime_error& e)
1721 __SS__ <<
"Error getting supervisor priority. Was there a change in the context?"
1722 <<
" Remember, if the context was changed, it is safest to relaunch "
1724 << e.what() << __E__;
1725 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
1728 RunControlStateMachine::theProgressBar_.step();
1732 GatewaySupervisor::BroadcastMessageIterationsDoneStruct supervisorIterationsDone;
1735 for(
const auto& vectorAtPriority : orderedSupervisors)
1736 supervisorIterationsDone.push(vectorAtPriority.size());
1740 unsigned int iteration = 0;
1742 unsigned int iterationBreakpoint;
1747 xoap::MessageReference originalMessage = SOAPUtilities::makeSOAPMessageReference(SOAPUtilities::translate(message));
1749 __COUT__ <<
"=========> Broadcasting state machine command = " << command << __E__;
1751 unsigned int numberOfThreads = 1;
1755 numberOfThreads = CorePropertySupervisorBase::getSupervisorTableNode().getNode(
"NumberOfStateMachineBroadcastThreads").getValue<
unsigned int>();
1760 __COUT__ <<
"Number of threads not in configuration, so defaulting to " << numberOfThreads << __E__;
1765 if(numberOfThreads == 1)
1766 numberOfThreads = 0;
1768 __COUTV__(numberOfThreads);
1770 std::vector<GatewaySupervisor::BroadcastThreadStruct> broadcastThreadStructs(numberOfThreads);
1774 for(
unsigned int i = 0; i < numberOfThreads; ++i)
1776 broadcastThreadStructs[i].threadIndex_ = i;
1778 std::thread([](GatewaySupervisor* supervisorPtr,
1779 GatewaySupervisor::BroadcastThreadStruct* threadStruct) { GatewaySupervisor::broadcastMessageThread(supervisorPtr, threadStruct); },
1781 &broadcastThreadStructs[i])
1785 RunControlStateMachine::theProgressBar_.step();
1793 broadcastIterationsDone_ =
true;
1796 std::lock_guard<std::mutex> lock(broadcastIterationBreakpointMutex_);
1797 iterationBreakpoint = broadcastIterationBreakpoint_;
1800 if(iterationBreakpoint < (
unsigned int)-1)
1801 __COUT__ <<
"Iteration breakpoint currently is " << iterationBreakpoint << __E__;
1802 if(iteration >= iterationBreakpoint)
1804 broadcastIterationsDone_ =
false;
1805 __COUT__ <<
"Waiting at transition breakpoint - iteration = " << iteration << __E__;
1806 usleep(5 * 1000 * 1000 );
1811 __COUT__ <<
"Starting iteration: " << iteration << __E__;
1813 for(
unsigned int i = 0; i < supervisorIterationsDone.size(); ++i)
1815 for(
unsigned int j = 0; j < supervisorIterationsDone.size(i); ++j)
1817 checkForAsyncError();
1819 if(supervisorIterationsDone[i][j])
1825 message = SOAPUtilities::makeSOAPMessageReference(SOAPUtilities::translate(originalMessage));
1832 parameters.addParameter(
"iterationIndex", iteration);
1833 SOAPUtilities::addParameters(message, parameters);
1839 assignedJob =
false;
1842 for(
unsigned int k = 0; k < numberOfThreads; ++k)
1844 if(!broadcastThreadStructs[k].workToDo_)
1848 __COUT__ <<
"Giving work to thread " << k << __E__;
1850 std::lock_guard<std::mutex> lock(broadcastThreadStructs[k].threadMutex);
1851 broadcastThreadStructs[k].setMessage(appInfo, message, command, iteration, supervisorIterationsDone[i][j]);
1859 __COUT__ <<
"No free broadcast threads, "
1860 <<
"waiting for an available thread..." << __E__;
1861 usleep(100 * 1000 );
1863 }
while(!assignedJob);
1867 if(handleBroadcastMessageTarget(appInfo, message, command, iteration, reply))
1868 supervisorIterationsDone[i][j] =
true;
1870 broadcastIterationsDone_ =
false;
1879 __COUT__ <<
"Done with priority level. Waiting for threads to finish..." << __E__;
1884 for(
unsigned int i = 0; i < numberOfThreads; ++i)
1885 if(broadcastThreadStructs[i].workToDo_)
1888 __COUT__ <<
"Still waiting on thread " << i <<
"..." << __E__;
1889 usleep(100 * 1000 );
1892 else if(broadcastThreadStructs[i].error_)
1894 __COUT__ <<
"Found thread in error! Throwing state "
1896 << broadcastThreadStructs[i].getReply() << __E__;
1897 XCEPT_RAISE(toolbox::fsm::exception::Exception, broadcastThreadStructs[i].getReply());
1900 __COUT__ <<
"All threads done with priority level work." << __E__;
1911 if(iteration || !broadcastIterationsDone_)
1912 __COUT__ <<
"Completed iteration: " << iteration << __E__;
1915 }
while(!broadcastIterationsDone_);
1917 RunControlStateMachine::theProgressBar_.step();
1921 __COUT__ <<
"Exception caught, exiting broadcast threads..." << __E__;
1928 for(
unsigned int i = 0; i < numberOfThreads; ++i)
1929 broadcastThreadStructs[i].exitThread_ =
true;
1930 usleep(100 * 1000 );
1937 __COUT__ <<
"All transitions completed. Wrapping up, exiting broadcast threads..." << __E__;
1945 for(
unsigned int i = 0; i < numberOfThreads; ++i)
1946 broadcastThreadStructs[i].exitThread_ =
true;
1947 usleep(100 * 1000 );
1950 __COUT__ <<
"Broadcast complete." << __E__;
1958 void GatewaySupervisor::loginRequest(xgi::Input* in, xgi::Output* out)
1960 cgicc::Cgicc cgi(in);
1961 std::string Command = CgiDataUtilities::getData(cgi,
"RequestType");
1962 __COUT__ <<
"*** Login RequestType = " << Command <<
" clock=" << clock() << __E__;
1971 std::vector<std::string> loggedOutUsernames;
1972 theWebUsers_.cleanupExpiredEntries(&loggedOutUsernames);
1973 for(
unsigned int i = 0; i < loggedOutUsernames.size(); ++i)
1974 makeSystemLogbookEntry(loggedOutUsernames[i] +
" login timed out.");
1976 if(Command ==
"sessionId")
1985 std::string uuid = CgiDataUtilities::postData(cgi,
"uuid");
1987 std::string sid = theWebUsers_.createNewLoginSession(uuid, cgi.getEnvironment().getRemoteAddr() );
1993 else if(Command ==
"checkCookie")
1997 std::string jumbledUser;
1998 std::string cookieCode;
2009 uuid = CgiDataUtilities::postData(cgi,
"uuid");
2010 jumbledUser = CgiDataUtilities::postData(cgi,
"ju");
2011 cookieCode = CgiDataUtilities::postData(cgi,
"cc");
2019 uid = theWebUsers_.isCookieCodeActiveForLogin(uuid, cookieCode,
2022 if(uid == theWebUsers_.NOT_FOUND_IN_DATABASE)
2024 __COUT__ <<
"cookieCode invalid" << __E__;
2029 __COUT__ <<
"cookieCode is good." << __E__;
2034 theWebUsers_.insertSettingsForUser(uid, &xmldoc);
2036 xmldoc.outputXmlDocument((std::ostringstream*)out);
2038 else if(Command ==
"login")
2049 std::string uuid = CgiDataUtilities::postData(cgi,
"uuid");
2050 std::string newAccountCode = CgiDataUtilities::postData(cgi,
"nac");
2051 std::string jumbledUser = CgiDataUtilities::postData(cgi,
"ju");
2052 std::string jumbledPw = CgiDataUtilities::postData(cgi,
"jp");
2060 uint64_t uid = theWebUsers_.attemptActiveSession(uuid,
2064 cgi.getEnvironment().getRemoteAddr());
2067 if(uid >= theWebUsers_.ACCOUNT_ERROR_THRESHOLD)
2069 __COUT__ <<
"Login invalid." << __E__;
2071 if(newAccountCode !=
"1")
2072 newAccountCode =
"0";
2075 makeSystemLogbookEntry(theWebUsers_.getUsersUsername(uid) +
" logged in.");
2082 if(uid == theWebUsers_.ACCOUNT_INACTIVE)
2083 xmldoc.addTextElementToData(
"Error",
"Account is inactive. Notify admins.");
2084 else if(uid == theWebUsers_.ACCOUNT_BLACKLISTED)
2085 xmldoc.addTextElementToData(
"Error",
"Account is blacklisted. Notify admins.");
2087 theWebUsers_.insertSettingsForUser(uid, &xmldoc);
2091 if(uid != theWebUsers_.NOT_FOUND_IN_DATABASE)
2093 uint64_t asCnt = theWebUsers_.getActiveSessionCountForUser(uid) - 1;
2095 sprintf(asStr,
"%lu", asCnt);
2096 xmldoc.addTextElementToData(
"user_active_session_count", asStr);
2099 xmldoc.outputXmlDocument((std::ostringstream*)out);
2101 else if(Command ==
"cert")
2112 std::string uuid = CgiDataUtilities::postData(cgi,
"uuid");
2113 std::string jumbledEmail = cgicc::form_urldecode(CgiDataUtilities::getData(cgi,
"httpsUser"));
2114 std::string username =
"";
2115 std::string cookieCode =
"";
2121 uint64_t uid = theWebUsers_.attemptActiveSessionWithCert(uuid,
2125 cgi.getEnvironment().getRemoteAddr());
2127 if(uid == theWebUsers_.NOT_FOUND_IN_DATABASE)
2129 __COUT__ <<
"cookieCode invalid" << __E__;
2131 if(cookieCode !=
"1")
2135 makeSystemLogbookEntry(theWebUsers_.getUsersUsername(uid) +
" logged in.");
2141 theWebUsers_.insertSettingsForUser(uid, &xmldoc);
2145 if(uid != theWebUsers_.NOT_FOUND_IN_DATABASE)
2147 uint64_t asCnt = theWebUsers_.getActiveSessionCountForUser(uid) - 1;
2149 sprintf(asStr,
"%lu", asCnt);
2150 xmldoc.addTextElementToData(
"user_active_session_count", asStr);
2153 xmldoc.outputXmlDocument((std::ostringstream*)out);
2155 else if(Command ==
"logout")
2157 std::string cookieCode = CgiDataUtilities::postData(cgi,
"CookieCode");
2158 std::string logoutOthers = CgiDataUtilities::postData(cgi,
"LogoutOthers");
2164 if(theWebUsers_.cookieCodeLogout(cookieCode,
2165 logoutOthers ==
"1",
2167 cgi.getEnvironment().getRemoteAddr()) != theWebUsers_.NOT_FOUND_IN_DATABASE)
2171 if(!theWebUsers_.isUserIdActive(uid))
2172 makeSystemLogbookEntry(theWebUsers_.getUsersUsername(uid) +
" logged out.");
2177 __COUT__ <<
"Invalid Command" << __E__;
2181 __COUT__ <<
"Done clock=" << clock() << __E__;
2185 void GatewaySupervisor::tooltipRequest(xgi::Input* in, xgi::Output* out)
2187 cgicc::Cgicc cgi(in);
2189 std::string Command = CgiDataUtilities::getData(cgi,
"RequestType");
2197 std::string cookieCode = CgiDataUtilities::postData(cgi,
"CookieCode");
2200 if(!theWebUsers_.cookieCodeIsActiveForRequest(cookieCode, 0 , &uid,
"0" ,
false ))
2210 if(Command ==
"check")
2212 WebUsers::tooltipCheckForUsername(theWebUsers_.getUsersUsername(uid),
2214 CgiDataUtilities::getData(cgi,
"srcFile"),
2215 CgiDataUtilities::getData(cgi,
"srcFunc"),
2216 CgiDataUtilities::getData(cgi,
"srcId"));
2218 else if(Command ==
"setNeverShow")
2220 WebUsers::tooltipSetNeverShowForUsername(theWebUsers_.getUsersUsername(uid),
2222 CgiDataUtilities::getData(cgi,
"srcFile"),
2223 CgiDataUtilities::getData(cgi,
"srcFunc"),
2224 CgiDataUtilities::getData(cgi,
"srcId"),
2225 CgiDataUtilities::getData(cgi,
"doNeverShow") ==
"1" ?
true :
false,
2226 CgiDataUtilities::getData(cgi,
"temporarySilence") ==
"1" ?
true :
false);
2229 __COUT__ <<
"Command Request, " << Command <<
", not recognized." << __E__;
2231 xmldoc.outputXmlDocument((std::ostringstream*)out,
false,
true);
2240 void GatewaySupervisor::setSupervisorPropertyDefaults()
2242 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
2243 std::string() +
"*=1 | gatewayLaunchOTS=-1 | gatewayLaunchWiz=-1");
2249 void GatewaySupervisor::forceSupervisorPropertyValues()
2255 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
2256 "getSystemMessages | getCurrentState | getIterationPlanStatus"
2258 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
2259 "gatewayLaunchOTS | gatewayLaunchWiz");
2265 void GatewaySupervisor::request(xgi::Input* in, xgi::Output* out)
2269 out->getHTTPResponseHeader().addHeader(
"Access-Control-Allow-Origin",
"*");
2275 __COUT__ <<
"Waiting for FSM access" << __E__;
2276 std::lock_guard<std::mutex> lock(stateMachineAccessMutex_);
2278 __COUT__ <<
"Have FSM access" << __E__;
2280 cgicc::Cgicc cgiIn(in);
2282 std::string requestType = CgiDataUtilities::getData(cgiIn,
"RequestType");
2287 CorePropertySupervisorBase::getRequestUserInfo(userInfo);
2289 if(!theWebUsers_.xmlRequestOnGateway(cgiIn, out, &xmlOut, userInfo))
2321 if(requestType ==
"getSettings")
2323 std::string accounts = CgiDataUtilities::getData(cgiIn,
"accounts");
2325 __COUT__ <<
"Get Settings Request" << __E__;
2326 __COUT__ <<
"accounts = " << accounts << __E__;
2327 theWebUsers_.insertSettingsForUser(userInfo.uid_, &xmlOut, accounts ==
"1");
2329 else if(requestType ==
"setSettings")
2331 std::string bgcolor = CgiDataUtilities::postData(cgiIn,
"bgcolor");
2332 std::string dbcolor = CgiDataUtilities::postData(cgiIn,
"dbcolor");
2333 std::string wincolor = CgiDataUtilities::postData(cgiIn,
"wincolor");
2334 std::string layout = CgiDataUtilities::postData(cgiIn,
"layout");
2335 std::string syslayout = CgiDataUtilities::postData(cgiIn,
"syslayout");
2337 __COUT__ <<
"Set Settings Request" << __E__;
2338 __COUT__ <<
"bgcolor = " << bgcolor << __E__;
2339 __COUT__ <<
"dbcolor = " << dbcolor << __E__;
2340 __COUT__ <<
"wincolor = " << wincolor << __E__;
2341 __COUT__ <<
"layout = " << layout << __E__;
2342 __COUT__ <<
"syslayout = " << syslayout << __E__;
2344 theWebUsers_.changeSettingsForUser(userInfo.uid_, bgcolor, dbcolor, wincolor, layout, syslayout);
2345 theWebUsers_.insertSettingsForUser(userInfo.uid_, &xmlOut,
true);
2347 else if(requestType ==
"accountSettings")
2349 std::string type = CgiDataUtilities::postData(cgiIn,
"type");
2352 if(type ==
"updateAccount")
2353 type_int = theWebUsers_.MOD_TYPE_UPDATE;
2354 else if(type ==
"createAccount")
2355 type_int = theWebUsers_.MOD_TYPE_ADD;
2356 else if(type ==
"deleteAccount")
2357 type_int = theWebUsers_.MOD_TYPE_DELETE;
2359 std::string username = CgiDataUtilities::postData(cgiIn,
"username");
2360 std::string displayname = CgiDataUtilities::postData(cgiIn,
"displayname");
2361 std::string email = CgiDataUtilities::postData(cgiIn,
"useremail");
2362 std::string permissions = CgiDataUtilities::postData(cgiIn,
"permissions");
2363 std::string accounts = CgiDataUtilities::getData(cgiIn,
"accounts");
2365 __COUT__ <<
"accountSettings Request" << __E__;
2366 __COUT__ <<
"type = " << type <<
" - " << type_int << __E__;
2367 __COUT__ <<
"username = " << username << __E__;
2368 __COUT__ <<
"useremail = " << email << __E__;
2369 __COUT__ <<
"displayname = " << displayname << __E__;
2370 __COUT__ <<
"permissions = " << permissions << __E__;
2372 theWebUsers_.modifyAccountSettings(userInfo.uid_, type_int, username, displayname, email, permissions);
2374 __COUT__ <<
"accounts = " << accounts << __E__;
2376 theWebUsers_.insertSettingsForUser(userInfo.uid_, &xmlOut, accounts ==
"1");
2378 else if(requestType ==
"stateMatchinePreferences")
2380 std::string set = CgiDataUtilities::getData(cgiIn,
"set");
2381 const std::string DEFAULT_FSM_VIEW =
"Default_FSM_View";
2383 theWebUsers_.setGenericPreference(userInfo.uid_, DEFAULT_FSM_VIEW, CgiDataUtilities::getData(cgiIn, DEFAULT_FSM_VIEW));
2385 theWebUsers_.getGenericPreference(userInfo.uid_, DEFAULT_FSM_VIEW, &xmlOut);
2387 else if(requestType ==
"getAliasList")
2389 std::string username = theWebUsers_.getUsersUsername(userInfo.uid_);
2390 std::string fsmName = CgiDataUtilities::getData(cgiIn,
"fsmName");
2391 __SUP_COUTV__(fsmName);
2393 std::string stateMachineAliasFilter =
"*";
2395 std::map<std::string , std::pair<std::string ,
TableGroupKey>> aliasMap =
2396 CorePropertySupervisorBase::theConfigurationManager_->getActiveGroupAliases();
2400 CorePropertySupervisorBase::theConfigurationManager_->getSupervisorTableNode(supervisorContextUID_, supervisorApplicationUID_);
2402 if(!configLinkNode.isDisconnected())
2406 ConfigurationTree fsmLinkNode = configLinkNode.getNode(
"LinkToStateMachineTable");
2407 if(!fsmLinkNode.isDisconnected())
2408 stateMachineAliasFilter = fsmLinkNode.getNode(fsmName +
"/SystemAliasFilter").getValue<std::string>();
2410 __COUT_INFO__ <<
"FSM Link disconnected." << __E__;
2412 catch(std::runtime_error& e)
2414 __COUT_INFO__ << e.what() << __E__;
2418 __COUT_ERR__ <<
"Unknown error. Should never happen." << __E__;
2422 __COUT_INFO__ <<
"FSM Link disconnected." << __E__;
2424 __COUT__ <<
"stateMachineAliasFilter = " << stateMachineAliasFilter << __E__;
2430 bool invertFilter = stateMachineAliasFilter.size() && stateMachineAliasFilter[0] ==
'!';
2431 std::vector<std::string> filterArr;
2438 while((f = stateMachineAliasFilter.find(
'*', i)) != std::string::npos)
2440 tmp = stateMachineAliasFilter.substr(i, f - i);
2442 filterArr.push_back(tmp);
2446 if(i <= stateMachineAliasFilter.size())
2448 tmp = stateMachineAliasFilter.substr(i);
2449 filterArr.push_back(tmp);
2455 for(
auto& aliasMapPair : aliasMap)
2461 if(filterArr.size() == 1)
2463 if(filterArr[0] !=
"" && filterArr[0] !=
"*" && aliasMapPair.first != filterArr[0])
2464 filterMatch =
false;
2469 for(f = 0; f < filterArr.size(); ++f)
2471 if(!filterArr[f].size())
2476 if((i = aliasMapPair.first.find(filterArr[f])) != 0)
2478 filterMatch =
false;
2482 else if(f == filterArr.size() - 1)
2484 if(aliasMapPair.first.rfind(filterArr[f]) != aliasMapPair.first.size() - filterArr[f].size())
2486 filterMatch =
false;
2490 else if((i = aliasMapPair.first.find(filterArr[f])) == std::string::npos)
2492 filterMatch =
false;
2499 filterMatch = !filterMatch;
2506 xmlOut.addTextElementToData(
"config_alias", aliasMapPair.first);
2507 xmlOut.addTextElementToData(
"config_key", TableGroupKey::getFullGroupString(aliasMapPair.second.first, aliasMapPair.second.second).c_str());
2509 std::string groupComment, groupAuthor, groupCreationTime;
2512 CorePropertySupervisorBase::theConfigurationManager_->loadTableGroup(aliasMapPair.second.first,
2513 aliasMapPair.second.second,
2523 xmlOut.addTextElementToData(
"config_comment", groupComment);
2524 xmlOut.addTextElementToData(
"config_author", groupAuthor);
2525 xmlOut.addTextElementToData(
"config_create_time", groupCreationTime);
2529 __COUT_WARN__ <<
"Failed to load group metadata." << __E__;
2535 std::string fn = ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" +
2536 FSM_LAST_GROUP_ALIAS_FILE_START + username +
"." +
2537 FSM_USERS_PREFERENCES_FILETYPE;
2538 __COUT__ <<
"Load preferences: " << fn << __E__;
2539 FILE* fp = fopen(fn.c_str(),
"r");
2542 char tmpLastAlias[500];
2543 fscanf(fp,
"%*s %s", tmpLastAlias);
2544 __COUT__ <<
"tmpLastAlias: " << tmpLastAlias << __E__;
2546 xmlOut.addTextElementToData(
"UserLastConfigAlias", tmpLastAlias);
2550 else if(requestType ==
"getAppStatus")
2552 for(
const auto& it : allSupervisorInfo_.getAllSupervisorInfo())
2554 const auto& appInfo = it.second;
2556 xmlOut.addTextElementToData(
"name",
2558 xmlOut.addTextElementToData(
"id", std::to_string(appInfo.getId()));
2559 xmlOut.addTextElementToData(
"status", appInfo.getStatus());
2560 xmlOut.addTextElementToData(
2561 "time", appInfo.getLastStatusTime() ? StringMacros::getTimestampString(appInfo.getLastStatusTime()) :
"0");
2562 xmlOut.addTextElementToData(
"stale",
2563 std::to_string(time(0) - appInfo.getLastStatusTime()));
2564 xmlOut.addTextElementToData(
"progress", std::to_string(appInfo.getProgress()));
2565 xmlOut.addTextElementToData(
"detail", appInfo.getDetail());
2566 xmlOut.addTextElementToData(
"class",
2567 appInfo.getClass());
2568 xmlOut.addTextElementToData(
"url",
2570 xmlOut.addTextElementToData(
"context",
2571 appInfo.getContextName());
2574 else if(requestType ==
"getAppId")
2576 GatewaySupervisor::handleGetApplicationIdRequest(&allSupervisorInfo_, cgiIn, xmlOut);
2578 else if(requestType ==
"getContextMemberNames")
2582 auto contexts = contextTable->getContexts();
2583 for(
const auto& context : contexts)
2585 xmlOut.addTextElementToData(
"ContextMember", context.contextUID_);
2588 else if(requestType ==
"getSystemMessages")
2590 xmlOut.addTextElementToData(
"systemMessages",
2591 theWebUsers_.getSystemMessage(userInfo.displayName_));
2593 xmlOut.addTextElementToData(
"username_with_lock",
2594 theWebUsers_.getUserWithLock());
2598 else if(requestType ==
"setUserWithLock")
2600 std::string username = CgiDataUtilities::postData(cgiIn,
"username");
2601 std::string lock = CgiDataUtilities::postData(cgiIn,
"lock");
2602 std::string accounts = CgiDataUtilities::getData(cgiIn,
"accounts");
2604 __COUTV__(username);
2606 __COUTV__(accounts);
2607 __COUTV__(userInfo.uid_);
2609 std::string tmpUserWithLock = theWebUsers_.getUserWithLock();
2610 if(!theWebUsers_.setUserWithLock(userInfo.uid_, lock ==
"1", username))
2611 xmlOut.addTextElementToData(
"server_alert",
2612 std::string(
"Set user lock action failed. You must have valid "
2613 "permissions and ") +
2614 "locking user must be currently logged in.");
2616 theWebUsers_.insertSettingsForUser(userInfo.uid_, &xmlOut, accounts ==
"1");
2618 if(tmpUserWithLock != theWebUsers_.getUserWithLock())
2619 theWebUsers_.addSystemMessage(
2620 "*", theWebUsers_.getUserWithLock() ==
"" ? tmpUserWithLock +
" has unlocked ots." : theWebUsers_.getUserWithLock() +
" has locked ots.");
2622 else if(requestType ==
"getStateMachine")
2625 std::vector<toolbox::fsm::State> states;
2626 states = theStateMachine_.getStates();
2629 std::string transName;
2630 std::string transParameter;
2633 for(
unsigned int i = 0; i < states.size(); ++i)
2635 stateStr[0] = states[i];
2636 DOMElement* stateParent = xmlOut.addTextElementToData(
"state", stateStr);
2638 xmlOut.addTextElementToParent(
"state_name", theStateMachine_.getStateName(states[i]), stateParent);
2645 std::map<std::string, toolbox::fsm::State, std::less<std::string>> trans = theStateMachine_.getTransitions(states[i]);
2646 std::set<std::string> actionNames = theStateMachine_.getInputs(states[i]);
2648 std::map<std::string, toolbox::fsm::State, std::less<std::string>>::iterator it = trans.begin();
2649 std::set<std::string>::iterator ait = actionNames.begin();
2657 for(; it != trans.end() && ait != actionNames.end(); ++it, ++ait)
2659 stateStr[0] = it->second;
2661 if(stateStr[0] ==
'R')
2664 xmlOut.addTextElementToParent(
"state_transition", stateStr, stateParent);
2668 xmlOut.addTextElementToParent(
"state_transition_action", *ait, stateParent);
2670 transName = theStateMachine_.getTransitionName(states[i], *ait);
2673 xmlOut.addTextElementToParent(
"state_transition_name", transName, stateParent);
2674 transParameter = theStateMachine_.getTransitionParameter(states[i], *ait);
2677 xmlOut.addTextElementToParent(
"state_transition_parameter", transParameter, stateParent);
2680 else if(stateStr[0] ==
'C')
2683 xmlOut.addTextElementToParent(
"state_transition", stateStr, stateParent);
2687 xmlOut.addTextElementToParent(
"state_transition_action", *ait, stateParent);
2689 transName = theStateMachine_.getTransitionName(states[i], *ait);
2692 xmlOut.addTextElementToParent(
"state_transition_name", transName, stateParent);
2693 transParameter = theStateMachine_.getTransitionParameter(states[i], *ait);
2696 xmlOut.addTextElementToParent(
"state_transition_parameter", transParameter, stateParent);
2703 ait = actionNames.begin();
2706 for(; it != trans.end() && ait != actionNames.end(); ++it, ++ait)
2710 stateStr[0] = it->second;
2712 if(stateStr[0] ==
'R')
2714 else if(stateStr[0] ==
'C')
2717 xmlOut.addTextElementToParent(
"state_transition", stateStr, stateParent);
2721 xmlOut.addTextElementToParent(
"state_transition_action", *ait, stateParent);
2723 transName = theStateMachine_.getTransitionName(states[i], *ait);
2726 xmlOut.addTextElementToParent(
"state_transition_name", transName, stateParent);
2727 transParameter = theStateMachine_.getTransitionParameter(states[i], *ait);
2730 xmlOut.addTextElementToParent(
"state_transition_parameter", transParameter, stateParent);
2734 else if(requestType ==
"getStateMachineNames")
2738 CorePropertySupervisorBase::theConfigurationManager_->getSupervisorTableNode(supervisorContextUID_, supervisorApplicationUID_);
2742 auto fsmNodes = configLinkNode.getNode(
"LinkToStateMachineTable").getChildren();
2743 for(
const auto& fsmNode : fsmNodes)
2744 xmlOut.addTextElementToData(
"stateMachineName", fsmNode.first);
2748 __COUT__ <<
"Caught exception, assuming no valid FSM names." << __E__;
2749 xmlOut.addTextElementToData(
"stateMachineName",
"");
2752 else if(requestType ==
"getIterationPlanStatus")
2755 theIterator_.handleCommandRequest(xmlOut, requestType,
"");
2757 else if(requestType ==
"getCurrentState")
2759 xmlOut.addTextElementToData(
"current_state", theStateMachine_.getCurrentStateName());
2760 xmlOut.addTextElementToData(
"in_transition", theStateMachine_.isInTransition() ?
"1" :
"0");
2761 if(theStateMachine_.isInTransition())
2762 xmlOut.addTextElementToData(
"transition_progress", RunControlStateMachine::theProgressBar_.readPercentageString());
2764 xmlOut.addTextElementToData(
"transition_progress",
"100");
2767 sprintf(tmp,
"%lu", theStateMachine_.getTimeInState());
2768 xmlOut.addTextElementToData(
"time_in_state", tmp);
2775 std::string fsmName = CgiDataUtilities::getData(cgiIn,
"fsmName");
2784 if(!theStateMachine_.isInTransition())
2786 std::string stateMachineRunAlias =
"Run";
2790 CorePropertySupervisorBase::theConfigurationManager_->getSupervisorTableNode(supervisorContextUID_, supervisorApplicationUID_);
2792 if(!configLinkNode.isDisconnected())
2796 ConfigurationTree fsmLinkNode = configLinkNode.getNode(
"LinkToStateMachineTable");
2797 if(!fsmLinkNode.isDisconnected())
2798 stateMachineRunAlias = fsmLinkNode.getNode(fsmName +
"/RunDisplayAlias").getValue<std::string>();
2802 catch(std::runtime_error& e)
2811 __COUT_ERR__ <<
"Unknown error. Should never happen." << __E__;
2813 __COUT_INFO__ <<
"No state machine Run alias. Ignoring and "
2814 "assuming alias of '"
2815 << stateMachineRunAlias <<
".'" << __E__;
2824 xmlOut.addTextElementToData(
"stateMachineRunAlias", stateMachineRunAlias);
2828 if(theStateMachine_.getCurrentStateName() ==
"Running" || theStateMachine_.getCurrentStateName() ==
"Paused")
2830 sprintf(tmp,
"Current %s Number: %u", stateMachineRunAlias.c_str(), getNextRunNumber(activeStateMachineName_) - 1);
2832 if(RunControlStateMachine::asyncSoftFailureReceived_)
2836 xmlOut.addTextElementToData(
"soft_error", RunControlStateMachine::getErrorMessage());
2840 sprintf(tmp,
"Next %s Number: %u", stateMachineRunAlias.c_str(), getNextRunNumber(fsmName));
2841 xmlOut.addTextElementToData(
"run_number", tmp);
2844 else if(requestType ==
"cancelStateMachineTransition")
2846 __SS__ <<
"State transition was cancelled by user!" << __E__;
2847 __MCOUT__(ss.str());
2848 RunControlStateMachine::theStateMachine_.setErrorMessage(ss.str());
2849 RunControlStateMachine::asyncFailureReceived_ =
true;
2851 else if(requestType ==
"getErrorInStateMatchine")
2853 xmlOut.addTextElementToData(
"FSM_Error", theStateMachine_.getErrorMessage());
2855 else if(requestType ==
"getDesktopIcons")
2868 const std::vector<DesktopIconTable::DesktopIcon>& icons = iconTable->getAllDesktopIcons();
2870 std::string iconString =
"";
2885 std::map<std::string, WebUsers::permissionLevel_t> userPermissionLevelsMap = theWebUsers_.getPermissionsForUser(userInfo.uid_);
2886 std::map<std::string, WebUsers::permissionLevel_t> iconPermissionThresholdsMap;
2888 bool firstIcon =
true;
2889 for(
const auto& icon : icons)
2894 CorePropertySupervisorBase::extractPermissionsMapFromString(icon.permissionThresholdString_, iconPermissionThresholdsMap);
2896 if(!CorePropertySupervisorBase::doPermissionsGrantAccess(userPermissionLevelsMap, iconPermissionThresholdsMap))
2907 iconString += icon.caption_;
2908 iconString +=
"," + icon.alternateText_;
2909 iconString +=
"," + std::string(icon.enforceOneWindowInstance_ ?
"1" :
"0");
2910 iconString +=
"," + std::string(
"1");
2914 iconString +=
"," + icon.imageURL_;
2915 iconString +=
"," + icon.windowContentURL_;
2916 iconString +=
"," + icon.folderPath_;
2920 xmlOut.addTextElementToData(
"iconList", iconString);
2922 else if(requestType ==
"addDesktopIcon")
2924 std::vector<DesktopIconTable::DesktopIcon> newIcons;
2926 bool success = GatewaySupervisor::handleAddDesktopIconRequest(theWebUsers_.getUsersUsername(userInfo.uid_), cgiIn, xmlOut, &newIcons);
2930 __COUT__ <<
"Attempting dynamic icon change..." << __E__;
2933 iconTable->setAllDesktopIcons(newIcons);
2936 __COUT__ <<
"Failed dynamic icon add." << __E__;
2938 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz")
2943 __COUT_WARN__ << requestType <<
" requestType received! " << __E__;
2944 __MOUT_WARN__ << requestType <<
" requestType received! " << __E__;
2947 theWebUsers_.saveActiveSessions();
2951 if(requestType ==
"gatewayLaunchOTS")
2952 GatewaySupervisor::launchStartOTSCommand(
"LAUNCH_OTS", CorePropertySupervisorBase::theConfigurationManager_);
2953 else if(requestType ==
"gatewayLaunchWiz")
2954 GatewaySupervisor::launchStartOTSCommand(
"LAUNCH_WIZ", CorePropertySupervisorBase::theConfigurationManager_);
2956 else if(requestType ==
"resetUserTooltips")
2958 WebUsers::resetAllUserTooltips(theWebUsers_.getUsersUsername(userInfo.uid_));
2960 else if(requestType ==
"silenceUserTooltips")
2962 WebUsers::silenceAllUserTooltips(theWebUsers_.getUsersUsername(userInfo.uid_));
2966 __SS__ <<
"requestType Request, " << requestType <<
", not recognized." << __E__;
2970 catch(
const std::runtime_error& e)
2972 __SS__ <<
"An error was encountered handling requestType '" << requestType <<
"':" << e.what() << __E__;
2973 __COUT__ <<
"\n" << ss.str();
2974 xmlOut.addTextElementToData(
"Error", ss.str());
2978 __SS__ <<
"An unknown error was encountered handling requestType '" << requestType <<
".' "
2979 <<
"Please check the printouts to debug." << __E__;
2980 __COUT__ <<
"\n" << ss.str();
2981 xmlOut.addTextElementToData(
"Error", ss.str());
2985 xmlOut.outputXmlDocument((std::ostringstream*)out,
false ,
true );
2994 void GatewaySupervisor::launchStartOTSCommand(
const std::string& command,
ConfigurationManager* cfgMgr)
2996 __COUT__ <<
"launch StartOTS Command = " << command << __E__;
2997 __COUT__ <<
"Extracting target context hostnames... " << __E__;
2999 std::vector<std::string> hostnames;
3006 auto contexts = contextTable->getContexts();
3008 for(
const auto& context : contexts)
3010 if(!context.status_)
3015 for(i = 0; i < context.address_.size(); ++i)
3016 if(context.address_[i] ==
'/')
3018 hostnames.push_back(context.address_.substr(j));
3019 __COUT__ <<
"StartOTS.sh hostname = " << hostnames.back() << __E__;
3024 __SS__ <<
"\nRelaunch of otsdaq interrupted! "
3025 <<
"The Configuration Manager could not be initialized." << __E__;
3030 for(
const auto& hostname : hostnames)
3032 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
"/StartOTS_action_" + hostname +
".cmd");
3033 FILE* fp = fopen(fn.c_str(),
"w");
3036 fprintf(fp,
"%s", command.c_str());
3041 __SS__ <<
"Unable to open command file: " << fn << __E__;
3049 for(
const auto& hostname : hostnames)
3051 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
"/StartOTS_action_" + hostname +
".cmd");
3052 FILE* fp = fopen(fn.c_str(),
"r");
3056 fgets(line, 100, fp);
3059 if(strcmp(line, command.c_str()) == 0)
3061 __SS__ <<
"The command looks to have been ignored by " << hostname <<
". Is StartOTS.sh still running on that node?" << __E__;
3068 __SS__ <<
"Unable to open command file for verification: " << fn << __E__;
3077 xoap::MessageReference GatewaySupervisor::supervisorCookieCheck(xoap::MessageReference message)
3084 parameters.addParameter(
"CookieCode");
3085 parameters.addParameter(
"RefreshOption");
3086 parameters.addParameter(
"IPAddress");
3087 SOAPUtilities::receive(message, parameters);
3088 std::string cookieCode = parameters.getValue(
"CookieCode");
3089 std::string refreshOption = parameters.getValue(
"RefreshOption");
3091 std::string ipAddress = parameters.getValue(
"IPAddress");
3097 std::map<std::string , WebUsers::permissionLevel_t> userGroupPermissionsMap;
3098 std::string userWithLock =
"";
3099 uint64_t activeSessionIndex, uid;
3100 theWebUsers_.cookieCodeIsActiveForRequest(
3101 cookieCode, &userGroupPermissionsMap, &uid , ipAddress, refreshOption ==
"1", &userWithLock, &activeSessionIndex);
3107 retParameters.addParameter(
"CookieCode", cookieCode);
3108 retParameters.addParameter(
"Permissions", StringMacros::mapToString(userGroupPermissionsMap).c_str());
3109 retParameters.addParameter(
"UserWithLock", userWithLock);
3110 retParameters.addParameter(
"Username", theWebUsers_.getUsersUsername(uid));
3111 retParameters.addParameter(
"DisplayName", theWebUsers_.getUsersDisplayName(uid));
3112 sprintf(tmpStringForConversions_,
"%lu", activeSessionIndex);
3113 retParameters.addParameter(
"ActiveSessionIndex", tmpStringForConversions_);
3117 return SOAPUtilities::makeSOAPMessageReference(
"CookieResponse", retParameters);
3123 xoap::MessageReference GatewaySupervisor::supervisorGetActiveUsers(xoap::MessageReference )
3127 SOAPParameters parameters(
"UserList", theWebUsers_.getActiveUsersString());
3128 return SOAPUtilities::makeSOAPMessageReference(
"ActiveUserResponse", parameters);
3136 xoap::MessageReference GatewaySupervisor::supervisorSystemMessage(xoap::MessageReference message)
3139 parameters.addParameter(
"ToUser");
3140 parameters.addParameter(
"Subject");
3141 parameters.addParameter(
"Message");
3142 parameters.addParameter(
"DoEmail");
3143 SOAPUtilities::receive(message, parameters);
3145 std::string toUserCSV = parameters.getValue(
"ToUser");
3146 std::string subject = parameters.getValue(
"Subject");
3147 std::string systemMessage = parameters.getValue(
"Message");
3148 std::string doEmail = parameters.getValue(
"DoEmail");
3150 __COUTV__(toUserCSV);
3152 __COUTV__(systemMessage);
3155 theWebUsers_.addSystemMessage(
3161 return SOAPUtilities::makeSOAPMessageReference(
"SystemMessageResponse");
3168 xoap::MessageReference GatewaySupervisor::supervisorSystemLogbookEntry(xoap::MessageReference message)
3171 parameters.addParameter(
"EntryText");
3172 SOAPUtilities::receive(message, parameters);
3174 __COUT__ <<
"EntryText: " << parameters.getValue(
"EntryText").substr(0, 10) << __E__;
3176 makeSystemLogbookEntry(parameters.getValue(
"EntryText"));
3178 return SOAPUtilities::makeSOAPMessageReference(
"SystemLogbookResponse");
3186 xoap::MessageReference GatewaySupervisor::supervisorLastTableGroupRequest(xoap::MessageReference message)
3190 parameters.addParameter(
"ActionOfLastGroup");
3191 SOAPUtilities::receive(message, parameters);
3193 return GatewaySupervisor::lastTableGroupRequestHandler(parameters);
3202 xoap::MessageReference GatewaySupervisor::lastTableGroupRequestHandler(
const SOAPParameters& parameters)
3204 std::string action = parameters.getValue(
"ActionOfLastGroup");
3205 __COUT__ <<
"ActionOfLastGroup: " << action.substr(0, 10) << __E__;
3207 std::string fileName =
"";
3208 if(action ==
"Configured")
3209 fileName = FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE;
3210 else if(action ==
"Started")
3211 fileName = FSM_LAST_STARTED_GROUP_ALIAS_FILE;
3212 else if(action ==
"ActivatedConfig")
3213 fileName = ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE;
3214 else if(action ==
"ActivatedContext")
3215 fileName = ConfigurationManager::LAST_ACTIVATED_CONTEXT_GROUP_FILE;
3216 else if(action ==
"ActivatedBackbone")
3217 fileName = ConfigurationManager::LAST_ACTIVATED_BACKBONE_GROUP_FILE;
3218 else if(action ==
"ActivatedIterator")
3219 fileName = ConfigurationManager::LAST_ACTIVATED_ITERATOR_GROUP_FILE;
3222 __COUT_ERR__ <<
"Invalid last group action requested." << __E__;
3223 return SOAPUtilities::makeSOAPMessageReference(
"LastConfigGroupResponseFailure");
3225 std::string timeString;
3227 ConfigurationManager::loadGroupNameAndKey(fileName, timeString);
3231 retParameters.addParameter(
"GroupName", theGroup.first);
3232 retParameters.addParameter(
"GroupKey", theGroup.second.toString());
3233 retParameters.addParameter(
"GroupAction", action);
3234 retParameters.addParameter(
"GroupActionTime", timeString);
3236 return SOAPUtilities::makeSOAPMessageReference(
"LastConfigGroupResponse", retParameters);
3246 unsigned int GatewaySupervisor::getNextRunNumber(
const std::string& fsmNameIn)
3248 std::string runNumberFileName = RUN_NUMBER_PATH +
"/";
3249 std::string fsmName = fsmNameIn ==
"" ? activeStateMachineName_ : fsmNameIn;
3251 for(
unsigned int i = 0; i < fsmName.size(); ++i)
3252 if((fsmName[i] >=
'a' && fsmName[i] <=
'z') || (fsmName[i] >=
'A' && fsmName[i] <=
'Z') || (fsmName[i] >=
'0' && fsmName[i] <=
'9'))
3253 runNumberFileName += fsmName[i];
3254 runNumberFileName += RUN_NUMBER_FILE_NAME;
3257 std::ifstream runNumberFile(runNumberFileName.c_str());
3258 if(!runNumberFile.is_open())
3260 __COUT__ <<
"Can't open file: " << runNumberFileName << __E__;
3262 __COUT__ <<
"Creating file and setting Run Number to 1: " << runNumberFileName << __E__;
3263 FILE* fp = fopen(runNumberFileName.c_str(),
"w");
3267 runNumberFile.open(runNumberFileName.c_str());
3268 if(!runNumberFile.is_open())
3270 __SS__ <<
"Error. Can't create file: " << runNumberFileName << __E__;
3271 __COUT_ERR__ << ss.str();
3275 std::string runNumberString;
3276 runNumberFile >> runNumberString;
3277 runNumberFile.close();
3278 return atoi(runNumberString.c_str());
3282 bool GatewaySupervisor::setNextRunNumber(
unsigned int runNumber,
const std::string& fsmNameIn)
3284 std::string runNumberFileName = RUN_NUMBER_PATH +
"/";
3285 std::string fsmName = fsmNameIn ==
"" ? activeStateMachineName_ : fsmNameIn;
3287 for(
unsigned int i = 0; i < fsmName.size(); ++i)
3288 if((fsmName[i] >=
'a' && fsmName[i] <=
'z') || (fsmName[i] >=
'A' && fsmName[i] <=
'Z') || (fsmName[i] >=
'0' && fsmName[i] <=
'9'))
3289 runNumberFileName += fsmName[i];
3290 runNumberFileName += RUN_NUMBER_FILE_NAME;
3291 __COUT__ <<
"runNumberFileName: " << runNumberFileName << __E__;
3293 std::ofstream runNumberFile(runNumberFileName.c_str());
3294 if(!runNumberFile.is_open())
3296 __SS__ <<
"Can't open file: " << runNumberFileName << __E__;
3297 __COUT__ << ss.str();
3300 std::stringstream runNumberStream;
3301 runNumberStream << runNumber;
3302 runNumberFile << runNumberStream.str().c_str();
3303 runNumberFile.close();
3310 std::string classNeedle = StringMacros::decodeURIComponent(CgiDataUtilities::getData(cgiIn,
"classNeedle"));
3311 __COUTV__(classNeedle);
3313 for(
auto it : allSupervisorInfo->getAllSupervisorInfo())
3317 auto appInfo = it.second;
3319 if(classNeedle != appInfo.getClass())
3322 xmlOut.addTextElementToData(
"name",
3324 xmlOut.addTextElementToData(
"id", std::to_string(appInfo.getId()));
3325 xmlOut.addTextElementToData(
"class",
3326 appInfo.getClass());
3327 xmlOut.addTextElementToData(
"url",
3329 xmlOut.addTextElementToData(
"context",
3330 appInfo.getContextName());
3336 bool GatewaySupervisor::handleAddDesktopIconRequest(
const std::string& author,
3337 cgicc::Cgicc& cgiIn,
3339 std::vector<DesktopIconTable::DesktopIcon>* newIcons )
3341 std::string iconCaption = CgiDataUtilities::getData(cgiIn,
"iconCaption");
3342 std::string iconAltText = CgiDataUtilities::getData(cgiIn,
"iconAltText");
3343 std::string iconFolderPath = CgiDataUtilities::getData(cgiIn,
"iconFolderPath");
3344 std::string iconImageURL = CgiDataUtilities::getData(cgiIn,
"iconImageURL");
3345 std::string iconWindowURL = CgiDataUtilities::getData(cgiIn,
"iconWindowURL");
3346 std::string iconPermissions = CgiDataUtilities::getData(cgiIn,
"iconPermissions");
3348 std::string windowLinkedApp = CgiDataUtilities::getData(cgiIn,
"iconLinkedApp");
3349 unsigned int windowLinkedAppLID = CgiDataUtilities::getDataAsInt(cgiIn,
"iconLinkedAppLID");
3350 bool enforceOneWindowInstance = CgiDataUtilities::getData(cgiIn,
"iconEnforceOneWindowInstance") ==
"1" ?
true :
false;
3352 std::string windowParameters = StringMacros::decodeURIComponent(CgiDataUtilities::postData(cgiIn,
"iconParameters"));
3355 __COUTV__(iconCaption);
3356 __COUTV__(iconAltText);
3357 __COUTV__(iconFolderPath);
3358 __COUTV__(iconImageURL);
3359 __COUTV__(iconWindowURL);
3360 __COUTV__(iconPermissions);
3361 __COUTV__(windowLinkedApp);
3362 __COUTV__(windowLinkedAppLID);
3363 __COUTV__(enforceOneWindowInstance);
3365 __COUTV__(windowParameters);
3369 bool success = ConfigurationSupervisorBase::handleAddDesktopIconXML(xmlOut,
3378 windowLinkedAppLID ,
3379 enforceOneWindowInstance ,
3382 if(newIcons && success)
3384 __COUT__ <<
"Passing new icons back to caller..." << __E__;
3386 const std::vector<DesktopIconTable::DesktopIcon>& tmpNewIcons = tmpCfgMgr.__GET_CONFIG__(
DesktopIconTable)->getAllDesktopIcons();
3389 for(
const auto& tmpNewIcon : tmpNewIcons)
3390 newIcons->push_back(tmpNewIcon);