otsdaq  3.04.02
GatewaySupervisor.h
1 #ifndef _ots_GatewaySupervisor_h
2 #define _ots_GatewaySupervisor_h
3 
4 #include "otsdaq/CoreSupervisors/ConfigurationSupervisorBase.h"
5 #include "otsdaq/CoreSupervisors/CorePropertySupervisorBase.h"
6 #include "otsdaq/FiniteStateMachine/RunControlStateMachine.h"
7 #include "otsdaq/GatewaySupervisor/Iterator.h"
8 #include "otsdaq/SOAPUtilities/SOAPMessenger.h"
9 #include "otsdaq/SupervisorInfo/AllSupervisorInfo.h"
10 #include "otsdaq/WebUsersUtilities/WebUsers.h"
11 #include "otsdaq/WorkLoopManager/WorkLoopManager.h"
12 
13 #include "otsdaq/CodeEditor/CodeEditor.h"
14 #include "otsdaq/TablePlugins/DesktopIconTable.h"
15 
16 #include "otsdaq/NetworkUtilities/TransceiverSocket.h" // for UDP state changer
17 
18 #pragma GCC diagnostic push
19 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
20 #include <xdaq/Application.h>
21 #pragma GCC diagnostic pop
22 #include "otsdaq/Macros/XDAQApplicationMacros.h"
23 
24 #include <toolbox/task/WorkLoop.h>
25 #include <xdata/String.h>
26 #include <xgi/Method.h>
27 #include "otsdaq/GatewaySupervisor/PixelHistoPicGen.h"
28 
29 #include <set>
30 #include <sstream>
31 #include <string>
32 
33 // clang-format off
34 
36 // #define FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE std::string("FSMLastConfiguredGroupAlias.hist")
37 // #define FSM_LAST_STARTED_GROUP_ALIAS_FILE std::string("FSMLastStartedGroupAlias.hist")
38 
39 // #define FSM_CONFIGURED_GROUP_ALIASES_FILE std::string("FSMConfiguredGroupAliases.hist")
40 // #define FSM_STARTED_GROUP_ALIASES_FILE std::string("FSMStartedGroupAlias.hist")
41 
42 // #define FSM_CONFIGURED_OR_STARTED_GROUP_ALIASES_FILE std::string("FSMConfiguredOrStartedGroupAlias.hist")
43 
44 // #define FSM_CONFIGURED_CONTEXTS_FILE std::string("FSMConfiguredContexts.hist")
45 // #define FSM_STARTED_CONTEXTS_FILE std::string("FSMStartedContexts.hist")
46 // #define FSM_CONFIGURED_OR_STARTED_CONTEXTS_FILE std::string("FSMConfiguredOrStartedContexts.hist")
47 
48 // #define FSM_CONFIGURED_BACKBONES_FILE std::string("FSMConfiguredBackbones.hist")
49 // #define FSM_STARTED_BACKBONES_FILE std::string("FSMStartedBackbones.hist")
50 // #define FSM_CONFIGURED_OR_STARTED_BACKBONES_FILE std::string("FSMConfiguredOrStartedBackbones.hist")
51 
52 // #define FSM_CONFIGURED_ITERATORS_FILE std::string("FSMConfiguredIterators.hist")
53 // #define FSM_STARTED_ITERATORS_FILE std::string("FSMStartedIterators.hist")
54 // #define FSM_CONFIGURED_OR_STARTED_ITERATORS_FILE std::string("FSMConfiguredOrStartedIterators.hist")
55 
56 
57 namespace ots
58 {
59 class ConfigurationManager;
60 class TableGroupKey;
61 class WorkLoopManager;
62 
63 
68  class GatewaySupervisor : public xdaq::Application,
69  public SOAPMessenger,
73  {
74  friend class WizardSupervisor;
75  friend class Iterator;
76 
77  public:
78  XDAQ_INSTANTIATOR();
79 
80  GatewaySupervisor (xdaq::ApplicationStub* s);
81  virtual ~GatewaySupervisor (void);
82 
83  void init (void);
84 
85  void Default (xgi::Input* in, xgi::Output* out);
86 
87  void loginRequest (xgi::Input* in, xgi::Output* out);
88  void request (xgi::Input* in, xgi::Output* out);
89  void tooltipRequest (xgi::Input* in, xgi::Output* out);
90  void XGI_Turtle (xgi::Input* in, xgi::Output* out);
91 
92  void addStateMachineStatusToXML (HttpXmlDocument& xmlOut, const std::string& fsmName, bool getRunNumber = true);
93  void addFilteredConfigAliasesToXML (HttpXmlDocument& xmlOut, const std::string& fsmName);
94  void addRequiredFsmLogInputToXML (HttpXmlDocument& xmlOut, const std::string& fsmName);
95 
96  // State Machine requests handlers
97  void stateMachineXgiHandler(xgi::Input* in, xgi::Output* out);
98  void stateMachineIterationBreakpoint(xgi::Input* in, xgi::Output* out);
99 
100  static std::string getIconHeaderString(void);
101  static bool handleAddDesktopIconRequest(const std::string& author, cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut, std::vector<DesktopIconTable::DesktopIcon>* newIcons = nullptr);
102  static void handleGetApplicationIdRequest(AllSupervisorInfo* applicationInfo, cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut, std::map<std::string /* requestOrigin */, std::map<std::string /* requestUrlHostPort */, std::string /* translatedHostPort */>>* portTranslationMap = nullptr);
103 
104  xoap::MessageReference stateMachineXoapHandler(xoap::MessageReference msg);
105 
106  bool stateMachineThread(toolbox::task::WorkLoop* workLoop);
107 
108  // Status requests handlers
109  void statusRequest(xgi::Input* in, xgi::Output* out);
110  void infoRequestResultHandler(xgi::Input* in, xgi::Output* out);
111  bool infoRequestThread(toolbox::task::WorkLoop* workLoop);
112 
113  // External GatewaySupervisor XOAP handlers
114  xoap::MessageReference supervisorCookieCheck(xoap::MessageReference msg);
115  xoap::MessageReference supervisorGetActiveUsers(xoap::MessageReference msg);
116  xoap::MessageReference supervisorSystemMessage(xoap::MessageReference msg);
117  xoap::MessageReference supervisorGetUserInfo(xoap::MessageReference msg);
118  xoap::MessageReference supervisorSystemLogbookEntry(xoap::MessageReference msg);
119  xoap::MessageReference supervisorLastTableGroupRequest(xoap::MessageReference msg);
120 
121  // Finite State Machine States
122  void stateInitial(toolbox::fsm::FiniteStateMachine& fsm) override;
123  void statePaused(toolbox::fsm::FiniteStateMachine& fsm) override;
124  void stateRunning(toolbox::fsm::FiniteStateMachine& fsm) override;
125  void stateHalted(toolbox::fsm::FiniteStateMachine& fsm) override;
126  void stateConfigured(toolbox::fsm::FiniteStateMachine& fsm) override;
127  void inError(toolbox::fsm::FiniteStateMachine& fsm) override;
128 
129  void transitionConfiguring(toolbox::Event::Reference e) override;
130  void transitionHalting(toolbox::Event::Reference e) override;
131  void transitionInitializing(toolbox::Event::Reference e) override;
132  void transitionPausing(toolbox::Event::Reference e) override;
133  void transitionResuming(toolbox::Event::Reference e) override;
134  void transitionStarting(toolbox::Event::Reference e) override;
135  void transitionStopping(toolbox::Event::Reference e) override;
136  void transitionShuttingDown(toolbox::Event::Reference e) override;
137  void transitionStartingUp(toolbox::Event::Reference e) override;
138  void enteringError(toolbox::Event::Reference e) override;
139 
140  void makeSystemLogEntry(const std::string& entryText, const std::string& subjectText = "");
141  static void addSystemMessage(std::string toUserCSV, std::string message);
142 
143  void checkForAsyncError(void);
144 
145  // CorePropertySupervisorBase override functions
146  virtual void setSupervisorPropertyDefaults (void) override;
147  virtual void forceSupervisorPropertyValues (void) override;
148 
149 
150  private:
151  unsigned int getNextRunNumber (const std::string& fsmName = "");
152  void setNextRunNumber (unsigned int runNumber, const std::string& fsmName = "");
153  std::string getLastLogEntry (const std::string& logType, const std::string& fsmName = "");
154  void setLastLogEntry (const std::string& logType, const std::string& logEntry, const std::string& fsmName = "");
155 
156 
157  static xoap::MessageReference lastTableGroupRequestHandler (const SOAPParameters& parameters);
158  static void launchStartOTSCommand (const std::string& command, ConfigurationManager* cfgMgr);
159  static void launchStartOneServerCommand (const std::string& command, ConfigurationManager* cfgMgr, const std::string& contextName);
160 
161  static void indicateOtsAlive (const CorePropertySupervisorBase* properties = 0);
162  xoap::MessageReference TRACESupervisorRequest (xoap::MessageReference message);
163 
164  static void StateChangerWorkLoop (GatewaySupervisor* supervisorPtr);
165  static void AppStatusWorkLoop (GatewaySupervisor* supervisorPtr, const bool doDisconnected = false);
166 
167  std::string attemptStateMachineTransition (HttpXmlDocument* xmldoc,
168  std::ostringstream* out,
169  const std::string& command,
170  const std::string& fsmName,
171  const std::string& fsmWindowName,
172  const std::string& username,
173  const std::vector<std::string>& parameters,
174  std::string logEntry = "");
175  void broadcastMessage (xoap::MessageReference msg);
176  void broadcastMessageToRemoteGateways (const xoap::MessageReference msg);
177  bool broadcastMessageToRemoteGatewaysComplete (const xoap::MessageReference msg);
178 
179  struct BroadcastMessageIterationsDoneStruct
180  {
181  // Creating std::vector<std::vector<bool>>
182  // because of problems with the standard library
183  // not allowing passing by reference of bool types.
184  // Broadcast thread implementation requires passing by reference.
185  ~BroadcastMessageIterationsDoneStruct()
186  {
187  for (auto& arr : iterationsDone_)
188  delete[] arr;
189  iterationsDone_.clear();
190  arraySizes_.clear();
191  } // end destructor
192 
193  void push(const unsigned int& size)
194  {
195  iterationsDone_.push_back(new bool[size]);
196  arraySizes_.push_back(size);
197 
198  // initialize to false
199  for (unsigned int i = 0; i < size; ++i)
200  iterationsDone_[iterationsDone_.size() - 1][i] = false;
201  } // end push()
202 
203  bool* operator[](unsigned int i) { return iterationsDone_[i]; }
204  const bool* operator[](unsigned int i) const { return iterationsDone_[i]; }
205  unsigned int size(unsigned int i = -1)
206  {
207  if (i == (unsigned int)-1)
208  return iterationsDone_.size();
209  return arraySizes_[i];
210  }
211 
212  private:
213  std::vector<bool*> iterationsDone_;
214  std::vector<unsigned int> arraySizes_;
215  }; // end BroadcastMessageIterationsDoneStruct definition
216 
217  struct BroadcastThreadStruct
218  {
219  //===================
220  BroadcastThreadStruct()
221  : threadIndex_(-1)
222  , exitThread_(false)
223  , working_(true)
224  , workToDo_(false)
225  , error_(false)
226  {
227  } // end BroadcastThreadStruct constructor()
228 
229  //===================
230  BroadcastThreadStruct(BroadcastThreadStruct &&b)
231  : threadIndex_(b.threadIndex_)
232  , exitThread_(b.exitThread_)
233  , working_(b.working_)
234  , workToDo_(b.workToDo_)
235  , error_(b.error_)
236  {
237  } // end BroadcastThreadStruct move constructor()
238 
239 
241  {
242  //===================
243  BroadcastMessageStruct(const SupervisorInfo& appInfo,
244  xoap::MessageReference message,
245  const std::string& command,
246  const unsigned int& iteration,
247  bool& iterationsDone)
248  : appInfo_(appInfo)
249  , message_(message)
250  , command_(command)
251  , iteration_(iteration)
252  , iterationsDone_(iterationsDone)
253  {
254  }
255 
256  const SupervisorInfo& appInfo_;
257  xoap::MessageReference message_;
258  const std::string command_;
259  const unsigned int iteration_;
260  bool& iterationsDone_;
261 
262  std::string reply_;
263  }; // end BroadcastMessageStruct definition
264 
265  //===================
266  void setMessage(const SupervisorInfo& appInfo,
267  xoap::MessageReference message,
268  const std::string& command,
269  const unsigned int& iteration,
270  bool& iterationsDone)
271  {
272  messages_.clear();
274  appInfo, message, command, iteration, iterationsDone));
275  workToDo_ = true;
276  } // end setMessage()
277 
278  const SupervisorInfo& getAppInfo() { return messages_[0].appInfo_; }
279  xoap::MessageReference getMessage() { return messages_[0].message_; }
280  const std::string& getCommand() { return messages_[0].command_; }
281  const unsigned int& getIteration() { return messages_[0].iteration_; }
282  std::string& getReply() { return messages_[0].reply_; }
283  bool& getIterationsDone() { return messages_[0].iterationsDone_; }
284 
285  // each thread accesses these members
286  std::mutex threadMutex_;
287  unsigned int threadIndex_;
288  volatile bool exitThread_, working_, workToDo_, error_;
289  // always just 1 message (for now)
290  std::vector<BroadcastThreadStruct::BroadcastMessageStruct> messages_;
291 
292  }; // end BroadcastThreadStruct declaration
293  static void broadcastMessageThread(
294  GatewaySupervisor* supervisorPtr,
295  std::shared_ptr<GatewaySupervisor::BroadcastThreadStruct> threadStruct);
296  bool handleBroadcastMessageTarget(const SupervisorInfo& appInfo,
297  xoap::MessageReference message,
298  const std::string& command,
299  const unsigned int& iteration,
300  std::string& reply,
301  unsigned int threadIndex = 0);
302 
303 
304  // Member Variables -----------------------
305 
306  bool supervisorGuiHasBeenLoaded_;
307  static WebUsers theWebUsers_;
308  std::map<std::string /* requestOrigin */, std::map<std::string /* requestUrlHostPort */,
309  std::string /* translatedHostPort */>>
310  portTranslationMap_;
311 
312  WorkLoopManager stateMachineWorkLoopManager_;
313  toolbox::BSem stateMachineSemaphore_;
314 
315  std::string activeStateMachineName_;
316  std::string activeStateMachineWindowName_;
317  std::string activeStateMachineDumpFormatOnRun_, activeStateMachineDumpFormatOnConfigure_;
318  std::string activeStateMachineConfigurationDumpOnRun_, activeStateMachineConfigurationDumpOnConfigure_;
319  bool activeStateMachineConfigurationDumpOnRunEnable_, activeStateMachineConfigurationDumpOnConfigureEnable_;
320  std::string activeStateMachineConfigurationDumpOnRunFilename_, activeStateMachineConfigurationDumpOnConfigureFilename_;
321  bool activeStateMachineRequireUserLogOnRun_, activeStateMachineRequireUserLogOnConfigure_;
322  std::string activeStateMachineRunInfoPluginType_;
323  std::map<std::string /* fsmName */, std::string /* logEntry */>
324  stateMachineConfigureLogEntry_, stateMachineStartLogEntry_, stateMachineStopLogEntry_;
325  std::string activeStateMachineRunNumber_, activeStateMachineRunAlias_, activeStateMachineConfigurationAlias_;
326  bool activeStateMachineRollOverLogOnConfigure_, activeStateMachineRollOverLogOnStart_;
327  std::chrono::steady_clock::time_point
328  activeStateMachineRunStartTime;
329  int activeStateMachineRunDuration_ms;
330  unsigned int activeStateMachineConfigureConditionID_, activeStateMachineRunConditionID_;
331 
332  std::mutex systemStatusMutex_;
333  std::string lastLogbookEntry_;
334  time_t lastLogbookEntryTime_ = 0;
335 
336  std::string lastConsoleErr_, lastConsoleWarn_, lastConsoleInfo_, lastConsoleErrTime_, lastConsoleWarnTime_, lastConsoleInfoTime_;
337  std::string firstConsoleErr_, firstConsoleWarn_, firstConsoleInfo_, firstConsoleErrTime_, firstConsoleWarnTime_, firstConsoleInfoTime_;
338  size_t systemConsoleErrCount_ = 0, systemConsoleWarnCount_ = 0, systemConsoleInfoCount_ = 0;
339 
340  std::pair<std::string /*group name*/, TableGroupKey>
341  theConfigurationTableGroup_;
342  std::string stateMachineTransitionUsername_;
343 
344  Iterator theIterator_;
345  std::mutex stateMachineAccessMutex_;
347  std::string stateMachineLastCommandInput_;
348  enum
349  {
350  VERBOSE_MUTEX = 0
351  };
352 
353  CodeEditor codeEditor_;
354 
355  std::mutex broadcastCommandMessageIndexMutex_, broadcastIterationsDoneMutex_;
356  unsigned int broadcastCommandMessageIndex_;
357  bool broadcastIterationsDone_;
358  std::mutex broadcastIterationBreakpointMutex_;
359  unsigned int broadcastIterationBreakpoint_;
361  std::mutex broadcastCommandStatusUpdateMutex_;
362  std::string broadcastCommandStatus_;
363  static std::vector<std::shared_ptr<GatewaySupervisor::BroadcastThreadStruct>> broadcastThreadStructs_;
364 
365  std::string securityType_;
366  PixelHistoPicGen picGen_;
367 
368  //Variable used by the RunInfo plugin
369  unsigned int conditionID_;
370 
371 public: //used by remote subsystem control and status
372 
375 
376  enum class ConfigDumpTypes
377  {
378  Text,
379  JSON_all,
380  Unknown
381  };
382 
383  std::string command, fsmName;
384  std::string error, config_dump;
385  ConfigDumpTypes config_dump_type = ConfigDumpTypes::Unknown;
386 
387  size_t ignoreStatusCount = 0;
388 
389  size_t consoleErrCount = 0, consoleWarnCount = 0;
390 
391  std::string fullName;
392  std::string user_data_path_record;
393  std::string setupType, instancePath, instanceHost, instanceUser;
394 
395  std::string selected_config_alias;
396  std::set<std::string> config_aliases;
397  std::string iconString, parentIconFolderPath, landingPage, permissionThresholdString;
398 
399  std::string usernameWithLock;
400 
401  enum class FSM_ModeTypes
402  {
403  Follow_FSM,
404  DoNotHalt,
405  OnlyConfigure,
406  };
407  FSM_ModeTypes fsm_mode = FSM_ModeTypes::Follow_FSM;
408  bool fsm_included = true;
409 
410  std::string getFsmMode() const {
411  switch(fsm_mode)
412  {
413  case FSM_ModeTypes::Follow_FSM: return "Follow FSM";
414  case FSM_ModeTypes::DoNotHalt: return "Do Not Halt";
415  case FSM_ModeTypes::OnlyConfigure: return "Only Configure";
416  default: return "Impossible";
417  }
418  } //end getFsmMode()
419 
420  std::string getConfigDumpType() const {
421  switch(config_dump_type)
422  {
423  case ConfigDumpTypes::Text: return "Text";
424  case ConfigDumpTypes::JSON_all: return "JSON all";
425  default: return "Unknown";
426  }
427  } //end getFsmMode()
428 
429  std::map<std::string, SupervisorInfo::SubappInfo> subapps;
430  }; //end GatewaySupervisor::RemoteGatewayInfo struct
431 
432  std::vector<GatewaySupervisor::RemoteGatewayInfo> remoteGatewayApps_;
433  std::mutex remoteGatewayAppsMutex_;
434  std::map<std::string /* appName */,
435  bool /* lastStatusGood */> appLastStatusGood_;
436  std::mutex dualStatusThreadMutex_;
437 
438  std::map<unsigned int /* lid */, SupervisorInfo> localAllSupervisorInfo_;
439 
440 
441  std::mutex latestGatewayIconsMutex_;
442  std::vector<DesktopIconTable::DesktopIcon> latestGatewayIcons_;
443  std::pair<std::string /* latestIconContext group */, TableGroupKey>
445 
447  std::pair<std::string /* latestIconContext group */, TableGroupKey>
449 
450  static void CheckRemoteGatewayStatus (GatewaySupervisor::RemoteGatewayInfo& remoteGatewayApp, const std::unique_ptr<TransceiverSocket>& remoteGatewaySocket, const std::string& ipForReverseLoginOverUDP, int portForReverseLoginOverUDP);
451  static void SendRemoteGatewayCommand (GatewaySupervisor::RemoteGatewayInfo& remoteGatewayApp, const std::unique_ptr<TransceiverSocket>& remoteGatewaySocket);
452  static void GetRemoteGatewayIcons (GatewaySupervisor::RemoteGatewayInfo& remoteGatewayApp, const std::unique_ptr<TransceiverSocket>& remoteGatewaySocket);
453  void loadRemoteGatewaySettings (std::vector<GatewaySupervisor::RemoteGatewayInfo>& remoteGateways, bool onlyNotFound = false) const;
454  void saveRemoteGatewaySettings (void) const;
455  static std::string translateURLForRequestOrigin (const std::string& url, const std::string& requestOrigin, std::map<std::string /* requestOrigin */, std::map<std::string /* requestUrlHostPort */, std::string /* translatedHostPort */>>& portTranslationMap);
456  static std::string translateRemoteIconStringForRequestOrigin (const std::string& iconString, const std::string& requestOrigin, std::map<std::string /* requestOrigin */, std::map<std::string /* requestUrlHostPort */, std::string /* translatedHostPort */>>& portTranslationMap);
457 
458  };
459 // clang-format on
460 
461 } // namespace ots
462 
463 #endif
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
void stateRunning(toolbox::fsm::FiniteStateMachine &fsm) override
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
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)
std::string permissionThresholdString
used for desktop icons
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
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
std::string user_data_path_record
used for remote gateway subapp control