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