1 #include "otsdaq/GatewaySupervisor/GatewaySupervisor.h"
2 #include "otsdaq/CgiDataUtilities/CgiDataUtilities.h"
3 #include "otsdaq/Macros/CoutMacros.h"
4 #include "otsdaq/MessageFacility/ITRACEController.h"
5 #include "otsdaq/MessageFacility/MessageFacility.h"
6 #include "otsdaq/SOAPUtilities/SOAPCommand.h"
7 #include "otsdaq/SOAPUtilities/SOAPUtilities.h"
8 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
10 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
11 #include "otsdaq/ConfigurationInterface/ConfigurationManagerRW.h"
12 #include "otsdaq/TablePlugins/XDAQContextTable/XDAQContextTable.h"
13 #include "otsdaq/WorkLoopManager/WorkLoopManager.h"
15 #include "otsdaq/FiniteStateMachine/MakeRunInfo.h"
16 #include "otsdaq/FiniteStateMachine/RunInfoVInterface.h"
18 #pragma GCC diagnostic push
19 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
20 #include <cgicc/HTMLClasses.h>
21 #include <cgicc/HTMLDoctype.h>
22 #include <cgicc/HTTPCookie.h>
23 #include <cgicc/HTTPHeader.h>
24 #include <xgi/Utils.h>
25 #pragma GCC diagnostic pop
27 #include <toolbox/fsm/FailedEvent.h>
28 #include <toolbox/task/WorkLoopFactory.h>
29 #include <xdaq/NamespaceURI.h>
30 #include <xoap/Method.h>
39 #define RUN_NUMBER_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/RunNumber/"
40 #define RUN_NUMBER_FILE_NAME "NextRunNumber.txt"
41 #define LOG_ENTRY_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/FSM_LastLogEntry/"
42 #define LOG_ENTRY_FILE_NAME "LastLogEntry.txt"
43 #define FSM_LAST_GROUP_ALIAS_FILE_START std::string("FSMLastGroupAlias-")
44 #define FSM_USERS_PREFERENCES_FILETYPE "pref"
46 #define REMOTE_SUBSYSTEM_SETTINGS_FILE_NAME "RemoteSubsystems.txt"
49 #define __MF_SUBJECT__ "GatewaySupervisor"
54 std::vector<std::shared_ptr<GatewaySupervisor::BroadcastThreadStruct>>
55 GatewaySupervisor::broadcastThreadStructs_;
59 : xdaq::Application(s)
63 , stateMachineWorkLoopManager_(toolbox::task::bind(
65 , stateMachineSemaphore_(toolbox::BSem::FULL)
66 , activeStateMachineName_(
"")
68 , broadcastCommandMessageIndex_(0)
69 , broadcastIterationBreakpoint_(
74 __COUT__ <<
"Constructing" << __E__;
79 ss <<
"This is a test" << std::endl;
82 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
84 catch(
const toolbox::fsm::exception::Exception& e)
93 std::cout <<
"Mismatch!" << std::endl;
100 mkdir((std::string(__ENV__(
"SERVICE_DATA_PATH"))).c_str(), 0755);
103 mkdir((ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH).c_str(), 0755);
104 mkdir((RUN_NUMBER_PATH).c_str(), 0755);
105 mkdir((LOG_ENTRY_PATH).c_str(), 0755);
107 securityType_ = GatewaySupervisor::theWebUsers_.
getSecurity();
109 __COUT__ <<
"Security: " << securityType_ << __E__;
111 xgi::bind(
this, &GatewaySupervisor::Default,
"Default");
112 xgi::bind(
this, &GatewaySupervisor::loginRequest,
"LoginRequest");
113 xgi::bind(
this, &GatewaySupervisor::request,
"Request");
114 xgi::bind(
this, &GatewaySupervisor::stateMachineXgiHandler,
"StateMachineXgiHandler");
116 &GatewaySupervisor::stateMachineIterationBreakpoint,
117 "StateMachineIterationBreakpoint");
118 xgi::bind(
this, &GatewaySupervisor::tooltipRequest,
"TooltipRequest");
119 xgi::bind(
this, &GatewaySupervisor::XGI_Turtle,
"XGI_Turtle");
122 &GatewaySupervisor::supervisorCookieCheck,
123 "SupervisorCookieCheck",
126 &GatewaySupervisor::supervisorGetActiveUsers,
127 "SupervisorGetActiveUsers",
130 &GatewaySupervisor::supervisorSystemMessage,
131 "SupervisorSystemMessage",
134 &GatewaySupervisor::supervisorSystemLogbookEntry,
135 "SupervisorSystemLogbookEntry",
138 &GatewaySupervisor::supervisorLastTableGroupRequest,
139 "SupervisorLastTableGroupRequest",
142 &GatewaySupervisor::TRACESupervisorRequest,
143 "TRACESupervisorRequest",
148 __SUP_COUT__ <<
"Constructed. getpid()=" << getpid() <<
" gettid()=" << gettid()
155 GatewaySupervisor::~GatewaySupervisor(
void)
157 delete CorePropertySupervisorBase::theConfigurationManager_;
162 doLog = __ENV__(
"OTS_LOG_INTERMEDIATE_STATES") == std::string(
"1");
170 makeSystemLogEntry(
"ots shutdown.");
177 CorePropertySupervisorBase::indicateOtsAlive(properties);
181 void GatewaySupervisor::init(
void)
183 supervisorGuiHasBeenLoaded_ =
false;
186 conditionID_ = (
unsigned int)-1;
190 bool enableStateChanges =
false;
191 bool enableLoginVerify =
false;
194 enableStateChanges = CorePropertySupervisorBase::getSupervisorTableNode()
195 .getNode(
"EnableStateChangesOverUDP")
197 enableLoginVerify = CorePropertySupervisorBase::getSupervisorTableNode()
198 .getNode(
"EnableAckForStateChangesOverUDP")
206 if(enableStateChanges || enableLoginVerify)
208 if(enableStateChanges)
209 __COUT_INFO__ <<
"Enabling state changes over UDP..." << __E__;
210 else if(enableLoginVerify)
212 __COUT_INFO__ <<
"Enabling this Gateway as source of primary login "
213 "verification over UDP..."
216 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
217 loadRemoteGatewaySettings(remoteGatewayApps_);
227 __COUT__ <<
"State changes over UDP are disabled." << __E__;
232 bool checkAppStatus =
false;
235 checkAppStatus = CorePropertySupervisorBase::getSupervisorTableNode()
236 .getNode(
"EnableApplicationStatusMonitoring")
246 __COUT__ <<
"Enabling App Status checking..." << __E__;
255 __COUT__ <<
"App Status checking is disabled." << __E__;
260 auto appInfo = it.second;
263 SupervisorInfo::APP_STATUS_NOT_MONITORED,
280 bool firstError =
true;
281 std::string status, progress, detail, appName;
282 std::vector<SupervisorInfo::SubappInfo> subapps;
284 bool oneStatusReqHasFailed =
false;
285 size_t loopCount = -1;
287 std::map<std::string ,
bool > appLastStatusGood;
289 std::unique_ptr<TransceiverSocket>
291 bool resetRemoteGatewayApps =
false;
292 bool commandingRemoteGatewayApps =
false;
293 size_t commandRemoteIdleCount = 0;
294 int portForReverseLoginOverUDP = 0;
295 std::string ipAddressForStateChangesOverUDP =
"";
306 oneStatusReqHasFailed =
false;
310 auto appInfo = it.second;
311 appName = appInfo.getName();
320 if(appInfo.isGatewaySupervisor())
325 const std::string& err =
326 theSupervisor->theStateMachine_.getErrorMessage();
329 __COUTVS__(39, theSupervisor->theStateMachine_.isInTransition());
330 if(theSupervisor->theStateMachine_.isInTransition())
332 theSupervisor->theStateMachine_
333 .getCurrentTransitionName());
335 39, theSupervisor->theStateMachine_.getProvenanceStateName());
337 theSupervisor->theStateMachine_.getCurrentStateName());
346 if(theSupervisor->theStateMachine_
352 status = theSupervisor->theStateMachine_
353 .getCurrentTransitionName();
357 status = theSupervisor->theStateMachine_
358 .getProvenanceStateName();
366 theSupervisor->theStateMachine_.getCurrentStateName();
372 status = (theSupervisor->theStateMachine_.getCurrentStateName() ==
373 RunControlStateMachine::PAUSED_STATE_NAME
380 __COUTVS__(39, status);
381 __COUTVS__(39, progress);
386 (theSupervisor->theStateMachine_.isInTransition()
387 ? theSupervisor->theStateMachine_
388 .getCurrentTransitionName(
389 theSupervisor->stateMachineLastCommandInput_)
390 : (std::string(
"Uptime: ") +
391 StringMacros::encodeURIComponent(
393 theSupervisor->CorePropertySupervisorBase::
getSupervisorUptime())) +
394 ", Time-in-state: " +
395 StringMacros::encodeURIComponent(
397 theSupervisor->theStateMachine_
400 std::lock_guard<std::mutex> lock(
401 theSupervisor->broadcastCommandStatusUpdateMutex_);
402 if(detail !=
"" && theSupervisor->broadcastCommandStatus_ !=
"")
403 detail +=
" - " + theSupervisor->broadcastCommandStatus_;
405 if(!theSupervisor->theStateMachine_.isInTransition() &&
406 (theSupervisor->theStateMachine_.getCurrentStateName() ==
407 RunControlStateMachine::CONFIGURED_STATE_NAME ||
408 theSupervisor->theStateMachine_.getCurrentStateName() ==
409 RunControlStateMachine::RUNNING_STATE_NAME ||
410 theSupervisor->theStateMachine_.getCurrentStateName() ==
411 RunControlStateMachine::PAUSED_STATE_NAME))
415 " - Configured with System Configuration Alias '" +
416 theSupervisor->activeStateMachineConfigurationAlias_ +
417 "' which translates to " +
418 theSupervisor->theConfigurationTableGroup_.first +
"(" +
419 theSupervisor->theConfigurationTableGroup_.second.str() +
420 "). Active Context Group " +
422 ->CorePropertySupervisorBase::theConfigurationManager_
423 ->getActiveGroupName(
424 ConfigurationManager::GroupType::CONTEXT_TYPE) +
427 ->CorePropertySupervisorBase::theConfigurationManager_
429 ConfigurationManager::GroupType::CONTEXT_TYPE)
439 std::vector<GatewaySupervisor::RemoteGatewayInfo>
442 std::lock_guard<std::mutex> lock(
443 theSupervisor->remoteGatewayAppsMutex_);
444 remoteApps = theSupervisor->remoteGatewayApps_;
447 if(!commandingRemoteGatewayApps)
449 for(
const auto& remoteApp : remoteApps)
451 if(remoteApp.command !=
"")
454 commandingRemoteGatewayApps =
true;
460 __COUTVS__(38, commandingRemoteGatewayApps);
463 if((!commandingRemoteGatewayApps && loopCount % 20 == 0) ||
474 const std::vector<DesktopIconTable::DesktopIcon>& icons =
475 iconTable->getAllDesktopIcons();
477 for(
auto& remoteGatewayApp : remoteApps)
478 remoteGatewayApp.appInfo.status =
481 resetRemoteGatewayApps =
true;
483 for(
const auto& icon : icons)
485 __COUTTV__(icon.windowContentURL_);
486 if(icon.windowContentURL_.size() > 4 &&
487 icon.windowContentURL_[0] ==
'o' &&
488 icon.windowContentURL_[1] ==
't' &&
489 icon.windowContentURL_[2] ==
's' &&
490 icon.windowContentURL_[3] ==
':')
492 __COUT__ <<
"Found '" << icon.recordUID_
493 <<
"' remote gateway icons url: "
494 << icon.windowContentURL_ << __E__;
496 GatewaySupervisor::RemoteGatewayInfo thisInfo;
498 std::string remoteURL = icon.windowContentURL_;
499 std::string remoteLandingPage =
"";
500 std::string remoteSetupType =
"";
502 if(remoteURL.find(
'?') != std::string::npos)
505 <<
"Extracting GET ? parameters from remote url."
507 std::vector<std::string> urlSplit =
510 if(urlSplit.size() > 0)
511 remoteURL = urlSplit[0];
512 if(urlSplit.size() > 1)
515 std::vector<std::string> parameterPairs =
518 for(
const auto& parameterPair : parameterPairs)
520 std::vector<std::string> parameterPairSplit =
522 parameterPair, {
'='});
523 if(parameterPairSplit.size() == 2)
525 __COUT__ <<
"Found remote URL parameter "
526 << parameterPairSplit[0] <<
", "
527 << parameterPairSplit[1]
529 if(parameterPairSplit[0] ==
"LandingPage")
533 parameterPairSplit[1]);
534 if(remoteLandingPage.find(
535 icon.folderPath_) != 0)
537 icon.folderPath_ +
"/" +
539 __COUT__ <<
"Found landing page "
541 <<
" for " << icon.recordUID_
544 if(parameterPairSplit[0] ==
"SetupType")
548 parameterPairSplit[1]);
550 __COUT__ <<
"Found setup_ots.sh type "
551 << remoteSetupType <<
" for "
552 << icon.recordUID_ << __E__;
559 thisInfo.appInfo.name = icon.recordUID_;
560 thisInfo.appInfo.status =
561 SupervisorInfo::APP_STATUS_UNKNOWN;
562 thisInfo.appInfo.progress = 0;
563 thisInfo.appInfo.detail =
"";
564 thisInfo.appInfo.url =
566 thisInfo.appInfo.class_name =
"Remote Gateway";
567 thisInfo.appInfo.lastStatusTime = time(0);
569 thisInfo.user_data_path_record = icon.alternateText_;
570 thisInfo.parentIconFolderPath = icon.folderPath_;
571 thisInfo.permissionThresholdString =
572 icon.permissionThresholdString_;
573 thisInfo.landingPage = remoteLandingPage;
574 thisInfo.setupType = remoteSetupType;
578 tmpCfgMgr.getOtherSubsystemInstanceInfo(
579 thisInfo.user_data_path_record,
580 &thisInfo.instancePath,
581 &thisInfo.instanceHost,
582 &thisInfo.instanceUser,
593 for(; i < remoteApps.size(); ++i)
595 if(thisInfo.appInfo.name ==
596 remoteApps[i].appInfo.name)
601 remoteApps[i].appInfo = thisInfo.appInfo;
602 remoteApps[i].user_data_path_record =
603 thisInfo.user_data_path_record;
604 remoteApps[i].parentIconFolderPath =
605 thisInfo.parentIconFolderPath;
606 remoteApps[i].permissionThresholdString =
607 thisInfo.permissionThresholdString;
608 remoteApps[i].landingPage = thisInfo.landingPage;
609 remoteApps[i].setupType = thisInfo.setupType;
610 remoteApps[i].fullName = thisInfo.fullName;
611 remoteApps[i].instancePath =
612 thisInfo.instancePath;
613 remoteApps[i].instanceHost =
614 thisInfo.instanceHost;
615 remoteApps[i].instanceUser =
616 thisInfo.instanceUser;
623 remoteApps.push_back(thisInfo);
628 __COUTTV__(remoteApps[i].fsmName);
629 remoteApps[i].config_aliases =
632 .user_data_path_record);
634 thisInfo.config_aliases));
638 remoteApps[i].selected_config_alias =
639 *(remoteApps[i].config_aliases.begin());
641 catch(
const std::runtime_error& e)
644 <<
"Failed to retrieve the list of Configuration "
645 "Aliases for Remote Subsystem '"
646 << remoteApps[i].appInfo.name
647 <<
".' Remote Subsystems are specified through "
648 "their Desktop Icon record. "
649 "Please specify a valid User Data Path record "
650 "as the Desktop Icon AlternateText field, "
651 "targeting a UID in the "
652 "SubsystemUserDataPathsTable."
654 ss <<
"\n\nHere was the error: " << e.what() << __E__;
655 __COUT__ << ss.str();
656 remoteApps[i].error = ss.str();
660 __COUTV__(remoteApps[i].error);
662 std::lock_guard<std::mutex> lock(
663 theSupervisor->remoteGatewayAppsMutex_);
665 i < theSupervisor->remoteGatewayApps_.size();
667 if(remoteApps[i].appInfo.name ==
668 theSupervisor->remoteGatewayApps_[i]
671 theSupervisor->remoteGatewayApps_[i]
672 .error = remoteApps[i].error;
683 bool remoteAppsExist =
false;
684 for(
size_t i = 0; i < remoteApps.size(); ++i)
686 if(remoteApps[i].appInfo.status ==
"")
689 remoteApps.erase(remoteApps.begin() + i);
693 remoteAppsExist = remoteApps.size();
695 if(remoteAppsExist &&
696 !remoteGatewaySocket)
699 <<
"Instantiating Remote Gateway App Status Socket!"
702 theSupervisor->CorePropertySupervisorBase::
getSupervisorTableNode();
703 ipAddressForStateChangesOverUDP =
704 configLinkNode.
getNode(
"IPAddressForStateChangesOverUDP")
706 __COUTTV__(ipAddressForStateChangesOverUDP);
710 WebUsers::SECURITY_TYPE_DIGEST_ACCESS)
712 bool enableLoginVerify =
714 .
getNode(
"EnableAckForStateChangesOverUDP")
717 if(enableLoginVerify)
719 portForReverseLoginOverUDP =
721 .
getNode(
"PortForStateChangesOverUDP")
723 if(portForReverseLoginOverUDP)
725 <<
"Enabling reverse login verification for "
726 "Remote Gateways at "
727 << ipAddressForStateChangesOverUDP <<
":"
728 << portForReverseLoginOverUDP << __E__;
733 <<
"Remote login verification at this Gateway, "
734 "for other Remote Gateways, is not enabled "
735 "unless the GatewaySupervisor has "
736 "'EnableStateChangesOverUDP' enabled."
740 remoteGatewaySocket = std::make_unique<TransceiverSocket>(
741 ipAddressForStateChangesOverUDP);
742 remoteGatewaySocket->initialize();
748 if(loopCount % 3 == 0 ||
749 resetRemoteGatewayApps ||
750 commandingRemoteGatewayApps)
752 if(theSupervisor->remoteGatewayApps_.size())
753 __COUTVS__(38, theSupervisor->remoteGatewayApps_[0].error);
756 bool commandSent =
false;
758 for(
auto& remoteGatewayApp : remoteApps)
759 if(remoteGatewayApp.command !=
"")
761 GatewaySupervisor::SendRemoteGatewayCommand(
762 remoteGatewayApp, remoteGatewaySocket);
763 if(remoteGatewayApp.error ==
"")
765 remoteGatewayApp.ignoreStatusCount =
772 __COUT__ <<
"remoteGatewayApp "
773 << remoteGatewayApp.appInfo.name
774 <<
" error: " << remoteGatewayApp.error
777 std::lock_guard<std::mutex> lock(
778 theSupervisor->remoteGatewayAppsMutex_);
780 i < theSupervisor->remoteGatewayApps_.size();
782 if(remoteGatewayApp.appInfo.name ==
783 theSupervisor->remoteGatewayApps_[i]
786 theSupervisor->remoteGatewayApps_[i].error =
787 remoteGatewayApp.error;
795 commandRemoteIdleCount = 0;
799 if(theSupervisor->remoteGatewayApps_.size())
800 __COUTVS__(38, theSupervisor->remoteGatewayApps_[0].error);
803 bool allAppsAreIdle =
true;
804 bool allApssAreUnknown =
true;
805 for(
auto& remoteGatewayApp : remoteApps)
807 GatewaySupervisor::CheckRemoteGatewayStatus(
810 ipAddressForStateChangesOverUDP,
811 portForReverseLoginOverUDP);
812 if(remoteGatewayApp.appInfo.status !=
813 SupervisorInfo::APP_STATUS_UNKNOWN)
815 allApssAreUnknown =
false;
816 if(!appLastStatusGood[remoteGatewayApp.appInfo.url +
817 remoteGatewayApp.appInfo.name])
820 <<
"First good status from "
821 <<
" Remote subapp = '"
822 << remoteGatewayApp.appInfo.name
823 <<
"' [URL=" << remoteGatewayApp.appInfo.url
826 appLastStatusGood[remoteGatewayApp.appInfo.url +
827 remoteGatewayApp.appInfo.name] =
true;
829 if(!(remoteGatewayApp.appInfo.progress ==
831 remoteGatewayApp.appInfo.progress == 100 ||
832 remoteGatewayApp.appInfo.status.find(
"Error") !=
835 remoteGatewayApp.appInfo.status.find(
"Fail") !=
839 << remoteGatewayApp.appInfo.name <<
" not idle: "
840 << remoteGatewayApp.appInfo.status
842 << remoteGatewayApp.appInfo.progress << __E__;
843 allAppsAreIdle =
false;
847 remoteGatewayApp.ignoreStatusCount =
851 if(allApssAreUnknown)
853 for(
auto& remoteGatewayApp : remoteApps)
854 remoteGatewayApp.ignoreStatusCount =
858 if(commandingRemoteGatewayApps && allAppsAreIdle)
860 ++commandRemoteIdleCount;
861 if(commandRemoteIdleCount >= 3)
863 __COUTT__ <<
"Back to idle statusing" << __E__;
864 commandingRemoteGatewayApps =
false;
868 __COUT_TYPE__(TLVL_DEBUG + 38)
869 << __COUT_HDR__ <<
"commandRemoteIdleCount "
870 << commandRemoteIdleCount <<
" " << allAppsAreIdle <<
" "
871 << commandingRemoteGatewayApps << __E__;
876 if(resetRemoteGatewayApps)
878 __COUT_TYPE__(TLVL_DEBUG + 35)
880 <<
"Attempting to get Remote Desktop Icons... size="
881 << remoteApps.size() << __E__;
883 for(
auto& remoteGatewayApp : remoteApps)
885 __COUTVS__(35, remoteGatewayApp.appInfo.name);
886 __COUTVS__(35, remoteGatewayApp.command);
887 if(remoteGatewayApp.command !=
"")
890 __COUT_TYPE__(TLVL_DEBUG + 14)
891 << __COUT_HDR__ << remoteGatewayApp.appInfo.name <<
": "
892 << remoteGatewayApp.appInfo.status << __E__;
893 if(remoteGatewayApp.appInfo.status ==
894 SupervisorInfo::APP_STATUS_UNKNOWN)
898 if(remoteGatewayApp.error.find(
"desktop icons") !=
901 __COUTV__(remoteGatewayApp.error);
903 std::lock_guard<std::mutex> lock(
904 theSupervisor->remoteGatewayAppsMutex_);
906 i < theSupervisor->remoteGatewayApps_.size();
908 if(remoteGatewayApp.appInfo.name ==
909 theSupervisor->remoteGatewayApps_[i].appInfo.name)
911 theSupervisor->remoteGatewayApps_[i].error =
"";
913 theSupervisor->remoteGatewayApps_[i].error);
916 remoteGatewayApp.error =
"";
919 if(remoteGatewayApp.error ==
922 GatewaySupervisor::GetRemoteGatewayIcons(
923 remoteGatewayApp, remoteGatewaySocket);
924 if(remoteGatewayApp.error !=
927 __COUTV__(remoteGatewayApp.error);
929 std::lock_guard<std::mutex> lock(
930 theSupervisor->remoteGatewayAppsMutex_);
932 i < theSupervisor->remoteGatewayApps_.size();
934 if(remoteGatewayApp.appInfo.name ==
935 theSupervisor->remoteGatewayApps_[i]
938 theSupervisor->remoteGatewayApps_[i].error =
939 remoteGatewayApp.error;
949 if(loopCount % 3 == 0 ||
950 resetRemoteGatewayApps ||
951 commandingRemoteGatewayApps)
953 if(theSupervisor->remoteGatewayApps_.size())
954 __COUTVS__(37, theSupervisor->remoteGatewayApps_[0].error);
959 std::lock_guard<std::mutex> lock(
960 theSupervisor->remoteGatewayAppsMutex_);
962 !commandingRemoteGatewayApps &&
963 i < theSupervisor->remoteGatewayApps_.size();
967 theSupervisor->remoteGatewayApps_[i].command);
968 if(theSupervisor->remoteGatewayApps_[i].command ==
970 theSupervisor->remoteGatewayApps_[i].appInfo.status =
974 for(
auto& remoteGatewayApp : remoteApps)
978 i < theSupervisor->remoteGatewayApps_.size();
981 if(remoteGatewayApp.appInfo.name ==
982 theSupervisor->remoteGatewayApps_[i].appInfo.name)
987 if(remoteGatewayApp.command ==
989 theSupervisor->remoteGatewayApps_[i].error =
990 remoteGatewayApp.error;
992 theSupervisor->remoteGatewayApps_[i]
994 remoteGatewayApp.ignoreStatusCount;
995 theSupervisor->remoteGatewayApps_[i]
997 remoteGatewayApp.consoleErrCount;
998 theSupervisor->remoteGatewayApps_[i]
1000 remoteGatewayApp.consoleWarnCount;
1002 theSupervisor->remoteGatewayApps_[i]
1004 remoteGatewayApp.usernameWithLock;
1006 theSupervisor->remoteGatewayApps_[i].config_dump =
1007 remoteGatewayApp.config_dump;
1009 theSupervisor->remoteGatewayApps_[i]
1010 .user_data_path_record =
1011 remoteGatewayApp.user_data_path_record;
1012 theSupervisor->remoteGatewayApps_[i].iconString =
1013 remoteGatewayApp.iconString;
1014 theSupervisor->remoteGatewayApps_[i]
1015 .parentIconFolderPath =
1016 remoteGatewayApp.parentIconFolderPath;
1017 theSupervisor->remoteGatewayApps_[i]
1018 .permissionThresholdString =
1019 remoteGatewayApp.permissionThresholdString;
1020 theSupervisor->remoteGatewayApps_[i].landingPage =
1021 remoteGatewayApp.landingPage;
1022 theSupervisor->remoteGatewayApps_[i].setupType =
1023 remoteGatewayApp.setupType;
1024 theSupervisor->remoteGatewayApps_[i].fullName =
1025 remoteGatewayApp.fullName;
1026 theSupervisor->remoteGatewayApps_[i]
1027 .instancePath = remoteGatewayApp.instancePath;
1028 theSupervisor->remoteGatewayApps_[i]
1029 .instanceHost = remoteGatewayApp.instanceHost;
1030 theSupervisor->remoteGatewayApps_[i]
1031 .instanceUser = remoteGatewayApp.instanceUser;
1034 theSupervisor->remoteGatewayApps_[i]
1036 remoteGatewayApp.config_aliases;
1038 if(remoteGatewayApp.config_aliases.find(
1039 theSupervisor->remoteGatewayApps_[i]
1040 .selected_config_alias) ==
1041 remoteGatewayApp.config_aliases.end())
1042 theSupervisor->remoteGatewayApps_[i]
1043 .selected_config_alias =
1044 remoteGatewayApp.selected_config_alias;
1046 __COUTTV__(theSupervisor->remoteGatewayApps_[i]
1047 .selected_config_alias);
1050 << remoteGatewayApp.appInfo.name
1051 <<
" -- Command: " << remoteGatewayApp.command
1053 << theSupervisor->remoteGatewayApps_[i]
1056 << remoteGatewayApp.appInfo.status
1058 << theSupervisor->remoteGatewayApps_[i]
1060 <<
" Error: " << remoteGatewayApp.error
1062 << remoteGatewayApp.appInfo.progress << __E__;
1064 if(remoteGatewayApp.command ==
1066 theSupervisor->remoteGatewayApps_[i].command =
1069 if(theSupervisor->remoteGatewayApps_[i].command !=
1071 (commandingRemoteGatewayApps &&
1072 theSupervisor->remoteGatewayApps_[i]
1073 .appInfo.status.find(
"Launching") ==
1075 remoteGatewayApp.appInfo.progress ==
1077 __COUT__ <<
"Ignoring '"
1078 << remoteGatewayApp.appInfo.name
1079 <<
"' assumed stale status: "
1080 << remoteGatewayApp.appInfo.status
1083 theSupervisor->remoteGatewayApps_[i].appInfo =
1084 remoteGatewayApp.appInfo;
1086 theSupervisor->remoteGatewayApps_[i].subapps =
1087 remoteGatewayApp.subapps;
1092 theSupervisor->remoteGatewayApps_.push_back(
1098 i < theSupervisor->remoteGatewayApps_.size();
1101 if(theSupervisor->remoteGatewayApps_[i].appInfo.status ==
1105 theSupervisor->remoteGatewayApps_.erase(
1106 theSupervisor->remoteGatewayApps_.begin() + i);
1112 if(theSupervisor->remoteGatewayApps_.size())
1113 __COUTVS__(38, theSupervisor->remoteGatewayApps_[0].error);
1118 std::lock_guard<std::mutex> lock(
1119 theSupervisor->remoteGatewayAppsMutex_);
1120 for(
const auto& remoteGatewayApp :
1121 theSupervisor->remoteGatewayApps_)
1122 subapps.push_back(remoteGatewayApp.appInfo);
1125 resetRemoteGatewayApps =
false;
1127 catch(
const std::runtime_error& e)
1129 status = SupervisorInfo::APP_STATUS_UNKNOWN;
1131 detail =
"SOAP Message Error";
1132 oneStatusReqHasFailed =
true;
1134 __COUT__ <<
"Failed getting status from Gateway"
1135 <<
" Supervisor instance = '" << appName
1136 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1137 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
1139 __COUT_WARN__ <<
"Failed to retrieve Gateway Supervisor status. Here "
1141 << e.what() << __E__;
1145 status = SupervisorInfo::APP_STATUS_UNKNOWN;
1147 detail =
"Unknown SOAP Message Error";
1148 oneStatusReqHasFailed =
true;
1150 __COUT__ <<
"Failed getting status from Gateway "
1151 <<
" Supervisor instance = '" << appName
1152 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1153 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
1155 __COUT_WARN__ <<
"Failed to retrieve Gateway Supervisor status to "
1164 appPointer.addParameter(
"ApplicationPointer");
1166 xoap::MessageReference tempMessage =
1167 SOAPUtilities::makeSOAPMessageReference(
"ApplicationStatusRequest");
1169 __COUT_TYPE__(TLVL_DEBUG + 39)
1170 << __COUT_HDR__ <<
"tempMessage... "
1171 << SOAPUtilities::translate(tempMessage) << std::endl;
1175 xoap::MessageReference statusMessage =
1176 theSupervisor->sendWithSOAPReply(appInfo.getDescriptor(),
1179 if(
"ContextARTDAQ" == appInfo.getContextName())
1180 __COUT_TYPE__(TLVL_DEBUG + 41)
1181 << __COUT_HDR__ <<
" Supervisor instance = '" << appName
1182 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1183 << appInfo.getContextName() <<
" statusMessage... "
1184 << SOAPUtilities::translate(statusMessage) << std::endl;
1186 __COUT_TYPE__(TLVL_DEBUG + 40)
1187 << __COUT_HDR__ <<
" Supervisor instance = '" << appName
1188 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1189 << appInfo.getContextName() <<
" statusMessage... "
1190 << SOAPUtilities::translate(statusMessage) << std::endl;
1193 parameters.addParameter(
"Status");
1194 parameters.addParameter(
"Progress");
1195 parameters.addParameter(
"Detail");
1196 parameters.addParameter(
"Subapps");
1197 SOAPUtilities::receive(statusMessage, parameters);
1199 status = parameters.getValue(
"Status");
1201 status = SupervisorInfo::APP_STATUS_UNKNOWN;
1203 progress = parameters.getValue(
"Progress");
1204 if(progress.empty())
1207 detail = parameters.getValue(
"Detail");
1208 if(appInfo.isTypeConsoleSupervisor())
1217 std::vector<std::string> parseDetail =
1220 __COUTVS__(50, detail);
1221 __COUTVS__(50, parseDetail.size());
1224 std::lock_guard<std::mutex> lock(
1225 theSupervisor->systemStatusMutex_);
1226 if(parseDetail.size() > 1)
1227 theSupervisor->systemConsoleErrCount_ =
1229 .substr(parseDetail[1].find(
':') + 1)
1231 if(parseDetail.size() > 2)
1232 theSupervisor->systemConsoleWarnCount_ =
1234 .substr(parseDetail[2].find(
':') + 1)
1236 __COUTVS__(36, theSupervisor->systemConsoleErrCount_);
1237 __COUTVS__(36, theSupervisor->systemConsoleWarnCount_);
1238 if(parseDetail.size() >
1241 size_t closeTimePos = parseDetail[3].find(
')');
1242 __COUTVS__(36, closeTimePos);
1243 theSupervisor->lastConsoleErr_ =
1244 parseDetail[3].substr(closeTimePos + 2);
1245 size_t openTimePos = parseDetail[3].find(
'(');
1246 __COUTVS__(36, openTimePos);
1247 theSupervisor->lastConsoleErrTime_ = parseDetail[3].substr(
1248 openTimePos, closeTimePos - openTimePos + 1);
1249 __COUTVS__(36, theSupervisor->lastConsoleErrTime_);
1251 if(parseDetail.size() >
1254 size_t closeTimePos = parseDetail[4].find(
')');
1255 theSupervisor->lastConsoleWarn_ =
1256 parseDetail[4].substr(closeTimePos + 2);
1257 size_t openTimePos = parseDetail[4].find(
'(');
1258 theSupervisor->lastConsoleWarnTime_ = parseDetail[4].substr(
1259 openTimePos, closeTimePos - openTimePos + 1);
1260 __COUTVS__(36, theSupervisor->lastConsoleWarnTime_);
1262 if(parseDetail.size() >
1265 size_t closeTimePos = parseDetail[5].find(
')');
1266 theSupervisor->lastConsoleInfo_ =
1267 parseDetail[5].substr(closeTimePos + 2);
1268 size_t openTimePos = parseDetail[5].find(
'(');
1269 theSupervisor->lastConsoleInfoTime_ = parseDetail[5].substr(
1270 openTimePos, closeTimePos - openTimePos + 1);
1271 __COUTVS__(36, theSupervisor->lastConsoleInfoTime_);
1273 if(parseDetail.size() > 6)
1274 theSupervisor->systemConsoleInfoCount_ =
1276 .substr(parseDetail[6].find(
':') + 1)
1279 if(parseDetail.size() >
1282 size_t closeTimePos = parseDetail[7].find(
')');
1283 theSupervisor->firstConsoleErr_ =
1284 parseDetail[7].substr(closeTimePos + 2);
1285 size_t openTimePos = parseDetail[7].find(
'(');
1286 theSupervisor->firstConsoleErrTime_ = parseDetail[7].substr(
1287 openTimePos, closeTimePos - openTimePos + 1);
1288 __COUTVS__(36, theSupervisor->firstConsoleErrTime_);
1290 if(parseDetail.size() >
1293 size_t closeTimePos = parseDetail[8].find(
')');
1294 theSupervisor->firstConsoleWarn_ =
1295 parseDetail[8].substr(closeTimePos + 2);
1296 size_t openTimePos = parseDetail[8].find(
'(');
1297 theSupervisor->firstConsoleWarnTime_ = parseDetail[8].substr(
1298 openTimePos, closeTimePos - openTimePos + 1);
1299 __COUTVS__(36, theSupervisor->firstConsoleWarnTime_);
1301 if(parseDetail.size() >
1304 size_t closeTimePos = parseDetail[9].find(
')');
1305 theSupervisor->firstConsoleInfo_ =
1306 parseDetail[9].substr(closeTimePos + 2);
1307 size_t openTimePos = parseDetail[9].find(
'(');
1308 theSupervisor->firstConsoleInfoTime_ = parseDetail[9].substr(
1309 openTimePos, closeTimePos - openTimePos + 1);
1310 __COUTVS__(36, theSupervisor->firstConsoleInfoTime_);
1314 subapps = SupervisorInfo::deserializeSubappInfos(
1315 parameters.getValue(
"Subapps"));
1317 if(!appLastStatusGood[appName])
1319 __COUT_INFO__ <<
"First good status from "
1320 <<
" Supervisor instance = '" << appName
1321 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1322 << appInfo.getContextName()
1323 <<
"' [URL=" << appInfo.getURL() <<
"].\n\n";
1324 __COUTTV__(SOAPUtilities::translate(tempMessage));
1326 appLastStatusGood[appName] =
true;
1328 catch(
const xdaq::exception::Exception& e)
1330 status = SupervisorInfo::APP_STATUS_UNKNOWN;
1332 detail =
"SOAP Message Error";
1333 oneStatusReqHasFailed =
true;
1339 if(appLastStatusGood[appName])
1341 __COUT__ <<
"Failed getting status from "
1342 <<
" Supervisor instance = '" << appName
1343 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1344 << appInfo.getContextName()
1345 <<
"' [URL=" << appInfo.getURL() <<
"].\n\n";
1346 __COUTTV__(SOAPUtilities::translate(tempMessage));
1347 __COUT_WARN__ <<
"Failed to send getStatus SOAP Message - will "
1348 "suppress repeat errors: "
1349 << e.what() << __E__;
1353 std::lock_guard<std::mutex> lock(
1354 theSupervisor->stateMachineAccessMutex_);
1356 std::string currentState =
1357 theSupervisor->theStateMachine_.getCurrentStateName();
1358 if(currentState != RunControlStateMachine::FAILED_STATE_NAME &&
1359 currentState != RunControlStateMachine::HALTED_STATE_NAME &&
1360 currentState != RunControlStateMachine::INITIAL_STATE_NAME)
1363 <<
"\nDid a supervisor crash? Failed getting status from "
1364 <<
" Supervisor instance = '" << appName
1365 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1366 << appInfo.getContextName()
1367 <<
"' [URL=" << appInfo.getURL() <<
"]." << __E__;
1368 __COUT_ERR__ <<
"\n" << ss.str();
1372 if(!appInfo.isTypeConsoleSupervisor())
1374 theSupervisor->theStateMachine_.setErrorMessage(ss.str());
1378 SOAPUtilities::makeSOAPMessageReference(
1380 ERROR_TRANSITION_NAME));
1388 <<
"Ignoring that Console type supervisor crashed."
1394 appLastStatusGood[appName] =
false;
1402 catch(
const std::runtime_error& e)
1404 __COUT_ERR__ <<
"Exception of type runtime_error message: "
1407 catch(
const std::exception& e)
1409 __COUT_ERR__ <<
"Exception of type " <<
typeid(e).name()
1410 <<
" message: " << e.what();
1416 status = SupervisorInfo::APP_STATUS_UNKNOWN;
1418 detail =
"Unknown SOAP Message Error";
1419 oneStatusReqHasFailed =
true;
1425 if(appLastStatusGood[appName])
1427 __COUT__ <<
"Failed getting status from "
1428 <<
" Supervisor instance = '" << appName
1429 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1430 << appInfo.getContextName()
1431 <<
"' [URL=" << appInfo.getURL() <<
"].\n\n";
1432 __COUTV__(SOAPUtilities::translate(tempMessage));
1433 __COUT_WARN__ <<
"Failed to send getStatus SOAP Message due to "
1434 "unknown error. Will suppress repeat errors "
1435 "from Supervisor instance = '"
1436 << appName <<
"' [LID=" << appInfo.getId()
1437 <<
"] in Context '" << appInfo.getContextName()
1438 <<
"' [URL=" << appInfo.getURL() <<
"]." << __E__;
1442 std::lock_guard<std::mutex> lock(
1443 theSupervisor->stateMachineAccessMutex_);
1445 std::string currentState =
1446 theSupervisor->theStateMachine_.getCurrentStateName();
1447 if(currentState != RunControlStateMachine::FAILED_STATE_NAME &&
1448 currentState != RunControlStateMachine::HALTED_STATE_NAME &&
1449 currentState != RunControlStateMachine::INITIAL_STATE_NAME)
1451 __SS__ <<
"\nDid a supervisor crash? Failed getting Status "
1452 <<
" Supervisor instance = '" << appName
1453 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
1454 << appInfo.getContextName()
1455 <<
"' [URL=" << appInfo.getURL() <<
"]." << __E__;
1456 __COUT_ERR__ <<
"\n" << ss.str();
1458 theSupervisor->theStateMachine_.setErrorMessage(ss.str());
1462 SOAPUtilities::makeSOAPMessageReference(
1463 RunControlStateMachine::ERROR_TRANSITION_NAME));
1472 appLastStatusGood[appName] =
false;
1476 __COUTVS__(38, status);
1477 __COUTVS__(38, progress);
1482 std::istringstream ssProgress(progress);
1483 ssProgress >> progressInteger;
1485 if(
"ContextARTDAQ" == appInfo.getContextName())
1486 __COUTVS__(41, progressInteger);
1488 __COUTVS__(40, progressInteger);
1491 appInfo, status, progressInteger, detail, subapps);
1495 if(oneStatusReqHasFailed)
1497 __COUTT__ <<
"oneStatusReqHasFailed" << __E__;
1507 void GatewaySupervisor::GetRemoteGatewayIcons(
1508 GatewaySupervisor::RemoteGatewayInfo& remoteGatewayApp,
1509 const std::unique_ptr<TransceiverSocket>&
1510 remoteGatewaySocket)
1523 std::string iconString =
"";
1525 std::string command =
"GetRemoteDesktopIcons";
1527 __COUTT__ <<
"Sending remote gateway command '" << command <<
"' to target '"
1528 << remoteGatewayApp.appInfo.name
1529 <<
"' at url: " << remoteGatewayApp.appInfo.url << __E__;
1533 std::vector<std::string> parsedFields =
1536 __COUTVS__(10, command);
1538 Socket gatewayRemoteSocket(parsedFields[1], atoi(parsedFields[2].c_str()));
1539 std::string remoteIconString = remoteGatewaySocket->sendAndReceive(
1540 gatewayRemoteSocket, command, 10 );
1541 __COUTVS__(10, remoteIconString);
1543 bool firstIcon =
true;
1547 remoteIconString +
",",
1549 const size_t numOfIconFields = 7;
1550 for(
size_t i = 0; i + numOfIconFields < remoteIconsCSV.size();
1551 i += numOfIconFields)
1558 __COUTVS__(10, remoteIconsCSV[i + 0]);
1559 if(remoteGatewayApp.parentIconFolderPath ==
1562 remoteGatewayApp.user_data_path_record
1563 +
" " + remoteIconsCSV[i + 0];
1565 iconString += remoteIconsCSV[i + 0];
1566 iconString +=
"," + remoteIconsCSV[i + 1];
1571 iconString +=
"," + std::string(
"1");
1575 iconString +=
"," + remoteIconsCSV[i + 4];
1576 iconString +=
"," + remoteIconsCSV[i + 5];
1578 iconString +=
"," + remoteGatewayApp.parentIconFolderPath
1579 +
"/" + remoteIconsCSV[i + 6];
1584 catch(
const std::runtime_error& e)
1586 __SS__ <<
"Failure gathering Remote Gateway desktop icons with command '"
1587 << command <<
"' from target '" << remoteGatewayApp.appInfo.name
1588 <<
"' at url: " << remoteGatewayApp.appInfo.url
1589 <<
" due to error: " << e.what() << __E__;
1590 __COUT_ERR__ << ss.str();
1591 remoteGatewayApp.error = ss.str();
1595 __COUTV__(iconString);
1596 remoteGatewayApp.iconString = iconString;
1603 void GatewaySupervisor::SendRemoteGatewayCommand(
1604 GatewaySupervisor::RemoteGatewayInfo& remoteGatewayApp,
1605 const std::unique_ptr<TransceiverSocket>&
1606 remoteGatewaySocket)
1608 remoteGatewayApp.error =
"";
1610 __COUT__ <<
"Sending remote gateway command '" << remoteGatewayApp.command
1611 <<
"' to target '" << remoteGatewayApp.appInfo.name
1612 <<
"' at url: " << remoteGatewayApp.appInfo.url << __E__;
1614 std::string tmpCommand = remoteGatewayApp.command;
1617 std::string command;
1620 if(remoteGatewayApp.command ==
"ResetConsoleCounts")
1621 command =
"ResetConsoleCounts";
1623 command = remoteGatewayApp.fsmName +
"," + remoteGatewayApp.command;
1625 remoteGatewayApp.command =
"Sent";
1626 if(tmpCommand ==
"Reboot")
1628 __COUT__ <<
"Reboot command handled by ots script command." << __E__;
1633 std::vector<std::string> parsedFields =
1636 __COUT__ <<
"Sending to subsystem '" << remoteGatewayApp.appInfo.name
1637 <<
"' the command: " << command << __E__;
1639 Socket gatewayRemoteSocket(parsedFields[1], atoi(parsedFields[2].c_str()));
1640 std::string commandResponseString = remoteGatewaySocket->sendAndReceive(
1641 gatewayRemoteSocket, command, 10 );
1642 __COUT__ <<
"Response from subsystem '" << remoteGatewayApp.appInfo.name
1643 <<
"' received: " << commandResponseString << __E__;
1645 if(commandResponseString.find(
"Done") != 0)
1647 __SS__ <<
"Unsuccessful response received from Remote Gateway '"
1648 << remoteGatewayApp.appInfo.name +
"' - here was the response: "
1649 << commandResponseString << __E__;
1653 if(commandResponseString.size() > strlen(
"Done") + 1)
1656 remoteGatewayApp.config_dump =
"\n\n************************\n";
1657 remoteGatewayApp.config_dump +=
1658 "* Remote Subsystem Dump from '" + remoteGatewayApp.appInfo.name +
1659 "' at url: " + remoteGatewayApp.appInfo.url +
"\n";
1660 remoteGatewayApp.config_dump +=
"* \n";
1661 remoteGatewayApp.config_dump +=
"\n\n";
1662 remoteGatewayApp.config_dump +=
1663 commandResponseString.substr(strlen(
"Done") + 1);
1665 __COUTTV__(remoteGatewayApp.config_dump);
1669 catch(
const std::runtime_error& e)
1671 __SS__ <<
"Failure sending Remote Gateway App '" << remoteGatewayApp.appInfo.name
1672 <<
"' the command '"
1673 << (tmpCommand.size() > 30 ? tmpCommand.substr(0, 30) : tmpCommand)
1674 <<
"' at url: " << remoteGatewayApp.appInfo.url
1675 <<
" due to error: " << e.what() << __E__;
1676 __COUT_ERR__ << ss.str();
1677 remoteGatewayApp.error = ss.str();
1686 void GatewaySupervisor::CheckRemoteGatewayStatus(
1687 GatewaySupervisor::RemoteGatewayInfo& remoteGatewayApp,
1688 const std::unique_ptr<TransceiverSocket>&
1689 remoteGatewaySocket,
1690 const std::string& ipForReverseLoginOverUDP,
1691 int portForReverseLoginOverUDP)
1694 __COUTT__ <<
"Checking remote gateway status of '" << remoteGatewayApp.appInfo.name
1696 std::vector<std::string> parsedFields =
1700 if(parsedFields.size() == 3)
1702 Socket gatewayRemoteSocket(parsedFields[1], atoi(parsedFields[2].c_str()));
1703 std::string requestString =
"GetRemoteGatewayStatus";
1704 if(portForReverseLoginOverUDP)
1705 requestString +=
"," + ipForReverseLoginOverUDP +
"," +
1706 std::to_string(portForReverseLoginOverUDP) +
"," +
1707 remoteGatewayApp.appInfo.name;
1708 __COUT_TYPE__(TLVL_DEBUG + 24)
1709 << __COUT_HDR__ <<
"requestString = " << requestString << __E__;
1710 std::string remoteStatusString = remoteGatewaySocket->sendAndReceive(
1711 gatewayRemoteSocket, requestString, 2 );
1712 __COUT_TYPE__(TLVL_DEBUG + 24)
1713 << __COUT_HDR__ <<
"remoteStatusString = " << remoteStatusString << __E__;
1715 std::string value, name;
1716 bool foundGateway =
false;
1719 remoteStatusString,
"name", 0, after, &after)) !=
"")
1721 after += std::string(
"name").size();
1725 if(value == XDAQContextTable::GATEWAY_SUPERVISOR_CLASS)
1727 foundGateway =
true;
1730 __COUTVS__(25, remoteStatusString.size());
1731 __COUTVS__(25, after);
1732 __COUTVS__(25, value);
1737 __COUTVS__(25, value);
1738 remoteGatewayApp.appInfo.status = value;
1741 remoteStatusString,
"progress", 0, after);
1742 __COUTVS__(25, value);
1743 remoteGatewayApp.appInfo.progress = atoi(value.c_str());
1747 __COUTVS__(25, value);
1748 remoteGatewayApp.appInfo.detail =
1753 __COUTVS__(25, value);
1754 remoteGatewayApp.appInfo.lastStatusTime = atoi(value.c_str());
1758 __COUTVS__(25, value);
1759 remoteGatewayApp.appInfo.parent_url = value;
1762 __COUTVS__(25, value);
1763 remoteGatewayApp.appInfo.id = atoi(value.c_str());
1769 remoteGatewayApp.subapps[name].class_name = value;
1770 __COUTVS__(25, value);
1775 __COUTVS__(25, value);
1776 remoteGatewayApp.subapps[name].status = value;
1779 remoteStatusString,
"progress", 0, after);
1780 __COUTVS__(25, value);
1781 remoteGatewayApp.subapps[name].progress = atoi(value.c_str());
1785 __COUTVS__(25, value);
1786 remoteGatewayApp.subapps[name].detail =
1791 __COUTVS__(25, value);
1792 remoteGatewayApp.subapps[name].lastStatusTime = atoi(value.c_str());
1796 __COUTVS__(25, value);
1797 remoteGatewayApp.subapps[name].parent_url = value;
1800 __COUTVS__(25, value);
1801 remoteGatewayApp.subapps[name].id = atoi(value.c_str());
1807 __SS__ <<
"Failure encountered while checking remote gateway status of '"
1808 << remoteGatewayApp.appInfo.name
1809 <<
"' - no Gateway app status reported!" << __E__;
1815 remoteStatusString,
"systemMessages", 0, after, &after);
1816 __COUT_TYPE__(TLVL_DEBUG + 2)
1817 << __COUT_HDR__ <<
"Remote System Messages:" << value << __E__;
1818 std::vector<std::string> parsedSysMsgs;
1822 for(
size_t i = 0; i + 2 < parsedSysMsgs.size(); i += 3)
1824 GatewaySupervisor::addSystemMessage(
1826 "Remote System Message from '" + remoteGatewayApp.appInfo.name +
1827 "' at url: " + remoteGatewayApp.appInfo.url +
" ... " +
1833 remoteStatusString,
"usernameWithLock", 0, after, &after);
1834 __COUT_TYPE__(TLVL_DEBUG + 2)
1835 << __COUT_HDR__ <<
"Remote User with Lock:" << value << __E__;
1836 remoteGatewayApp.usernameWithLock = value;
1840 remoteStatusString,
"console_err_count", 0, after, &after);
1841 __COUTVS__(25, value);
1842 remoteGatewayApp.consoleErrCount = atoi(value.c_str());
1845 remoteStatusString,
"console_warn_count", 0, after);
1846 __COUTVS__(25, value);
1847 remoteGatewayApp.consoleWarnCount = atoi(value.c_str());
1850 __COUT_WARN__ <<
"Illegal Remote Gateawy App URL (must be ots:<IP>:<PORT>): "
1851 << remoteGatewayApp.appInfo.url << __E__;
1853 catch(
const std::runtime_error& e)
1855 __COUT_WARN__ <<
"Failure getting Remote Gateway App status of '"
1856 << remoteGatewayApp.appInfo.name
1857 <<
"' at url: " << remoteGatewayApp.appInfo.url
1858 <<
" due to error: " << e.what() << __E__;
1860 remoteGatewayApp.appInfo.status = SupervisorInfo::APP_STATUS_UNKNOWN;
1861 remoteGatewayApp.appInfo.progress = 0;
1862 remoteGatewayApp.appInfo.detail =
"Unknown UDP Message Error";
1863 remoteGatewayApp.appInfo.lastStatusTime = time(0);
1872 theSupervisor->CorePropertySupervisorBase::getSupervisorTableNode();
1874 std::string ipAddressForStateChangesOverUDP =
1875 configLinkNode.
getNode(
"IPAddressForStateChangesOverUDP").
getValue<std::string>();
1876 int portForStateChangesOverUDP =
1878 bool acknowledgementEnabled =
1879 configLinkNode.
getNode(
"EnableAckForStateChangesOverUDP").
getValue<
bool>();
1880 bool enableStateChanges =
1883 __COUTV__(ipAddressForStateChangesOverUDP);
1884 __COUTV__(portForStateChangesOverUDP);
1885 __COUTV__(acknowledgementEnabled);
1886 __COUTV__(enableStateChanges);
1889 portForStateChangesOverUDP);
1897 __SS__ <<
"FATAL Console error. Could not initialize socket at ip '"
1898 << ipAddressForStateChangesOverUDP <<
"' and port "
1899 << portForStateChangesOverUDP
1900 <<
". Perhaps it is already in use? Exiting State Changer "
1901 "SOAPUtilities::receive loop."
1907 std::size_t commaPosition;
1908 unsigned int commaCounter = 0;
1909 std::size_t begin = 0;
1911 std::string errorStr;
1912 std::string fsmName;
1913 std::string command;
1914 std::vector<std::string> parameters;
1924 buffer, 0 , 1 ,
false ) !=
1927 __COUT_TYPE__(TLVL_DEBUG + 9)
1928 << __COUT_HDR__ <<
"UDP State Changer packet received from ip:port "
1929 << sock.getLastIncomingIPAddress() <<
":" << sock.getLastIncomingPort()
1930 <<
" of size = " << buffer.size() << __E__;
1931 __COUTVS__(11, buffer);
1935 bool remoteGatewayStatus = buffer.find(
"GetRemoteGatewayStatus") == 0;
1936 if(remoteGatewayStatus || buffer ==
"GetRemoteAppStatus")
1938 __COUT_TYPE__(TLVL_DEBUG + 12)
1939 <<
"Giving app status to remote monitor..." << __E__;
1941 if(remoteGatewayStatus &&
1942 buffer.size() > strlen(
"GetRemoteGatewayStatus") + 1)
1944 std::vector<std::string> params =
1946 if(params.size() == 4)
1953 std::string tmpIP = params[1];
1954 int tmpPort = atoi(params[2].c_str());
1956 if(!theSupervisor->theWebUsers_
1958 theSupervisor->theWebUsers_.remoteLoginVerificationIP_ !=
1963 theSupervisor->theWebUsers_.remoteLoginVerificationIP_ =
1969 theSupervisor->theWebUsers_
1975 <<
"' is now under remote control and will validate "
1976 "logins through remote Gateway Supervisor at "
1977 << theSupervisor->theWebUsers_
1978 .remoteLoginVerificationIP_
1980 << theSupervisor->theWebUsers_
1986 __COUT_ERR__ <<
"Parameter count is not 4, it is "
1987 << params.size() << __E__;
1991 for(
const auto& it :
1994 const auto& appInfo = it.second;
1996 remoteGatewayStatus &&
1997 appInfo.getClass() !=
1998 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS)
2001 xmlOut.addTextElementToData(
2004 xmlOut.addTextElementToData(
2005 "id", std::to_string(appInfo.getId()));
2006 xmlOut.addTextElementToData(
"status",
2007 appInfo.getStatus());
2008 xmlOut.addTextElementToData(
2012 .getLastStatusTime()));
2013 xmlOut.addTextElementToData(
2017 appInfo.getLastStatusTime()));
2018 xmlOut.addTextElementToData(
2020 std::to_string(appInfo.getProgress()));
2021 xmlOut.addTextElementToData(
"detail",
2022 appInfo.getDetail());
2023 xmlOut.addTextElementToData(
2025 appInfo.getClass());
2026 xmlOut.addTextElementToData(
2029 xmlOut.addTextElementToData(
2031 appInfo.getContextName());
2032 auto subappElement = xmlOut.addTextElementToData(
"subapps",
"");
2033 for(
auto& subappInfoPair : appInfo.getSubappInfo())
2036 "subapp_name", subappInfoPair.first, subappElement);
2038 subappInfoPair.second.status,
2042 subappInfoPair.second.lastStatusTime
2044 subappInfoPair.second.lastStatusTime)
2049 std::to_string(time(0) -
2050 subappInfoPair.second.lastStatusTime),
2054 std::to_string(subappInfoPair.second.progress),
2057 subappInfoPair.second.detail,
2060 subappInfoPair.second.url,
2064 subappInfoPair.second.class_name,
2069 if(remoteGatewayStatus)
2071 __COUT_TYPE__(TLVL_DEBUG + 12)
2072 <<
"Giving extra Gateway info to remote monitor..." << __E__;
2074 xmlOut.addTextElementToData(
"systemMessages",
2076 xmlOut.addTextElementToData(
"usernameWithLock",
2077 theWebUsers_.getUserWithLock());
2079 std::lock_guard<std::mutex> lock(
2080 theSupervisor->systemStatusMutex_);
2081 xmlOut.addTextElementToData(
2082 "console_err_count",
2083 std::to_string(theSupervisor->systemConsoleErrCount_));
2084 xmlOut.addTextElementToData(
2085 "console_warn_count",
2086 std::to_string(theSupervisor->systemConsoleWarnCount_));
2089 std::stringstream out;
2093 __COUT_TYPE__(TLVL_DEBUG + 23)
2094 << __COUT_HDR__ <<
"App status to monitor: " << out.str()
2096 sock.acknowledge(out.str(),
false );
2099 if(buffer ==
"ResetConsoleCounts")
2101 __COUT__ <<
"Remote request to reset Console Counts..." << __E__;
2105 for(
const auto& it :
2108 const auto& appInfo = it.second;
2109 if(appInfo.isTypeConsoleSupervisor())
2111 xoap::MessageReference tempMessage =
2112 SOAPUtilities::makeSOAPMessageReference(
2113 "ResetConsoleCounts");
2115 theSupervisor->
send(appInfo.getDescriptor(), tempMessage);
2119 __SS__ <<
"Error while resetting console counts of "
2120 "Supervisor instance = '"
2121 << appInfo.getName()
2122 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
2123 << appInfo.getContextName()
2124 <<
"' [URL=" << appInfo.getURL() <<
"].\n\n"
2128 __COUT__ <<
"Reset console counts of Supervisor instance = '"
2129 << appInfo.getName() <<
"' [LID=" << appInfo.getId()
2130 <<
"] in Context '" << appInfo.getContextName()
2131 <<
"' [URL=" << appInfo.getURL() <<
"]." << __E__;
2136 std::lock_guard<std::mutex> lock(
2137 theSupervisor->systemStatusMutex_);
2138 theSupervisor->lastConsoleErrTime_ =
"0";
2139 theSupervisor->lastConsoleErr_ =
"";
2140 theSupervisor->lastConsoleWarnTime_ =
"0";
2141 theSupervisor->lastConsoleWarn_ =
"";
2142 theSupervisor->lastConsoleInfoTime_ =
"0";
2143 theSupervisor->lastConsoleInfo_ =
"";
2144 theSupervisor->firstConsoleErrTime_ =
"0";
2145 theSupervisor->firstConsoleErr_ =
"";
2146 theSupervisor->firstConsoleWarnTime_ =
"0";
2147 theSupervisor->firstConsoleWarn_ =
"";
2148 theSupervisor->firstConsoleInfoTime_ =
"0";
2149 theSupervisor->firstConsoleInfo_ =
"";
2151 sock.acknowledge(
"Done",
false );
2154 else if(buffer.find(
"loginVerify") == 0)
2157 <<
"Checking login verification request from remote gateway..."
2168 std::vector<std::string> rxParams =
2172 if(rxParams.size() != 5)
2174 __COUT_ERR__ <<
"Invalid remote login verify attempt! Expected 5 "
2176 << rxParams.size() << __E__;
2177 sock.acknowledge(
"0",
false );
2184 std::map<std::string , WebUsers::permissionLevel_t>
2185 userGroupPermissionsMap;
2186 std::string userWithLock =
"";
2187 uint64_t uid, userSessionIndex;
2188 std::string cookieCode = rxParams[1];
2191 &userGroupPermissionsMap,
2200 __COUT_ERR__ <<
"Remote login failed!" << __E__;
2201 sock.acknowledge(
"0",
false );
2206 const std::string& remoteName = rxParams[4];
2207 __COUTVS__(23, remoteName);
2208 std::vector<GatewaySupervisor::RemoteGatewayInfo>
2211 std::lock_guard<std::mutex> lock(
2212 theSupervisor->remoteGatewayAppsMutex_);
2213 remoteGatewayApps = theSupervisor->remoteGatewayApps_;
2214 __COUTVS__(22, remoteGatewayApps.size());
2218 for(
const auto& remoteGatewayApp : remoteGatewayApps)
2219 if(remoteName == remoteGatewayApp.appInfo.name)
2222 __COUTVS__(21, remoteGatewayApp.permissionThresholdString);
2224 std::map<std::string ,
2225 WebUsers::permissionLevel_t>
2226 remoteIconPermissionsMap;
2228 remoteGatewayApp.permissionThresholdString,
2229 remoteIconPermissionsMap);
2239 if(remoteIconPermissionsMap.size() == 1 &&
2240 remoteIconPermissionsMap.begin()->first !=
2241 WebUsers::DEFAULT_USER_GROUP)
2245 remoteIconPermissionsMap.begin()->first);
2247 auto it = userGroupPermissionsMap.find(
2248 remoteIconPermissionsMap.begin()->first);
2249 std::map<std::string ,
2250 WebUsers::permissionLevel_t>::iterator it2 =
2251 userGroupPermissionsMap.find(
2252 WebUsers::DEFAULT_USER_GROUP);
2253 if(it != userGroupPermissionsMap.end() &&
2254 it2 != userGroupPermissionsMap.end())
2256 __COUT_TYPE__(TLVL_DEBUG + 21)
2257 << __COUT_HDR__ <<
"Found user group '"
2259 <<
"' to modify: " << (uint16_t)it2->second
2260 <<
" --> " << (uint16_t)it->second << __E__;
2261 it2->second = it->second;
2262 __COUTVS__(21, (uint16_t)it2->second);
2266 userGroupPermissionsMap
2268 userGroupPermissionsMap
2269 [remoteIconPermissionsMap.begin()->first] =
2270 WebUsers::PERMISSION_LEVEL_INACTIVE;
2278 __COUT_ERR__ <<
"Did not find any matching subsystems for remote "
2279 "login verify from '"
2280 << remoteName <<
"' attempted!" << __E__;
2291 std::string retStr =
"";
2293 retStr += cookieCode;
2295 "," + StringMacros::encodeURIComponent(
2297 retStr +=
"," + userWithLock;
2298 retStr +=
"," + username;
2300 retStr +=
"," + std::to_string(userSessionIndex);
2302 __COUTVS__(23, retStr);
2303 __COUTT__ <<
"Remote login successful for " << username
2304 <<
", userWithLock = " << userWithLock << __E__;
2305 sock.acknowledge(retStr,
false );
2308 else if(buffer ==
"GetRemoteDesktopIcons")
2310 __COUT__ <<
"Giving desktop icons to remote gateway..." << __E__;
2324 const std::vector<DesktopIconTable::DesktopIcon>& icons =
2325 iconTable->getAllDesktopIcons();
2327 std::string iconString =
"";
2339 bool getRemoteIcons =
true;
2340 bool firstIcon =
true;
2349 iconString +=
"User Settings";
2350 iconString +=
"," + std::string(
"User");
2356 "," + std::string(
"1");
2360 iconString +=
"," + std::string(
2361 "/WebPath/images/dashboardImages/"
2362 "icon-Settings.png");
2365 &tmpCfgMgr,
"/WebPath/html/UserSettings.html");
2366 iconString +=
"," + std::string(
"");
2369 for(
const auto& icon : icons)
2371 __COUTVS__(40, icon.caption_);
2372 __COUTVS__(40, icon.permissionThresholdString_);
2378 __COUTVS__(10, icon.windowContentURL_);
2379 if(icon.windowContentURL_.size() > 4 &&
2380 icon.windowContentURL_[0] ==
'o' &&
2381 icon.windowContentURL_[1] ==
't' &&
2382 icon.windowContentURL_[2] ==
's' &&
2383 icon.windowContentURL_[3] ==
':')
2385 __COUT_TYPE__(TLVL_DEBUG + 10)
2386 << __COUT_HDR__ <<
"Retrieving remote icons at "
2387 << icon.windowContentURL_ << __E__;
2389 std::vector<std::string> parsedFields =
2391 icon.windowContentURL_, {
':'});
2395 if(parsedFields.size() == 3)
2398 parsedFields[1], atoi(parsedFields[2].c_str()));
2402 __COUTVS__(10, ipAddressForStateChangesOverUDP);
2404 ipAddressForStateChangesOverUDP);
2405 std::string remoteIconString =
2406 iconSocket.sendAndReceive(iconRemoteSocket,
2407 "GetRemoteDesktopIcons",
2409 __COUTVS__(10, remoteIconString);
2421 __COUTVS__(10, icon.caption_);
2422 iconString += icon.caption_;
2423 iconString +=
"," + icon.alternateText_;
2425 "," + std::string(icon.enforceOneWindowInstance_ ?
"1" :
"0");
2427 "," + std::string(
"1");
2431 iconString +=
"," + icon.imageURL_;
2433 &tmpCfgMgr, icon.windowContentURL_);
2434 iconString +=
"," + icon.folderPath_;
2436 __COUTVS__(10, iconString);
2438 sock.acknowledge(iconString,
true );
2441 else if(!enableStateChanges)
2443 __COUT_WARN__ <<
"Skipping potential FSM Command because "
2444 "enableStateChanges=false"
2449 __COUT__ <<
"Received a remote FSM Command attempt!" << __E__;
2451 size_t nCommas = std::count(buffer.begin(), buffer.end(),
',');
2454 __SS__ <<
"Unrecognized State Machine command :-" << buffer
2455 <<
"-. Format is FiniteStateMachineName,Command,Parameter(s). "
2456 "Where Parameter(s) is/are optional."
2458 __COUT_ERR__ << ss.str();
2459 if(acknowledgementEnabled)
2461 __COUTT__ <<
"Ack'ing" << __E__;
2462 sock.acknowledge(ss.str(),
true );
2469 while((commaPosition = buffer.find(
',', begin)) != std::string::npos ||
2470 commaCounter == nCommas)
2472 if(commaCounter == nCommas)
2473 commaPosition = buffer.size();
2474 if(commaCounter == 0)
2475 fsmName = buffer.substr(begin, commaPosition - begin);
2476 else if(commaCounter == 1)
2477 command = buffer.substr(begin, commaPosition - begin);
2479 parameters.push_back(buffer.substr(begin, commaPosition - begin));
2480 __COUT__ <<
"Word[" << commaCounter
2481 <<
"]: " << buffer.substr(begin, commaPosition - begin)
2484 begin = commaPosition + 1;
2492 std::string extraDoneContent =
"";
2498 if(theSupervisor->VERBOSE_MUTEX)
2499 __COUT__ <<
"Waiting for FSM access" << __E__;
2500 std::lock_guard<std::mutex> lock(
2501 theSupervisor->stateMachineAccessMutex_);
2502 if(theSupervisor->VERBOSE_MUTEX)
2503 __COUT__ <<
"Have FSM access" << __E__;
2505 errorStr = theSupervisor->attemptStateMachineTransition(
2510 WebUsers::DEFAULT_STATECHANGER_USERNAME ,
2511 WebUsers::DEFAULT_STATECHANGER_USERNAME,
2514 if(errorStr ==
"" &&
2515 command == RunControlStateMachine::CONFIGURE_TRANSITION_NAME)
2518 ->activeStateMachineConfigurationDumpOnConfigure_;
2520 if(errorStr ==
"" &&
2521 command == RunControlStateMachine::START_TRANSITION_NAME)
2523 theSupervisor->activeStateMachineConfigurationDumpOnRun_;
2529 <<
"UDP State Changer failed to execute command because of the "
2532 __COUT_ERR__ << ss.str();
2533 if(acknowledgementEnabled)
2534 sock.acknowledge(errorStr,
true );
2538 __SS__ <<
"Successfully executed state change command '" << command
2540 __COUT_INFO__ << ss.str();
2541 if(acknowledgementEnabled)
2543 "Done" + (extraDoneContent.size()
2544 ? (
"," + extraDoneContent)
2552 __SS__ <<
"Error was caught handling UDP command." << __E__;
2557 catch(
const std::runtime_error& e)
2559 ss <<
"Here is the error: " << e.what() << __E__;
2563 ss <<
"Unrecognized error." << __E__;
2566 __COUT_ERR__ << ss.str();
2567 if(acknowledgementEnabled)
2568 sock.acknowledge(ss.str(),
true );
2573 __COUT_TYPE__(TLVL_DEBUG + 9)
2574 << __COUT_HDR__ <<
"UDP State Changer waiting..." << __E__;
2586 void GatewaySupervisor::makeSystemLogEntry(
const std::string& entryText,
2587 const std::string& subjectText )
2589 __COUT__ <<
"Making System Logbook Entry: " << entryText << __E__;
2590 if(subjectText.size())
2591 __COUTV__(subjectText);
2592 lastLogbookEntry_ = entryText;
2593 lastLogbookEntryTime_ = time(0);
2595 SupervisorInfoMap logbookInfoMap =
2596 allSupervisorInfo_.getAllLogbookTypeSupervisorInfo();
2598 if(logbookInfoMap.size() == 0)
2600 __COUT__ <<
"No logbooks found! Here is entry: " << entryText << __E__;
2605 __COUT__ <<
"Making logbook entry: " << entryText << __E__;
2608 SOAPParameters parameters(
"EntryText", StringMacros::encodeURIComponent(entryText));
2609 parameters.addParameter(
"SubjectText", StringMacros::encodeURIComponent(subjectText));
2611 for(
auto& logbookInfo : logbookInfoMap)
2615 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
2616 logbookInfo.second.getDescriptor(),
"MakeSystemLogEntry", parameters);
2619 SOAPUtilities::receive(retMsg, retParameters);
2621 std::string status = retParameters.getValue(
"Status");
2622 __COUT__ <<
"Returned Status: " << status
2624 if(status !=
"Success")
2626 __SS__ <<
"Invalid return status on MakeSystemLogEntry: " << status
2631 catch(
const xdaq::exception::Exception& e)
2633 __SS__ <<
"Failed to send system log SOAP entry to "
2634 << logbookInfo.second.getContextName() <<
"/"
2635 << logbookInfo.second.getName() <<
" w/app ID=" << logbookInfo.first
2636 << __E__ << e.what();
2640 catch(std::runtime_error& e)
2642 __SS__ <<
"Error during handling of system log SOAP entry at "
2643 << logbookInfo.second.getContextName() <<
"/"
2644 << logbookInfo.second.getName() <<
" w/app ID=" << logbookInfo.first
2645 << __E__ << e.what();
2652 void GatewaySupervisor::Default(xgi::Input* , xgi::Output* out)
2654 if(!supervisorGuiHasBeenLoaded_ &&
2655 (supervisorGuiHasBeenLoaded_ =
2661 doLog = __ENV__(
"OTS_LOG_INTERMEDIATE_STATES") == std::string(
"1");
2669 makeSystemLogEntry(
"ots started.");
2672 *out <<
"<!DOCTYPE HTML><html lang='en'><head><title>ots</title>"
2673 << GatewaySupervisor::getIconHeaderString() <<
2676 <<
"<frameset col='100%' row='100%'>"
2677 <<
"<frame src='/WebPath/html/Desktop.html?urn="
2678 << this->getApplicationDescriptor()->getLocalId()
2679 <<
"&securityType=" << securityType_ <<
"'></frameset></html>";
2683 std::string GatewaySupervisor::getIconHeaderString(
void)
2687 return "<link rel='apple-touch-icon' sizes='57x57' href='/WebPath/images/otsdaqIcons/apple-icon-57x57.png'>\
2688 <link rel='apple-touch-icon' sizes='60x60' href='/WebPath/images/otsdaqIcons/apple-icon-60x60.png'>\
2689 <link rel='apple-touch-icon' sizes='72x72' href='/WebPath/images/otsdaqIcons/apple-icon-72x72.png'>\
2690 <link rel='apple-touch-icon' sizes='76x76' href='/WebPath/images/otsdaqIcons/apple-icon-76x76.png'>\
2691 <link rel='apple-touch-icon' sizes='114x114' href='/WebPath/images/otsdaqIcons/apple-icon-114x114.png'>\
2692 <link rel='apple-touch-icon' sizes='120x120' href='/WebPath/images/otsdaqIcons/apple-icon-120x120.png'>\
2693 <link rel='apple-touch-icon' sizes='144x144' href='/WebPath/images/otsdaqIcons/apple-icon-144x144.png'>\
2694 <link rel='apple-touch-icon' sizes='152x152' href='/WebPath/images/otsdaqIcons/apple-icon-152x152.png'>\
2695 <link rel='apple-touch-icon' sizes='180x180' href='/WebPath/images/otsdaqIcons/apple-icon-180x180.png'>\
2696 <link rel='icon' type='image/png' sizes='192x192' href='/WebPath/images/otsdaqIcons/android-icon-192x192.png'>\
2697 <link rel='icon' type='image/png' sizes='144x144' href='/WebPath/images/otsdaqIcons/android-icon-144x144.png'>\
2698 <link rel='icon' type='image/png' sizes='48x48' href='/WebPath/images/otsdaqIcons/android-icon-48x48.png'>\
2699 <link rel='icon' type='image/png' sizes='72x72' href='/WebPath/images/otsdaqIcons/android-icon-72x72.png'>\
2700 <link rel='icon' type='image/png' sizes='32x32' href='/WebPath/images/otsdaqIcons/favicon-32x32.png'>\
2701 <link rel='icon' type='image/png' sizes='96x96' href='/WebPath/images/otsdaqIcons/favicon-96x96.png'>\
2702 <link rel='icon' type='image/png' sizes='16x16' href='/WebPath/images/otsdaqIcons/favicon-16x16.png'>\
2703 <link rel='manifest' href='/WebPath/images/otsdaqIcons/manifest.json'>\
2704 <meta name='msapplication-TileColor' content='#ffffff'>\
2705 <meta name='msapplication-TileImage' content='/WebPath/images/otsdaqIcons/ms-icon-144x144.png'>\
2706 <meta name='theme-color' content='#ffffff'>";
2712 void GatewaySupervisor::XGI_Turtle(xgi::Input* , xgi::Output* out)
2715 if(!picGen_.imageMagickInstallChecked)
2720 __COUTVS__(50, ret);
2721 picGen_.imageMagickInstallChecked =
true;
2722 picGen_.imageMagickInstalled = ret ==
"" ? false :
true;
2725 std::string filepath =
2726 __ENV__(
"OTSDAQ_WEB_PATH") + std::string(
"/images/otsdaqIcons/");
2728 std::string filename = filepath +
"generated/turtle.png";
2729 if(picGen_.imageMagickInstalled)
2730 picGen_.generateTurtle(filepath);
2732 filename = filepath +
"turtle.png";
2738 is.open(filename.c_str());
2740 *out <<
"data:image/png;charset=US-ASCII,";
2745 sprintf(CodeURL,
"%%%2.2X", (
unsigned char)(is.get()));
2757 void GatewaySupervisor::stateMachineIterationBreakpoint(xgi::Input* in, xgi::Output* out)
2760 cgicc::Cgicc cgiIn(in);
2773 __COUTV__(requestType);
2777 if(requestType ==
"get")
2779 std::stringstream v;
2781 std::lock_guard<std::mutex> lock(broadcastIterationBreakpointMutex_);
2782 v << broadcastIterationBreakpoint_;
2785 xmlOut.addTextElementToData(
"iterationBreakpoint", v.str());
2787 else if(requestType ==
"set")
2789 unsigned int breakpointSetValue =
2790 CgiDataUtilities::getDataAsInt(cgiIn,
"breakpointSetValue");
2791 __COUTV__(breakpointSetValue);
2794 std::lock_guard<std::mutex> lock(broadcastIterationBreakpointMutex_);
2795 broadcastIterationBreakpoint_ = breakpointSetValue;
2799 std::stringstream v;
2800 v << breakpointSetValue;
2801 xmlOut.addTextElementToData(
"iterationBreakpoint", v.str());
2805 __SS__ <<
"Unknown iteration breakpoint request type = " << requestType
2810 catch(
const std::runtime_error& e)
2812 __SS__ <<
"Error caught handling iteration breakpoint command: " << e.what()
2814 __COUT_ERR__ << ss.str();
2815 xmlOut.addTextElementToData(
"Error", ss.str());
2819 __SS__ <<
"Unknown error caught handling iteration breakpoint command." << __E__;
2824 catch(
const std::exception& e)
2826 ss <<
"Exception message: " << e.what();
2831 __COUT_ERR__ << ss.str();
2832 xmlOut.addTextElementToData(
"Error", ss.str());
2838 catch(
const std::runtime_error& e)
2840 __SS__ <<
"Error caught handling iteration breakpoint command: " << e.what() << __E__;
2841 __COUT_ERR__ << ss.str();
2845 __SS__ <<
"Unknown error caught handling iteration breakpoint command." << __E__;
2850 catch(
const std::exception& e)
2852 ss <<
"Exception message: " << e.what();
2857 __COUT_ERR__ << ss.str();
2861 void GatewaySupervisor::stateMachineXgiHandler(xgi::Input* in, xgi::Output* out)
2867 __COUT__ <<
"Waiting for FSM access" << __E__;
2868 std::lock_guard<std::mutex> lock(stateMachineAccessMutex_);
2870 __COUT__ <<
"Have FSM access" << __E__;
2872 out->getHTTPResponseHeader().addHeader(
2873 "Access-Control-Allow-Origin",
2875 cgicc::Cgicc cgiIn(in);
2878 std::string requestType =
2879 "StateMachine-" + command;
2880 __COUTV__(requestType);
2894 std::string currentState = theStateMachine_.getCurrentStateName();
2896 __COUT__ <<
"Check for Handled by theIterator_" << __E__;
2899 if((activeStateMachineWindowName_ ==
"" ||
2900 activeStateMachineWindowName_ ==
"iterator" ||
2901 (activeStateMachineName_ == fsmName &&
2902 command.find(
"iterate") ==
2904 theIterator_.handleCommandRequest(xmlOut, command, fsmWindowName))
2906 __COUT__ <<
"Handled by theIterator_" << __E__;
2912 if(theStateMachine_.isInTransition())
2914 __SS__ <<
"Error - Can not accept request because the State Machine is already "
2917 __COUT_ERR__ <<
"\n" << ss.str();
2919 xmlOut.addTextElementToData(
"state_tranisition_attempted",
2921 xmlOut.addTextElementToData(
2922 "state_tranisition_attempted_err",
2930 std::vector<std::string> parameters;
2932 if(command ==
"Configure")
2935 std::string logEntry =
2938 attemptStateMachineTransition(&xmlOut,
2950 std::string GatewaySupervisor::attemptStateMachineTransition(
2952 std::ostringstream* out,
2953 const std::string& command,
2954 const std::string& fsmName,
2955 const std::string& fsmWindowName,
2956 const std::string& username,
2957 const std::vector<std::string>& commandParameters,
2958 std::string logEntry )
2961 std::string errorStr =
"";
2963 std::string currentState = theStateMachine_.getCurrentStateName();
2964 __COUT__ <<
"State Machine command = " << command << __E__;
2965 __COUT__ <<
"fsmName = " << fsmName << __E__;
2966 __COUT__ <<
"fsmWindowName = " << fsmWindowName << __E__;
2967 __COUTV__(username);
2968 __COUT__ <<
"activeStateMachineName_ = " << activeStateMachineName_ << __E__;
2969 __COUTV__(logEntry);
2970 __COUT__ <<
"command = " << command << __E__;
2971 __COUT__ <<
"commandParameters.size = " << commandParameters.size() << __E__;
2975 if(!logEntry.size() && commandParameters.size() &&
2976 commandParameters.back().find(
"LogEntry:") == 0 &&
2977 commandParameters.back().size() > strlen(
"LogEntry:"))
2979 logEntry = commandParameters.back().substr(strlen(
"LogEntry:"));
2980 __COUTV__(logEntry);
2989 if(activeStateMachineName_ !=
"" && activeStateMachineName_ != fsmName)
2991 __COUT__ <<
"Validating... currentFSM = " << activeStateMachineName_
2992 <<
", currentState = " << currentState <<
", newFSM = " << fsmName
2993 <<
", command = " << command << __E__;
2994 if(currentState != RunControlStateMachine::HALTED_STATE_NAME &&
2995 currentState != RunControlStateMachine::INITIAL_STATE_NAME)
2999 __SS__ <<
"Error - Can not accept request because the State Machine "
3000 <<
"with window name '" << activeStateMachineWindowName_
3001 <<
"' (UID: " << activeStateMachineName_
3004 <<
"in control of State Machine progress. ";
3005 ss <<
"\n\nIn order for this State Machine with window name '"
3006 << fsmWindowName <<
"' (UID: " << fsmName
3008 "to control progress, please transition to "
3009 << RunControlStateMachine::HALTED_STATE_NAME <<
" using the active "
3010 <<
"State Machine '" << activeStateMachineWindowName_ <<
".'" << __E__;
3015 activeStateMachineName_ =
"";
3016 activeStateMachineWindowName_ =
"";
3025 if(command == RunControlStateMachine::START_TRANSITION_NAME &&
3026 getLastLogEntry(RunControlStateMachine::CONFIGURE_TRANSITION_NAME).size())
3031 "\n\nThe last Configure transition log entry was this:\n" +
3032 getLastLogEntry(RunControlStateMachine::CONFIGURE_TRANSITION_NAME);
3038 doLog = __ENV__(
"OTS_LOG_TRANSITION_STARTS") == std::string(
"1");
3046 makeSystemLogEntry(
"Attempting FSM command '" + command +
"' from state '" +
3047 currentState +
"' with user log entry: " + logEntry);
3050 setLastLogEntry(command, logEntry);
3053 if(command == RunControlStateMachine::CONFIGURE_TRANSITION_NAME)
3055 activeStateMachineConfigurationDumpOnConfigure_ =
3057 activeStateMachineConfigurationDumpOnRun_ =
3059 activeStateMachineConfigurationDumpOnRunEnable_ =
false,
3060 activeStateMachineConfigurationDumpOnConfigureEnable_ =
3062 activeStateMachineConfigurationDumpOnConfigureFilename_ =
3064 activeStateMachineConfigurationDumpOnRunFilename_ =
3067 activeStateMachineRequireUserLogOnRun_ =
false,
3068 activeStateMachineRequireUserLogOnConfigure_ =
3070 activeStateMachineRunInfoPluginType_ = TableViewColumnInfo::
3071 DATATYPE_STRING_DEFAULT;
3073 if(currentState != RunControlStateMachine::HALTED_STATE_NAME &&
3077 __SS__ <<
"Error - Can only transition to Configured if the current "
3078 <<
"state is Initial or Halted. The current state is '" << currentState
3079 <<
".' Perhaps your state machine is out of sync, or you need to Halt "
3080 "before Configuring."
3087 if(commandParameters.size() == 0)
3089 __SS__ <<
"Error - Can only transition to Configured if a Configuration "
3090 "Alias parameter is provided."
3096 std::string dumpFormatOnConfigure, dumpFormatOnRun;
3099 CorePropertySupervisorBase::theConfigurationManager_
3100 ->getSupervisorTableNode(supervisorContextUID_,
3101 supervisorApplicationUID_);
3104 bool doThrow =
false;
3108 configLinkNode.
getNode(
"LinkToStateMachineTable")
3113 activeStateMachineRequireUserLogOnConfigure_ =
3115 .
getNode(
"RequireUserLogInputOnConfigureTransition")
3124 activeStateMachineRequireUserLogOnRun_ =
3125 fsmLinkNode.
getNode(
"RequireUserLogInputOnRunTransition")
3134 activeStateMachineRunAlias_ =
3135 fsmLinkNode.
getNode(
"RunDisplayAlias")
3141 activeStateMachineRunAlias_ =
"Run";
3145 activeStateMachineRollOverLogOnConfigure_ =
3146 fsmLinkNode.
getNode(
"RollOverLogOnConfigure")
3151 activeStateMachineRollOverLogOnConfigure_ =
false;
3155 activeStateMachineRollOverLogOnStart_ =
3156 fsmLinkNode.
getNode(
"RollOverLogOnStart")
3161 activeStateMachineRollOverLogOnStart_ =
false;
3166 activeStateMachineRunInfoPluginType_ =
3167 fsmLinkNode.
getNode(
"RunInfoPluginType")
3172 __COUT__ <<
"RunInfoPluginType not defined for FSM name '"
3174 <<
"' - please setup a valid run info plugin type to "
3175 "enable external Run Number coordination and dumping "
3176 "configuration info to an external location."
3180 activeStateMachineConfigurationDumpOnConfigureEnable_ =
3182 .
getNode(
"EnableConfigurationDumpOnConfigureTransition")
3184 activeStateMachineConfigurationDumpOnRunEnable_ =
3185 fsmLinkNode.
getNode(
"EnableConfigurationDumpOnRunTransition")
3190 dumpFormatOnConfigure =
3191 fsmLinkNode.
getNode(
"ConfigurationDumpOnConfigureFormat")
3193 dumpFormatOnRun = fsmLinkNode.
getNode(
"ConfigurationDumpOnRunFormat")
3196 std::string dumpFilePath, dumpFileRadix;
3198 fsmLinkNode.
getNode(
"ConfigurationDumpOnConfigureFilePath")
3201 fsmLinkNode.
getNode(
"ConfigurationDumpOnConfigureFileRadix")
3203 "ConfigTransitionConfigurationDump");
3204 activeStateMachineConfigurationDumpOnConfigureFilename_ =
3205 dumpFilePath +
"/" + dumpFileRadix;
3207 fsmLinkNode.
getNode(
"ConfigurationDumpOnRunFilePath")
3209 dumpFileRadix = fsmLinkNode.
getNode(
"ConfigurationDumpOnRunFileRadix")
3211 "ConfigTransitionConfigurationDump");
3212 activeStateMachineConfigurationDumpOnRunFilename_ =
3213 dumpFilePath +
"/" + dumpFileRadix;
3220 (activeStateMachineConfigurationDumpOnConfigureEnable_ ||
3221 activeStateMachineConfigurationDumpOnRunEnable_))
3223 __SS__ <<
"Configuration Dump was enabled, but there are missing "
3225 << e.what() << __E__;
3229 __COUT_INFO__ <<
"FSM configuration dump Link disconnected at '"
3230 << ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME
3231 <<
"/" << supervisorContextUID_ <<
"/"
3232 << supervisorApplicationUID_ <<
"/"
3233 <<
"LinkToStateMachineTable/" << fsmName <<
"/"
3234 <<
"EnableConfigurationDumpOnConfigureTransition "
3235 "and/or EnableConfigurationDumpOnRunTransition"
3240 __COUT_INFO__ <<
"No Gateway Supervisor configuration record found at '"
3241 << ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME <<
"/"
3242 << supervisorContextUID_ <<
"/" << supervisorApplicationUID_
3243 <<
"' - consider adding one to control configuration dumps "
3244 "and state machine properties."
3248 __COUTTV__(activeStateMachineRequireUserLogOnConfigure_);
3249 __COUTTV__(activeStateMachineRequireUserLogOnRun_);
3250 __COUTTV__(activeStateMachineRunAlias_);
3251 __COUTTV__(activeStateMachineRunInfoPluginType_);
3252 __COUTTV__(activeStateMachineConfigurationDumpOnConfigureEnable_);
3253 __COUTTV__(activeStateMachineConfigurationDumpOnRunEnable_);
3254 __COUTTV__(dumpFormatOnConfigure);
3255 __COUTTV__(dumpFormatOnRun);
3256 __COUTTV__(activeStateMachineConfigurationDumpOnConfigureFilename_);
3257 __COUTTV__(activeStateMachineConfigurationDumpOnRunFilename_);
3258 __COUTTV__(activeStateMachineRollOverLogOnConfigure_);
3259 __COUTTV__(activeStateMachineRollOverLogOnStart_);
3261 if(activeStateMachineRequireUserLogOnConfigure_ &&
3262 getLastLogEntry(RunControlStateMachine::CONFIGURE_TRANSITION_NAME).size() < 3)
3264 __SS__ <<
"Error - the state machine property "
3265 "'RequireUserLogInputOnConfigureTransition' has been enabled which "
3266 "requires the user to enter "
3267 "at least 3 characters of log info to proceed with the Configure "
3273 parameters.addParameter(
"ConfigurationAlias", commandParameters[0]);
3275 std::string configurationAlias = parameters.getValue(
"ConfigurationAlias");
3276 __COUT__ <<
"Configure --> Name: ConfigurationAlias Value: " << configurationAlias
3278 lastConfigurationAlias_ = configurationAlias;
3280 std::string fn = ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" +
3281 FSM_LAST_GROUP_ALIAS_FILE_START + fsmName +
"." +
3282 FSM_USERS_PREFERENCES_FILETYPE;
3284 __COUT__ <<
"Save FSM preferences: " << fn << __E__;
3285 FILE* fp = fopen(fn.c_str(),
"w");
3288 __SS__ << (
"Could not open file: " + fn) << __E__;
3291 fprintf(fp,
"FSM_last_configuration_alias %s", configurationAlias.c_str());
3294 activeStateMachineName_ = fsmName;
3295 activeStateMachineWindowName_ = fsmWindowName;
3297 if(activeStateMachineName_ ==
"")
3299 <<
"The active state machine is an empty string, this is allowed for "
3300 "backwards compatibility, but may not be intentional! "
3301 <<
"Make sure you or your system admins understand why the active FSM "
3310 CorePropertySupervisorBase::theConfigurationManager_
3315 __SS__ <<
"\nTransition to Configuring interrupted! "
3316 <<
"The Configuration Manager could not be initialized." << __E__;
3323 theConfigurationTableGroup_ =
3324 CorePropertySupervisorBase::theConfigurationManager_
3325 ->getTableGroupFromAlias(configurationAlias);
3330 <<
"Exception occurred translating the Configuration System Alias."
3334 if(theConfigurationTableGroup_.second.isInvalid())
3337 <<
"\nTransition to Configuring interrupted! System Configuration Alias '"
3338 << configurationAlias
3339 <<
"' could not be translated to a group name and key." << __E__;
3343 __COUT_INFO__ <<
"Configuration table group name: "
3344 << theConfigurationTableGroup_.first
3345 <<
" key: " << theConfigurationTableGroup_.second << __E__;
3351 std::string groupTypeString;
3352 CorePropertySupervisorBase::theConfigurationManager_->loadTableGroup(
3353 theConfigurationTableGroup_.first,
3354 theConfigurationTableGroup_.second,
3364 if(groupTypeString != ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
3366 __SS__ <<
"Illegal attempted configuration group type. The table group '"
3367 << theConfigurationTableGroup_.first <<
"("
3368 << theConfigurationTableGroup_.second <<
")' is of type "
3369 << groupTypeString <<
". It must be "
3370 << ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION <<
"."
3375 CorePropertySupervisorBase::theConfigurationManager_->loadTableGroup(
3376 theConfigurationTableGroup_.first,
3377 theConfigurationTableGroup_.second,
3380 __COUT__ <<
"Done loading Configuration Alias." << __E__;
3384 std::string(theConfigurationTableGroup_.first),
3385 theConfigurationTableGroup_.second);
3386 ConfigurationManager::saveGroupNameAndKey(
3387 activatedGroup, ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE);
3389 __COUT__ <<
"Done activating Configuration Alias." << __E__;
3391 catch(
const std::runtime_error& e)
3394 <<
"\nTransition to Configuring interrupted! System Configuration Alias "
3395 << configurationAlias <<
" was translated to "
3396 << theConfigurationTableGroup_.first <<
" ("
3397 << theConfigurationTableGroup_.second
3398 <<
") but could not be loaded and initialized." << __E__;
3399 ss <<
"\n\nHere was the error: " << e.what()
3400 <<
"\n\nTo help debug this problem, try activating this group in the "
3403 <<
" and detailed errors will be shown." << __E__;
3409 <<
"\nTransition to Configuring interrupted! System Configuration Alias "
3410 << configurationAlias <<
" was translated to "
3411 << theConfigurationTableGroup_.first <<
" ("
3412 << theConfigurationTableGroup_.second
3413 <<
") but could not be loaded and initialized." << __E__;
3418 catch(
const std::exception& e)
3420 ss <<
"Exception message: " << e.what();
3425 ss <<
"\n\nTo help debug this problem, try activating this group in the "
3428 <<
" and detailed errors will be shown." << __E__;
3438 if(activeStateMachineConfigurationDumpOnRunEnable_ ||
3439 ((activeStateMachineRunInfoPluginType_ !=
3440 TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
3441 activeStateMachineRunInfoPluginType_ !=
"No Run Info Plugin")))
3444 <<
"Caching the Configuration Dump for the Run transition..."
3448 std::stringstream dumpSs;
3449 CorePropertySupervisorBase::theConfigurationManager_
3450 ->dumpActiveConfiguration(
3453 lastConfigurationAlias_,
3455 RunControlStateMachine::CONFIGURE_TRANSITION_NAME),
3459 activeStateMachineConfigurationDumpOnRun_ = dumpSs.str();
3463 <<
"Not caching the Configuration Dump on the Run transition."
3467 if(activeStateMachineConfigurationDumpOnConfigureEnable_ ||
3468 ((activeStateMachineRunInfoPluginType_ !=
3469 TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
3470 activeStateMachineRunInfoPluginType_ !=
"No Run Info Plugin")))
3473 <<
"Caching the Configuration Dump for the Configure transition..."
3477 std::stringstream dumpSs;
3478 CorePropertySupervisorBase::theConfigurationManager_
3479 ->dumpActiveConfiguration(
3481 dumpFormatOnConfigure,
3482 lastConfigurationAlias_,
3484 RunControlStateMachine::CONFIGURE_TRANSITION_NAME),
3488 activeStateMachineConfigurationDumpOnConfigure_ = dumpSs.str();
3492 <<
"Not caching the Configuration Dump on the Configure transition."
3496 catch(
const std::runtime_error& e)
3498 __SS__ <<
"Error encoutered during configuration dump. Here is the error: "
3504 __SS__ <<
"Unknown error encoutered during configuration dump.";
3509 else if(command == RunControlStateMachine::START_TRANSITION_NAME)
3512 RunControlStateMachine::CONFIGURED_STATE_NAME)
3515 <<
"Error - Can only transition to Configured if the current "
3516 <<
"state is Halted. Perhaps your state machine is out of sync. "
3517 <<
"(Likely the server was restarted or another user changed the state)"
3522 if(activeStateMachineRequireUserLogOnRun_ &&
3523 getLastLogEntry(RunControlStateMachine::START_TRANSITION_NAME).size() < 3)
3526 <<
"Error - the state machine property "
3527 "'RequireUserLogInputOnRunTransition' has been enabled which requires "
3528 "the user to enter "
3529 "at least 3 characters of log info to proceed with the Run transition."
3534 unsigned long runNumber;
3535 if(commandParameters.size() == 0)
3537 runNumber = getNextRunNumber();
3540 __COUTV__(activeStateMachineRunInfoPluginType_);
3542 if(activeStateMachineRunInfoPluginType_ !=
3543 TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
3544 activeStateMachineRunInfoPluginType_ !=
"No Run Info Plugin")
3546 std::unique_ptr<RunInfoVInterface> runInfoInterface =
nullptr;
3550 activeStateMachineRunInfoPluginType_, activeStateMachineName_));
3556 if(runInfoInterface ==
nullptr)
3558 __SS__ <<
"Run Info interface plugin construction failed of type "
3559 << activeStateMachineRunInfoPluginType_
3560 <<
" for claiming next run number!" << __E__;
3565 runNumber = runInfoInterface->claimNextRunNumber(
3566 conditionID_, activeStateMachineConfigurationDumpOnRun_);
3569 setNextRunNumber(runNumber + 1);
3573 sscanf(commandParameters[0].c_str(),
"%lu", &runNumber);
3574 __COUTV__(runNumber);
3575 setNextRunNumber(runNumber + 1);
3578 setLastLogEntry(command,
"Run #" + std::to_string(runNumber) +
": " + logEntry);
3579 parameters.addParameter(
"RunNumber", runNumber);
3581 else if(!(command == RunControlStateMachine::HALT_TRANSITION_NAME ||
3582 command == RunControlStateMachine::SHUTDOWN_TRANSITION_NAME ||
3583 command == RunControlStateMachine::ERROR_TRANSITION_NAME ||
3584 command == RunControlStateMachine::FAIL_TRANSITION_NAME ||
3585 command == RunControlStateMachine::STARTUP_TRANSITION_NAME ||
3586 command == RunControlStateMachine::INIT_TRANSITION_NAME ||
3587 command == RunControlStateMachine::ABORT_TRANSITION_NAME ||
3588 command == RunControlStateMachine::PAUSE_TRANSITION_NAME ||
3589 command == RunControlStateMachine::RESUME_TRANSITION_NAME ||
3590 command == RunControlStateMachine::STOP_TRANSITION_NAME))
3592 __SS__ <<
"Error - illegal state machine command received '" << command <<
".'"
3597 theStateMachine_.setErrorMessage(
3599 xoap::MessageReference message =
3600 SOAPUtilities::makeSOAPMessageReference(command, parameters);
3602 xoap::MessageReference reply = stateMachineXoapHandler(message);
3607 xmldoc->addTextElementToData(
"state_tranisition_attempted",
3611 __COUT__ <<
"FSM state transition launched!" << __E__;
3613 stateMachineLastCommandInput_ = command;
3618 __SS__ <<
"Error - transition '" << command <<
"' attempt failed!" << __E__;
3623 catch(
const std::runtime_error& e)
3625 ss <<
"\nHere is the error: " << e.what() << __E__;
3629 ss <<
"Uknown error caught." << __E__;
3632 __COUT_ERR__ <<
"\n" << ss.str();
3635 xmldoc->addTextElementToData(
"state_tranisition_attempted",
3638 xmldoc->addTextElementToData(
3639 "state_tranisition_attempted_err",
3643 (std::ostringstream*)out,
false ,
true );
3649 xoap::MessageReference GatewaySupervisor::stateMachineXoapHandler(
3650 xoap::MessageReference message)
3653 __COUT__ <<
"FSM Soap Handler!" << __E__;
3654 stateMachineWorkLoopManager_.removeProcessedRequests();
3656 __COUT__ <<
"Done - FSM Soap Handler!" << __E__;
3666 bool GatewaySupervisor::stateMachineThread(toolbox::task::WorkLoop* workLoop)
3668 stateMachineSemaphore_.take();
3669 std::string command =
3670 SOAPUtilities::translate(stateMachineWorkLoopManager_.getMessage(workLoop))
3673 __COUT__ <<
"Propagating FSM command '" << command <<
"'..." << __E__;
3675 std::string reply =
send(allSupervisorInfo_.getGatewayDescriptor(),
3676 stateMachineWorkLoopManager_.getMessage(workLoop));
3677 stateMachineWorkLoopManager_.report(workLoop, reply, 100,
true);
3679 __COUT__ <<
"Done with FSM command '" << command <<
".' Reply = " << reply << __E__;
3680 stateMachineSemaphore_.give();
3682 if(reply ==
"Fault")
3684 __SS__ <<
"Failure to send Workloop transition command '" << command
3685 <<
"!' An error response '" << reply <<
"' was received." << __E__;
3686 __COUT_ERR__ << ss.str();
3698 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
3706 auto pause = std::chrono::system_clock::now();
3707 std::time_t pause_time = std::chrono::system_clock::to_time_t(pause);
3708 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() <<
" at "
3709 << std::ctime(&pause_time) << __E__;
3711 if(theStateMachine_.getProvenanceStateName() ==
3712 RunControlStateMachine::RUNNING_STATE_NAME)
3717 CorePropertySupervisorBase::theConfigurationManager_
3718 ->getSupervisorTableNode(supervisorContextUID_,
3719 supervisorApplicationUID_);
3723 configLinkNode.
getNode(
"LinkToStateMachineTable")
3724 .
getNode(activeStateMachineName_);
3725 std::string runInfoPluginType =
3727 __COUTV__(runInfoPluginType);
3728 if(runInfoPluginType != TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
3729 runInfoPluginType !=
"No Run Info Plugin")
3731 std::unique_ptr<RunInfoVInterface> runInfoInterface =
nullptr;
3734 runInfoInterface.reset(
3735 makeRunInfo(runInfoPluginType, activeStateMachineName_));
3741 if(runInfoInterface ==
nullptr)
3743 __SS__ <<
"Run Info interface plugin construction failed of type "
3744 << runInfoPluginType << __E__;
3748 runInfoInterface->updateRunInfo(
3749 getNextRunNumber(activeStateMachineName_) - 1,
3750 RunInfoVInterface::RunStopType::PAUSE);
3754 catch(
const std::runtime_error& e)
3757 __SS__ <<
"RUN INFO PAUSE TIME UPDATE INTO DATABASE FAILED!!! " << e.what()
3764 __SS__ <<
"RUN INFO PAUSE TIME UPDATE INTO DATABASE FAILED!!! " << __E__;
3769 catch(
const std::exception& e)
3771 ss <<
"Exception message: " << e.what();
3784 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
3786 if(theStateMachine_.getProvenanceStateName() ==
3787 RunControlStateMachine::PAUSED_STATE_NAME)
3789 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName()
3790 <<
" coming from resume" << __E__;
3795 CorePropertySupervisorBase::theConfigurationManager_
3796 ->getSupervisorTableNode(supervisorContextUID_,
3797 supervisorApplicationUID_);
3801 configLinkNode.
getNode(
"LinkToStateMachineTable")
3802 .
getNode(activeStateMachineName_);
3803 std::string runInfoPluginType =
3805 __COUTV__(runInfoPluginType);
3806 if(runInfoPluginType != TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
3807 runInfoPluginType !=
"No Run Info Plugin")
3809 std::unique_ptr<RunInfoVInterface> runInfoInterface =
nullptr;
3812 runInfoInterface.reset(
3813 makeRunInfo(runInfoPluginType, activeStateMachineName_));
3819 if(runInfoInterface ==
nullptr)
3821 __SS__ <<
"Run Info interface plugin construction failed of type "
3822 << runInfoPluginType << __E__;
3826 runInfoInterface->updateRunInfo(
3827 getNextRunNumber(activeStateMachineName_) - 1,
3828 RunInfoVInterface::RunStopType::RESUME);
3832 catch(
const std::runtime_error& e)
3835 __SS__ <<
"RUN INFO RESUME TIME UPDATE INTO DATABASE FAILED!!! " << e.what()
3842 __SS__ <<
"RUN INFO RESUME TIME UPDATE INTO DATABASE FAILED!!! " << __E__;
3847 catch(
const std::exception& e)
3849 ss <<
"Exception message: " << e.what();
3862 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName()
3863 <<
" from " << theStateMachine_.getProvenanceStateName() << __E__;
3864 __COUT__ <<
"Fsm is in transition? "
3865 << (theStateMachine_.isInTransition() ?
"yes" :
"no") << __E__;
3868 SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getCommand());
3871 if(theStateMachine_.getProvenanceStateName() ==
3872 RunControlStateMachine::RUNNING_STATE_NAME ||
3873 theStateMachine_.getProvenanceStateName() ==
3874 RunControlStateMachine::PAUSED_STATE_NAME)
3879 CorePropertySupervisorBase::theConfigurationManager_
3880 ->getSupervisorTableNode(supervisorContextUID_,
3881 supervisorApplicationUID_);
3885 configLinkNode.
getNode(
"LinkToStateMachineTable")
3886 .
getNode(activeStateMachineName_);
3887 std::string runInfoPluginType =
3889 __COUTV__(runInfoPluginType);
3890 if(runInfoPluginType != TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
3891 runInfoPluginType !=
"No Run Info Plugin")
3893 std::unique_ptr<RunInfoVInterface> runInfoInterface =
nullptr;
3896 runInfoInterface.reset(
3897 makeRunInfo(runInfoPluginType, activeStateMachineName_));
3906 if(runInfoInterface ==
nullptr)
3908 __SS__ <<
"Run Info interface plugin construction failed of type "
3909 << runInfoPluginType << __E__;
3913 runInfoInterface->updateRunInfo(
3914 getNextRunNumber(activeStateMachineName_) - 1,
3915 RunInfoVInterface::RunStopType::HALT);
3919 catch(
const std::runtime_error& e)
3922 __SS__ <<
"RUN INFO UPDATE INTO DATABASE FAILED!!! " << e.what() << __E__;
3928 __SS__ <<
"RUN INFO UPDATE INTO DATABASE FAILED!!! " << __E__;
3933 catch(
const std::exception& e)
3935 ss <<
"Exception message: " << e.what();
3948 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName()
3949 <<
" from " << theStateMachine_.getProvenanceStateName() << __E__;
3950 __COUT__ <<
"Fsm is in transition? "
3951 << (theStateMachine_.isInTransition() ?
"yes" :
"no") << __E__;
3954 SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getCommand());
3957 if(theStateMachine_.getProvenanceStateName() ==
3958 RunControlStateMachine::RUNNING_STATE_NAME ||
3959 theStateMachine_.getProvenanceStateName() ==
3960 RunControlStateMachine::PAUSED_STATE_NAME)
3965 CorePropertySupervisorBase::theConfigurationManager_
3966 ->getSupervisorTableNode(supervisorContextUID_,
3967 supervisorApplicationUID_);
3971 configLinkNode.
getNode(
"LinkToStateMachineTable")
3972 .
getNode(activeStateMachineName_);
3973 std::string runInfoPluginType =
3975 __COUTV__(runInfoPluginType);
3976 if(runInfoPluginType != TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
3977 runInfoPluginType !=
"No Run Info Plugin")
3979 std::unique_ptr<RunInfoVInterface> runInfoInterface =
nullptr;
3982 runInfoInterface.reset(
3983 makeRunInfo(runInfoPluginType, activeStateMachineName_));
3992 if(runInfoInterface ==
nullptr)
3994 __SS__ <<
"Run Info interface plugin construction failed of type "
3995 << runInfoPluginType << __E__;
3999 runInfoInterface->updateRunInfo(
4000 getNextRunNumber(activeStateMachineName_) - 1,
4001 RunInfoVInterface::RunStopType::STOP);
4005 catch(
const std::runtime_error& e)
4008 __SS__ <<
"RUN INFO INSERT OR UPDATE INTO DATABASE FAILED!!! " << e.what()
4015 __SS__ <<
"RUN INFO INSERT OR UPDATE INTO DATABASE FAILED!!! " << __E__;
4020 catch(
const std::exception& e)
4022 ss <<
"Exception message: " << e.what();
4034 void GatewaySupervisor::inError(toolbox::fsm::FiniteStateMachine& )
4036 __COUT__ <<
"Error occured - FSM current state: "
4037 <<
"Failed? = " << theStateMachine_.getCurrentStateName()
4040 " from " << theStateMachine_.getProvenanceStateName() << __E__;
4043 <<
"Error occured on command: "
4044 << (SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getCommand())
4048 if(theStateMachine_.getProvenanceStateName() ==
4049 RunControlStateMachine::RUNNING_STATE_NAME ||
4050 theStateMachine_.getProvenanceStateName() ==
4051 RunControlStateMachine::PAUSED_STATE_NAME)
4056 CorePropertySupervisorBase::theConfigurationManager_
4057 ->getSupervisorTableNode(supervisorContextUID_,
4058 supervisorApplicationUID_);
4062 configLinkNode.
getNode(
"LinkToStateMachineTable")
4063 .
getNode(activeStateMachineName_);
4064 std::string runInfoPluginType =
4066 __COUTV__(runInfoPluginType);
4067 if(runInfoPluginType != TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
4068 runInfoPluginType !=
"No Run Info Plugin")
4070 std::unique_ptr<RunInfoVInterface> runInfoInterface =
nullptr;
4073 runInfoInterface.reset(
4074 makeRunInfo(runInfoPluginType, activeStateMachineName_));
4083 if(runInfoInterface ==
nullptr)
4085 __SS__ <<
"Run Info interface plugin construction failed of type "
4086 << runInfoPluginType << __E__;
4090 runInfoInterface->updateRunInfo(
4091 getNextRunNumber(activeStateMachineName_) - 1,
4092 RunInfoVInterface::RunStopType::ERROR);
4096 catch(
const std::runtime_error& e)
4099 __SS__ <<
"RUN INFO INSERT OR UPDATE INTO DATABASE FAILED!!! " << e.what()
4106 __SS__ <<
"RUN INFO INSERT OR UPDATE INTO DATABASE FAILED!!! " << __E__;
4111 catch(
const std::exception& e)
4113 ss <<
"Exception message: " << e.what();
4125 void GatewaySupervisor::enteringError(toolbox::Event::Reference e)
4127 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName()
4128 <<
", Error event type: " << e->type() << __E__;
4134 toolbox::fsm::FailedEvent& failedEvent =
dynamic_cast<toolbox::fsm::FailedEvent&
>(*e);
4135 xcept::Exception& failedException = failedEvent.getException();
4141 bool asyncFailureIdentified =
false;
4144 if(RunControlStateMachine::asyncFailureReceived_)
4146 ss <<
"\nAn asynchronous failure was encountered."
4147 <<
".\n\nException:\n"
4148 << failedException.message() << __E__;
4150 RunControlStateMachine::asyncFailureReceived_ =
false;
4151 asyncFailureIdentified =
true;
4155 ss <<
"\nFailure performing transition from " << failedEvent.getFromState() <<
"-"
4156 << theStateMachine_.getStateName(failedEvent.getFromState()) <<
" to "
4157 << failedEvent.getToState() <<
"-"
4158 << theStateMachine_.getStateName(failedEvent.getToState())
4159 <<
".\n\nException:\n"
4160 << failedException.message() << __E__;
4164 __COUT_ERR__ <<
"\n" << ss.str();
4166 theStateMachine_.setErrorMessage(ss.str());
4168 if(!asyncFailureIdentified && theStateMachine_.getCurrentStateName() ==
4169 RunControlStateMachine::FAILED_STATE_NAME)
4170 __COUT__ <<
"Already in failed state, so not broadcasting Error transition again."
4173 broadcastMessage(SOAPUtilities::makeSOAPMessageReference(
4174 RunControlStateMachine::ERROR_TRANSITION_NAME));
4178 void GatewaySupervisor::checkForAsyncError()
4180 if(RunControlStateMachine::asyncFailureReceived_)
4182 __COUTV__(RunControlStateMachine::asyncFailureReceived_);
4184 XCEPT_RAISE(toolbox::fsm::exception::Exception,
4185 RunControlStateMachine::getErrorMessage());
4195 void GatewaySupervisor::transitionConfiguring(toolbox::Event::Reference )
4198 checkForAsyncError();
4200 RunControlStateMachine::theProgressBar_.step();
4202 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
4204 std::string configurationAlias =
4205 SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
4207 .getValue(
"ConfigurationAlias");
4209 __COUT__ <<
"Transition parameter ConfigurationAlias: " << configurationAlias
4212 RunControlStateMachine::theProgressBar_.step();
4214 __COUT__ <<
"Configuration table group name: " << theConfigurationTableGroup_.first
4215 <<
" key: " << theConfigurationTableGroup_.second << __E__;
4218 if(activeStateMachineRollOverLogOnConfigure_)
4220 __COUT_INFO__ <<
"Rolling over log file on Configure transition..." << __E__;
4221 std::stringstream runSs;
4222 runSs <<
"LOG_ROLLOVER";
4225 <<
"_" << theConfigurationTableGroup_.first <<
"_v"
4226 << theConfigurationTableGroup_.second;
4228 GatewaySupervisor::launchStartOTSCommand(
4229 runSs.str(), CorePropertySupervisorBase::theConfigurationManager_);
4232 RunControlStateMachine::theProgressBar_.step();
4238 doLog = __ENV__(
"OTS_LOG_TRANSITION_STARTS") == std::string(
"1");
4246 std::stringstream ss;
4247 ss <<
"Configuring with System Configuration Alias '" << configurationAlias
4248 <<
"' which translates to " << theConfigurationTableGroup_.first <<
"("
4249 << theConfigurationTableGroup_.second <<
"). Active Context Group "
4250 << CorePropertySupervisorBase::theConfigurationManager_->getActiveGroupName(
4251 ConfigurationManager::GroupType::CONTEXT_TYPE)
4253 << CorePropertySupervisorBase::theConfigurationManager_->getActiveGroupKey(
4254 ConfigurationManager::GroupType::CONTEXT_TYPE)
4257 if(getLastLogEntry(RunControlStateMachine::CONFIGURE_TRANSITION_NAME) !=
"")
4258 ss <<
"\n\n-----------------\nUser log entry:\n"
4259 << getLastLogEntry(RunControlStateMachine::CONFIGURE_TRANSITION_NAME)
4260 <<
"\n-----------------\n";
4262 ss <<
" No user log entry.";
4263 makeSystemLogEntry(ss.str());
4266 RunControlStateMachine::theProgressBar_.step();
4270 CorePropertySupervisorBase::theConfigurationManager_->dumpMacroMakerModeFhicl();
4274 __COUT_ERR__ <<
"Failed to dump MacroMaker mode fhicl." << __E__;
4277 RunControlStateMachine::theProgressBar_.step();
4279 parameters.addParameter(
"ConfigurationTableGroupName",
4280 theConfigurationTableGroup_.first);
4281 parameters.addParameter(
"ConfigurationTableGroupKey",
4282 theConfigurationTableGroup_.second.toString());
4285 if(CorePropertySupervisorBase::allSupervisorInfo_.getAllMacroMakerTypeSupervisorInfo()
4288 __COUT__ <<
"Initializing Macro Maker." << __E__;
4289 xoap::MessageReference message =
4290 SOAPUtilities::makeSOAPMessageReference(
"FECommunication");
4293 parameters.addParameter(
"type",
"initFElist");
4294 parameters.addParameter(
"groupName", theConfigurationTableGroup_.first);
4295 parameters.addParameter(
"groupKey",
4296 theConfigurationTableGroup_.second.toString());
4297 SOAPUtilities::addParameters(message, parameters);
4299 __COUT__ <<
"Sending FE communication: " << SOAPUtilities::translate(message)
4304 .getAllMacroMakerTypeSupervisorInfo()
4306 ->second.getDescriptor(),
4309 __COUT__ <<
"Macro Maker init reply: " << reply << __E__;
4310 if(reply ==
"Error")
4312 __SS__ <<
"\nTransition to Configuring interrupted! There was an error "
4313 "identified initializing Macro Maker.\n\n "
4315 __COUT_ERR__ <<
"\n" << ss.str();
4316 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4320 RunControlStateMachine::theProgressBar_.step();
4322 xoap::MessageReference message = theStateMachine_.getCurrentMessage();
4323 SOAPUtilities::addParameters(message, parameters);
4325 broadcastMessage(message);
4326 RunControlStateMachine::theProgressBar_.step();
4329 std::string remoteSubsystemDump =
"";
4331 std::vector<GatewaySupervisor::RemoteGatewayInfo> remoteGatewayApps;
4333 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
4334 __SUP_COUTVS__(22, remoteGatewayApps_.size());
4335 remoteGatewayApps = remoteGatewayApps_;
4336 if(remoteGatewayApps_.size())
4337 __SUP_COUT_TYPE__(TLVL_DEBUG + 22)
4338 << __COUT_HDR__ << remoteGatewayApps_[0].command <<
" "
4339 << (remoteGatewayApps_[0].appInfo.status) << __E__;
4341 for(
auto& remoteGatewayApp : remoteGatewayApps)
4343 if(!remoteGatewayApp.fsm_included)
4345 remoteSubsystemDump += remoteGatewayApp.config_dump;
4348 if(remoteSubsystemDump.size())
4349 __COUTV__(remoteSubsystemDump);
4351 RunControlStateMachine::theProgressBar_.step();
4353 if(activeStateMachineConfigurationDumpOnConfigureEnable_)
4356 std::string fullfilename =
4357 activeStateMachineConfigurationDumpOnConfigureFilename_ +
"_" +
4358 std::to_string(time(0)) +
".dump";
4359 FILE* fp = fopen(fullfilename.c_str(),
"w");
4362 __SS__ <<
"Configuration dump failed to file: " << fullfilename << __E__;
4367 fullfilename = __ENV__(
"HOSTNAME") + std::string(
":") + fullfilename;
4369 fp,
"Original location of dump: %s\n", fullfilename.c_str());
4371 if(activeStateMachineConfigurationDumpOnConfigure_.size())
4372 fwrite(&activeStateMachineConfigurationDumpOnConfigure_[0],
4374 activeStateMachineConfigurationDumpOnConfigure_.size(),
4376 __COUT__ <<
"Wrote configuration dump of char count "
4377 << activeStateMachineConfigurationDumpOnConfigure_.size()
4378 <<
" to file: " << fullfilename << __E__;
4380 if(remoteSubsystemDump.size())
4382 fwrite(&remoteSubsystemDump[0], 1, remoteSubsystemDump.size(), fp);
4384 __COUT__ <<
"Wrote remote subsystem configuration dump of char count "
4385 << remoteSubsystemDump.size() <<
" to file: " << fullfilename
4390 __COUT_INFO__ <<
"Configure transition Configuration Dump saved to file: "
4391 << fullfilename << __E__;
4393 RunControlStateMachine::theProgressBar_.step();
4399 if(activeStateMachineRunInfoPluginType_ !=
4400 TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
4401 activeStateMachineRunInfoPluginType_ !=
"No Run Info Plugin")
4403 __COUT_INFO__ <<
"Instantiating Run Info plugin '"
4404 << activeStateMachineRunInfoPluginType_
4405 <<
"' to insert Configure run condition entry." << __E__;
4406 std::unique_ptr<RunInfoVInterface> runInfoInterface =
nullptr;
4409 runInfoInterface.reset(
makeRunInfo(activeStateMachineRunInfoPluginType_,
4410 activeStateMachineName_));
4416 if(runInfoInterface ==
nullptr)
4418 __SS__ <<
"Run Info interface plugin construction failed of type "
4419 << activeStateMachineRunInfoPluginType_
4420 <<
" for inserting Run Condition record of char size "
4421 << activeStateMachineConfigurationDumpOnConfigure_.size() << __E__;
4425 conditionID_ = runInfoInterface->insertRunCondition(
4426 activeStateMachineConfigurationDumpOnConfigure_ + remoteSubsystemDump);
4429 catch(
const std::runtime_error& e)
4431 __SS__ <<
"RUN CONDITION INSERT INTO DATABASE FAILED!!! " << e.what() << __E__;
4436 __SS__ <<
"RUN CONDITION INSERT INTO DATABASE FAILED!!! " << __E__;
4441 catch(
const std::exception& e)
4443 ss <<
"Exception message: " << e.what();
4450 RunControlStateMachine::theProgressBar_.step();
4453 ConfigurationManager::saveGroupNameAndKey(theConfigurationTableGroup_,
4454 FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE);
4456 activeStateMachineConfigurationAlias_ = configurationAlias;
4460 doLog = __ENV__(
"OTS_LOG_INTERMEDIATE_STATES") == std::string(
"1");
4468 std::stringstream ss;
4469 ss <<
"Configured with System Configuration Alias '"
4470 << activeStateMachineConfigurationAlias_ <<
"' which translates to "
4471 << theConfigurationTableGroup_.first <<
"("
4472 << theConfigurationTableGroup_.second <<
"). Active Context Group "
4473 << CorePropertySupervisorBase::theConfigurationManager_->getActiveGroupName(
4474 ConfigurationManager::GroupType::CONTEXT_TYPE)
4476 << CorePropertySupervisorBase::theConfigurationManager_->getActiveGroupKey(
4477 ConfigurationManager::GroupType::CONTEXT_TYPE)
4480 if(getLastLogEntry(RunControlStateMachine::CONFIGURE_TRANSITION_NAME) !=
"")
4481 ss <<
"\n\n-----------------\nUser log entry:\n"
4482 << getLastLogEntry(RunControlStateMachine::CONFIGURE_TRANSITION_NAME)
4483 <<
"\n-----------------\n";
4485 ss <<
" No user log entry.";
4489 ss <<
"\n\n~~~ System Status and Detail ~~~\n";
4492 const auto& appInfo = it.second;
4493 if(appInfo.getClass() != XDAQContextTable::GATEWAY_SUPERVISOR_CLASS)
4495 ss <<
"\tStatus: " << appInfo.getStatus() << __E__
4496 <<
"\tDetail: " << appInfo.getDetail() << __E__;
4500 std::vector<GatewaySupervisor::RemoteGatewayInfo> remoteApps;
4502 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
4503 remoteApps = remoteGatewayApps_;
4506 if(remoteApps.size())
4508 ss <<
"\n\n~~~ Subsystem Status and Detail ~~~\n";
4510 for(
const auto& remoteApp : remoteApps)
4512 const auto& appInfo = remoteApp.appInfo;
4513 ss <<
"Subsystem Name: " << appInfo.name << __E__
4514 <<
"\tStatus: " << appInfo.status << __E__
4515 <<
"\tDetail: " << appInfo.detail << __E__;
4520 makeSystemLogEntry(ss.str());
4522 __COUT__ <<
"Done configuring." << __E__;
4523 RunControlStateMachine::theProgressBar_.complete();
4525 catch(
const xdaq::exception::Exception& e)
4527 __SS__ <<
"\nTransition to Configuring interrupted! There was a system communication "
4530 << __E__ << e.what();
4531 __COUT_ERR__ <<
"\n" << ss.str();
4532 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4534 catch(std::runtime_error& e)
4536 __SS__ <<
"\nTransition to Configuring interrupted! There was an error "
4538 << __E__ << e.what();
4539 __COUT_ERR__ <<
"\n" << ss.str();
4540 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4542 catch(toolbox::fsm::exception::Exception& e)
4548 __SS__ <<
"\nTransition to Configuring interrupted! There was an unknown error "
4555 catch(
const std::exception& e)
4557 ss <<
"Exception message: " << e.what();
4562 __COUT_ERR__ <<
"\n" << ss.str();
4563 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4567 void GatewaySupervisor::transitionHalting(toolbox::Event::Reference )
4570 checkForAsyncError();
4572 RunControlStateMachine::theProgressBar_.step();
4574 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
4579 doLog = __ENV__(
"OTS_LOG_TRANSITION_STARTS") == std::string(
"1");
4585 bool doLogIntermediate =
false;
4588 doLogIntermediate = __ENV__(
"OTS_LOG_INTERMEDIATE_STATES") == std::string(
"1");
4595 if(doLog && doLogIntermediate)
4596 makeSystemLogEntry(
"System halting.");
4598 RunControlStateMachine::theProgressBar_.step();
4600 broadcastMessage(theStateMachine_.getCurrentMessage());
4602 if(doLogIntermediate)
4603 makeSystemLogEntry(
"System halted.");
4604 __COUT__ <<
"Done halting." << __E__;
4605 RunControlStateMachine::theProgressBar_.complete();
4607 catch(
const xdaq::exception::Exception& e)
4610 <<
"\nTransition to Halting interrupted! There was a system communication error "
4612 << __E__ << e.what();
4613 __COUT_ERR__ <<
"\n" << ss.str();
4614 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4616 catch(std::runtime_error& e)
4618 __SS__ <<
"\nTransition to Halting interrupted! There was an error "
4620 << __E__ << e.what();
4621 __COUT_ERR__ <<
"\n" << ss.str();
4622 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4624 catch(toolbox::fsm::exception::Exception& e)
4630 __SS__ <<
"\nTransition to Halting interrupted! There was an unknown error "
4637 catch(
const std::exception& e)
4639 ss <<
"Exception message: " << e.what();
4644 __COUT_ERR__ <<
"\n" << ss.str();
4645 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4649 void GatewaySupervisor::transitionShuttingDown(toolbox::Event::Reference )
4652 checkForAsyncError();
4654 __COUT__ <<
"transitionShuttingDown -- Fsm current state: "
4655 << theStateMachine_.getCurrentStateName()
4656 <<
" message: " << theStateMachine_.getCurrentStateName() << __E__;
4658 RunControlStateMachine::theProgressBar_.step();
4662 doLog = __ENV__(
"OTS_LOG_TRANSITION_STARTS") == std::string(
"1");
4668 bool doLogIntermediate =
false;
4671 doLogIntermediate = __ENV__(
"OTS_LOG_INTERMEDIATE_STATES") == std::string(
"1");
4678 if(doLog && doLogIntermediate)
4679 makeSystemLogEntry(
"System shutting down.");
4680 RunControlStateMachine::theProgressBar_.step();
4683 GatewaySupervisor::launchStartOTSCommand(
4684 "OTS_APP_SHUTDOWN", CorePropertySupervisorBase::theConfigurationManager_);
4685 RunControlStateMachine::theProgressBar_.step();
4689 for(
int i = 0; i < 5; ++i)
4692 RunControlStateMachine::theProgressBar_.step();
4695 broadcastMessage(theStateMachine_.getCurrentMessage());
4697 if(doLogIntermediate)
4698 makeSystemLogEntry(
"System shutdown complete.");
4699 __COUT__ <<
"Done shutting down." << __E__;
4700 RunControlStateMachine::theProgressBar_.complete();
4702 catch(
const xdaq::exception::Exception& e)
4704 __SS__ <<
"\nTransition to Shutting Down interrupted! There was a system "
4705 "communication error "
4707 << __E__ << e.what();
4708 __COUT_ERR__ <<
"\n" << ss.str();
4709 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4711 catch(std::runtime_error& e)
4713 __SS__ <<
"\nTransition to Shutting Down interrupted! There was an error "
4715 << __E__ << e.what();
4716 __COUT_ERR__ <<
"\n" << ss.str();
4717 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4719 catch(toolbox::fsm::exception::Exception& e)
4725 __SS__ <<
"\nTransition to Shutting Down interrupted! There was an unknown error "
4732 catch(
const std::exception& e)
4734 ss <<
"Exception message: " << e.what();
4739 __COUT_ERR__ <<
"\n" << ss.str();
4740 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4744 void GatewaySupervisor::transitionStartingUp(toolbox::Event::Reference )
4747 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
4749 RunControlStateMachine::theProgressBar_.step();
4753 doLog = __ENV__(
"OTS_LOG_TRANSITION_STARTS") == std::string(
"1");
4759 bool doLogIntermediate =
false;
4762 doLogIntermediate = __ENV__(
"OTS_LOG_INTERMEDIATE_STATES") == std::string(
"1");
4769 if(doLog && doLogIntermediate)
4770 makeSystemLogEntry(
"System starting up.");
4771 RunControlStateMachine::theProgressBar_.step();
4774 GatewaySupervisor::launchStartOTSCommand(
4775 "OTS_APP_STARTUP", CorePropertySupervisorBase::theConfigurationManager_);
4776 RunControlStateMachine::theProgressBar_.step();
4780 for(
int i = 0; i < 10; ++i)
4783 RunControlStateMachine::theProgressBar_.step();
4786 broadcastMessage(theStateMachine_.getCurrentMessage());
4788 if(doLogIntermediate)
4789 makeSystemLogEntry(
"System startup complete.");
4790 __COUT__ <<
"Done starting up." << __E__;
4791 RunControlStateMachine::theProgressBar_.complete();
4794 catch(
const xdaq::exception::Exception& e)
4796 __SS__ <<
"\nTransition to Starting Up interrupted! There was a system communication "
4799 << __E__ << e.what();
4800 __COUT_ERR__ <<
"\n" << ss.str();
4801 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4803 catch(std::runtime_error& e)
4805 __SS__ <<
"\nTransition to Starting Up interrupted! There was an error "
4807 << __E__ << e.what();
4808 __COUT_ERR__ <<
"\n" << ss.str();
4809 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4811 catch(toolbox::fsm::exception::Exception& e)
4817 __SS__ <<
"\nTransition to Starting Up interrupted! There was an unknown error "
4824 catch(
const std::exception& e)
4826 ss <<
"Exception message: " << e.what();
4831 __COUT_ERR__ <<
"\n" << ss.str();
4832 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4836 void GatewaySupervisor::transitionInitializing(toolbox::Event::Reference event)
4839 __COUT__ << theStateMachine_.getCurrentStateName() << __E__;
4841 broadcastMessage(theStateMachine_.getCurrentMessage());
4843 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
4844 __COUT__ <<
"Fsm current transition: "
4845 << theStateMachine_.getCurrentTransitionName(event->type()) << __E__;
4846 __COUT__ <<
"Fsm final state: "
4847 << theStateMachine_.getTransitionFinalStateName(event->type()) << __E__;
4852 doLog = __ENV__(
"OTS_LOG_INTERMEDIATE_STATES") == std::string(
"1");
4859 makeSystemLogEntry(
"System initialized.");
4861 __COUT__ <<
"Done initializing." << __E__;
4862 RunControlStateMachine::theProgressBar_.complete();
4865 catch(
const xdaq::exception::Exception& e)
4867 __SS__ <<
"\nTransition to Initializing interrupted! There was a system "
4868 "communication error "
4870 << __E__ << e.what();
4871 __COUT_ERR__ <<
"\n" << ss.str();
4872 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4874 catch(std::runtime_error& e)
4876 __SS__ <<
"\nTransition to Initializing interrupted! There was an error "
4878 << __E__ << e.what();
4879 __COUT_ERR__ <<
"\n" << ss.str();
4880 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4882 catch(toolbox::fsm::exception::Exception& e)
4888 __SS__ <<
"\nTransition to Initializing interrupted! There was an unknown error "
4895 catch(
const std::exception& e)
4897 ss <<
"Exception message: " << e.what();
4902 __COUT_ERR__ <<
"\n" << ss.str();
4903 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4907 void GatewaySupervisor::transitionPausing(toolbox::Event::Reference )
4910 checkForAsyncError();
4912 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
4914 RunControlStateMachine::theProgressBar_.step();
4920 doLog = __ENV__(
"OTS_LOG_TRANSITION_STARTS") == std::string(
"1");
4927 std::ostringstream dur_ss;
4929 int dur = std::chrono::duration_cast<std::chrono::milliseconds>(
4930 std::chrono::steady_clock::now() - activeStateMachineRunStartTime)
4932 activeStateMachineRunDuration_ms;
4933 int dur_s = dur / 1000;
4935 int dur_m = dur_s / 60;
4937 int dur_h = dur_m / 60;
4939 dur_ss << activeStateMachineRunAlias_ <<
" '" << activeStateMachineRunNumber_
4940 <<
"' duration so far of " << std::setw(2) << std::setfill(
'0') << dur_h
4941 <<
":" << std::setw(2) << std::setfill(
'0') << dur_m <<
":" << std::setw(2)
4942 << std::setfill(
'0')
4944 if(dur_h == 0 && dur_m == 0 && dur_s < 5)
4945 dur_ss <<
"." << dur <<
" seconds.";
4950 makeSystemLogEntry(
"Run pausing. " + dur_ss.str());
4953 activeStateMachineRunDuration_ms +=
4954 std::chrono::duration_cast<std::chrono::milliseconds>(
4955 std::chrono::steady_clock::now() - activeStateMachineRunStartTime)
4959 if(RunControlStateMachine::asyncPauseExceptionReceived_)
4961 __COUT_ERR__ <<
"Broadcasting pause for async PAUSE exception!" << __E__;
4962 broadcastMessage(SOAPUtilities::makeSOAPMessageReference(
"Pause"));
4965 broadcastMessage(theStateMachine_.getCurrentMessage());
4968 "Run paused. " + dur_ss.str(),
4969 activeStateMachineRunAlias_ +
" '" + activeStateMachineRunNumber_ +
"' paused");
4970 __COUT__ <<
"Done pausing." << __E__;
4971 RunControlStateMachine::theProgressBar_.complete();
4974 catch(
const xdaq::exception::Exception& e)
4977 <<
"\nTransition to Pausing interrupted! There was a system communication error "
4979 << __E__ << e.what();
4980 __COUT_ERR__ <<
"\n" << ss.str();
4981 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4983 catch(std::runtime_error& e)
4985 __SS__ <<
"\nTransition to Pausing interrupted! There was an error "
4987 << __E__ << e.what();
4988 __COUT_ERR__ <<
"\n" << ss.str();
4989 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
4991 catch(toolbox::fsm::exception::Exception& e)
4997 __SS__ <<
"\nTransition to Pausing interrupted! There was an unknown error "
5004 catch(
const std::exception& e)
5006 ss <<
"Exception message: " << e.what();
5011 __COUT_ERR__ <<
"\n" << ss.str();
5012 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5016 void GatewaySupervisor::transitionResuming(toolbox::Event::Reference )
5019 if(RunControlStateMachine::asyncPauseExceptionReceived_)
5022 __COUT_INFO__ <<
"Clearing async PAUSE exception!" << __E__;
5023 RunControlStateMachine::asyncPauseExceptionReceived_ =
false;
5025 else if(RunControlStateMachine::asyncStopExceptionReceived_)
5028 __COUT_INFO__ <<
"Clearing async STOP exception!" << __E__;
5029 RunControlStateMachine::asyncStopExceptionReceived_ =
false;
5032 checkForAsyncError();
5034 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
5039 doLog = __ENV__(
"OTS_LOG_TRANSITION_STARTS") == std::string(
"1");
5047 std::stringstream ss;
5048 ss << activeStateMachineRunAlias_ <<
" '" << activeStateMachineRunNumber_
5051 if(getLastLogEntry(RunControlStateMachine::RESUME_TRANSITION_NAME) !=
"")
5052 ss <<
"\n\n-----------------\nUser log entry:\n"
5053 << getLastLogEntry(RunControlStateMachine::RESUME_TRANSITION_NAME)
5054 <<
"\n-----------------\n";
5056 ss <<
" No user log entry.";
5058 makeSystemLogEntry(ss.str());
5061 activeStateMachineRunStartTime = std::chrono::steady_clock::now();
5063 broadcastMessage(theStateMachine_.getCurrentMessage());
5067 std::stringstream ss;
5068 ss << activeStateMachineRunAlias_ <<
" '" << activeStateMachineRunNumber_
5071 if(getLastLogEntry(RunControlStateMachine::RESUME_TRANSITION_NAME) !=
"")
5072 ss <<
"\n\n-----------------\nUser log entry:\n"
5073 << getLastLogEntry(RunControlStateMachine::RESUME_TRANSITION_NAME)
5074 <<
"\n-----------------\n";
5076 ss <<
" No user log entry.";
5078 makeSystemLogEntry(ss.str(),
5079 activeStateMachineRunAlias_ +
" '" +
5080 activeStateMachineRunNumber_ +
"' resumed");
5083 __COUT__ <<
"Done resuming." << __E__;
5084 RunControlStateMachine::theProgressBar_.complete();
5086 catch(
const xdaq::exception::Exception& e)
5089 <<
"\nTransition to Resuming interrupted! There was a system communication error "
5091 << __E__ << e.what();
5092 __COUT_ERR__ <<
"\n" << ss.str();
5093 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5095 catch(std::runtime_error& e)
5097 __SS__ <<
"\nTransition to Resuming interrupted! There was an error "
5099 << __E__ << e.what();
5100 __COUT_ERR__ <<
"\n" << ss.str();
5101 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5103 catch(toolbox::fsm::exception::Exception& e)
5109 __SS__ <<
"\nTransition to Resuming interrupted! There was an unknown error "
5116 catch(
const std::exception& e)
5118 ss <<
"Exception message: " << e.what();
5123 __COUT_ERR__ <<
"\n" << ss.str();
5124 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5128 void GatewaySupervisor::transitionStarting(toolbox::Event::Reference )
5131 if(RunControlStateMachine::asyncPauseExceptionReceived_)
5134 __COUT_INFO__ <<
"Clearing async PAUSE exception!" << __E__;
5135 RunControlStateMachine::asyncPauseExceptionReceived_ =
false;
5137 else if(RunControlStateMachine::asyncStopExceptionReceived_)
5140 __COUT_INFO__ <<
"Clearing async STOP exception!" << __E__;
5141 RunControlStateMachine::asyncStopExceptionReceived_ =
false;
5144 checkForAsyncError();
5146 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
5148 RunControlStateMachine::theProgressBar_.step();
5151 SOAPUtilities::receive(theStateMachine_.getCurrentMessage(), parameters);
5153 activeStateMachineRunNumber_ = parameters.getValue(
"RunNumber");
5154 __COUTV__(activeStateMachineRunNumber_);
5156 RunControlStateMachine::theProgressBar_.step();
5159 if(activeStateMachineRollOverLogOnStart_)
5161 __COUT_INFO__ <<
"Rolling over log file on Start transition..." << __E__;
5162 std::stringstream runSs;
5163 runSs <<
"LOG_ROLLOVER";
5164 runSs <<
";" << activeStateMachineRunAlias_ <<
"_"
5165 << activeStateMachineRunNumber_;
5167 GatewaySupervisor::launchStartOTSCommand(
5168 runSs.str(), CorePropertySupervisorBase::theConfigurationManager_);
5171 RunControlStateMachine::theProgressBar_.step();
5177 doLog = __ENV__(
"OTS_LOG_TRANSITION_STARTS") == std::string(
"1");
5185 std::stringstream ss;
5186 ss << activeStateMachineRunAlias_ <<
" '" << activeStateMachineRunNumber_
5189 if(getLastLogEntry(RunControlStateMachine::START_TRANSITION_NAME) !=
"")
5190 ss <<
"\n\n-----------------\nUser log entry:\n"
5191 << getLastLogEntry(RunControlStateMachine::START_TRANSITION_NAME)
5192 <<
"\n-----------------\n";
5194 ss <<
" No user log entry.";
5196 makeSystemLogEntry(ss.str());
5198 RunControlStateMachine::theProgressBar_.step();
5200 activeStateMachineRunStartTime = std::chrono::steady_clock::now();
5201 activeStateMachineRunDuration_ms = 0;
5204 .getCurrentMessage());
5205 RunControlStateMachine::theProgressBar_.step();
5208 std::string remoteSubsystemDump =
"";
5210 std::vector<GatewaySupervisor::RemoteGatewayInfo> remoteGatewayApps;
5212 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
5213 __SUP_COUTVS__(22, remoteGatewayApps_.size());
5214 remoteGatewayApps = remoteGatewayApps_;
5215 if(remoteGatewayApps_.size())
5216 __SUP_COUT_TYPE__(TLVL_DEBUG + 22)
5217 << __COUT_HDR__ << remoteGatewayApps_[0].command <<
" "
5218 << (remoteGatewayApps_[0].appInfo.status) << __E__;
5221 remoteSubsystemDump +=
5222 "--------------- Remote Subsystem Status ---------------\n";
5223 remoteSubsystemDump +=
5224 "Remote Subsystem Count: " + std::to_string(remoteGatewayApps.size()) +
"\n";
5226 for(
auto& remoteGatewayApp : remoteGatewayApps)
5228 remoteSubsystemDump += std::to_string(ssi) +
". ~~ subsystem_name: " +
5229 remoteGatewayApp.appInfo.name +
"\n. ";
5230 remoteSubsystemDump +=
5231 "subsystem_url: " + remoteGatewayApp.appInfo.url +
"\n. ";
5233 remoteSubsystemDump +=
5234 "subsystem_status: " + remoteGatewayApp.appInfo.status +
"\n. ";
5235 remoteSubsystemDump +=
"subsystem_progress: " +
5236 std::to_string(remoteGatewayApp.appInfo.progress) +
5238 remoteSubsystemDump +=
5239 "subsystem_detail: " + remoteGatewayApp.appInfo.detail +
"\n. ";
5243 remoteSubsystemDump +=
5244 "subsystem_configAlias: " + remoteGatewayApp.selected_config_alias +
5246 remoteSubsystemDump +=
5247 "subsystem_fsmMode: " + remoteGatewayApp.getFsmMode() +
"\n. ";
5248 remoteSubsystemDump +=
5249 "subsystem_fsmIncluded: " +
5250 std::string(remoteGatewayApp.fsm_included ?
"1" :
"0") +
"\n. ";
5252 remoteSubsystemDump +=
5253 "--------------- end Remote Subsystem Status ---------------\n";
5255 remoteSubsystemDump +=
"\n\n-----------------\nRemote Configuration dump:\n";
5256 for(
auto& remoteGatewayApp : remoteGatewayApps)
5258 if(!remoteGatewayApp.fsm_included)
5260 remoteSubsystemDump += remoteGatewayApp.config_dump;
5262 remoteSubsystemDump +=
"\nEND Remote Configuration dump:\n-----------------\n";
5264 if(remoteSubsystemDump.size())
5265 __COUTV__(remoteSubsystemDump);
5267 RunControlStateMachine::theProgressBar_.step();
5269 if(activeStateMachineConfigurationDumpOnRunEnable_)
5272 std::string fullfilename = activeStateMachineConfigurationDumpOnRunFilename_ +
5273 "_" + std::to_string(time(0)) +
".dump";
5274 FILE* fp = fopen(fullfilename.c_str(),
"w");
5277 __SS__ <<
"Configuration dump failed to file: " << fullfilename << __E__;
5282 fullfilename = __ENV__(
"HOSTNAME") + std::string(
":") + fullfilename;
5284 fp,
"Original location of dump: %s\n", fullfilename.c_str());
5286 if(activeStateMachineConfigurationDumpOnRun_.size())
5287 fwrite(&activeStateMachineConfigurationDumpOnRun_[0],
5289 activeStateMachineConfigurationDumpOnRun_.size(),
5291 __COUT__ <<
"Wrote configuration dump of char count "
5292 << activeStateMachineConfigurationDumpOnRun_.size()
5293 <<
" to file: " << fullfilename << __E__;
5295 if(remoteSubsystemDump.size())
5297 fwrite(&remoteSubsystemDump[0], 1, remoteSubsystemDump.size(), fp);
5299 __COUT__ <<
"Wrote remote subsystem configuration dump of char count "
5300 << remoteSubsystemDump.size() <<
" to file: " << fullfilename
5305 __COUT_INFO__ <<
"Run transition Configuration Dump saved to file: "
5306 << fullfilename << __E__;
5308 RunControlStateMachine::theProgressBar_.step();
5311 ConfigurationManager::saveGroupNameAndKey(theConfigurationTableGroup_,
5312 FSM_LAST_STARTED_GROUP_ALIAS_FILE);
5313 RunControlStateMachine::theProgressBar_.complete();
5317 std::stringstream ss;
5318 ss << activeStateMachineRunAlias_ <<
" '" << activeStateMachineRunNumber_
5321 if(getLastLogEntry(RunControlStateMachine::START_TRANSITION_NAME) !=
"")
5322 ss <<
"\n\n-----------------\nUser log entry:\n"
5323 << getLastLogEntry(RunControlStateMachine::START_TRANSITION_NAME)
5324 <<
"\n-----------------\n";
5326 ss <<
" No user log entry.";
5330 ss <<
"\n\n~~~ System Status and Detail ~~~\n";
5333 const auto& appInfo = it.second;
5334 if(appInfo.getClass() != XDAQContextTable::GATEWAY_SUPERVISOR_CLASS)
5336 ss <<
"\tStatus: " << appInfo.getStatus() << __E__
5337 <<
"\tDetail: " << appInfo.getDetail() << __E__;
5341 std::vector<GatewaySupervisor::RemoteGatewayInfo> remoteApps;
5343 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
5344 remoteApps = remoteGatewayApps_;
5347 if(remoteApps.size())
5349 ss <<
"\n\n~~~ Subsystem Status and Detail ~~~\n";
5351 for(
const auto& remoteApp : remoteApps)
5353 const auto& appInfo = remoteApp.appInfo;
5354 ss <<
"Subsystem Name: " << appInfo.name << __E__
5355 <<
"\tStatus: " << appInfo.status << __E__
5356 <<
"\tDetail: " << appInfo.detail << __E__;
5363 ss <<
"\n\nConfigured with System Configuration Alias '"
5364 << activeStateMachineConfigurationAlias_ <<
"' which translates to "
5365 << theConfigurationTableGroup_.first <<
"("
5366 << theConfigurationTableGroup_.second <<
"). Active Context Group "
5367 << CorePropertySupervisorBase::theConfigurationManager_
5368 ->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
5370 << CorePropertySupervisorBase::theConfigurationManager_->getActiveGroupKey(
5371 ConfigurationManager::GroupType::CONTEXT_TYPE)
5374 if(activeStateMachineConfigurationDumpOnRunEnable_)
5376 ss <<
"\n\n-----------------\nConfiguration dump:\n"
5377 << activeStateMachineConfigurationDumpOnRun_;
5378 ss <<
"\nEND Remote Configuration dump:\n-----------------\n";
5381 if(remoteSubsystemDump.size())
5382 ss << remoteSubsystemDump;
5385 makeSystemLogEntry(ss.str(),
5386 activeStateMachineRunAlias_ +
" '" +
5387 activeStateMachineRunNumber_ +
"' started");
5389 __COUT__ <<
"Done starting run." << __E__;
5390 RunControlStateMachine::theProgressBar_.complete();
5393 catch(
const xdaq::exception::Exception& e)
5395 __SS__ <<
"\nTransition to Starting Run interrupted! There was a system "
5396 "communication error "
5398 << __E__ << e.what();
5399 __COUT_ERR__ <<
"\n" << ss.str();
5400 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5402 catch(std::runtime_error& e)
5404 __SS__ <<
"\nTransition to Starting Run interrupted! There was an error "
5406 << __E__ << e.what();
5407 __COUT_ERR__ <<
"\n" << ss.str();
5408 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5410 catch(toolbox::fsm::exception::Exception& e)
5416 __SS__ <<
"\nTransition to Starting Run interrupted! There was an unknown error "
5423 catch(
const std::exception& e)
5425 ss <<
"Exception message: " << e.what();
5430 __COUT_ERR__ <<
"\n" << ss.str();
5431 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5435 void GatewaySupervisor::transitionStopping(toolbox::Event::Reference )
5438 checkForAsyncError();
5440 __COUT__ <<
"Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
5442 activeStateMachineRunDuration_ms +=
5443 std::chrono::duration_cast<std::chrono::milliseconds>(
5444 std::chrono::steady_clock::now() - activeStateMachineRunStartTime)
5447 RunControlStateMachine::theProgressBar_.step();
5452 doLog = __ENV__(
"OTS_LOG_TRANSITION_STARTS") == std::string(
"1");
5460 std::ostringstream dur_ss;
5462 int dur = activeStateMachineRunDuration_ms;
5463 int dur_s = dur / 1000;
5465 int dur_m = dur_s / 60;
5467 int dur_h = dur_m / 60;
5469 dur_ss << activeStateMachineRunAlias_ <<
" '" << activeStateMachineRunNumber_
5470 <<
"' duration of " << std::setw(2) << std::setfill(
'0') << dur_h <<
":"
5471 << std::setw(2) << std::setfill(
'0') << dur_m <<
":" << std::setw(2)
5472 << std::setfill(
'0')
5474 if(dur_h == 0 && dur_m == 0 && dur_s < 5)
5475 dur_ss <<
"." << dur <<
" seconds.";
5481 std::stringstream ss;
5483 if(getLastLogEntry(RunControlStateMachine::STOP_TRANSITION_NAME) !=
"")
5484 ss <<
"\n\n-----------------\nUser log entry:\n"
5485 << getLastLogEntry(RunControlStateMachine::STOP_TRANSITION_NAME)
5486 <<
"\n-----------------\n";
5488 ss <<
" No user log entry.";
5490 makeSystemLogEntry(
"Run stopping. " + ss.str());
5495 if(RunControlStateMachine::asyncStopExceptionReceived_)
5497 __COUT_ERR__ <<
"Broadcasting stop for async STOP exception!" << __E__;
5498 broadcastMessage(SOAPUtilities::makeSOAPMessageReference(
"Stop"));
5501 broadcastMessage(theStateMachine_.getCurrentMessage());
5505 std::stringstream ss;
5507 if(getLastLogEntry(RunControlStateMachine::STOP_TRANSITION_NAME) !=
"")
5508 ss <<
"\n\n-----------------\nUser log entry:\n"
5509 << getLastLogEntry(RunControlStateMachine::STOP_TRANSITION_NAME)
5510 <<
"\n-----------------\n";
5512 ss <<
" No user log entry.";
5514 makeSystemLogEntry(
"Run stopped.\n" + ss.str(),
5515 activeStateMachineRunAlias_ +
" '" +
5516 activeStateMachineRunNumber_ +
"' stopped");
5519 __COUT__ <<
"Done stopping run." << __E__;
5520 RunControlStateMachine::theProgressBar_.complete();
5523 if(activeStateMachineRollOverLogOnStart_)
5525 __COUT_INFO__ <<
"Rolling over log file on Stop transition..." << __E__;
5526 std::stringstream runSs;
5527 runSs <<
"LOG_ROLLOVER";
5528 runSs <<
";Post" << activeStateMachineRunAlias_ <<
"_"
5529 << activeStateMachineRunNumber_;
5531 GatewaySupervisor::launchStartOTSCommand(
5532 runSs.str(), CorePropertySupervisorBase::theConfigurationManager_);
5535 RunControlStateMachine::theProgressBar_.step();
5538 catch(
const xdaq::exception::Exception& e)
5540 __SS__ <<
"\nTransition to Stopping Run interrupted! There was a system "
5541 "communication error "
5543 << __E__ << e.what();
5544 __COUT_ERR__ <<
"\n" << ss.str();
5545 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5547 catch(std::runtime_error& e)
5549 __SS__ <<
"\nTransition to Stopping Run interrupted! There was an error "
5551 << __E__ << e.what();
5552 __COUT_ERR__ <<
"\n" << ss.str();
5553 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5555 catch(toolbox::fsm::exception::Exception& e)
5561 __SS__ <<
"\nTransition to Stopping Run interrupted! There was an unknown error "
5568 catch(
const std::exception& e)
5570 ss <<
"Exception message: " << e.what();
5575 __COUT_ERR__ <<
"\n" << ss.str();
5576 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5589 bool GatewaySupervisor::handleBroadcastMessageTarget(
const SupervisorInfo& appInfo,
5590 xoap::MessageReference message,
5591 const std::string& command,
5592 const unsigned int& iteration,
5594 unsigned int threadIndex)
5597 unsigned int subIteration = 0;
5598 bool subIterationsDone =
false;
5599 bool iterationsDone =
true;
5601 while(!subIterationsDone)
5603 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5604 <<
"Supervisor instance = '" << appInfo.getName()
5605 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
5606 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
5607 <<
"] Command = " << command << __E__;
5609 checkForAsyncError();
5611 subIterationsDone =
true;
5612 RunControlStateMachine::theProgressBar_.step();
5618 parameters.addParameter(
"subIterationIndex", subIteration);
5619 SOAPUtilities::addParameters(message, parameters);
5622 if(iteration || subIteration)
5623 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5624 <<
"Adding iteration parameters " << iteration <<
"." << subIteration
5627 RunControlStateMachine::theProgressBar_.step();
5629 std::string givenAppStatus = SupervisorInfo::APP_STATUS_UNKNOWN;
5632 givenAppStatus = theStateMachine_.getCurrentTransitionName(command);
5639 unsigned int givenAppProgress = appInfo.getProgress();
5640 std::string givenAppDetail = appInfo.getDetail();
5641 if(givenAppProgress >= 100)
5643 givenAppProgress = 0;
5644 givenAppDetail =
"";
5647 if(iteration == 0 && subIteration == 0)
5649 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5650 <<
"Sending message to Supervisor " << appInfo.getName()
5651 <<
" [LID=" << appInfo.getId() <<
"]: " << command << __E__;
5653 givenAppDetail =
"";
5657 if(givenAppDetail ==
"")
5659 std::to_string(iteration) +
":" + std::to_string(subIteration);
5660 if(subIteration == 0)
5662 for(
unsigned int j = 0; j < 4; ++j)
5663 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5664 <<
"Sending message to Supervisor " << appInfo.getName()
5665 <<
" [LID=" << appInfo.getId() <<
"]: " << command
5666 <<
" (iteration: " << iteration <<
")" << __E__;
5670 for(
unsigned int j = 0; j < 4; ++j)
5671 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5672 <<
"Sending message to Supervisor " << appInfo.getName()
5673 <<
" [LID=" << appInfo.getId() <<
"]: " << command
5674 <<
" (iteration: " << iteration
5675 <<
", sub-iteration: " << subIteration <<
")" << __E__;
5683 std::lock_guard<std::mutex> lock(broadcastCommandMessageIndexMutex_);
5684 parameters.addParameter(
"commandId", broadcastCommandMessageIndex_++);
5686 SOAPUtilities::addParameters(message, parameters);
5689 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5690 <<
"Sending... \t" << SOAPUtilities::translate(message) << std::endl;
5694 __COUT__ <<
"Broadcast thread " << threadIndex
5695 <<
"\t givenAppStatus=" << givenAppStatus << __E__;
5696 __COUT__ <<
"Broadcast thread " << threadIndex
5697 <<
"\t appInfo.getStatus()=" << appInfo.getStatus() << __E__;
5700 int waitAttempts = 0;
5701 while(appInfo.getStatus() == SupervisorInfo::APP_STATUS_UNKNOWN)
5703 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5704 <<
"Waiting for Supervisor " << appInfo.getName()
5705 <<
" [LID=" << appInfo.getId()
5706 <<
"] in unknown state. waitAttempts of 10 = " << waitAttempts
5709 if(waitAttempts == 10)
5711 __SS__ <<
"Error! Gateway Supervisor failed to send message to app "
5713 "Supervisor instance = '"
5714 << appInfo.getName() <<
"' [LID=" << appInfo.getId()
5715 <<
"] in Context '" << appInfo.getContextName()
5716 <<
"' [URL=" << appInfo.getURL() <<
"].\n\n";
5717 __COUT_ERR__ << ss.str();
5718 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5724 std::lock_guard<std::recursive_mutex> lock(
5725 allSupervisorInfo_.getSupervisorInfoMutex(appInfo.getId()));
5728 appInfo, givenAppStatus, givenAppProgress, givenAppDetail);
5732 __COUTV__(tmpReply);
5738 catch(
const xdaq::exception::Exception& e)
5741 __SS__ <<
"Error! Gateway Supervisor can NOT " << command
5742 <<
" Supervisor instance = '" << appInfo.getName()
5743 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
5744 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
5746 <<
"Xoap message failure. Did the target Supervisor crash? Try "
5747 "re-initializing or restarting otsdaq."
5749 __COUT_ERR__ << ss.str();
5753 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5754 <<
"Try again.." << __E__;
5759 parameters.addParameter(
"retransmission",
"1");
5760 SOAPUtilities::addParameters(message, parameters);
5767 std::lock_guard<std::mutex> lock(
5768 broadcastCommandMessageIndexMutex_);
5769 parameters.addParameter(
"commandId",
5770 broadcastCommandMessageIndex_++);
5772 SOAPUtilities::addParameters(message, parameters);
5775 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5776 <<
"Re-Sending... " << SOAPUtilities::translate(message)
5781 catch(
const xdaq::exception::Exception& e)
5783 __COUT_ERR__ <<
"Broadcast thread " << threadIndex <<
"\t"
5784 <<
"Second try failed.." << __E__;
5785 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5787 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5788 <<
"2nd try passed.." << __E__;
5791 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5792 <<
"Reply received from " << appInfo.getName()
5793 <<
" [LID=" << appInfo.getId() <<
"]: " << reply << __E__;
5795 if((reply != command +
"Done") && (reply != command +
"Response") &&
5796 (reply != command +
"Iterate") && (reply != command +
"SubIterate"))
5798 __SS__ <<
"Error! Gateway Supervisor can NOT " << command
5799 <<
" Supervisor instance = '" << appInfo.getName()
5800 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
5801 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
5804 __COUT_ERR__ << ss.str() << __E__;
5806 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5807 <<
"Getting error message..." << __E__;
5810 xoap::MessageReference errorMessage =
5812 SOAPUtilities::makeSOAPMessageReference(
5813 "StateMachineErrorMessageRequest"));
5815 parameters.addParameter(
"ErrorMessage");
5816 SOAPUtilities::receive(errorMessage, parameters);
5818 std::string error = parameters.getValue(
"ErrorMessage");
5821 std::stringstream err;
5822 err <<
"Unknown error from Supervisor instance = '"
5823 << appInfo.getName() <<
"' [LID=" << appInfo.getId()
5824 <<
"] in Context '" << appInfo.getContextName()
5825 <<
"' [URL=" << appInfo.getURL()
5826 <<
"]. If the problem persists or is repeatable, please notify "
5831 __SS__ <<
"Received error message from Supervisor instance = '"
5832 << appInfo.getName() <<
"' [LID=" << appInfo.getId()
5833 <<
"] in Context '" << appInfo.getContextName()
5834 <<
"' [URL=" << appInfo.getURL()
5835 <<
"].\n\n Error Message = " << error << __E__;
5837 __COUT_ERR__ << ss.str() << __E__;
5839 if(command == RunControlStateMachine::ERROR_TRANSITION_NAME)
5843 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5845 catch(
const xdaq::exception::Exception& e)
5848 __SS__ <<
"Error! Gateway Supervisor failed to read error message from "
5849 "Supervisor instance = '"
5850 << appInfo.getName() <<
"' [LID=" << appInfo.getId()
5851 <<
"] in Context '" << appInfo.getContextName()
5852 <<
"' [URL=" << appInfo.getURL() <<
"].\n\n"
5853 <<
"Xoap message failure. Did the target Supervisor crash? Try "
5854 "re-initializing or restarting otsdaq."
5856 __COUT_ERR__ << ss.str();
5857 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5860 else if(reply == command +
"Iterate")
5867 iterationsDone =
false;
5868 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5869 <<
"Supervisor instance = '" << appInfo.getName()
5870 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
5871 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
5872 <<
"] flagged for another iteration to " << command
5873 <<
"... (iteration: " << iteration <<
")" << __E__;
5876 else if(reply == command +
"SubIterate")
5883 subIterationsDone =
false;
5884 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5885 <<
"Supervisor instance = '" << appInfo.getName()
5886 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
5887 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
5888 <<
"] flagged for another sub-iteration to " << command
5889 <<
"... (iteration: " << iteration
5890 <<
", sub-iteration: " << subIteration <<
")" << __E__;
5894 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5895 <<
"Supervisor instance = '" << appInfo.getName()
5896 <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
5897 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
5898 <<
"] was " << command <<
"'d correctly!" << __E__;
5902 __COUT__ <<
"Broadcast thread " << threadIndex <<
"\t"
5903 <<
"Completed sub-iteration: " << subIteration << __E__;
5908 return iterationsDone;
5911 catch(
const toolbox::fsm::exception::Exception& e)
5918 __SS__ <<
"Error! Gateway Supervisor failed to broadcast message '" << command
5920 "Supervisor instance = '"
5921 << appInfo.getName() <<
"' [LID=" << appInfo.getId() <<
"] in Context '"
5922 << appInfo.getContextName() <<
"' [URL=" << appInfo.getURL()
5923 <<
"]. Try re-initializing or restarting otsdaq." << __E__;
5924 __COUT_ERR__ << ss.str();
5925 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
5932 void GatewaySupervisor::broadcastMessageThread(
5934 std::shared_ptr<GatewaySupervisor::BroadcastThreadStruct> threadStruct)
5936 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
5937 <<
"established..." << __E__;
5939 while(!threadStruct->exitThread_)
5945 std::lock_guard<std::mutex> lock(threadStruct->threadMutex_);
5946 if(threadStruct->workToDo_)
5948 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
5949 <<
"starting work... command = " << threadStruct->getCommand()
5954 if(supervisorPtr->handleBroadcastMessageTarget(
5955 threadStruct->getAppInfo(),
5956 threadStruct->getMessage(),
5957 threadStruct->getCommand(),
5958 threadStruct->getIteration(),
5959 threadStruct->getReply(),
5960 threadStruct->threadIndex_))
5961 threadStruct->getIterationsDone() =
true;
5963 catch(
const toolbox::fsm::exception::Exception& e)
5965 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
5966 <<
"going into error: " << e.what() << __E__;
5968 threadStruct->getReply() = e.what();
5969 threadStruct->error_ =
true;
5970 threadStruct->workToDo_ =
false;
5971 threadStruct->working_ =
false;
5975 if(!threadStruct->getIterationsDone())
5977 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
5978 <<
"flagged for another iteration." << __E__;
5981 std::lock_guard<std::mutex> lock(
5982 supervisorPtr->broadcastIterationsDoneMutex_);
5983 supervisorPtr->broadcastIterationsDone_ =
false;
5986 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
5987 <<
"done with work." << __E__;
5989 threadStruct->workToDo_ =
false;
5994 __COUT__ <<
"Broadcast thread " << threadStruct->threadIndex_ <<
"\t"
5995 <<
"exited." << __E__;
5996 threadStruct->working_ =
false;
6004 void GatewaySupervisor::broadcastMessage(xoap::MessageReference message)
6007 std::lock_guard<std::mutex> lock(broadcastCommandStatusUpdateMutex_);
6008 broadcastCommandStatus_ =
"";
6011 RunControlStateMachine::theProgressBar_.step();
6016 std::string command = SOAPUtilities::translate(message).getCommand();
6019 broadcastIterationsDone_ =
false;
6022 std::vector<std::vector<const SupervisorInfo*>> orderedSupervisors;
6026 orderedSupervisors = allSupervisorInfo_.getOrderedSupervisorDescriptors(
6029 command == RunControlStateMachine::SHUTDOWN_TRANSITION_NAME ||
6030 command == RunControlStateMachine::STARTUP_TRANSITION_NAME);
6032 catch(
const std::runtime_error& e)
6035 <<
"Error getting supervisor priority. Was there a change in the context?"
6036 <<
" Remember, if the context was changed, it is recommended to relaunch the "
6038 << e.what() << __E__;
6039 XCEPT_RAISE(toolbox::fsm::exception::Exception, ss.str());
6042 RunControlStateMachine::theProgressBar_.step();
6046 GatewaySupervisor::BroadcastMessageIterationsDoneStruct supervisorIterationsDone;
6049 for(
const auto& vectorAtPriority : orderedSupervisors)
6050 supervisorIterationsDone.push(vectorAtPriority.size());
6054 unsigned int iteration = 0;
6056 unsigned int iterationBreakpoint;
6061 xoap::MessageReference originalMessage =
6062 SOAPUtilities::makeSOAPMessageReference(SOAPUtilities::translate(message));
6064 __COUT__ <<
"=========> Broadcasting state machine command = " << command << __E__;
6066 unsigned int numberOfThreads = 1;
6070 numberOfThreads = CorePropertySupervisorBase::getSupervisorTableNode()
6071 .getNode(
"NumberOfStateMachineBroadcastThreads")
6072 .getValue<
unsigned int>();
6077 __COUT__ <<
"Number of threads not in configuration, so defaulting to "
6078 << numberOfThreads << __E__;
6083 if(numberOfThreads == 1)
6084 numberOfThreads = 0;
6086 __COUTV__(numberOfThreads);
6089 broadcastThreadStructs_.clear();
6093 for(
unsigned int i = 0; i < numberOfThreads; ++i)
6095 broadcastThreadStructs_.push_back(
6096 std::make_shared<GatewaySupervisor::BroadcastThreadStruct>());
6097 broadcastThreadStructs_[i]->threadIndex_ = i;
6101 std::shared_ptr<GatewaySupervisor::BroadcastThreadStruct> threadStruct) {
6102 GatewaySupervisor::broadcastMessageThread(supervisorPtr, threadStruct);
6105 broadcastThreadStructs_[i])
6109 RunControlStateMachine::theProgressBar_.step();
6111 broadcastMessageToRemoteGateways(originalMessage);
6113 RunControlStateMachine::theProgressBar_.step();
6121 broadcastIterationsDone_ =
true;
6124 std::lock_guard<std::mutex> lock(broadcastIterationBreakpointMutex_);
6125 iterationBreakpoint = broadcastIterationBreakpoint_;
6128 if(iterationBreakpoint < (
unsigned int)-1)
6129 __COUT__ <<
"Iteration breakpoint currently is " << iterationBreakpoint
6131 if(iteration >= iterationBreakpoint)
6133 broadcastIterationsDone_ =
false;
6134 __COUT__ <<
"Waiting at transition breakpoint - iteration = " << iteration
6136 usleep(5 * 1000 * 1000 );
6141 __COUT__ <<
"Starting iteration: " << iteration << __E__;
6143 for(
unsigned int i = 0; i < supervisorIterationsDone.size(); ++i)
6145 for(
unsigned int j = 0; j < supervisorIterationsDone.size(i); ++j)
6147 checkForAsyncError();
6149 if(supervisorIterationsDone[i][j])
6155 message = SOAPUtilities::makeSOAPMessageReference(
6156 SOAPUtilities::translate(originalMessage));
6163 parameters.addParameter(
"iterationIndex", iteration);
6164 SOAPUtilities::addParameters(message, parameters);
6170 assignedJob =
false;
6173 for(
unsigned int k = 0; k < numberOfThreads; ++k)
6175 if(!broadcastThreadStructs_[k]->workToDo_)
6179 __COUT__ <<
"Giving work to thread " << k
6180 <<
", command = " << command << __E__;
6182 std::lock_guard<std::mutex> lock(
6183 broadcastThreadStructs_[k]->threadMutex_);
6184 broadcastThreadStructs_[k]->setMessage(
6189 supervisorIterationsDone[i][j]);
6197 __COUT__ <<
"No free broadcast threads, "
6198 <<
"waiting for an available thread..." << __E__;
6199 usleep(100 * 1000 );
6201 }
while(!assignedJob);
6205 if(handleBroadcastMessageTarget(
6206 appInfo, message, command, iteration, reply))
6207 supervisorIterationsDone[i][j] =
true;
6209 broadcastIterationsDone_ =
false;
6219 <<
"Done with priority level. Waiting for threads to finish..."
6225 unsigned int numOfThreadsWithWork = 0;
6226 unsigned int lastUnfinishedThread = -1;
6228 for(
unsigned int i = 0; i < numberOfThreads; ++i)
6229 if(broadcastThreadStructs_[i]->workToDo_)
6232 ++numOfThreadsWithWork;
6233 lastUnfinishedThread = i;
6235 else if(broadcastThreadStructs_[i]->error_)
6237 __COUT__ <<
"Found thread in error! Throwing state "
6239 << broadcastThreadStructs_[i]->getReply()
6241 XCEPT_RAISE(toolbox::fsm::exception::Exception,
6242 broadcastThreadStructs_[i]->getReply());
6247 std::stringstream waitSs;
6248 waitSs <<
"Waiting on " << numOfThreadsWithWork <<
" of "
6250 <<
" threads to finish. Command = " << command;
6252 RunControlStateMachine::CONFIGURE_TRANSITION_NAME)
6253 waitSs <<
" w/" + RunControlStateMachine::
6254 getLastAttemptedConfigureGroup();
6255 if(numOfThreadsWithWork == 1)
6258 << broadcastThreadStructs_[lastUnfinishedThread]
6262 << broadcastThreadStructs_[lastUnfinishedThread]
6267 __COUT__ << waitSs.str();
6270 std::lock_guard<std::mutex> lock(
6271 broadcastCommandStatusUpdateMutex_);
6272 broadcastCommandStatus_ = waitSs.str();
6274 usleep(100 * 1000 );
6278 __COUT__ <<
"All threads done with priority level work." << __E__;
6289 if(iteration || !broadcastIterationsDone_)
6290 __COUT__ <<
"Completed iteration: " << iteration << __E__;
6293 }
while(!broadcastIterationsDone_);
6295 RunControlStateMachine::theProgressBar_.step();
6299 __COUT__ <<
"Exception caught, exiting broadcast threads..." << __E__;
6306 for(
unsigned int i = 0; i < numberOfThreads; ++i)
6307 broadcastThreadStructs_[i]->exitThread_ =
true;
6308 usleep(100 * 1000 );
6315 __COUT__ <<
"All transitions completed. Wrapping up, exiting broadcast threads..."
6324 for(
unsigned int i = 0; i < numberOfThreads; ++i)
6325 broadcastThreadStructs_[i]->exitThread_ =
true;
6326 usleep(100 * 1000 );
6329 RunControlStateMachine::theProgressBar_.step();
6331 if(broadcastMessageToRemoteGatewaysComplete(originalMessage))
6333 RunControlStateMachine::theProgressBar_.step();
6334 __COUT__ <<
"Broadcast complete." << __E__;
6339 void GatewaySupervisor::broadcastMessageToRemoteGateways(
6340 const xoap::MessageReference message)
6342 SOAPCommand commandObj = SOAPUtilities::translate(message);
6343 std::string command = commandObj.
getCommand();
6346 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
6347 for(
auto& remoteGatewayApp : remoteGatewayApps_)
6350 std::string commandAndParams = command;
6351 if(commandObj.hasParameters())
6354 for(
const auto& param : commandObj.getParameters())
6356 __COUTTV__(param.first);
6357 __COUTTV__(param.second);
6358 if(param.first ==
"ConfigurationAlias")
6360 if(remoteGatewayApp.selected_config_alias !=
"")
6361 commandAndParams +=
"," + remoteGatewayApp.selected_config_alias;
6363 commandAndParams +=
"," + param.second;
6365 else if(param.first ==
"RunNumber")
6367 commandAndParams +=
"," +
6374 __COUTV__(commandAndParams);
6377 if(!remoteGatewayApp.fsm_included)
6379 __COUT__ <<
"Skipping excluded Remote gateway '"
6380 << remoteGatewayApp.appInfo.name
6381 <<
"' for FSM command = " << commandAndParams << __E__;
6387 (command == RunControlStateMachine::ERROR_TRANSITION_NAME ||
6388 command == RunControlStateMachine::FAIL_TRANSITION_NAME ||
6389 command == RunControlStateMachine::HALT_TRANSITION_NAME ||
6390 command == RunControlStateMachine::ABORT_TRANSITION_NAME))
6392 __COUT__ <<
"Skipping '" << remoteGatewayApp.getFsmMode()
6393 <<
"' Remote gateway '" << remoteGatewayApp.appInfo.name
6394 <<
"' for FSM command = " << commandAndParams << __E__;
6400 (remoteGatewayApp.appInfo.status ==
6401 RunControlStateMachine::INITIAL_STATE_NAME ||
6402 remoteGatewayApp.appInfo.status ==
6403 RunControlStateMachine::HALTED_STATE_NAME ||
6404 remoteGatewayApp.appInfo.status.find(
6405 RunControlStateMachine::FAILED_STATE_NAME) == 0 ||
6406 remoteGatewayApp.appInfo.status.find(
"Error") !=
6407 std::string::npos ||
6408 (remoteGatewayApp.appInfo.status ==
6409 RunControlStateMachine::HALTED_STATE_NAME &&
6410 command == RunControlStateMachine::CONFIGURE_TRANSITION_NAME)))
6412 __COUT__ <<
"Skipping '" << remoteGatewayApp.getFsmMode()
6413 <<
"' Remote gateway '" << remoteGatewayApp.appInfo.name
6414 <<
"' w/status = " << remoteGatewayApp.appInfo.status
6415 <<
"... for FSM command = " << commandAndParams << __E__;
6419 __COUT__ <<
"Launching FSM command '" << commandAndParams
6420 <<
"' on Remote gateway '" << remoteGatewayApp.appInfo.name <<
"'..."
6423 if(remoteGatewayApp.command !=
"")
6425 __SUP_SS__ <<
"Can not target the remote subsystem '"
6426 << remoteGatewayApp.appInfo.name <<
"' with command '" << command
6427 <<
"' which already has a pending command '"
6428 << remoteGatewayApp.command
6429 <<
".' Please try again after the pending command is sent."
6434 remoteGatewayApp.config_dump =
"";
6435 remoteGatewayApp.command = commandAndParams;
6437 std::string logEntry = getLastLogEntry(command);
6439 remoteGatewayApp.command +=
6440 ",LogEntry:" + StringMacros::encodeURIComponent(logEntry);
6441 remoteGatewayApp.fsmName =
6442 activeStateMachineName_;
6444 remoteGatewayApp.appInfo.status =
"Launching " + commandAndParams;
6445 remoteGatewayApp.appInfo.progress = 0;
6450 bool GatewaySupervisor::broadcastMessageToRemoteGatewaysComplete(
6451 const xoap::MessageReference message)
6453 std::string command = SOAPUtilities::translate(message).getCommand();
6455 std::string destinationState = theStateMachine_.getTransitionFinalStateName(command);
6456 __COUTV__(destinationState);
6458 size_t countOfRemoteGateways = 0;
6460 bool done = command ==
"Error";
6463 __COUT__ <<
"Checking " << remoteGatewayApps_.size()
6464 <<
" remote gateway(s) completion for command = " << command << __E__;
6468 std::vector<GatewaySupervisor::RemoteGatewayInfo> remoteGatewayApps;
6470 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
6471 __SUP_COUTVS__(22, remoteGatewayApps_.size());
6472 countOfRemoteGateways = remoteGatewayApps_.size();
6473 remoteGatewayApps = remoteGatewayApps_;
6474 if(remoteGatewayApps_.size())
6475 __SUP_COUT_TYPE__(TLVL_DEBUG + 22)
6476 << __COUT_HDR__ << remoteGatewayApps_[0].command <<
" "
6477 << (remoteGatewayApps_[0].appInfo.status) << __E__;
6480 for(
auto& remoteGatewayApp : remoteGatewayApps)
6483 if(!remoteGatewayApp.fsm_included)
6487 (command == RunControlStateMachine::ERROR_TRANSITION_NAME ||
6488 command == RunControlStateMachine::FAIL_TRANSITION_NAME ||
6489 command == RunControlStateMachine::HALT_TRANSITION_NAME ||
6490 command == RunControlStateMachine::ABORT_TRANSITION_NAME))
6492 if(remoteGatewayApp.fsm_mode ==
6495 (remoteGatewayApp.appInfo.status ==
6496 RunControlStateMachine::INITIAL_STATE_NAME ||
6497 remoteGatewayApp.appInfo.status ==
6498 RunControlStateMachine::HALTED_STATE_NAME ||
6499 remoteGatewayApp.appInfo.status.find(
6500 RunControlStateMachine::FAILED_STATE_NAME) == 0 ||
6501 remoteGatewayApp.appInfo.status.find(
"Error") !=
6502 std::string::npos ||
6503 (remoteGatewayApp.appInfo.status ==
6504 RunControlStateMachine::HALTED_STATE_NAME &&
6505 command == RunControlStateMachine::CONFIGURE_TRANSITION_NAME)))
6509 if(!((remoteGatewayApp.appInfo.status == destinationState &&
6510 remoteGatewayApp.appInfo.progress == 100) ||
6511 remoteGatewayApp.appInfo.status.find(
"Error") != std::string::npos ||
6512 remoteGatewayApp.appInfo.status.find(
"Fail") != std::string::npos))
6515 if(remoteGatewayApp.appInfo.status == SupervisorInfo::APP_STATUS_UNKNOWN)
6517 __SS__ <<
"Can not complete FSM command '" << command
6518 <<
"' with unknown status from Remote gateway '"
6519 << remoteGatewayApp.appInfo.name
6520 <<
"' - it seems communication was lost. Please check the "
6521 "connection or notify admins."
6525 __COUT__ <<
"Remote gateway '" << remoteGatewayApp.appInfo.name
6526 <<
"' not done w/command '" << command
6527 <<
"' status = " << remoteGatewayApp.appInfo.status
6528 <<
",... progress = " << remoteGatewayApp.appInfo.progress
6536 __COUTT__ <<
"Done Remote gateway '" << remoteGatewayApp.appInfo.name
6537 <<
"' w/command '" << command
6538 <<
"' status = " << remoteGatewayApp.appInfo.status
6539 <<
",... progress = " << remoteGatewayApp.appInfo.progress
6546 checkForAsyncError();
6549 __COUT__ <<
"Done with " << countOfRemoteGateways
6550 <<
" remote gateway(s) command = " << command << __E__;
6560 void GatewaySupervisor::loginRequest(xgi::Input* in, xgi::Output* out)
6562 std::chrono::steady_clock::time_point startClock = std::chrono::steady_clock::now();
6563 cgicc::Cgicc cgi(in);
6565 __COUT__ <<
"*** Login RequestType = " << Command <<
" time=" << time(0) << __E__;
6576 std::vector<std::string> loggedOutUsernames;
6579 if(loggedOutUsernames.size())
6583 doLog = __ENV__(
"OTS_LOG_LOGIN_LOGOUT") == std::string(
"1");
6590 for(
unsigned int i = 0; i < loggedOutUsernames.size();
6593 makeSystemLogEntry(loggedOutUsernames[i] +
" login timed out.");
6595 if(Command ==
"sessionId")
6607 uuid, cgi.getEnvironment().getRemoteAddr() );
6613 else if(Command ==
"checkCookie")
6617 std::string jumbledUser;
6618 std::string cookieCode;
6644 if(uid == theWebUsers_.NOT_FOUND_IN_DATABASE)
6646 __COUT__ <<
"cookieCode invalid" << __E__;
6651 __COUT__ <<
"cookieCode is good." << __E__;
6660 else if(Command ==
"login")
6686 cgi.getEnvironment()
6689 if(uid >= theWebUsers_.ACCOUNT_ERROR_THRESHOLD)
6691 __COUT__ <<
"Login invalid." << __E__;
6693 if(newAccountCode !=
"1")
6694 newAccountCode =
"0";
6701 doLog = __ENV__(
"OTS_LOG_LOGIN_LOGOUT") == std::string(
"1");
6718 if(uid == theWebUsers_.ACCOUNT_INACTIVE)
6719 xmldoc.addTextElementToData(
"Error",
6720 "Account is inactive. Notify admins.");
6721 else if(uid == theWebUsers_.ACCOUNT_BLACKLISTED)
6722 xmldoc.addTextElementToData(
"Error",
6723 "Account is blacklisted. Notify admins.");
6729 if(uid != theWebUsers_.NOT_FOUND_IN_DATABASE)
6735 sprintf(asStr,
"%lu", asCnt);
6736 xmldoc.addTextElementToData(
"user_active_session_count", asStr);
6741 else if(Command ==
"cert")
6753 std::string jumbledEmail =
6755 std::string username =
"";
6756 std::string cookieCode =
"";
6767 cgi.getEnvironment()
6770 if(uid == theWebUsers_.NOT_FOUND_IN_DATABASE)
6772 __COUT__ <<
"cookieCode invalid" << __E__;
6774 if(cookieCode !=
"1")
6782 doLog = __ENV__(
"OTS_LOG_LOGIN_LOGOUT") == std::string(
"1");
6802 if(uid != theWebUsers_.NOT_FOUND_IN_DATABASE)
6808 sprintf(asStr,
"%lu", asCnt);
6809 xmldoc.addTextElementToData(
"user_active_session_count", asStr);
6814 else if(Command ==
"logout")
6824 logoutOthers ==
"1",
6826 cgi.getEnvironment().getRemoteAddr()) !=
6827 theWebUsers_.NOT_FOUND_IN_DATABASE)
6836 doLog = __ENV__(
"OTS_LOG_LOGIN_LOGOUT") == std::string(
"1");
6851 __COUT_WARN__ <<
"Invalid Command" << __E__;
6855 catch(
const std::runtime_error& e)
6857 __SS__ <<
"An error was encountered handling Command '" << Command
6858 <<
"':" << e.what() << __E__;
6859 __COUT__ <<
"\n" << ss.str();
6861 xmldoc.addTextElementToData(
"Error", ss.str());
6863 (std::ostringstream*)out,
false ,
true );
6867 __SS__ <<
"An unknown error was encountered handling Command '" << Command
6869 <<
"Please check the printouts to debug." << __E__;
6874 catch(
const std::exception& e)
6876 ss <<
"Exception message: " << e.what();
6881 __COUT__ <<
"\n" << ss.str();
6883 xmldoc.addTextElementToData(
"Error", ss.str());
6885 (std::ostringstream*)out,
false ,
true );
6888 __COUTT__ <<
"Login end clock=" << artdaq::TimeUtils::GetElapsedTime(startClock)
6893 void GatewaySupervisor::tooltipRequest(xgi::Input* in, xgi::Output* out)
6895 cgicc::Cgicc cgi(in);
6898 __COUTT__ <<
"Tooltip RequestType = " << Command << __E__;
6924 if(Command ==
"check")
6932 else if(Command ==
"setNeverShow")
6944 __COUT__ <<
"Command Request, " << Command <<
", not recognized." << __E__;
6948 catch(
const std::runtime_error& e)
6950 __SS__ <<
"An error was encountered handling Tooltip Command '" << Command
6951 <<
"':" << e.what() << __E__;
6952 __COUT__ <<
"\n" << ss.str();
6954 xmldoc.addTextElementToData(
"Error", ss.str());
6956 (std::ostringstream*)out,
false ,
true );
6960 __SS__ <<
"An unknown error was encountered handling Tooltip Command '" << Command
6962 <<
"Please check the printouts to debug." << __E__;
6967 catch(
const std::exception& e)
6969 ss <<
"Exception message: " << e.what();
6974 __COUT__ <<
"\n" << ss.str();
6976 xmldoc.addTextElementToData(
"Error", ss.str());
6978 (std::ostringstream*)out,
false ,
true );
6990 CorePropertySupervisorBase::setSupervisorProperty(
6991 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
6993 "*=1 | gatewayLaunchOTS=-1 | gatewayLaunchWiz=-1"
6994 " | gatewayLaunchOTSInstance=-1"
6995 " | StateMachine-*=10"
6996 " | cancelStateMachineTransition=10"
6997 " | resetConsoleCounts=10"
6998 " | commandRemoteSubsystem=10 | setRemoteSubsystemFsmControl=10"
7001 CorePropertySupervisorBase::setSupervisorProperty(
7002 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AllowNoLoginRequestTypes,
7004 " | getAppStatus | getRemoteSubsystems | getRemoteSubsystemStatus");
7016 CorePropertySupervisorBase::setSupervisorProperty(
7017 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
7018 "getSystemMessages | getCurrentState | getIterationPlanStatus"
7019 " | getAppStatus | getRemoteSubsystems | getRemoteSubsystemStatus");
7020 CorePropertySupervisorBase::addSupervisorProperty(
7021 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
7022 "gatewayLaunchOTS | gatewayLaunchWiz | gatewayLaunchOTSInstance"
7023 " | commandRemoteSubsystem");
7024 CorePropertySupervisorBase::addSupervisorProperty(
7025 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
7030 CorePropertySupervisorBase::setSupervisorProperty(
7031 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
7032 "*=0 | getSystemMessages=1 | getDesktopIcons=1");
7033 __COUT_INFO__ <<
"readOnly true in setSupervisorProperty" << __E__;
7038 void GatewaySupervisor::request(xgi::Input* in, xgi::Output* out)
7041 out->getHTTPResponseHeader().addHeader(
7042 "Access-Control-Allow-Origin",
7049 __COUT__ <<
"Waiting for FSM access" << __E__;
7050 std::lock_guard<std::mutex> lock(stateMachineAccessMutex_);
7052 __COUT__ <<
"Have FSM access" << __E__;
7054 cgicc::Cgicc cgiIn(in);
7057 __COUTVS__(40, requestType);
7108 CorePropertySupervisorBase::theConfigurationManager_->getSupervisorTableNode(
7109 supervisorContextUID_, supervisorApplicationUID_);
7113 __COUT__ <<
"requestType " << requestType <<
" v"
7119 if(requestType ==
"getSettings")
7123 __COUT__ <<
"Get Settings Request" << __E__;
7124 __COUT__ <<
"accounts = " << accounts << __E__;
7127 else if(requestType ==
"setSettings")
7135 __COUT__ <<
"Set Settings Request" << __E__;
7136 __COUT__ <<
"bgcolor = " << bgcolor << __E__;
7137 __COUT__ <<
"dbcolor = " << dbcolor << __E__;
7138 __COUT__ <<
"wincolor = " << wincolor << __E__;
7139 __COUT__ <<
"layout = " << layout << __E__;
7140 __COUT__ <<
"syslayout = " << syslayout << __E__;
7143 userInfo.uid_, bgcolor, dbcolor, wincolor, layout, syslayout);
7145 userInfo.uid_, &xmlOut,
true);
7147 else if(requestType ==
"accountSettings")
7153 if(type ==
"updateAccount")
7154 type_int = theWebUsers_.MOD_TYPE_UPDATE;
7155 else if(type ==
"createAccount")
7156 type_int = theWebUsers_.MOD_TYPE_ADD;
7157 else if(type ==
"deleteAccount")
7158 type_int = theWebUsers_.MOD_TYPE_DELETE;
7166 __COUT__ <<
"accountSettings Request" << __E__;
7167 __COUT__ <<
"type = " << type <<
" - " << type_int << __E__;
7168 __COUT__ <<
"username = " << username << __E__;
7169 __COUT__ <<
"useremail = " << email << __E__;
7170 __COUT__ <<
"displayname = " << displayname << __E__;
7171 __COUT__ <<
"permissions = " << permissions << __E__;
7174 userInfo.uid_, type_int, username, displayname, email, permissions);
7176 __COUT__ <<
"accounts = " << accounts << __E__;
7180 else if(requestType ==
"stateMatchinePreferences")
7183 const std::string DEFAULT_FSM_VIEW =
"Default_FSM_View";
7191 userInfo.uid_, DEFAULT_FSM_VIEW, &xmlOut);
7193 else if(requestType ==
"getAliasList")
7197 __SUP_COUTV__(fsmName);
7199 addFilteredConfigAliasesToXML(xmlOut, fsmName);
7202 std::string stateMachineAliasFilter =
"*";
7207 std::map<std::string ,
7215 CorePropertySupervisorBase::theConfigurationManager_
7216 ->getSupervisorTableNode(supervisorContextUID_,
7217 supervisorApplicationUID_);
7224 configLinkNode.
getNode(
"LinkToStateMachineTable");
7226 !fsmLinkNode.
getNode(fsmName +
"/SystemAliasFilter")
7228 stateMachineAliasFilter =
7229 fsmLinkNode.
getNode(fsmName +
"/SystemAliasFilter")
7232 __COUT_INFO__ <<
"FSM Link disconnected." << __E__;
7234 catch(std::runtime_error& e)
7236 __COUT_INFO__ << e.what() << __E__;
7240 __COUT_ERR__ <<
"Unknown error. Should never happen." << __E__;
7244 __COUT_INFO__ <<
"FSM Link disconnected." << __E__;
7246 __COUT__ <<
"For FSM '" << fsmName
7247 <<
",' stateMachineAliasFilter = " << stateMachineAliasFilter
7254 bool invertFilter = stateMachineAliasFilter.size() &&
7255 stateMachineAliasFilter[0] ==
'!';
7256 std::vector<std::string> filterArr;
7263 while((f = stateMachineAliasFilter.find(
'*', i)) != std::string::npos)
7265 tmp = stateMachineAliasFilter.substr(i, f - i);
7267 filterArr.push_back(tmp);
7271 if(i <= stateMachineAliasFilter.size())
7273 tmp = stateMachineAliasFilter.substr(i);
7274 filterArr.push_back(tmp);
7280 for(
auto& aliasMapPair : aliasMap)
7286 if(filterArr.size() == 1)
7288 if(filterArr[0] !=
"" && filterArr[0] !=
"*" &&
7289 aliasMapPair.first != filterArr[0])
7290 filterMatch =
false;
7295 for(f = 0; f < filterArr.size(); ++f)
7297 if(!filterArr[f].size())
7302 if((i = aliasMapPair.first.find(filterArr[f])) != 0)
7304 filterMatch =
false;
7308 else if(f == filterArr.size() -
7311 if(aliasMapPair.first.rfind(filterArr[f]) !=
7312 aliasMapPair.first.size() - filterArr[f].size())
7314 filterMatch =
false;
7318 else if((i = aliasMapPair.first.find(filterArr[f])) ==
7321 filterMatch =
false;
7328 filterMatch = !filterMatch;
7335 xmlOut.addTextElementToData(
"config_alias", aliasMapPair.first);
7336 xmlOut.addTextElementToData(
7339 aliasMapPair.second.second,
7346 xmlOut.addTextElementToData(
7347 "config_alias_comment",
7349 .getNode(ConfigurationManager::GROUP_ALIASES_TABLE_NAME)
7350 .getNode(aliasMapPair.first)
7351 .getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7352 .getValue<std::string>());
7354 std::string groupComment, groupAuthor, groupCreationTime;
7358 aliasMapPair.second.second,
7368 xmlOut.addTextElementToData(
"config_comment", groupComment);
7369 xmlOut.addTextElementToData(
"config_author", groupAuthor);
7370 xmlOut.addTextElementToData(
"config_create_time",
7375 __COUT_WARN__ <<
"Failed to load group metadata." << __E__;
7381 std::string fn = ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" +
7382 FSM_LAST_GROUP_ALIAS_FILE_START + fsmName +
"." +
7383 FSM_USERS_PREFERENCES_FILETYPE;
7384 __COUT__ <<
"Load preferences: " << fn << __E__;
7385 FILE* fp = fopen(fn.c_str(),
"r");
7388 char tmpLastAlias[500];
7389 fscanf(fp,
"%*s %s", tmpLastAlias);
7390 __COUT__ <<
"tmpLastAlias: " << tmpLastAlias << __E__;
7392 xmlOut.addTextElementToData(
"UserLastConfigAlias", tmpLastAlias);
7395 else if(aliasMap.size())
7396 xmlOut.addTextElementToData(
"UserLastConfigAlias",
7397 aliasMap.begin()->first);
7400 else if(requestType ==
"getAppStatus")
7404 const auto& appInfo = it.second;
7406 xmlOut.addTextElementToData(
"name",
7408 xmlOut.addNumberElementToData(
"id",
7410 xmlOut.addTextElementToData(
"status", appInfo.getStatus());
7411 xmlOut.addTextElementToData(
7413 appInfo.getLastStatusTime()
7416 xmlOut.addNumberElementToData(
7417 "stale", time(0) - appInfo.getLastStatusTime());
7418 xmlOut.addNumberElementToData(
"progress",
7419 appInfo.getProgress());
7420 xmlOut.addTextElementToData(
"detail", appInfo.getDetail());
7421 xmlOut.addTextElementToData(
"class",
7422 appInfo.getClass());
7423 xmlOut.addTextElementToData(
"url",
7425 xmlOut.addTextElementToData(
"context",
7426 appInfo.getContextName());
7427 auto subappElement = xmlOut.addTextElementToData(
"subapps",
"");
7428 for(
auto& subappInfoPair : appInfo.getSubappInfo())
7431 "subapp_name", subappInfoPair.first, subappElement);
7433 subappInfoPair.second.status,
7437 subappInfoPair.second.lastStatusTime
7439 subappInfoPair.second.lastStatusTime)
7442 xmlOut.addNumberElementToParent(
7444 time(0) - subappInfoPair.second.lastStatusTime,
7446 xmlOut.addNumberElementToParent(
"subapp_progress",
7447 subappInfoPair.second.progress,
7450 subappInfoPair.second.detail,
7453 subappInfoPair.second.url,
7455 xmlOut.addNumberElementToParent(
7456 "subapp_id", subappInfoPair.second.id, subappElement);
7458 subappInfoPair.second.class_name,
7464 std::vector<GatewaySupervisor::RemoteGatewayInfo> remoteApps;
7466 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
7467 remoteApps = remoteGatewayApps_;
7470 for(
const auto& remoteApp : remoteApps)
7472 const auto& appInfo = remoteApp.appInfo;
7475 if(appInfo.status == SupervisorInfo::APP_STATUS_UNKNOWN)
7478 xmlOut.addTextElementToData(
"name",
7480 xmlOut.addNumberElementToData(
"id", appInfo.id);
7481 xmlOut.addTextElementToData(
"status", appInfo.status);
7482 xmlOut.addTextElementToData(
7484 appInfo.lastStatusTime
7487 xmlOut.addNumberElementToData(
7489 time(0) - appInfo.lastStatusTime);
7490 xmlOut.addNumberElementToData(
"progress",
7492 xmlOut.addTextElementToData(
"detail", appInfo.detail);
7493 xmlOut.addTextElementToData(
"class",
7494 appInfo.class_name);
7495 xmlOut.addTextElementToData(
"url",
7496 appInfo.parent_url);
7497 xmlOut.addTextElementToData(
7498 "context", appInfo.name +
" at " + appInfo.url);
7499 auto subappElement = xmlOut.addTextElementToData(
"subapps",
"");
7500 for(
auto& subappInfoPair : remoteApp.subapps)
7503 "subapp_name", subappInfoPair.first, subappElement);
7505 subappInfoPair.second.status,
7509 subappInfoPair.second.lastStatusTime
7511 subappInfoPair.second.lastStatusTime)
7514 xmlOut.addNumberElementToParent(
7516 time(0) - subappInfoPair.second.lastStatusTime,
7518 xmlOut.addNumberElementToParent(
"subapp_progress",
7519 subappInfoPair.second.progress,
7522 subappInfoPair.second.detail,
7525 subappInfoPair.second.parent_url,
7527 xmlOut.addNumberElementToParent(
7528 "subapp_id", subappInfoPair.second.id, subappElement);
7530 subappInfoPair.second.class_name,
7535 else if(requestType ==
"getAppId")
7537 GatewaySupervisor::handleGetApplicationIdRequest(
7538 &allSupervisorInfo_, cgiIn, xmlOut);
7540 else if(requestType ==
"getContextMemberNames")
7543 CorePropertySupervisorBase::theConfigurationManager_->__GET_CONFIG__(
7546 auto contexts = contextTable->getContexts();
7547 for(
const auto& context : contexts)
7549 xmlOut.addTextElementToData(
7550 "ContextMember", context.contextUID_);
7554 std::vector<GatewaySupervisor::RemoteGatewayInfo>
7557 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
7558 remoteGatewayApps = remoteGatewayApps_;
7561 for(
const auto& remoteGatewayApp : remoteGatewayApps)
7562 xmlOut.addTextElementToData(
"RemoteGateway",
7563 remoteGatewayApp.appInfo.name +
" at " +
7564 remoteGatewayApp.appInfo.url);
7566 else if(requestType ==
"getSystemMessages")
7568 xmlOut.addTextElementToData(
7571 xmlOut.addTextElementToData(
7572 "username_with_lock",
7573 theWebUsers_.getUserWithLock());
7575 __COUTVS__(20, theWebUsers_.getUserWithLock());
7578 std::vector<GatewaySupervisor::RemoteGatewayInfo>
7581 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
7582 remoteGatewayApps = remoteGatewayApps_;
7585 for(
const auto& remoteGatewayApp : remoteGatewayApps)
7587 __COUTVS__(21, remoteGatewayApp.appInfo.status);
7590 if(remoteGatewayApp.appInfo.status == SupervisorInfo::APP_STATUS_UNKNOWN)
7593 xmlOut.addTextElementToData(
"RemoteGateway_name",
7594 remoteGatewayApp.appInfo.name);
7595 xmlOut.addTextElementToData(
"RemoteGateway_usernameWithLock",
7596 remoteGatewayApp.usernameWithLock);
7599 else if(requestType ==
"setUserWithLock")
7605 __COUTV__(username);
7607 __COUTV__(accounts);
7608 __COUTV__(userInfo.uid_);
7610 std::string tmpUserWithLock = theWebUsers_.getUserWithLock();
7611 if(!theWebUsers_.
setUserWithLock(userInfo.uid_, lock ==
"1", username))
7612 xmlOut.addTextElementToData(
7614 std::string(
"Set user lock action failed. You must have valid "
7615 "permissions and ") +
7616 "locking user must be currently logged in.");
7620 if(tmpUserWithLock !=
7625 theWebUsers_.getUserWithLock() ==
""
7626 ? tmpUserWithLock +
" has unlocked ots."
7627 : theWebUsers_.getUserWithLock() +
" has locked ots.");
7630 std::vector<GatewaySupervisor::RemoteGatewayInfo>
7633 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
7634 remoteGatewayApps = remoteGatewayApps_;
7637 for(
const auto& remoteGatewayApp : remoteGatewayApps)
7640 if(remoteGatewayApp.appInfo.status == SupervisorInfo::APP_STATUS_UNKNOWN)
7643 xmlOut.addTextElementToData(
"RemoteGateway_name",
7644 remoteGatewayApp.appInfo.name);
7645 xmlOut.addTextElementToData(
"RemoteGateway_usernameWithLock",
7646 remoteGatewayApp.usernameWithLock);
7649 else if(requestType ==
"getStateMachineLastLogEntry")
7653 __SUP_COUTV__(fsmName);
7654 __SUP_COUTV__(transition);
7657 std::string lastLog = getLastLogEntry(transition, fsmName);
7658 __SUP_COUTTV__(lastLog);
7659 size_t i = lastLog.rfind(
'(');
7660 if(i != std::string::npos && i > 1)
7662 lastLog = lastLog.substr(0, i - 1);
7663 __SUP_COUTTV__(lastLog);
7666 if(transition == RunControlStateMachine::START_TRANSITION_NAME)
7668 i = lastLog.find(
':');
7669 if(i != std::string::npos &&
7670 i + 2 < lastLog.size())
7672 lastLog = lastLog.substr(i + 2);
7673 __SUP_COUTTV__(lastLog);
7677 xmlOut.addTextElementToData(
"lastLogEntry", lastLog);
7679 else if(requestType ==
"getStateMachine")
7682 __SUP_COUTVS__(20, fsmName);
7684 addRequiredFsmLogInputToXML(xmlOut, fsmName);
7686 std::vector<toolbox::fsm::State> states;
7687 states = theStateMachine_.getStates();
7690 std::string transName;
7691 std::string transParameter;
7693 for(
unsigned int i = 0; i < states.size(); ++i)
7695 stateStr[0] = states[i];
7696 DOMElement* stateParent = xmlOut.addTextElementToData(
"state", stateStr);
7699 "state_name", theStateMachine_.getStateName(states[i]), stateParent);
7703 std::map<std::string, toolbox::fsm::State, std::less<std::string>> trans =
7704 theStateMachine_.getTransitions(states[i]);
7705 std::set<std::string> actionNames = theStateMachine_.getInputs(states[i]);
7707 std::map<std::string, toolbox::fsm::State, std::less<std::string>>::
7708 iterator it = trans.begin();
7709 std::set<std::string>::iterator ait = actionNames.begin();
7714 for(; it != trans.end() && ait != actionNames.end(); ++it, ++ait)
7716 stateStr[0] = it->second;
7718 if(stateStr[0] ==
'R')
7721 "state_transition", stateStr, stateParent);
7723 "state_transition_action", *ait, stateParent);
7724 transName = theStateMachine_.getTransitionName(states[i], *ait);
7726 "state_transition_name", transName, stateParent);
7728 theStateMachine_.getTransitionParameter(states[i], *ait);
7730 "state_transition_parameter", transParameter, stateParent);
7733 else if(stateStr[0] ==
'C')
7736 "state_transition", stateStr, stateParent);
7738 "state_transition_action", *ait, stateParent);
7739 transName = theStateMachine_.getTransitionName(states[i], *ait);
7741 "state_transition_name", transName, stateParent);
7743 theStateMachine_.getTransitionParameter(states[i], *ait);
7745 "state_transition_parameter", transParameter, stateParent);
7752 ait = actionNames.begin();
7755 for(; it != trans.end() && ait != actionNames.end(); ++it, ++ait)
7757 stateStr[0] = it->second;
7759 if(stateStr[0] ==
'R')
7761 else if(stateStr[0] ==
'C')
7765 "state_transition", stateStr, stateParent);
7767 "state_transition_action", *ait, stateParent);
7768 transName = theStateMachine_.getTransitionName(states[i], *ait);
7770 "state_transition_name", transName, stateParent);
7772 theStateMachine_.getTransitionParameter(states[i], *ait);
7774 "state_transition_parameter", transParameter, stateParent);
7778 else if(requestType ==
"getStateMachineNames")
7782 CorePropertySupervisorBase::theConfigurationManager_
7783 ->getSupervisorTableNode(supervisorContextUID_,
7784 supervisorApplicationUID_);
7790 for(
const auto& fsmNode : fsmNodes)
7791 xmlOut.addTextElementToData(
"stateMachineName", fsmNode.first);
7795 __COUT__ <<
"Caught exception, assuming no valid FSM names." << __E__;
7796 xmlOut.addTextElementToData(
"stateMachineName",
"");
7799 else if(requestType ==
"getIterationPlanStatus")
7802 theIterator_.handleCommandRequest(xmlOut, requestType,
"");
7804 else if(requestType ==
"getCurrentState")
7807 addStateMachineStatusToXML(xmlOut, fsmName);
7809 else if(requestType ==
"cancelStateMachineTransition")
7811 __SS__ <<
"State transition was cancelled by user!" << __E__;
7812 __COUTV__(ss.str());
7813 RunControlStateMachine::theStateMachine_.setErrorMessage(ss.str());
7814 RunControlStateMachine::asyncFailureReceived_ =
true;
7816 else if(requestType ==
"getErrorInStateMatchine")
7818 xmlOut.addTextElementToData(
"FSM_Error", theStateMachine_.getErrorMessage());
7820 else if(requestType ==
"getDesktopIcons")
7833 const std::vector<DesktopIconTable::DesktopIcon>& icons =
7834 iconTable->getAllDesktopIcons();
7836 std::string iconString =
"";
7848 std::map<std::string, WebUsers::permissionLevel_t> userPermissionLevelsMap =
7850 std::map<std::string, WebUsers::permissionLevel_t>
7851 iconPermissionThresholdsMap;
7855 bool getRemoteIcons =
7858 std::vector<GatewaySupervisor::RemoteGatewayInfo>
7862 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
7863 remoteGatewayApps = remoteGatewayApps_;
7866 std::string ipAddressForRemoteIconsOverUDP =
"";
7868 bool firstIcon =
true;
7869 for(
const auto& icon : icons)
7871 __COUTVS__(21, icon.caption_);
7872 __COUTVS__(21, icon.permissionThresholdString_);
7875 icon.permissionThresholdString_, iconPermissionThresholdsMap);
7878 userPermissionLevelsMap, iconPermissionThresholdsMap))
7880 __COUTT__ <<
"No user access to icon '" << icon.caption_ <<
"'"
7885 __COUTVS__(21, icon.caption_);
7889 __COUTV__(icon.windowContentURL_);
7890 if(icon.windowContentURL_.size() > 4 &&
7891 icon.windowContentURL_[0] ==
'o' &&
7892 icon.windowContentURL_[1] ==
't' &&
7893 icon.windowContentURL_[2] ==
's' &&
7894 icon.windowContentURL_[3] ==
':')
7898 for(
const auto& remoteGatewayApp : remoteGatewayApps)
7900 if(icon.recordUID_ != remoteGatewayApp.appInfo.name)
7902 __COUTVS__(21, icon.caption_);
7905 if(remoteGatewayApp.iconString ==
7909 if(remoteGatewayApp.error.find(
"desktop icons") !=
7911 xmlOut.addTextElementToData(
"Error",
7912 remoteGatewayApp.error);
7920 if(remoteGatewayApp.parentIconFolderPath !=
"")
7921 iconString += remoteGatewayApp.parentIconFolderPath +
7923 else if(remoteGatewayApp.user_data_path_record !=
"")
7924 iconString += remoteGatewayApp.user_data_path_record +
7927 iconString += remoteGatewayApp.appInfo.name +
7950 iconString += remoteGatewayApp.iconString;
7956 __SUP_SS__ <<
"Illegal missing remote icon definition for "
7958 << icon.recordUID_ <<
".' Please notify admins."
7973 iconString += icon.caption_;
7974 iconString +=
"," + icon.alternateText_;
7976 "," + std::string(icon.enforceOneWindowInstance_ ?
"1" :
"0");
7977 iconString +=
"," + std::string(
"1");
7981 iconString +=
"," + icon.imageURL_;
7982 iconString +=
"," + icon.windowContentURL_;
7983 iconString +=
"," + icon.folderPath_;
7985 __COUTVS__(23, iconString);
7987 xmlOut.addTextElementToData(
"iconList", iconString);
7989 else if(requestType ==
"addDesktopIcon")
7991 std::vector<DesktopIconTable::DesktopIcon> newIcons;
7993 bool success = GatewaySupervisor::handleAddDesktopIconRequest(
7994 userInfo.username_, cgiIn, xmlOut, &newIcons);
7998 __COUT__ <<
"Attempting dynamic icon change..." << __E__;
8002 CorePropertySupervisorBase::theConfigurationManager_
8003 ->getDesktopIconTable();
8007 __COUT__ <<
"Failed dynamic icon add." << __E__;
8009 else if(requestType ==
"resetConsoleCounts")
8015 const auto& appInfo = it.second;
8016 if(appInfo.isTypeConsoleSupervisor())
8018 xoap::MessageReference tempMessage =
8019 SOAPUtilities::makeSOAPMessageReference(
"ResetConsoleCounts");
8024 __SUP_SS__ <<
"Error while resetting console counts of "
8025 "Supervisor instance = '"
8026 << appInfo.getName() <<
"' [LID=" << appInfo.getId()
8027 <<
"] in Context '" << appInfo.getContextName()
8028 <<
"' [URL=" << appInfo.getURL() <<
"].\n\n"
8032 __SUP_COUT__ <<
"Reset console counts of Supervisor instance = '"
8033 << appInfo.getName() <<
"' [LID=" << appInfo.getId()
8034 <<
"] in Context '" << appInfo.getContextName()
8035 <<
"' [URL=" << appInfo.getURL() <<
"]." << __E__;
8040 std::lock_guard<std::mutex> lock(
8041 systemStatusMutex_);
8042 lastConsoleErrTime_ =
"0";
8043 lastConsoleErr_ =
"";
8044 lastConsoleWarnTime_ =
"0";
8045 lastConsoleWarn_ =
"";
8046 lastConsoleInfoTime_ =
"0";
8047 lastConsoleInfo_ =
"";
8048 firstConsoleErrTime_ =
"0";
8049 firstConsoleErr_ =
"";
8050 firstConsoleWarnTime_ =
"0";
8051 firstConsoleWarn_ =
"";
8052 firstConsoleInfoTime_ =
"0";
8053 firstConsoleInfo_ =
"";
8056 else if(requestType ==
"getRemoteSubsystems" ||
8057 requestType ==
"getRemoteSubsystemStatus")
8060 bool getRunTypeNote = CgiDataUtilities::getDataAsInt(cgiIn,
"getRunTypeNote");
8061 bool getFullInfo = (requestType ==
"getRemoteSubsystems");
8062 bool getRunNumber = CgiDataUtilities::getDataAsInt(cgiIn,
"getRunNumber");
8071 __SUP_COUTV__(fsmName);
8072 __SUP_COUTV__(getRunTypeNote);
8075 addFilteredConfigAliasesToXML(xmlOut, fsmName);
8077 addRequiredFsmLogInputToXML(xmlOut,
8084 xmlOut.addTextElementToData(
8085 "last_run_log_entry",
8086 getLastLogEntry(RunControlStateMachine::START_TRANSITION_NAME,
8092 addStateMachineStatusToXML(
8093 xmlOut, fsmName, getRunNumber);
8094 theIterator_.handleCommandRequest(xmlOut,
"getIterationPlanStatus",
"");
8096 std::lock_guard<std::mutex> lock(
8097 systemStatusMutex_);
8099 xmlOut.addTextElementToData(
"last_logbook_entry", lastLogbookEntry_);
8100 xmlOut.addTextElementToData(
8101 "last_logbook_entry_time",
8102 lastLogbookEntryTime_
8106 xmlOut.addTextElementToData(
"last_system_message", msgPair.first);
8107 xmlOut.addTextElementToData(
8108 "last_system_message_time",
8111 xmlOut.addNumberElementToData(
"active_user_count",
8113 xmlOut.addTextElementToData(
"active_user_list",
8115 xmlOut.addNumberElementToData(
"console_err_count",
8116 systemConsoleErrCount_);
8117 xmlOut.addNumberElementToData(
"console_warn_count",
8118 systemConsoleWarnCount_);
8119 xmlOut.addNumberElementToData(
"console_info_count",
8120 systemConsoleInfoCount_);
8121 xmlOut.addTextElementToData(
"last_console_err_msg", lastConsoleErr_);
8122 xmlOut.addTextElementToData(
"last_console_warn_msg", lastConsoleWarn_);
8123 xmlOut.addTextElementToData(
"last_console_info_msg", lastConsoleInfo_);
8124 xmlOut.addTextElementToData(
"last_console_err_msg_time",
8125 lastConsoleErrTime_);
8126 xmlOut.addTextElementToData(
"last_console_warn_msg_time",
8127 lastConsoleWarnTime_);
8128 xmlOut.addTextElementToData(
"last_console_info_msg_time",
8129 lastConsoleInfoTime_);
8130 xmlOut.addTextElementToData(
"first_console_err_msg", firstConsoleErr_);
8131 xmlOut.addTextElementToData(
"first_console_warn_msg", firstConsoleWarn_);
8132 xmlOut.addTextElementToData(
"first_console_info_msg", firstConsoleInfo_);
8133 xmlOut.addTextElementToData(
"first_console_err_msg_time",
8134 firstConsoleErrTime_);
8135 xmlOut.addTextElementToData(
"first_console_warn_msg_time",
8136 firstConsoleWarnTime_);
8137 xmlOut.addTextElementToData(
"first_console_info_msg_time",
8138 firstConsoleInfoTime_);
8142 std::vector<GatewaySupervisor::RemoteGatewayInfo>
8145 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
8146 __SUP_COUTVS__(22, remoteGatewayApps_.size());
8147 remoteGatewayApps = remoteGatewayApps_;
8148 if(remoteGatewayApps_.size())
8149 __SUP_COUT_TYPE__(TLVL_DEBUG + 22)
8150 << __COUT_HDR__ << remoteGatewayApps_[0].command <<
" "
8151 << (remoteGatewayApps_[0].appInfo.status) << __E__;
8154 std::string accumulateErrors =
"";
8155 for(
const auto& remoteSubsystem : remoteGatewayApps)
8157 xmlOut.addTextElementToData(
"subsystem_name",
8158 remoteSubsystem.appInfo.name);
8159 xmlOut.addTextElementToData(
"subsystem_url", remoteSubsystem.appInfo.url);
8160 xmlOut.addTextElementToData(
"subsystem_landingPage",
8161 remoteSubsystem.landingPage);
8162 xmlOut.addTextElementToData(
"subsystem_status",
8163 remoteSubsystem.appInfo.status);
8164 xmlOut.addTextElementToData(
8165 "subsystem_progress",
8166 std::to_string(remoteSubsystem.appInfo.progress));
8167 xmlOut.addTextElementToData(
"subsystem_detail",
8168 remoteSubsystem.appInfo.detail);
8169 xmlOut.addTextElementToData(
"subsystem_lastStatusTime",
8171 remoteSubsystem.appInfo.lastStatusTime));
8172 xmlOut.addTextElementToData(
8173 "subsystem_consoleErrCount",
8174 std::to_string(remoteSubsystem.consoleErrCount));
8175 xmlOut.addTextElementToData(
8176 "subsystem_consoleWarnCount",
8177 std::to_string(remoteSubsystem.consoleWarnCount));
8179 if(remoteSubsystem.command ==
"" && remoteSubsystem.error !=
"")
8181 __COUTT__ <<
"Error from Subsystem '" << remoteSubsystem.appInfo.name
8182 <<
"' = " << remoteSubsystem.error << __E__;
8184 if(remoteSubsystem.error.find(
8185 "Failure gathering Remote Gateway desktop icons") ==
8188 if(accumulateErrors.size())
8189 accumulateErrors +=
"\n";
8190 accumulateErrors += remoteSubsystem.error;
8195 xmlOut.addTextElementToData(
"subsystem_configAlias",
8196 remoteSubsystem.selected_config_alias);
8200 if(remoteSubsystem.user_data_path_record ==
"")
8204 <<
"Remote Subsystem '" << remoteSubsystem.appInfo.name
8205 <<
"' user data path is empty. Perhaps the system is still "
8206 "booting up. If the problem persists, note that Remote "
8207 "Subsystems are specified through their Desktop Icon "
8209 "Please specify a valid User Data Path record as the "
8210 "Desktop Icon AlternateText field, targeting a UID in the "
8211 "SubsystemUserDataPathsTable (or contact system admins "
8217 xmlOut.addTextElementToData(
8218 "subsystem_configAliasChoices",
8221 xmlOut.addTextElementToData(
"subsystem_fsmMode",
8222 remoteSubsystem.getFsmMode());
8223 xmlOut.addTextElementToData(
"subsystem_fsmIncluded",
8224 remoteSubsystem.fsm_included ?
"1" :
"0");
8227 if(accumulateErrors !=
"")
8228 xmlOut.addTextElementToData(
"system_error", accumulateErrors);
8231 else if(requestType ==
"setRemoteSubsystemFsmControl")
8233 std::string targetSubsystem =
8236 std::string controlType =
8240 __SUP_COUTV__(targetSubsystem);
8241 __SUP_COUTV__(setValue);
8242 __SUP_COUTV__(controlType);
8244 bool changedSomething =
false;
8245 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
8246 for(
auto& remoteGatewayApp : remoteGatewayApps_)
8247 if(targetSubsystem ==
"*" ||
8248 targetSubsystem == remoteGatewayApp.appInfo.name)
8250 changedSomething =
true;
8251 if(controlType ==
"include")
8252 remoteGatewayApp.fsm_included = setValue ==
"1" ? true :
false;
8253 if(controlType ==
"configAlias")
8255 if(remoteGatewayApp.config_aliases.find(setValue) ==
8256 remoteGatewayApp.config_aliases.end())
8259 <<
"Configuration Alias value '" << setValue
8260 <<
"' for target Subsystem '"
8261 << remoteGatewayApp.appInfo.name
8262 <<
"' is not found in list of Configuration Aliases: "
8264 remoteGatewayApp.config_aliases)
8268 remoteGatewayApp.selected_config_alias = setValue;
8270 else if(controlType ==
"mode")
8271 remoteGatewayApp.fsm_mode =
8272 setValue ==
"Do Not Halt"
8274 : (setValue ==
"Only Configure"
8276 : RemoteGatewayInfo::FSM_ModeTypes::Follow_FSM);
8279 if(!changedSomething)
8281 __SUP_SS__ <<
"Did not find any matching subsystems for target '"
8282 << targetSubsystem <<
"' attempted!" << __E__;
8286 saveRemoteGatewaySettings();
8289 else if(requestType ==
"getSubsystemConfigAliasSelectInfo")
8291 std::string targetSubsystem =
8293 __SUP_COUTV__(targetSubsystem);
8297 std::vector<GatewaySupervisor::RemoteGatewayInfo>
8300 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
8301 __SUP_COUTVS__(22, remoteGatewayApps_.size());
8302 remoteGatewayApps = remoteGatewayApps_;
8303 if(remoteGatewayApps_.size())
8304 __SUP_COUT_TYPE__(TLVL_DEBUG + 22)
8305 << __COUT_HDR__ << remoteGatewayApps_[0].command <<
" "
8306 << (remoteGatewayApps_[0].appInfo.status) << __E__;
8308 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
8309 for(
auto& remoteGatewayApp : remoteGatewayApps)
8310 if(targetSubsystem == remoteGatewayApp.appInfo.name)
8314 if(remoteGatewayApp.selected_config_alias ==
"")
8316 __SUP_SS__ <<
"No selected Configuration Alias found for target "
8318 << remoteGatewayApp.appInfo.name
8319 <<
"' - please select one before requesting info."
8324 std::pair<std::string, TableGroupKey> groupTranslation;
8325 std::string groupComment, groupAuthor, groupCreationTime;
8330 remoteGatewayApp.user_data_path_record,
8331 remoteGatewayApp.selected_config_alias,
8337 std::stringstream returnInfo;
8338 returnInfo <<
"At remote Subsystem <b>'"
8339 << remoteGatewayApp.appInfo.name
8340 <<
",'</b> the Configure Alias <b>'"
8341 << remoteGatewayApp.selected_config_alias
8342 <<
"'</b> translates to <b>" << groupTranslation.first
8343 <<
"(" << groupTranslation.second
8344 <<
")</b> w/comment: <br><br><i>"
8346 if(groupCreationTime !=
"" && groupCreationTime !=
"0")
8347 returnInfo <<
"<br><br>";
8348 returnInfo <<
"<b>" << groupTranslation.first <<
"("
8349 << groupTranslation.second <<
")</b> was created by "
8350 << groupAuthor <<
" ("
8353 returnInfo <<
"</i>";
8355 xmlOut.addTextElementToData(
"alias_info", returnInfo.str());
8361 __SUP_SS__ <<
"Did not find any matching subsystems for target '"
8362 << targetSubsystem <<
"' attempted!" << __E__;
8367 else if(requestType ==
"commandRemoteSubsystem")
8369 std::string targetSubsystem =
8375 __SUP_COUTV__(targetSubsystem);
8376 __SUP_COUTV__(command);
8377 __SUP_COUTV__(parameter);
8378 __SUP_COUTV__(fsmName);
8383 <<
"Illegal empty command received to target remote subsystem '"
8384 << targetSubsystem <<
"' attempted!" << __E__;
8387 if(targetSubsystem ==
"")
8389 __SUP_SS__ <<
"Illegal empty targetSubsystem received for remote "
8390 "subsystem command '"
8391 << command <<
"' attempted!" << __E__;
8396 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
8397 for(
auto& remoteGatewayApp : remoteGatewayApps_)
8399 if(targetSubsystem == remoteGatewayApp.appInfo.name)
8401 if(remoteGatewayApp.command !=
"")
8404 <<
"Can not target the remote subsystem '" << targetSubsystem
8405 <<
"' with command '" << command
8406 <<
"' which already has a pending command '"
8407 << remoteGatewayApp.command
8408 <<
".' Please try again after the pending command is sent."
8412 remoteGatewayApp.error =
"";
8413 remoteGatewayApp.command =
8414 command + (parameter !=
"" ? (
"," + parameter) :
"");
8417 if(command !=
"ResetConsoleCounts")
8418 remoteGatewayApp.fsmName = fsmName;
8421 remoteGatewayApp.appInfo.status =
"Launching " + command;
8422 remoteGatewayApp.appInfo.progress = 0;
8429 __SUP_SS__ <<
"Target remote subsystem '" << targetSubsystem
8430 <<
"' was not found for attempted command '" << command <<
"!'"
8435 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz")
8440 __COUT_WARN__ << requestType <<
" requestType received! " << __E__;
8447 if(requestType ==
"gatewayLaunchOTS")
8448 GatewaySupervisor::launchStartOTSCommand(
8449 "LAUNCH_OTS", CorePropertySupervisorBase::theConfigurationManager_);
8450 else if(requestType ==
"gatewayLaunchWiz")
8451 GatewaySupervisor::launchStartOneServerCommand(
8453 CorePropertySupervisorBase::theConfigurationManager_,
8456 else if(requestType ==
"gatewayLaunchOTSInstance")
8458 __COUT_WARN__ << requestType <<
" requestType received! " << __E__;
8460 std::string targetSubsystem =
8462 __SUP_COUTV__(targetSubsystem);
8466 std::lock_guard<std::mutex> lock(remoteGatewayAppsMutex_);
8467 for(
auto& remoteGatewayApp : remoteGatewayApps_)
8468 if(targetSubsystem == remoteGatewayApp.appInfo.name)
8472 std::stringstream commandSs;
8473 commandSs <<
"LAUNCH_INSTANCE";
8474 commandSs <<
";" << remoteGatewayApp.instanceUser;
8475 commandSs <<
";" << remoteGatewayApp.instanceHost;
8477 size_t i = remoteGatewayApp.instancePath.rfind(
'/');
8478 if(i != std::string::npos)
8479 commandSs <<
";" << remoteGatewayApp.instancePath.substr(0, i);
8481 commandSs <<
";" << remoteGatewayApp.instancePath;
8484 commandSs <<
";" << remoteGatewayApp.setupType;
8486 << remoteGatewayApp.instancePath;
8487 __SUP_COUTV__(commandSs.str());
8489 GatewaySupervisor::launchStartOneServerCommand(
8492 CorePropertySupervisorBase::theConfigurationManager_,
8496 remoteGatewayApp.command =
8498 remoteGatewayApp.appInfo.status =
"Rebooting... ";
8499 remoteGatewayApp.appInfo.progress = 1;
8504 __SUP_SS__ <<
"Did not find any matching subsystems for target '"
8505 << targetSubsystem <<
"' attempted!" << __E__;
8509 else if(requestType ==
"resetUserTooltips")
8513 else if(requestType ==
"silenceUserTooltips")
8517 else if(requestType ==
"restartApps")
8520 __COUT__ <<
"launch ots script Command = "
8521 <<
"OTS_APP_SHUTDOWN" << __E__;
8522 GatewaySupervisor::launchStartOneServerCommand(
8524 CorePropertySupervisorBase::theConfigurationManager_,
8527 GatewaySupervisor::launchStartOneServerCommand(
8529 CorePropertySupervisorBase::theConfigurationManager_,
8532 xmlOut.addTextElementToData(
"status",
"restarted");
8536 __SS__ <<
"requestType Request, " << requestType <<
", not recognized."
8541 catch(
const std::runtime_error& e)
8543 __SS__ <<
"An error was encountered handling requestType '" << requestType
8544 <<
"':" << e.what() << __E__;
8545 __COUT__ <<
"\n" << ss.str();
8546 xmlOut.addTextElementToData(
"Error", ss.str());
8550 __SS__ <<
"An unknown error was encountered handling requestType '" << requestType
8552 <<
"Please check the printouts to debug." << __E__;
8557 catch(
const std::exception& e)
8559 ss <<
"Exception message: " << e.what();
8564 __COUT__ <<
"\n" << ss.str();
8565 xmlOut.addTextElementToData(
"Error", ss.str());
8570 (std::ostringstream*)out,
8576 catch(
const std::runtime_error& e)
8578 __COUT_ERR__ <<
"Caught error at request(): " << e.what() << __E__;
8583 void GatewaySupervisor::addStateMachineStatusToXML(
HttpXmlDocument& xmlOut,
8584 const std::string& fsmName,
8587 xmlOut.addTextElementToData(
"active_fsmName", activeStateMachineName_);
8588 xmlOut.addTextElementToData(
"current_state", theStateMachine_.getCurrentStateName());
8589 const std::string& gatewayStatus = allSupervisorInfo_.getGatewayInfo().getStatus();
8590 if(gatewayStatus.size() >
8591 std::string(RunControlStateMachine::FAILED_STATE_NAME).length() &&
8592 (gatewayStatus[0] ==
'F' ||
8595 xmlOut.addTextElementToData(
"current_error", gatewayStatus);
8597 xmlOut.addTextElementToData(
"in_transition",
8598 theStateMachine_.isInTransition() ?
"1" :
"0");
8599 if(theStateMachine_.isInTransition())
8601 xmlOut.addTextElementToData(
8602 "transition_progress",
8603 RunControlStateMachine::theProgressBar_.readPercentageString());
8604 xmlOut.addTextElementToData(
"current_transition",
8605 theStateMachine_.getCurrentTransitionName());
8609 xmlOut.addTextElementToData(
"transition_progress",
"100");
8610 xmlOut.addTextElementToData(
"current_transition",
"");
8612 xmlOut.addTextElementToData(
"time_in_state",
8632 bool useRunInfoDb =
false;
8634 if(!theStateMachine_.isInTransition())
8636 if(RunControlStateMachine::asyncStopExceptionReceived_)
8640 xmlOut.addTextElementToData(
"soft_error",
8641 RunControlStateMachine::getErrorMessage());
8644 std::string stateMachineRunAlias =
"Run";
8645 bool rollOverLogOnConfigure =
false, rollOverLogOnStart =
false;
8646 std::string rollOverLogOnSize =
"";
8650 CorePropertySupervisorBase::theConfigurationManager_->getSupervisorTableNode(
8651 supervisorContextUID_, supervisorApplicationUID_);
8658 configLinkNode.
getNode(
"LinkToStateMachineTable");
8661 if(!fsmLinkNode.
getNode(fsmName +
"/RunDisplayAlias")
8663 stateMachineRunAlias =
8664 fsmLinkNode.
getNode(fsmName +
"/RunDisplayAlias")
8666 std::string runInfoPluginType =
8667 fsmLinkNode.
getNode(fsmName +
"/RunInfoPluginType")
8669 if(runInfoPluginType !=
8670 TableViewColumnInfo::DATATYPE_STRING_DEFAULT &&
8671 runInfoPluginType !=
"No Run Info Plugin")
8672 useRunInfoDb =
true;
8676 rollOverLogOnConfigure =
8677 fsmLinkNode.
getNode(
"RollOverLogOnConfigure")
8682 rollOverLogOnConfigure =
false;
8686 rollOverLogOnStart =
8687 fsmLinkNode.
getNode(
"RollOverLogOnConfigure")
8692 rollOverLogOnStart =
false;
8696 catch(std::runtime_error& e)
8703 <<
"Unknown error looking for Run alias. Should never happen."
8708 xmlOut.addTextElementToData(
"stateMachineRunAlias", stateMachineRunAlias);
8713 (getenv(
"OTS_LOG_ROLLOVER") ? getenv(
"OTS_LOG_ROLLOVER") :
"");
8714 std::stringstream ss;
8715 if(rollOverLogOnConfigure || rollOverLogOnStart || rollOverLogOnSize !=
"")
8717 ss <<
"ots log files will rollover ";
8718 if(!rollOverLogOnConfigure &&
8719 !rollOverLogOnStart)
8720 ss <<
" on size-in-bytes: " << rollOverLogOnSize
8721 <<
". To enable on FSM transitions set RollOverLogOnConfigure "
8722 "and/or RollOverLogOnStart in the FSM Configuration Tree.";
8725 if(rollOverLogOnConfigure && rollOverLogOnStart)
8726 ss <<
" on the Configure and Start FSM transitions";
8727 else if(rollOverLogOnConfigure)
8728 ss <<
" on the Configure FSM transition";
8729 else if(rollOverLogOnStart)
8730 ss <<
" on the Start FSM transition";
8732 if(rollOverLogOnSize !=
"")
8733 ss <<
". To enable rollover on 100MB size, for example, export "
8734 "OTS_LOG_ROLLOVER=100000000.";
8736 ss <<
", and also on size-in-bytes: " << rollOverLogOnSize;
8740 ss <<
"ots log files will not rollover. "
8741 "To enable rollover on 100MB size, for example, export "
8742 "OTS_LOG_ROLLOVER=100000000; "
8743 "to enable on FSM transitions set RollOverLogOnConfigure and/or "
8744 "RollOverLogOnStart in the FSM Configuration Tree.";
8746 xmlOut.addTextElementToData(
"stateMachineLogRollover", ss.str());
8751 if(theStateMachine_.getCurrentStateName() ==
8752 RunControlStateMachine::RUNNING_STATE_NAME ||
8753 theStateMachine_.getCurrentStateName() ==
8754 RunControlStateMachine::PAUSED_STATE_NAME)
8758 "Current %s Number from DB: %s",
8759 activeStateMachineRunAlias_.c_str(),
8760 activeStateMachineRunNumber_.c_str());
8765 "Current %s Number: %s",
8766 activeStateMachineRunAlias_.c_str(),
8767 activeStateMachineRunNumber_
8769 xmlOut.addTextElementToData(
"run_number", tmp);
8771 if(RunControlStateMachine::asyncPauseExceptionReceived_)
8775 xmlOut.addTextElementToData(
"soft_error",
8776 RunControlStateMachine::getErrorMessage());
8783 sprintf(tmp,
"Next %s Number from DB.", stateMachineRunAlias.c_str());
8786 "Next %s Number: %u",
8787 stateMachineRunAlias.c_str(),
8788 getNextRunNumber(fsmName));
8790 xmlOut.addTextElementToData(
"run_number", tmp);
8797 void GatewaySupervisor::addRequiredFsmLogInputToXML(
HttpXmlDocument& xmlOut,
8798 const std::string& fsmName)
8800 bool requireUserLogInputOnConfigure =
false, requireUserLogInputOnRun =
false;
8806 CorePropertySupervisorBase::theConfigurationManager_->getSupervisorTableNode(
8807 supervisorContextUID_, supervisorApplicationUID_);
8814 try { requireUserLogInputOnConfigure = fsmLinkNode.
getNode(
"RequireUserLogInputOnConfigureTransition").
getValue<
bool>(); }
catch(...) { __SUP_COUTT__ <<
"RequireUserLogInputOnConfigureTransition not set."; }
8815 try { requireUserLogInputOnRun = fsmLinkNode.
getNode(
"RequireUserLogInputOnRunTransition").
getValue<
bool>(); }
catch(...) { __SUP_COUTT__ <<
"RequireUserLogInputOnRunTransition not set."; }
8818 { __SUP_COUTT__ <<
"Settings not set for fsm name = " << fsmName << __E__; }
8823 xmlOut.addTextElementToData(
"RequireUserLogInputOnConfigureTransition",
8824 requireUserLogInputOnConfigure ?
"1" :
"0");
8825 xmlOut.addTextElementToData(
"RequireUserLogInputOnRunTransition",
8826 requireUserLogInputOnRun ?
"1" :
"0");
8830 void GatewaySupervisor::addFilteredConfigAliasesToXML(
HttpXmlDocument& xmlOut,
8831 const std::string& fsmName)
8833 __SUP_COUTV__(fsmName);
8838 std::map<std::string , std::pair<std::string ,
TableGroupKey>>
8845 CorePropertySupervisorBase::theConfigurationManager_->getSupervisorTableNode(
8846 supervisorContextUID_, supervisorApplicationUID_);
8848 std::string stateMachineAliasFilter =
"*";
8854 configLinkNode.
getNode(
"LinkToStateMachineTable");
8857 stateMachineAliasFilter =
8858 fsmLinkNode.
getNode(fsmName +
"/SystemAliasFilter")
8861 __COUT_INFO__ <<
"FSM Link disconnected." << __E__;
8863 catch(std::runtime_error& e)
8865 __COUT_INFO__ << e.what() << __E__;
8869 __COUT_ERR__ <<
"Unknown error. Should never happen." << __E__;
8873 __COUT_INFO__ <<
"FSM Link disconnected." << __E__;
8875 __COUT__ <<
"For FSM '" << fsmName
8876 <<
",' stateMachineAliasFilter = " << stateMachineAliasFilter << __E__;
8883 stateMachineAliasFilter.size() && stateMachineAliasFilter[0] ==
'!';
8884 std::vector<std::string> filterArr;
8891 while((f = stateMachineAliasFilter.find(
'*', i)) != std::string::npos)
8893 tmp = stateMachineAliasFilter.substr(i, f - i);
8895 filterArr.push_back(tmp);
8899 if(i <= stateMachineAliasFilter.size())
8901 tmp = stateMachineAliasFilter.substr(i);
8902 filterArr.push_back(tmp);
8908 for(
auto& aliasMapPair : aliasMap)
8914 if(filterArr.size() == 1)
8916 if(filterArr[0] !=
"" && filterArr[0] !=
"*" &&
8917 aliasMapPair.first != filterArr[0])
8918 filterMatch =
false;
8923 for(f = 0; f < filterArr.size(); ++f)
8925 if(!filterArr[f].size())
8930 if((i = aliasMapPair.first.find(filterArr[f])) != 0)
8932 filterMatch =
false;
8936 else if(f == filterArr.size() - 1)
8938 if(aliasMapPair.first.rfind(filterArr[f]) !=
8939 aliasMapPair.first.size() - filterArr[f].size())
8941 filterMatch =
false;
8945 else if((i = aliasMapPair.first.find(filterArr[f])) ==
8948 filterMatch =
false;
8955 filterMatch = !filterMatch;
8962 xmlOut.addTextElementToData(
"config_alias", aliasMapPair.first);
8963 xmlOut.addTextElementToData(
8966 aliasMapPair.second.second,
8973 xmlOut.addTextElementToData(
8974 "config_alias_comment",
8975 temporaryConfigMgr.
getNode(ConfigurationManager::GROUP_ALIASES_TABLE_NAME)
8977 .
getNode(TableViewColumnInfo::COL_NAME_COMMENT)
8980 std::string groupComment, groupAuthor, groupCreationTime;
8984 aliasMapPair.second.second,
8994 xmlOut.addTextElementToData(
"config_comment", groupComment);
8995 xmlOut.addTextElementToData(
"config_author", groupAuthor);
8996 xmlOut.addTextElementToData(
"config_create_time", groupCreationTime);
9000 __COUT_WARN__ <<
"Failed to load group metadata." << __E__;
9001 xmlOut.addTextElementToData(
"config_comment",
"");
9002 xmlOut.addTextElementToData(
"config_author",
"");
9003 xmlOut.addTextElementToData(
"config_create_time",
"");
9009 std::string fn = ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" +
9010 FSM_LAST_GROUP_ALIAS_FILE_START + fsmName +
"." +
9011 FSM_USERS_PREFERENCES_FILETYPE;
9012 __COUT__ <<
"Load preferences: " << fn << __E__;
9013 FILE* fp = fopen(fn.c_str(),
"r");
9016 char tmpLastAlias[500];
9017 fscanf(fp,
"%*s %s", tmpLastAlias);
9018 __COUT__ <<
"tmpLastAlias: " << tmpLastAlias << __E__;
9020 xmlOut.addTextElementToData(
"UserLastConfigAlias", tmpLastAlias);
9023 else if(aliasMap.size())
9024 xmlOut.addTextElementToData(
"UserLastConfigAlias", aliasMap.begin()->first);
9032 void GatewaySupervisor::launchStartOneServerCommand(
const std::string& command,
9034 const std::string& contextName)
9036 __COUT__ <<
"launch ots script Command = " << command << __E__;
9037 __COUT__ <<
"Extracting target context hostname... " << __E__;
9039 std::string hostname;
9044 auto contexts = contextTable->getContexts();
9047 for(
const auto& context : contexts)
9049 if(context.contextUID_ != contextName)
9052 __COUT__ <<
"contextUID_ is: " << context.contextUID_ << __E__;
9056 for(i = 0; i < context.address_.size(); ++i)
9057 if(context.address_[i] ==
'/')
9059 hostname = context.address_.substr(j);
9060 __COUT__ <<
"ots script command '" << command
9061 <<
"' launching on hostname = " << hostname <<
" in context name "
9062 << context.contextUID_ << __E__;
9067 __SS__ <<
"\nRelaunch of otsdaq interrupted! "
9068 <<
"The Configuration Manager could not be initialized." << __E__;
9073 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
"/StartOTS_action_" +
9075 FILE* fp = fopen(fn.c_str(),
"w");
9078 fprintf(fp,
"%s", command.c_str());
9083 __SS__ <<
"Unable to open command file: " << fn << __E__;
9090 fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
"/StartOTS_action_" + hostname +
9092 fp = fopen(fn.c_str(),
"r");
9096 fgets(line, 100, fp);
9099 if(strcmp(line, command.c_str()) == 0)
9101 __SS__ <<
"The command looks to have been ignored by " << hostname
9102 <<
". Is the ots launch script still running on that node?" << __E__;
9109 __SS__ <<
"Unable to open command file for verification: " << fn << __E__;
9118 void GatewaySupervisor::launchStartOTSCommand(
const std::string& command,
9121 __COUT__ <<
"launch ots script Command = " << command << __E__;
9122 __COUT__ <<
"Extracting target context hostnames... " << __E__;
9124 std::vector<std::string> hostnames;
9131 auto contexts = contextTable->getContexts();
9133 for(
const auto& context : contexts)
9135 if(!context.status_)
9140 for(i = 0; i < context.address_.size(); ++i)
9141 if(context.address_[i] ==
'/')
9143 hostnames.push_back(context.address_.substr(j));
9144 __COUT__ <<
"ots script command '" << command
9145 <<
"' launching on hostname = " << hostnames.back() << __E__;
9150 __SS__ <<
"Launch of command '" << command <<
"' interrupted! "
9151 <<
"The Configuration Manager could not be initialized to find targets."
9157 for(
const auto& hostname : hostnames)
9159 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
9160 "/StartOTS_action_" + hostname +
".cmd");
9161 FILE* fp = fopen(fn.c_str(),
"w");
9164 fprintf(fp,
"%s", command.c_str());
9169 __SS__ <<
"Unable to open command file: " << fn << __E__;
9177 for(
const auto& hostname : hostnames)
9179 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
9180 "/StartOTS_action_" + hostname +
".cmd");
9181 FILE* fp = fopen(fn.c_str(),
"r");
9185 fgets(line, 100, fp);
9188 if(strcmp(line, command.c_str()) == 0)
9190 __SS__ <<
"The command '" << command <<
"' looks to have been ignored by "
9192 <<
". Is the ots launch script still running on that node?"
9200 __SS__ <<
"Unable to open command file for verification: " << fn << __E__;
9209 xoap::MessageReference GatewaySupervisor::supervisorCookieCheck(
9210 xoap::MessageReference message)
9214 <<
"request from remote Supervisor for GatewaySupervisor::supervisorCookieCheck()"
9219 parameters.addParameter(
"CookieCode");
9220 parameters.addParameter(
"RefreshOption");
9221 parameters.addParameter(
"IPAddress");
9222 SOAPUtilities::receive(message, parameters);
9223 std::string cookieCode = parameters.getValue(
"CookieCode");
9224 std::string refreshOption =
9225 parameters.getValue(
"RefreshOption");
9227 std::string ipAddress =
9228 parameters.getValue(
"IPAddress");
9234 std::map<std::string , WebUsers::permissionLevel_t>
9235 userGroupPermissionsMap;
9236 std::string userWithLock =
"";
9237 uint64_t uid, userSessionIndex;
9239 &userGroupPermissionsMap,
9242 refreshOption ==
"1",
9247 __COUTTV__(userWithLock);
9251 retParameters.addParameter(
"CookieCode", cookieCode);
9252 retParameters.addParameter(
9254 retParameters.addParameter(
"UserWithLock", userWithLock);
9255 retParameters.addParameter(
"Username", theWebUsers_.
getUsersUsername(uid));
9257 retParameters.addParameter(
"UserSessionIndex", std::to_string(userSessionIndex));
9259 __COUTT__ <<
"Login response: " << retParameters.getValue(
"Username") << __E__;
9261 return SOAPUtilities::makeSOAPMessageReference(
"CookieResponse", retParameters);
9267 xoap::MessageReference GatewaySupervisor::supervisorGetActiveUsers(
9268 xoap::MessageReference )
9273 return SOAPUtilities::makeSOAPMessageReference(
"ActiveUserResponse", parameters);
9281 xoap::MessageReference GatewaySupervisor::supervisorSystemMessage(
9282 xoap::MessageReference message)
9285 parameters.addParameter(
"ToUser");
9286 parameters.addParameter(
"Subject");
9287 parameters.addParameter(
"Message");
9288 parameters.addParameter(
"DoEmail");
9289 SOAPUtilities::receive(message, parameters);
9291 std::string toUserCSV = parameters.getValue(
"ToUser");
9292 std::string subject = parameters.getValue(
"Subject");
9293 std::string systemMessage = parameters.getValue(
"Message");
9294 std::string doEmail = parameters.getValue(
"DoEmail");
9299 theWebUsers_.
addSystemMessage(toUserCSV, subject, systemMessage, doEmail ==
"1");
9301 return SOAPUtilities::makeSOAPMessageReference(
"SystemMessageResponse");
9306 void GatewaySupervisor::addSystemMessage(std::string toUserCSV, std::string message)
9308 __COUTTV__(toUserCSV);
9309 __COUTVS__(45, message);
9317 xoap::MessageReference GatewaySupervisor::supervisorSystemLogbookEntry(
9318 xoap::MessageReference message)
9321 parameters.addParameter(
"EntryText");
9322 SOAPUtilities::receive(message, parameters);
9324 __COUT__ <<
"EntryText: " << parameters.getValue(
"EntryText").substr(0, 10) << __E__;
9326 makeSystemLogEntry(parameters.getValue(
"EntryText"));
9328 return SOAPUtilities::makeSOAPMessageReference(
"SystemLogbookResponse");
9336 xoap::MessageReference GatewaySupervisor::supervisorLastTableGroupRequest(
9337 xoap::MessageReference message)
9340 parameters.addParameter(
"ActionOfLastGroup");
9341 SOAPUtilities::receive(message, parameters);
9343 return GatewaySupervisor::lastTableGroupRequestHandler(parameters);
9352 xoap::MessageReference GatewaySupervisor::lastTableGroupRequestHandler(
9355 std::string action = parameters.getValue(
"ActionOfLastGroup");
9356 __COUT__ <<
"ActionOfLastGroup: " << action.substr(0, 30) << __E__;
9358 std::vector<std::string> actions;
9359 std::vector<std::string> fileNames;
9362 actions = std::vector<std::string>({
"Configured",
9366 "ActivatedBackbone",
9367 "ActivatedIterator"});
9368 fileNames = std::vector<std::string>(
9369 {FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE,
9370 FSM_LAST_STARTED_GROUP_ALIAS_FILE,
9371 ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE,
9372 ConfigurationManager::LAST_ACTIVATED_CONTEXT_GROUP_FILE,
9373 ConfigurationManager::LAST_ACTIVATED_BACKBONE_GROUP_FILE,
9374 ConfigurationManager::LAST_ACTIVATED_ITERATOR_GROUP_FILE});
9378 actions.push_back(action);
9380 if(action ==
"Configured")
9381 fileNames.push_back(FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE);
9382 else if(action ==
"Started")
9383 fileNames.push_back(FSM_LAST_STARTED_GROUP_ALIAS_FILE);
9384 else if(action ==
"ActivatedConfig")
9385 fileNames.push_back(ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE);
9386 else if(action ==
"ActivatedContext")
9387 fileNames.push_back(ConfigurationManager::LAST_ACTIVATED_CONTEXT_GROUP_FILE);
9388 else if(action ==
"ActivatedBackbone")
9389 fileNames.push_back(ConfigurationManager::LAST_ACTIVATED_BACKBONE_GROUP_FILE);
9390 else if(action ==
"ActivatedIterator")
9391 fileNames.push_back(ConfigurationManager::LAST_ACTIVATED_ITERATOR_GROUP_FILE);
9394 __COUT_ERR__ <<
"Invalid last group action requested." << __E__;
9395 return SOAPUtilities::makeSOAPMessageReference(
9396 "LastConfigGroupResponseFailure");
9400 std::string groupNames =
"";
9401 std::string groupKeys =
"";
9402 std::string groupActions =
"";
9403 std::string groupTimes =
"";
9404 for(
size_t i = 0; i < fileNames.size(); ++i)
9410 groupActions +=
",";
9414 std::string timeString;
9418 groupNames += theGroup.first;
9419 groupKeys += theGroup.second.toString();
9420 groupActions += actions[i];
9421 groupTimes += timeString;
9425 retParameters.addParameter(
"GroupName", groupNames);
9426 retParameters.addParameter(
"GroupKey", groupKeys);
9427 retParameters.addParameter(
"GroupAction", groupActions);
9428 retParameters.addParameter(
"GroupActionTime", groupTimes);
9430 return SOAPUtilities::makeSOAPMessageReference(
"LastConfigGroupResponse",
9441 unsigned int GatewaySupervisor::getNextRunNumber(
const std::string& fsmNameIn)
9443 std::string runNumberFileName = RUN_NUMBER_PATH +
"/";
9444 std::string fsmName = fsmNameIn ==
"" ? activeStateMachineName_ : fsmNameIn;
9446 for(
unsigned int i = 0; i < fsmName.size(); ++i)
9447 if((fsmName[i] >=
'a' && fsmName[i] <=
'z') ||
9448 (fsmName[i] >=
'A' && fsmName[i] <=
'Z') ||
9449 (fsmName[i] >=
'0' && fsmName[i] <=
'9'))
9450 runNumberFileName += fsmName[i];
9451 runNumberFileName += RUN_NUMBER_FILE_NAME;
9454 std::ifstream runNumberFile(runNumberFileName.c_str());
9455 if(!runNumberFile.is_open())
9457 __COUT__ <<
"Cannot open file: " << runNumberFileName << __E__;
9459 __COUT__ <<
"Creating file and setting Run Number to 1: " << runNumberFileName
9461 FILE* fp = fopen(runNumberFileName.c_str(),
"w");
9465 runNumberFile.open(runNumberFileName.c_str());
9466 if(!runNumberFile.is_open())
9468 __SS__ <<
"Error. Cannot create file: " << runNumberFileName << __E__;
9472 std::string runNumberString;
9473 runNumberFile >> runNumberString;
9474 runNumberFile.close();
9475 return atoi(runNumberString.c_str());
9479 void GatewaySupervisor::setNextRunNumber(
unsigned int runNumber,
9480 const std::string& fsmNameIn)
9482 std::string runNumberFileName = RUN_NUMBER_PATH +
"/";
9483 std::string fsmName = fsmNameIn ==
"" ? activeStateMachineName_ : fsmNameIn;
9485 for(
unsigned int i = 0; i < fsmName.size(); ++i)
9486 if((fsmName[i] >=
'a' && fsmName[i] <=
'z') ||
9487 (fsmName[i] >=
'A' && fsmName[i] <=
'Z') ||
9488 (fsmName[i] >=
'0' && fsmName[i] <=
'9'))
9489 runNumberFileName += fsmName[i];
9490 runNumberFileName += RUN_NUMBER_FILE_NAME;
9491 __COUTTV__(runNumberFileName);
9493 std::ofstream runNumberFile(runNumberFileName.c_str());
9494 if(!runNumberFile.is_open())
9496 __SS__ <<
"Cannot open file: " << runNumberFileName << __E__;
9499 std::stringstream runNumberStream;
9500 runNumberStream << runNumber;
9501 runNumberFile << runNumberStream.str().c_str();
9502 runNumberFile.close();
9512 std::string GatewaySupervisor::getLastLogEntry(
const std::string& logType,
9513 const std::string& fsmNameIn )
9515 std::string logEntryFileName = LOG_ENTRY_PATH +
"/";
9516 std::string fsmName = fsmNameIn ==
"" ? activeStateMachineName_ : fsmNameIn;
9518 if(logType == RunControlStateMachine::START_TRANSITION_NAME &&
9519 stateMachineStartLogEntry_.find(fsmName) != stateMachineStartLogEntry_.end())
9520 return stateMachineStartLogEntry_.at(fsmName);
9521 else if(logType == RunControlStateMachine::CONFIGURE_TRANSITION_NAME &&
9522 stateMachineConfigureLogEntry_.find(fsmName) !=
9523 stateMachineConfigureLogEntry_.end())
9524 return stateMachineConfigureLogEntry_.at(fsmName);
9525 else if(logType == RunControlStateMachine::STOP_TRANSITION_NAME &&
9526 stateMachineStopLogEntry_.find(fsmName) != stateMachineStopLogEntry_.end())
9527 return stateMachineStopLogEntry_.at(fsmName);
9530 for(
unsigned int i = 0; i < fsmName.size(); ++i)
9531 if((fsmName[i] >=
'a' && fsmName[i] <=
'z') ||
9532 (fsmName[i] >=
'A' && fsmName[i] <=
'Z') ||
9533 (fsmName[i] >=
'0' && fsmName[i] <=
'9'))
9534 logEntryFileName += fsmName[i];
9535 logEntryFileName +=
"_" + logType +
"_" + LOG_ENTRY_FILE_NAME;
9536 __SUP_COUTTV__(logEntryFileName);
9538 std::string contents;
9539 std::FILE* fp = std::fopen(logEntryFileName.c_str(),
"rb");
9542 __SUP_COUTT__ <<
"Could not open file at " << logEntryFileName
9543 <<
". Error: " << errno <<
" - " << strerror(errno) << __E__;
9548 std::fseek(fp, 0, SEEK_END);
9549 contents.resize(std::ftell(fp));
9551 std::fread(&contents[0], 1, contents.size(), fp);
9555 __SUP_COUTTV__(contents);
9557 if(logType == RunControlStateMachine::START_TRANSITION_NAME)
9558 stateMachineStartLogEntry_[fsmName] = contents;
9559 else if(logType == RunControlStateMachine::CONFIGURE_TRANSITION_NAME)
9560 stateMachineConfigureLogEntry_[fsmName] = contents;
9561 else if(logType == RunControlStateMachine::STOP_TRANSITION_NAME)
9562 stateMachineStopLogEntry_[fsmName] = contents;
9574 void GatewaySupervisor::setLastLogEntry(
const std::string& logType,
9575 const std::string& logEntry,
9576 const std::string& fsmNameIn )
9578 std::string logEntryFileName = LOG_ENTRY_PATH +
"/";
9579 std::string fsmName = fsmNameIn ==
"" ? activeStateMachineName_ : fsmNameIn;
9581 if(logType == RunControlStateMachine::START_TRANSITION_NAME)
9582 stateMachineStartLogEntry_[fsmName] = logEntry;
9583 else if(logType == RunControlStateMachine::CONFIGURE_TRANSITION_NAME)
9584 stateMachineConfigureLogEntry_[fsmName] = logEntry;
9585 else if(logType == RunControlStateMachine::STOP_TRANSITION_NAME)
9586 stateMachineStopLogEntry_[fsmName] = logEntry;
9590 __COUT_WARN__ <<
"Log entry for log type '" << logType
9591 <<
"' not implemented for saving." << __E__;
9596 for(
unsigned int i = 0; i < fsmName.size(); ++i)
9597 if((fsmName[i] >=
'a' && fsmName[i] <=
'z') ||
9598 (fsmName[i] >=
'A' && fsmName[i] <=
'Z') ||
9599 (fsmName[i] >=
'0' && fsmName[i] <=
'9'))
9600 logEntryFileName += fsmName[i];
9601 logEntryFileName +=
"_" + logType +
"_" + LOG_ENTRY_FILE_NAME;
9602 __COUTTV__(logEntryFileName);
9603 __COUTTV__(logType);
9604 __COUTTV__(logEntry);
9606 std::FILE* fp = std::fopen(logEntryFileName.c_str(),
"w");
9609 __SUP_SS__ <<
"Could not open file at " << logEntryFileName
9610 <<
". Error: " << errno <<
" - " << strerror(errno) << __E__;
9614 std::fwrite(&logEntry[0], 1, logEntry.size(), fp);
9625 void GatewaySupervisor::loadRemoteGatewaySettings(
9626 std::vector<GatewaySupervisor::RemoteGatewayInfo>& remoteGateways,
9627 bool onlyNotFound )
const
9629 std::string filepath = std::string(__ENV__(
"SERVICE_DATA_PATH")) +
"/" +
9630 REMOTE_SUBSYSTEM_SETTINGS_FILE_NAME;
9631 __SUP_COUTV__(filepath);
9633 std::ifstream settingsFile(filepath.c_str());
9634 if(!settingsFile.is_open())
9637 <<
"Cannot open Remote Gateway settings file (assuming no settings yet!): "
9638 << filepath << __E__;
9640 __SUP_COUT__ <<
"Creating empty Remote Gateway settings file: " << filepath
9642 FILE* fp = fopen(filepath.c_str(),
"w");
9646 settingsFile.open(filepath.c_str());
9647 if(!settingsFile.is_open())
9649 __SUP_SS__ <<
"Error. Cannot create or load Remote Gateway settings file: "
9650 << filepath << __E__;
9655 size_t NUM_FIELDS = 4;
9656 std::vector<std::string> values;
9657 float formatVersion = 0.0;
9662 for(i = 0; i < NUM_FIELDS; ++i)
9664 if(i >= values.size())
9665 values.push_back(
"");
9667 if(!std::getline(settingsFile, values[i]))
9672 settingsFile.close();
9674 <<
"Error. Illegal file format in Remote Gateway settings file: "
9675 << filepath << __E__;
9682 __SUP_COUTVS__(20, values[i]);
9693 "Remote Gateway Settings, file format v") !=
9696 sscanf(values[i].c_str(),
9697 "Remote Gateway Settings, file format v%f",
9699 __SUP_COUTV__(formatVersion);
9701 if(formatVersion > 0.5)
9704 __SUP_COUTV__(NUM_FIELDS);
9717 for(i = 0; i < remoteGateways.size(); ++i)
9718 if(values[0] == remoteGateways[i].appInfo.name)
9726 remoteGateways.push_back(GatewaySupervisor::RemoteGatewayInfo());
9727 remoteGateways[i].appInfo.name = values[0];
9729 else if(onlyNotFound)
9732 remoteGateways[i].fsm_mode =
9733 values[1] ==
"Do Not Halt"
9735 : (values[1] ==
"Only Configure"
9737 : RemoteGatewayInfo::FSM_ModeTypes::Follow_FSM);
9738 remoteGateways[i].fsm_included = values[2] ==
"1" ? true :
false;
9739 if(values.size() > 3)
9740 remoteGateways[i].selected_config_alias = values[3];
9742 __SUP_COUT__ <<
"Loaded Remote Gateway '" << remoteGateways[i].appInfo.name
9743 <<
"' ==> " << remoteGateways[i].getFsmMode() <<
" :"
9744 << remoteGateways[i].fsm_included
9745 <<
"configAlias=" << remoteGateways[i].selected_config_alias
9750 settingsFile.close();
9754 void GatewaySupervisor::saveRemoteGatewaySettings()
const
9756 std::string filepath = std::string(__ENV__(
"SERVICE_DATA_PATH")) +
"/" +
9757 REMOTE_SUBSYSTEM_SETTINGS_FILE_NAME;
9758 __SUP_COUTV__(filepath);
9760 std::vector<GatewaySupervisor::RemoteGatewayInfo> remoteGateways = remoteGatewayApps_;
9763 loadRemoteGatewaySettings(remoteGateways,
true );
9765 std::ofstream settingsFile(filepath.c_str());
9766 if(!settingsFile.is_open())
9768 __SUP_SS__ <<
"Cannot open Remote Gateway settings file: " << filepath << __E__;
9771 settingsFile <<
"Remote Gateway Settings, file format v1.0"
9773 for(
size_t i = 0; i < remoteGateways.size(); ++i)
9775 settingsFile << remoteGateways[i].appInfo.name << __E__;
9776 settingsFile << remoteGateways[i].getFsmMode() << __E__;
9777 settingsFile << std::string(remoteGateways[i].fsm_included ?
"1" :
"0") << __E__;
9778 settingsFile << remoteGateways[i].selected_config_alias << __E__;
9781 settingsFile.close();
9785 void GatewaySupervisor::handleGetApplicationIdRequest(
9788 std::string classNeedle =
9790 __COUTV__(classNeedle);
9796 auto appInfo = it.second;
9798 if(classNeedle != appInfo.getClass())
9801 xmlOut.addTextElementToData(
"name",
9803 xmlOut.addTextElementToData(
9804 "id", std::to_string(appInfo.getId()));
9805 xmlOut.addTextElementToData(
"class",
9806 appInfo.getClass());
9807 xmlOut.addTextElementToData(
"url",
9809 xmlOut.addTextElementToData(
"context",
9810 appInfo.getContextName());
9816 bool GatewaySupervisor::handleAddDesktopIconRequest(
9817 const std::string& author,
9818 cgicc::Cgicc& cgiIn,
9820 std::vector<DesktopIconTable::DesktopIcon>* newIcons )
9822 std::string iconCaption =
9824 std::string iconAltText =
9826 std::string iconFolderPath =
9828 std::string iconImageURL =
9830 std::string iconWindowURL =
9832 std::string iconPermissions =
9835 std::string windowLinkedApp =
9837 unsigned int windowLinkedAppLID =
9838 CgiDataUtilities::getDataAsInt(cgiIn,
"iconLinkedAppLID");
9839 bool enforceOneWindowInstance =
9848 __COUTV__(iconCaption);
9849 __COUTV__(iconAltText);
9850 __COUTV__(iconFolderPath);
9851 __COUTV__(iconImageURL);
9852 __COUTV__(iconWindowURL);
9853 __COUTV__(iconPermissions);
9854 __COUTV__(windowLinkedApp);
9855 __COUTV__(windowLinkedAppLID);
9856 __COUTV__(enforceOneWindowInstance);
9858 __COUTV__(windowParameters);
9862 bool success = ConfigurationSupervisorBase::handleAddDesktopIconXML(
9872 windowLinkedAppLID ,
9873 enforceOneWindowInstance ,
9876 if(newIcons && success)
9878 __COUT__ <<
"Passing new icons back to caller..." << __E__;
9880 const std::vector<DesktopIconTable::DesktopIcon>& tmpNewIcons =
9884 for(
const auto& tmpNewIcon : tmpNewIcons)
9885 newIcons->push_back(tmpNewIcon);
9892 xoap::MessageReference GatewaySupervisor::TRACESupervisorRequest(
9893 xoap::MessageReference message)
9895 return CorePropertySupervisorBase::TRACESupervisorRequest(message);
9897
void setSupervisorStatus(xdaq::Application *app, const std::string &status, const unsigned int progress=100, const std::string &detail="", std::vector< SupervisorInfo::SubappInfo > subapps={})
SETTERs.
const std::map< unsigned int, SupervisorInfo > & getAllSupervisorInfo(void) const
GETTERs (so searching and iterating is easier)
static std::string postData(cgicc::Cgicc &cgi, const std::string &needle)
static std::string getData(cgicc::Cgicc &cgi, const std::string &needle)
void loadTableGroup(const std::string &tableGroupName, const TableGroupKey &tableGroupKey, bool doActivate=false, std::map< std::string, TableVersion > *groupMembers=0, ProgressBar *progressBar=0, std::string *accumulateWarnings=0, std::string *groupComment=0, std::string *groupAuthor=0, std::string *groupCreateTime=0, bool doNotLoadMember=false, std::string *groupTypeString=0, std::map< std::string, std::string > *groupAliases=0, ConfigurationManager::LoadGroupType onlyLoadIfBackboneOrContext=ConfigurationManager::LoadGroupType::ALL_TYPES, bool ignoreVersionTracking=false)
std::set< std::string > getOtherSubsystemConfigAliases(const std::string &otherSubsystemUID)
Ignore any System Aliases with "Context" or "Iterat" in the name.
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
"root/parent/parent/"
void init(std::string *accumulatedErrors=0, bool initForWriteAccess=false, std::string *accumulatedWarnings=0)
void getOtherSubsystemConfigAliasInfo(const std::string &otherSubsystemUID, const std::string &configAlias, std::pair< std::string, TableGroupKey > &groupTranslation, std::string &groupComment, std::string &groupAuthor, std::string &groupCreationTime)
returns configAlias translation group info by reference
static std::pair< std::string, TableGroupKey > loadGroupNameAndKey(const std::string &fileName, std::string &returnedTimeString)
std::map< std::string, std::pair< std::string, TableGroupKey > > getActiveGroupAliases(void)
const TableVersion & getTableVersion(void) const
getTableVersion
bool isDisconnected(void) const
ConfigurationTree getNode(const std::string &nodeName, bool doNotThrowOnBrokenUIDLinks=false) const
navigating between nodes
T getValueWithDefault(const T &defaultValue) const
void getValue(T &value) const
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
bool isDefaultValue(void) const
boolean info
static void extractPermissionsMapFromString(const std::string &permissionsString, std::map< std::string, WebUsers::permissionLevel_t > &permissionsMap)
static bool doPermissionsGrantAccess(std::map< std::string, WebUsers::permissionLevel_t > &permissionLevelsMap, std::map< std::string, WebUsers::permissionLevel_t > &permissionThresholdsMap)
friend class GatewaySupervisor
for access to indicateOtsAlive()
void getRequestUserInfo(WebUsers::RequestUserInfo &requestUserInfo)
std::string getRemoteURL(ConfigurationManager *configManager, const std::string &localURL) const
Convert to remote URL assuming port forwarding to primary Gateway Port.
void setAllDesktopIcons(const std::vector< DesktopIconTable::DesktopIcon > &newIcons)
overwrite dynamically the init result
time_t getTimeInState(void) const
virtual void setSupervisorPropertyDefaults(void) override
override to control supervisor specific defaults
void stateHalted(toolbox::fsm::FiniteStateMachine &fsm) override
virtual void forceSupervisorPropertyValues(void) override
override to force supervisor property values (and ignore user settings)
void statePaused(toolbox::fsm::FiniteStateMachine &fsm) override
void stateRunning(toolbox::fsm::FiniteStateMachine &fsm) override
void stateConfigured(toolbox::fsm::FiniteStateMachine &fsm) override
void stateInitial(toolbox::fsm::FiniteStateMachine &fsm) override
void outputXmlDocument(std::ostringstream *out, bool dispStdOut=false, bool allowWhiteSpace=false)
std::string readPercentageString()
return percentage complete as std::string
xoap::MessageReference runControlMessageHandler(xoap::MessageReference message)
Run Control Messages.
const std::string & getCommand(void) const
Getters.
std::string send(XDAQ_CONST_CALL xdaq::ApplicationDescriptor *d, xoap::MessageReference message)
XDAQ_CONST_CALL xdaq::ApplicationDescriptor * getDescriptor(void) const
Getters ----------------—.
static std::string getFullGroupString(const std::string &groupName, const TableGroupKey &key, const std::string &preKey="_v", const std::string &postKey="")
void addSystemMessage(const std::string &targetUsersCSV, const std::string &message)
const std::string & getSecurity(void)
WebUsers::getSecurity.
std::string getGenericPreference(uint64_t uid, const std::string &preferenceName, HttpXmlDocument *xmldoc=0) const
bool setUserWithLock(uint64_t actingUid, bool lock, const std::string &username)
static void silenceAllUserTooltips(const std::string &username)
size_t getActiveUserCount(void)
std::map< std::string, WebUsers::permissionLevel_t > getPermissionsForUser(uint64_t uid)
from Gateway, use public version which considers remote users
uint64_t attemptActiveSession(const std::string &uuid, std::string &jumbledUser, const std::string &jumbledPw, std::string &newAccountCode, const std::string &ip)
void setGenericPreference(uint64_t uid, const std::string &preferenceName, const std::string &preferenceValue)
std::string getAllSystemMessages(void)
void cleanupExpiredEntries(std::vector< std::string > *loggedOutUsernames=0)
void changeSettingsForUser(uint64_t uid, const std::string &bgcolor, const std::string &dbcolor, const std::string &wincolor, const std::string &layout, const std::string &syslayout)
WebUsers::changeSettingsForUser.
uint64_t isCookieCodeActiveForLogin(const std::string &uuid, std::string &cookieCode, std::string &username)
std::string createNewLoginSession(const std::string &uuid, const std::string &ip)
std::string getActiveUsersString(void)
void modifyAccountSettings(uint64_t actingUid, uint8_t cmd_type, const std::string &username, const std::string &displayname, const std::string &email, const std::string &permissions)
WebUsers::modifyAccountSettings.
int remoteLoginVerificationPort_
Port of remote Gateway to be used for login verification.
bool isUserIdActive(uint64_t uid) const
void saveActiveSessions(void)
static std::atomic< bool > remoteLoginVerificationEnabled_
true if this supervisor is under control of a remote supervisor
std::string getUsersUsername(uint64_t uid)
from Gateway, use public version which considers remote users
bool xmlRequestOnGateway(cgicc::Cgicc &cgi, std::ostringstream *out, HttpXmlDocument *xmldoc, WebUsers::RequestUserInfo &userInfo)
uint64_t cookieCodeLogout(const std::string &cookieCode, bool logoutOtherUserSessions, uint64_t *uid=0, const std::string &ip="0")
std::string getSystemMessage(const std::string &targetUser)
uint64_t getActiveSessionCountForUser(uint64_t uid)
static void resetAllUserTooltips(const std::string &userNeedle="*")
WebUsers::resetAllUserTooltips.
static void tooltipSetNeverShowForUsername(const std::string &username, HttpXmlDocument *xmldoc, const std::string &srcFile, const std::string &srcFunc, const std::string &srcId, bool doNeverShow, bool temporarySilence)
std::string getUsersDisplayName(uint64_t uid)
from Gateway, use public version which considers remote users
std::pair< std::string, time_t > getLastSystemMessage(void)
uint64_t attemptActiveSessionWithCert(const std::string &uuid, std::string &jumbledEmail, std::string &cookieCode, std::string &username, const std::string &ip)
static void tooltipCheckForUsername(const std::string &username, HttpXmlDocument *xmldoc, const std::string &srcFile, const std::string &srcFunc, const std::string &srcId)
std::string remoteGatewaySelfName_
IP of remote Gateway to be used for login verification.
bool cookieCodeIsActiveForRequest(std::string &cookieCode, std::map< std::string, WebUsers::permissionLevel_t > *userPermissions=0, uint64_t *uid=0, const std::string &ip="0", bool refresh=true, bool doNotGoRemote=false, std::string *userWithLock=0, uint64_t *userSessionIndex=0)
void insertSettingsForUser(uint64_t uid, HttpXmlDocument *xmldoc, bool includeAccounts=false)
HttpXmlDocument processRequest(cgicc::Cgicc &cgi)
xercesc::DOMElement * addTextElementToParent(const std::string &childName, const std::string &childText, xercesc::DOMElement *parent)
void INIT_MF(const char *name)
RunInfoVInterface * makeRunInfo(const std::string &runInfoPluginName, const std::string &runInfoUID)
@ OnlyConfigure
(e.g. for DCS/DQM)
@ DoNotHalt
(e.g. for artdaq)
static std::string getTimestampString(const std::string &linuxTimeInSeconds)
static std::string extractXmlField(const std::string &xml, const std::string &field, uint32_t occurrence, size_t after, size_t *returnFindPos=nullptr, const std::string &valueField="value=", const std::string "eType="'")
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string exec(const char *cmd)
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
setToString ~
static std::string vectorToString(const std::vector< T > &setToReturn, const std::string &delimeter=", ")
vectorToString ~
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static void getMapFromString(const std::string &inputString, std::map< S, T > &mapToReturn, const std::set< char > &pairPairDelimiter={',', '|', '&'}, const std::set< char > &nameValueDelimiter={'=', ':'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
getMapFromString ~
static std::string getTimeDurationString(const time_t durationInSeconds=time(0))
static std::string decodeURIComponent(const std::string &data)