1 #ifndef _ots_GatewaySupervisor_h
2 #define _ots_GatewaySupervisor_h
4 #include <condition_variable>
10 #include "otsdaq/CoreSupervisors/ConfigurationSupervisorBase.h"
11 #include "otsdaq/CoreSupervisors/CorePropertySupervisorBase.h"
12 #include "otsdaq/FiniteStateMachine/RunControlStateMachine.h"
13 #include "otsdaq/FiniteStateMachine/RunInfoVInterface.h"
14 #include "otsdaq/GatewaySupervisor/Iterator.h"
15 #include "otsdaq/SOAPUtilities/SOAPMessenger.h"
16 #include "otsdaq/SupervisorInfo/AllSupervisorInfo.h"
17 #include "otsdaq/WebUsersUtilities/WebUsers.h"
18 #include "otsdaq/WorkLoopManager/WorkLoopManager.h"
20 #include "otsdaq/CodeEditor/CodeEditor.h"
21 #include "otsdaq/TablePlugins/DesktopIconTable.h"
23 #include "otsdaq/NetworkUtilities/TransceiverSocket.h"
25 #pragma GCC diagnostic push
26 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
27 #include <xdaq/Application.h>
28 #pragma GCC diagnostic pop
29 #include "otsdaq/Macros/XDAQApplicationMacros.h"
31 #include <toolbox/task/WorkLoop.h>
32 #include <xdata/String.h>
33 #include <xgi/Method.h>
34 #include "otsdaq/GatewaySupervisor/PixelHistoPicGen.h"
67 class ConfigurationManager;
69 class WorkLoopManager;
85 static const std::string COMMAND_PARAM_LOG_ENTRY_PREAMBLE;
86 static const std::string COMMAND_PARAM_SUBSYSTEM_COMMON_PREAMBLE;
87 static const std::string COMMAND_PARAM_SUBSYSTEM_COMMON_OVERRIDE_PREAMBLE;
88 static const std::string COMMAND_PARAM_SUBSYSTEM_COMMON_CONTEXT_PREAMBLE;
89 static const std::string COMMAND_PARAM_SUBSYSTEM_COMMON_CONTEXT_OVERRIDE_PREAMBLE;
90 static const std::string COMMAND_PARAM_ITERATION_INDEX_PREAMBLE;
91 static const std::string COMMAND_PARAM_MIN_EVENT_GEN_START_ITERATION_PREAMBLE;
101 void Default (xgi::Input* in, xgi::Output* out);
103 void loginRequest (xgi::Input* in, xgi::Output* out);
104 void request (xgi::Input* in, xgi::Output* out);
105 void tooltipRequest (xgi::Input* in, xgi::Output* out);
106 void XGI_Turtle (xgi::Input* in, xgi::Output* out);
108 void addStateMachineStatusToXML (
HttpXmlDocument& xmlOut,
const std::string& fsmName,
bool getRunNumber =
true);
109 void addFilteredConfigAliasesToXML (
HttpXmlDocument& xmlOut,
const std::string& fsmName);
110 void addRequiredFsmLogInputToXML (
HttpXmlDocument& xmlOut,
const std::string& fsmName);
111 static std::string getGlobalFieldsString (
ConfigurationManager* cfgMgr,
const std::map<std::string, TableVersion>& memberMap = {});
114 void stateMachineXgiHandler(xgi::Input* in, xgi::Output* out);
115 void stateMachineIterationBreakpoint(xgi::Input* in, xgi::Output* out);
117 static std::string getIconHeaderString(
void);
118 static bool handleAddDesktopIconRequest(
const std::string& author, cgicc::Cgicc& cgiIn,
HttpXmlDocument& xmlOut, std::vector<DesktopIconTable::DesktopIcon>* newIcons =
nullptr);
119 static void handleGetApplicationIdRequest(
AllSupervisorInfo* applicationInfo, cgicc::Cgicc& cgiIn,
HttpXmlDocument& xmlOut, std::map<std::string , std::map<std::string /* requestUrlHostPort */, std::string /* translatedHostPort */>>* portTranslationMap =
nullptr);
121 xoap::MessageReference stateMachineXoapHandler(xoap::MessageReference msg);
123 bool stateMachineThread(toolbox::task::WorkLoop* workLoop);
126 void statusRequest(xgi::Input* in, xgi::Output* out);
127 void infoRequestResultHandler(xgi::Input* in, xgi::Output* out);
128 bool infoRequestThread(toolbox::task::WorkLoop* workLoop);
131 xoap::MessageReference supervisorCookieCheck(xoap::MessageReference msg);
132 xoap::MessageReference supervisorGetActiveUsers(xoap::MessageReference msg);
133 xoap::MessageReference supervisorSystemMessage(xoap::MessageReference msg);
134 xoap::MessageReference supervisorGetUserInfo(xoap::MessageReference msg);
135 xoap::MessageReference supervisorSystemLogbookEntry(xoap::MessageReference msg);
136 xoap::MessageReference supervisorLastTableGroupRequest(xoap::MessageReference msg);
144 void inError(toolbox::fsm::FiniteStateMachine& fsm)
override;
146 void transitionConfiguring(toolbox::Event::Reference e)
override;
147 void transitionHalting(toolbox::Event::Reference e)
override;
148 void transitionInitializing(toolbox::Event::Reference e)
override;
149 void transitionPausing(toolbox::Event::Reference e)
override;
150 void transitionResuming(toolbox::Event::Reference e)
override;
151 void transitionStarting(toolbox::Event::Reference e)
override;
152 void transitionStopping(toolbox::Event::Reference e)
override;
153 void transitionShuttingDown(toolbox::Event::Reference e)
override;
154 void transitionStartingUp(toolbox::Event::Reference e)
override;
155 void enteringError(toolbox::Event::Reference e)
override;
157 void makeSystemLogEntry(
const std::string& entryText,
const std::string& subjectText =
"",
bool skipFooter =
false);
158 static void addSystemMessage(std::string toUserCSV, std::string message);
160 void checkForAsyncError(
void);
170 struct RemoteFEMacroInfo
174 std::vector<std::string> inputs, outputs;
178 std::string supervisor, feType;
179 std::map<std::string ,
MacroInfo> macros;
181 std::map<std::string ,
FEInfo> fes;
182 std::map<std::string ,
MacroInfo> publicMacros;
184 std::string getRemoteMacroMakerUDPAddress (
const std::string& targetSubsystem);
185 static std::string queryRemoteMacroMaker (
const std::string& ipPort,
const std::string& command,
unsigned int inactivityTimeoutSeconds,
const std::string& localIpAddress, std::function<
void(
int )> progressCb =
nullptr,
const std::atomic<bool>* abortFlag =
nullptr);
186 static RemoteFEMacroInfo parseFEMacroInfo (
const std::string& feMacroInfoXml);
188 unsigned int getNextRunNumber (
const std::string& fsmName =
"");
189 void setNextRunNumber (
unsigned int runNumber,
const std::string& fsmName =
"");
190 std::string getLastLogEntry (
const std::string& logType,
const std::string& fsmName =
"");
191 void setLastLogEntry (
const std::string& logType,
const std::string& logEntry,
const std::string& fsmName =
"");
192 void writeRunInfoTransition (RunInfoVInterface::RunTransitionType transitionType,
const std::string& comment);
195 static xoap::MessageReference lastTableGroupRequestHandler (
const SOAPParameters& parameters);
197 static void launchStartOTSCommand (
const std::string& command,
const std::vector<std::string>& hostnames);
198 std::vector<std::string> getLiveContextHostnames (
void)
const;
199 static void launchStartOneServerCommand (
const std::string& command,
ConfigurationManager* cfgMgr,
const std::string& contextName);
202 xoap::MessageReference TRACESupervisorRequest (xoap::MessageReference message);
205 static void AppStatusWorkLoop (
GatewaySupervisor* supervisorPtr,
const bool doDisconnected =
false);
208 std::ostringstream* out,
209 const std::string& command,
210 const std::string& fsmName,
211 const std::string& fsmWindowName,
212 const std::string& username,
213 const std::vector<std::string>& parameters,
214 std::string logEntry =
"");
215 void broadcastMessage (xoap::MessageReference msg);
216 void broadcastMessageToRemoteGateways (
const xoap::MessageReference msg,
unsigned int iteration = 0);
217 void broadcastMessageToRemoteGatewaysComplete (
const xoap::MessageReference msg,
unsigned int iterationIndex = 0);
218 void signalAndWaitForBroadcastThreads (
unsigned int numberOfThreads);
220 struct BroadcastMessageIterationsDoneStruct
226 ~BroadcastMessageIterationsDoneStruct()
228 for (
auto& arr : iterationsDone_)
230 iterationsDone_.clear();
234 void push(
const unsigned int& size)
236 iterationsDone_.push_back(
new bool[size]);
237 arraySizes_.push_back(size);
240 for (
unsigned int i = 0; i < size; ++i)
241 iterationsDone_[iterationsDone_.size() - 1][i] =
false;
244 bool* operator[](
unsigned int i) {
return iterationsDone_[i]; }
245 const bool* operator[](
unsigned int i)
const {
return iterationsDone_[i]; }
246 unsigned int size(
unsigned int i = -1)
248 if (i == (
unsigned int)-1)
249 return iterationsDone_.size();
250 return arraySizes_[i];
254 std::vector<bool*> iterationsDone_;
255 std::vector<unsigned int> arraySizes_;
258 struct BroadcastThreadStruct
261 BroadcastThreadStruct()
271 BroadcastThreadStruct(BroadcastThreadStruct &&b)
272 : threadIndex_(b.threadIndex_)
273 , exitThread_(b.exitThread_.load())
274 , working_(b.working_.load())
275 , workToDo_(b.workToDo_.load())
276 , error_(b.error_.load())
285 xoap::MessageReference message,
286 const std::string& command,
287 const unsigned int& iteration,
288 bool& iterationsDone,
289 std::shared_ptr<BroadcastMessageIterationsDoneStruct> iterationsDoneOwner)
293 , iteration_(iteration)
294 , iterationsDone_(iterationsDone)
295 , iterationsDoneOwner_(iterationsDoneOwner)
300 xoap::MessageReference message_;
301 const std::string command_;
302 const unsigned int iteration_;
303 bool& iterationsDone_;
307 std::shared_ptr<BroadcastMessageIterationsDoneStruct> iterationsDoneOwner_;
314 xoap::MessageReference message,
315 const std::string& command,
316 const unsigned int& iteration,
317 bool& iterationsDone,
318 std::shared_ptr<BroadcastMessageIterationsDoneStruct> iterationsDoneOwner)
322 appInfo, message, command, iteration, iterationsDone, iterationsDoneOwner));
326 const SupervisorInfo& getAppInfo() {
return messages_[0].appInfo_; }
327 xoap::MessageReference getMessage() {
return messages_[0].message_; }
328 const std::string& getCommand() {
return messages_[0].command_; }
329 const unsigned int& getIteration() {
return messages_[0].iteration_; }
330 std::string& getReply() {
return messages_[0].reply_; }
331 bool& getIterationsDone() {
return messages_[0].iterationsDone_; }
334 std::mutex threadMutex_;
335 unsigned int threadIndex_;
336 std::atomic<bool> exitThread_, working_, workToDo_, error_;
338 std::vector<BroadcastThreadStruct::BroadcastMessageStruct> messages_;
341 static void broadcastMessageThread(
343 std::shared_ptr<GatewaySupervisor::BroadcastThreadStruct> threadStruct);
344 bool handleBroadcastMessageTarget(
const SupervisorInfo& appInfo,
345 xoap::MessageReference message,
346 const std::string& command,
347 const unsigned int& iteration,
349 unsigned int threadIndex = 0,
350 const std::atomic<bool>* exitFlag =
nullptr);
355 bool supervisorGuiHasBeenLoaded_;
356 static WebUsers theWebUsers_;
357 std::map<std::string , std::map<std::string ,
361 WorkLoopManager stateMachineWorkLoopManager_;
362 toolbox::BSem stateMachineSemaphore_;
364 std::string activeStateMachineName_;
365 std::string activeStateMachineWindowName_;
366 std::string activeStateMachineDumpFormatOnRun_, activeStateMachineDumpFormatOnConfigure_;
367 std::string activeStateMachineSystemDumpOnRun_, activeStateMachineSystemDumpOnConfigure_;
368 std::unique_ptr<std::thread> configDumpCachingThread_;
369 std::string configDumpCachingError_;
370 bool activeStateMachineSystemDumpOnRunEnable_, activeStateMachineSystemDumpOnConfigureEnable_;
371 std::string activeStateMachineSystemDumpOnRunFilename_, activeStateMachineSystemDumpOnConfigureFilename_;
372 bool activeStateMachineRequireUserLogOnRun_, activeStateMachineRequireUserLogOnConfigure_;
373 std::string activeStateMachineRunInfoPluginType_;
374 std::map<std::string , std::string >
375 stateMachineConfigureLogEntry_, stateMachineStartLogEntry_, stateMachineStopLogEntry_;
376 std::string activeStateMachineRawStartComment_, activeStateMachineRawStopComment_;
377 std::string activeStateMachineRunNumber_, activeStateMachineRunAlias_, activeStateMachineConfigurationAlias_;
378 bool activeStateMachineRollOverLogOnConfigure_, activeStateMachineRollOverLogOnStart_;
379 std::chrono::steady_clock::time_point
380 activeStateMachineRunStartTime;
381 time_t activeStateMachineRunWallClockStartTime_ = 0;
382 int activeStateMachineRunDuration_ms;
383 bool activeStateMachineWriteToEcl_ =
true;
384 bool activeStateMachineDiscardRun_ =
false;
385 unsigned int activeStateMachineConfigureConditionID_, activeStateMachineRunConditionID_;
386 unsigned int minReadyForEventGenerationStartIteration_ = 0;
387 std::string activeStateMachineSubsystemCommonList_, activeStateMachineSubsystemCommonOverrideList_;
388 std::string activeSubsystemCommonContextList_, activeSubsystemCommonContextOverrideList_;
389 std::string appliedContextCommonList_, appliedContextCommonOverrideList_;
390 std::mutex contextCommonMutex_;
392 std::string cachedSubsystemCommonBackboneKey_;
393 std::string cachedSubsystemCommonList_, cachedSubsystemCommonOverrideList_;
394 std::string cachedSubsystemCommonContextList_, cachedSubsystemCommonContextOverrideList_;
396 std::mutex systemStatusMutex_;
397 std::string lastLogbookEntry_;
398 time_t lastLogbookEntryTime_ = 0;
400 std::string lastConsoleErr_, lastConsoleWarn_, lastConsoleInfo_, lastConsoleErrTime_, lastConsoleWarnTime_, lastConsoleInfoTime_;
401 std::string firstConsoleErr_, firstConsoleWarn_, firstConsoleInfo_, firstConsoleErrTime_, firstConsoleWarnTime_, firstConsoleInfoTime_;
402 size_t systemConsoleErrCount_ = 0, systemConsoleWarnCount_ = 0, systemConsoleInfoCount_ = 0;
404 std::pair<std::string , TableGroupKey>
405 theConfigurationTableGroup_;
406 std::string stateMachineTransitionUsername_;
408 Iterator theIterator_;
409 std::mutex stateMachineAccessMutex_;
411 std::string stateMachineLastCommandInput_;
417 CodeEditor codeEditor_;
419 std::mutex broadcastCommandMessageIndexMutex_;
420 unsigned int broadcastCommandMessageIndex_;
421 std::atomic<bool> broadcastSubsystemIterationsDone_{
true};
422 std::atomic<bool> broadcastIterationsDone_{
true};
423 std::mutex broadcastIterationBreakpointMutex_;
424 unsigned int broadcastIterationBreakpoint_;
426 std::mutex broadcastCommandStatusUpdateMutex_;
427 std::string broadcastCommandStatus_;
429 std::mutex remoteIterationMutex_;
430 std::condition_variable remoteIterationCV_;
431 unsigned int remoteIterationIndex_ = 0;
432 std::atomic<bool> isRemoteSubsystemIteration_{
false};
433 std::atomic<bool> remoteSubsystemErrorReceived_{
false};
435 static std::vector<std::shared_ptr<GatewaySupervisor::BroadcastThreadStruct>> broadcastThreadStructs_;
437 std::string securityType_;
441 unsigned int conditionID_;
458 time_t errorTimestamp = 0;
460 void setError(
const std::string& err) { error = err; errorTimestamp = time(0); }
461 void clearError() { error =
""; errorTimestamp = 0; }
462 void copyError(
const RemoteGatewayInfo& r) { error = r.error; errorTimestamp = r.errorTimestamp; }
463 const std::string& getError()
const {
return error; }
466 std::string config_dump;
473 size_t consoleErrCount = 0, consoleWarnCount = 0;
475 std::string fullName;
483 std::string usernameWithLock;
492 bool fsm_included =
true;
494 std::string getFsmMode()
const {
497 case FSM_ModeTypes::Follow_FSM:
return "Follow FSM";
500 default:
return "Impossible";
504 std::string getConfigDumpType()
const {
505 switch(config_dump_type)
507 case ConfigDumpTypes::Text:
return "Text";
508 case ConfigDumpTypes::JSON_all:
return "JSON all";
509 default:
return "Unknown";
513 std::map<std::string, SupervisorInfo::SubappInfo>
subapps;
517 std::string activeContextGroupName, activeConfigGroupName;
521 std::string selectedConfigGroupName;
523 bool doNotHaltWasCommandedHalt =
false;
526 std::vector<GatewaySupervisor::RemoteGatewayInfo> remoteGatewayApps_;
533 std::set<std::string> broadcastIncludedRemoteGatewayNames_;
534 bool isRemoteGatewayIncludedInBroadcast(
const RemoteGatewayInfo& remoteGatewayApp)
const;
535 std::map<std::string ,
536 bool > appLastStatusGood_;
537 std::mutex dualStatusThreadMutex_;
545 std::mutex latestGatewayIconsMutex_;
554 std::string cachedGlobalFieldsString_;
555 std::pair<std::string, TableGroupKey> cachedGlobalFieldsGroup_;
557 static void CheckRemoteGatewayStatus (
GatewaySupervisor::RemoteGatewayInfo& remoteGatewayApp,
const std::unique_ptr<TransceiverSocket>& remoteGatewaySocket,
const std::string& ipForReverseLoginOverUDP,
int portForReverseLoginOverUDP,
const std::string& contextCommonList =
"",
const std::string& contextCommonOverrideList =
"");
559 static void applyContextCommonTables (
GatewaySupervisor* supervisor,
const std::string& contextCommonList,
const std::string& contextCommonOverrideList);
561 void loadRemoteGatewaySettings (std::vector<GatewaySupervisor::RemoteGatewayInfo>& remoteGateways,
bool onlyNotFound =
false)
const;
562 void saveRemoteGatewaySettings (
void)
const;
563 static std::string translateURLForRequestOrigin (
const std::string& url,
const std::string& requestOrigin, std::map<std::string , std::map<std::string /* requestUrlHostPort */, std::string /* translatedHostPort */>>& portTranslationMap);
564 static std::string translateRemoteIconStringForRequestOrigin (
const std::string& iconString,
const std::string& requestOrigin, std::map<std::string , std::map<std::string /* requestUrlHostPort */, std::string /* translatedHostPort */>>& portTranslationMap);
friend class GatewaySupervisor
for access to indicateOtsAlive()
std::string latestGatewayRemoteIconsString_
cached string of remote gateway icons for quick access
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)
std::vector< DesktopIconTable::DesktopIcon > latestGatewayIcons_
used to track the latest desktop icons (which are defined by the active context but allowed to change...
void statePaused(toolbox::fsm::FiniteStateMachine &fsm) override
std::string ipAddressForStateChangesOverUDP_
IP used for UDP reverse-login propagation to remote gateways.
void joinConfigDumpCachingThread(void)
reap the deferred dump-caching thread; safe when none is running
void stateRunning(toolbox::fsm::FiniteStateMachine &fsm) override
int portForReverseLoginOverUDP_
UDP port for reverse-login; 0 = disabled.
std::map< unsigned int, SupervisorInfo > localAllSupervisorInfo_
only use in main thread, stable copy of app status
std::pair< std::string, TableGroupKey > latestGatewayIconsContextGroup_
used to track the table group key for the latest desktop icons
void stateConfigured(toolbox::fsm::FiniteStateMachine &fsm) override
std::mutex remoteGatewayAppsMutex_
void stateInitial(toolbox::fsm::FiniteStateMachine &fsm) override
std::pair< std::string, TableGroupKey > latestGatewayRemoteIconsContextGroup_
used to track the table group key for the latest remote desktop icons
defines used also by OtsConfigurationWizardSupervisor
ConfigDumpTypes
<FSM Modes: 'Follow FSM,' 'Do not Halt' (artdaq), or 'Only Configure' (DCS/DQM)
FSM_ModeTypes
<FSM Modes: 'Follow FSM,' 'Do not Halt' (artdaq), or 'Only Configure' (DCS/DQM)
@ OnlyConfigure
(e.g. for DCS/DQM)
@ DoNotHalt
(e.g. for artdaq)
TableGroupKey activeConfigGroupKey
selected_config_alias resolved to a group name+key by the remote subsystem itself (against its own ac...
std::string permissionThresholdString
used for desktop icons
time_t relaunchTime
timestamp of last relaunch via gatewayLaunchOTSInstance
std::set< std::string > config_aliases
used for remote gateway subapp control
std::string selected_config_alias
used for remote gateway subapp control
FSM_ModeTypes fsm_mode
used for remote gateway subapp control
std::string fsmName
when not "", need to send
bool iterationsDone
tracks per-gateway iteration completion during FSM transitions
std::map< std::string, SupervisorInfo::SubappInfo > subapps
remote gateways can have subapps
size_t ignoreStatusCount
if non-zero, do not ask for status
std::string instanceUser
used for remote ots instance ssh launch
time_t commandSentTime
timestamp of last command send; suppresses stale status write-backs briefly
std::string user_data_path_record
used for remote gateway subapp control
static std::string getTimestampString(const std::string &linuxTimeInSeconds)