otsdaq  v2_05_02_indev
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/SystemMessenger/SystemMessenger.h"
11 //#include "otsdaq/TableCore/TableGroupKey.h"
12 #include "otsdaq/WebUsersUtilities/WebUsers.h"
13 #include "otsdaq/WorkLoopManager/WorkLoopManager.h"
14 
15 #include "otsdaq/CodeEditor/CodeEditor.h"
16 #include "otsdaq/TablePlugins/DesktopIconTable.h"
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 //#include <toolbox/fsm/FiniteStateMachine.h>
24 #include <toolbox/task/WorkLoop.h>
25 #include <xdata/String.h>
26 #include <xgi/Method.h>
27 
28 #include <set>
29 #include <sstream>
30 #include <string>
31 
32 // defines used also by OtsConfigurationWizardSupervisor
33 #define FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE std::string("FSMLastConfiguredGroupAlias.hist")
34 #define FSM_LAST_STARTED_GROUP_ALIAS_FILE std::string("FSMLastStartedGroupAlias.hist")
35 
36 namespace ots
37 {
38  class ConfigurationManager;
39  class TableGroupKey;
40  class WorkLoopManager;
41 
42  // clang-format off
43 
44  // GatewaySupervisor
45  // This class is the gateway server for all otsdaq requests in "Normal Mode." It
46  // validates user access for every request. It synchronizes the state machines of all
47  // other supervisors.
48  class GatewaySupervisor : public xdaq::Application,
49  public SOAPMessenger,
53  {
54  friend class WizardSupervisor;
55  friend class Iterator;
56 
57  public:
58  XDAQ_INSTANTIATOR();
59 
60  GatewaySupervisor(xdaq::ApplicationStub* s);
61  virtual ~GatewaySupervisor(void);
62 
63  void init(void);
64 
65  void Default(xgi::Input* in, xgi::Output* out);
66 
67  void loginRequest(xgi::Input* in, xgi::Output* out);
68  void request(xgi::Input* in, xgi::Output* out);
69  void tooltipRequest(xgi::Input* in, xgi::Output* out);
70 
71  // State Machine requests handlers
72  void stateMachineXgiHandler(xgi::Input* in, xgi::Output* out);
73  void stateMachineIterationBreakpoint(xgi::Input* in, xgi::Output* out);
74 
75  static std::string getIconHeaderString(void);
76  static bool handleAddDesktopIconRequest(const std::string& author, cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut, std::vector<DesktopIconTable::DesktopIcon>* newIcons = nullptr);
77  static void handleGetApplicationIdRequest(AllSupervisorInfo* applicationInfo, cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut);
78 
79  xoap::MessageReference stateMachineXoapHandler(xoap::MessageReference msg);
80 
81  bool stateMachineThread(toolbox::task::WorkLoop* workLoop);
82 
83  // Status requests handlers
84  void statusRequest(xgi::Input* in, xgi::Output* out);
85  void infoRequestResultHandler(xgi::Input* in, xgi::Output* out);
86  bool infoRequestThread(toolbox::task::WorkLoop* workLoop);
87 
88  // External GatewaySupervisor XOAP handlers
89  xoap::MessageReference supervisorCookieCheck(xoap::MessageReference msg);
90  xoap::MessageReference supervisorGetActiveUsers(xoap::MessageReference msg);
91  xoap::MessageReference supervisorSystemMessage(xoap::MessageReference msg);
92  xoap::MessageReference supervisorGetUserInfo(xoap::MessageReference msg);
93  xoap::MessageReference supervisorSystemLogbookEntry(xoap::MessageReference msg);
94  xoap::MessageReference supervisorLastTableGroupRequest(xoap::MessageReference msg);
95 
96  // Finite State Machine States
97  void stateInitial(toolbox::fsm::FiniteStateMachine& fsm) override;
98  void statePaused(toolbox::fsm::FiniteStateMachine& fsm) override;
99  void stateRunning(toolbox::fsm::FiniteStateMachine& fsm) override;
100  void stateHalted(toolbox::fsm::FiniteStateMachine& fsm) override;
101  void stateConfigured(toolbox::fsm::FiniteStateMachine& fsm) override;
102  void inError(toolbox::fsm::FiniteStateMachine& fsm) override;
103 
104  void transitionConfiguring(toolbox::Event::Reference e) override;
105  void transitionHalting(toolbox::Event::Reference e) override;
106  void transitionInitializing(toolbox::Event::Reference e) override;
107  void transitionPausing(toolbox::Event::Reference e) override;
108  void transitionResuming(toolbox::Event::Reference e) override;
109  void transitionStarting(toolbox::Event::Reference e) override;
110  void transitionStopping(toolbox::Event::Reference e) override;
111  void transitionShuttingDown(toolbox::Event::Reference e) override;
112  void transitionStartingUp(toolbox::Event::Reference e) override;
113  void enteringError(toolbox::Event::Reference e) override;
114 
115  void makeSystemLogbookEntry(std::string entryText);
116 
117  void checkForAsyncError(void);
118 
119  // CorePropertySupervisorBase override functions
120  virtual void setSupervisorPropertyDefaults(void) override; // override to control supervisor specific defaults
121  virtual void forceSupervisorPropertyValues(void) override; // override to force
122  // supervisor property
123  // values (and ignore user
124  // settings)
125 
126  private:
127  unsigned int getNextRunNumber(const std::string& fsmName = "");
128  bool setNextRunNumber(unsigned int runNumber, const std::string& fsmName = "");
129 
130  static xoap::MessageReference lastTableGroupRequestHandler(const SOAPParameters& parameters);
131  static void launchStartOTSCommand(const std::string& command, ConfigurationManager* cfgMgr);
132  static void indicateOtsAlive(const CorePropertySupervisorBase* properties = 0);
133 
134  static void StateChangerWorkLoop(GatewaySupervisor* supervisorPtr);
135  static void AppStatusWorkLoop(GatewaySupervisor* supervisorPtr);
136 
137  std::string attemptStateMachineTransition(HttpXmlDocument* xmldoc,
138  std::ostringstream* out,
139  const std::string& command,
140  const std::string& fsmName,
141  const std::string& fsmWindowName,
142  const std::string& username,
143  const std::vector<std::string>& parameters);
144  void broadcastMessage(xoap::MessageReference msg);
145 
146  struct BroadcastMessageIterationsDoneStruct
147  {
148  // Creating std::vector<std::vector<bool>>
149  // because of problems with the standard library
150  // not allowing passing by reference of bool types.
151  // Broadcast thread implementation requires passing by reference.
152  ~BroadcastMessageIterationsDoneStruct()
153  {
154  for (auto& arr : iterationsDone_)
155  delete[] arr;
156  iterationsDone_.clear();
157  arraySizes_.clear();
158  } // end destructor
159 
160  void push(const unsigned int& size)
161  {
162  iterationsDone_.push_back(new bool[size]);
163  arraySizes_.push_back(size);
164 
165  // initialize to false
166  for (unsigned int i = 0; i < size; ++i)
167  iterationsDone_[iterationsDone_.size() - 1][i] = false;
168  } // end push()
169 
170  bool* operator[](unsigned int i) { return iterationsDone_[i]; }
171  const bool* operator[](unsigned int i) const { return iterationsDone_[i]; }
172  unsigned int size(unsigned int i = -1)
173  {
174  if (i == (unsigned int)-1)
175  return iterationsDone_.size();
176  return arraySizes_[i];
177  }
178 
179  private:
180  std::vector<bool*> iterationsDone_;
181  std::vector<unsigned int> arraySizes_;
182  }; // end BroadcastMessageIterationsDoneStruct definition
183 
184  struct BroadcastThreadStruct
185  {
186  //===================
187  BroadcastThreadStruct()
188  : threadIndex_(-1)
189  , exitThread_(false)
190  , working_(true)
191  , workToDo_(false)
192  , error_(false)
193  {
194  } // end BroadcastThreadStruct constructor()
195 
197  {
198  //===================
199  BroadcastMessageStruct(const SupervisorInfo& appInfo,
200  xoap::MessageReference message,
201  const std::string& command,
202  const unsigned int& iteration,
203  bool& iterationsDone)
204  : appInfo_(appInfo)
205  , message_(message)
206  , command_(command)
207  , iteration_(iteration)
208  , iterationsDone_(iterationsDone)
209  {
210  }
211 
212  const SupervisorInfo& appInfo_;
213  xoap::MessageReference message_;
214  const std::string& command_;
215  const unsigned int& iteration_;
216  bool& iterationsDone_;
217 
218  std::string reply_;
219  }; // end BroadcastMessageStruct definition
220 
221  //===================
222  void setMessage(const SupervisorInfo& appInfo,
223  xoap::MessageReference message,
224  const std::string& command,
225  const unsigned int& iteration,
226  bool& iterationsDone)
227  {
228  messages_.clear();
230  appInfo, message, command, iteration, iterationsDone));
231  workToDo_ = true;
232  } // end setMessage()
233 
234  const SupervisorInfo& getAppInfo() { return messages_[0].appInfo_; }
235  xoap::MessageReference getMessage() { return messages_[0].message_; }
236  const std::string& getCommand() { return messages_[0].command_; }
237  const unsigned int& getIteration() { return messages_[0].iteration_; }
238  std::string& getReply() { return messages_[0].reply_; }
239  bool& getIterationsDone() { return messages_[0].iterationsDone_; }
240 
241  // each thread accesses these members
242  std::mutex threadMutex;
243  unsigned int threadIndex_;
244  volatile bool exitThread_, working_, workToDo_, error_;
245  // always just 1 message (for now)
246  std::vector<BroadcastThreadStruct::BroadcastMessageStruct> messages_;
247 
248  }; // end BroadcastThreadStruct declaration
249  static void broadcastMessageThread(
250  GatewaySupervisor* supervisorPtr,
251  GatewaySupervisor::BroadcastThreadStruct* threadStruct);
252  bool handleBroadcastMessageTarget(const SupervisorInfo& appInfo,
253  xoap::MessageReference message,
254  const std::string& command,
255  const unsigned int& iteration,
256  std::string& reply,
257  unsigned int threadIndex = 0);
258 
259  bool supervisorGuiHasBeenLoaded_; // use to indicate first access by user of ots
260  // since execution
261 
262  // Member Variables
263 
264  static WebUsers theWebUsers_;
265 
266  WorkLoopManager stateMachineWorkLoopManager_;
267  toolbox::BSem stateMachineSemaphore_;
268 
269  std::string activeStateMachineName_; // when multiple state machines, this is the
270  // name of the state machine which executed the
271  // configure transition
272  std::string activeStateMachineWindowName_;
273  std::pair<std::string /*group name*/, TableGroupKey>
274  theConfigurationTableGroup_; // used to track the active configuration group at
275  // states after the configure state
276 
277  Iterator theIterator_;
278  std::mutex stateMachineAccessMutex_; // for sharing state machine access with
279  // iterator thread
280  std::string stateMachineLastCommandInput_;
281 
282  enum
283  {
284  VERBOSE_MUTEX = 0
285  };
286 
287  CodeEditor codeEditor_;
288 
289  std::mutex broadcastCommandMessageIndexMutex_, broadcastIterationsDoneMutex_;
290  unsigned int broadcastCommandMessageIndex_;
291  bool broadcastIterationsDone_;
292  std::mutex broadcastIterationBreakpointMutex_;
293  unsigned int broadcastIterationBreakpoint_; // pause transition when iteration index
294  // matches breakpoint index
295 
296  // temporary member variable to avoid redeclaration in repetitive functions
297  char tmpStringForConversions_[100];
298 
299  std::string securityType_;
300  };
301  // clang-format on
302 
303 } // namespace ots
304 
305 #endif