otsdaq  v2_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/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 
17 #pragma GCC diagnostic push
18 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
19 #include <xdaq/Application.h>
20 #pragma GCC diagnostic pop
21 #include "otsdaq/Macros/XDAQApplicationMacros.h"
22 //#include <toolbox/fsm/FiniteStateMachine.h>
23 #include <toolbox/task/WorkLoop.h>
24 #include <xdata/String.h>
25 #include <xgi/Method.h>
26 
27 #include <set>
28 #include <sstream>
29 #include <string>
30 
31 // defines used also by OtsConfigurationWizardSupervisor
32 #define FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE \
33  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 void handleAddDesktopIconRequest (const std::string& author, cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut);
76 
77  xoap::MessageReference stateMachineXoapHandler(xoap::MessageReference msg);
78  xoap::MessageReference stateMachineResultXoapHandler(xoap::MessageReference msg);
79 
80  bool stateMachineThread(toolbox::task::WorkLoop* workLoop);
81 
82  // Status requests handlers
83  void statusRequest(xgi::Input* in, xgi::Output* out);
84  void infoRequestResultHandler(xgi::Input* in, xgi::Output* out);
85  bool infoRequestThread(toolbox::task::WorkLoop* workLoop);
86 
87  // External GatewaySupervisor XOAP handlers
88  xoap::MessageReference supervisorCookieCheck(xoap::MessageReference msg);
89  xoap::MessageReference supervisorGetActiveUsers(xoap::MessageReference msg);
90  xoap::MessageReference supervisorSystemMessage(xoap::MessageReference msg);
91  xoap::MessageReference supervisorGetUserInfo(xoap::MessageReference msg);
92  xoap::MessageReference supervisorSystemLogbookEntry(xoap::MessageReference msg);
93  xoap::MessageReference supervisorLastConfigGroupRequest(xoap::MessageReference msg);
94 
95  // Finite State Machine States
96  void stateInitial(toolbox::fsm::FiniteStateMachine& fsm);
97  void statePaused(toolbox::fsm::FiniteStateMachine& fsm);
98  void stateRunning(toolbox::fsm::FiniteStateMachine& fsm);
99  void stateHalted(toolbox::fsm::FiniteStateMachine& fsm);
100  void stateConfigured(toolbox::fsm::FiniteStateMachine& fsm);
101  void inError(toolbox::fsm::FiniteStateMachine& fsm);
102 
103  void transitionConfiguring(toolbox::Event::Reference e);
104  void transitionHalting(toolbox::Event::Reference e);
105  void transitionInitializing(toolbox::Event::Reference e);
106  void transitionPausing(toolbox::Event::Reference e);
107  void transitionResuming(toolbox::Event::Reference e);
108  void transitionStarting(toolbox::Event::Reference e);
109  void transitionStopping(toolbox::Event::Reference e);
110  void transitionShuttingDown(toolbox::Event::Reference e);
111  void transitionStartingUp(toolbox::Event::Reference e);
112  void enteringError(toolbox::Event::Reference e);
113 
114  void makeSystemLogbookEntry(std::string entryText);
115 
116  void checkForAsyncError(void);
117 
118  // CorePropertySupervisorBase override functions
119  virtual void setSupervisorPropertyDefaults(
120  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  static std::pair<std::string /*group name*/, TableGroupKey> loadGroupNameAndKey(
130  const std::string& fileName, std::string& returnedTimeString);
131  void saveGroupNameAndKey(
132  const std::pair<std::string /*group name*/, TableGroupKey>& theGroup,
133  const std::string& fileName);
134  static xoap::MessageReference lastConfigGroupRequestHandler(
135  const SOAPParameters& parameters);
136  static void launchStartOTSCommand(const std::string& command,
137  ConfigurationManager* cfgMgr);
138  static void indicateOtsAlive(const CorePropertySupervisorBase* properties = 0);
139 
140  static void StateChangerWorkLoop(GatewaySupervisor* supervisorPtr);
141  static void AppStatusWorkLoop(GatewaySupervisor* supervisorPtr);
142 
143  std::string attemptStateMachineTransition(HttpXmlDocument* xmldoc,
144  std::ostringstream* out,
145  const std::string& command,
146  const std::string& fsmName,
147  const std::string& fsmWindowName,
148  const std::string& username,
149  const std::vector<std::string>& parameters);
150  void broadcastMessage(xoap::MessageReference msg);
151 
152  struct BroadcastMessageIterationsDoneStruct
153  {
154  // Creating std::vector<std::vector<bool>>
155  // because of problems with the standard library
156  // not allowing passing by reference of bool types.
157  // Broadcast thread implementation requires passing by reference.
158  ~BroadcastMessageIterationsDoneStruct()
159  {
160  for(auto& arr : iterationsDone_)
161  delete[] arr;
162  iterationsDone_.clear();
163  arraySizes_.clear();
164  } // end destructor
165 
166  void push(const unsigned int& size)
167  {
168  iterationsDone_.push_back(new bool[size]);
169  arraySizes_.push_back(size);
170 
171  // initialize to false
172  for(unsigned int i = 0; i < size; ++i)
173  iterationsDone_[iterationsDone_.size() - 1][i] = false;
174  } // end push()
175 
176  bool* operator[](unsigned int i) { return iterationsDone_[i]; }
177  const bool* operator[](unsigned int i) const { return iterationsDone_[i]; }
178  unsigned int size(unsigned int i = -1)
179  {
180  if(i == (unsigned int)-1)
181  return iterationsDone_.size();
182  return arraySizes_[i];
183  }
184 
185  private:
186  std::vector<bool*> iterationsDone_;
187  std::vector<unsigned int> arraySizes_;
188  }; // end BroadcastMessageIterationsDoneStruct definition
189 
190  struct BroadcastThreadStruct
191  {
192  //===================
193  BroadcastThreadStruct()
194  : threadIndex_(-1)
195  , exitThread_(false)
196  , working_(true)
197  , workToDo_(false)
198  , error_(false)
199  {
200  } // end BroadcastThreadStruct constructor()
201 
203  {
204  //===================
205  BroadcastMessageStruct(const SupervisorInfo& appInfo,
206  xoap::MessageReference message,
207  const std::string& command,
208  const unsigned int& iteration,
209  bool& iterationsDone)
210  : appInfo_(appInfo)
211  , message_(message)
212  , command_(command)
213  , iteration_(iteration)
214  , iterationsDone_(iterationsDone)
215  {
216  }
217 
218  const SupervisorInfo& appInfo_;
219  xoap::MessageReference message_;
220  const std::string& command_;
221  const unsigned int& iteration_;
222  bool& iterationsDone_;
223 
224  std::string reply_;
225  }; // end BroadcastMessageStruct definition
226 
227  //===================
228  void setMessage(const SupervisorInfo& appInfo,
229  xoap::MessageReference message,
230  const std::string& command,
231  const unsigned int& iteration,
232  bool& iterationsDone)
233  {
234  messages_.clear();
236  appInfo, message, command, iteration, iterationsDone));
237  workToDo_ = true;
238  } // end setMessage()
239 
240  const SupervisorInfo& getAppInfo() { return messages_[0].appInfo_; }
241  xoap::MessageReference getMessage() { return messages_[0].message_; }
242  const std::string& getCommand() { return messages_[0].command_; }
243  const unsigned int& getIteration() { return messages_[0].iteration_; }
244  std::string& getReply() { return messages_[0].reply_; }
245  bool& getIterationsDone() { return messages_[0].iterationsDone_; }
246 
247  // each thread accesses these members
248  std::mutex threadMutex;
249  unsigned int threadIndex_;
250  volatile bool exitThread_, working_, workToDo_, error_;
251  // always just 1 message (for now)
252  std::vector<BroadcastThreadStruct::BroadcastMessageStruct> messages_;
253 
254  }; // end BroadcastThreadStruct declaration
255  static void broadcastMessageThread(
256  GatewaySupervisor* supervisorPtr,
257  GatewaySupervisor::BroadcastThreadStruct* threadStruct);
258  bool handleBroadcastMessageTarget(const SupervisorInfo& appInfo,
259  xoap::MessageReference message,
260  const std::string& command,
261  const unsigned int& iteration,
262  std::string& reply,
263  unsigned int threadIndex = 0);
264 
265  bool supervisorGuiHasBeenLoaded_; // use to indicate first access by user of ots
266  // since execution
267 
268  // Member Variables
269 
270  WebUsers theWebUsers_;
271  SystemMessenger theSystemMessenger_;
272 
273  WorkLoopManager stateMachineWorkLoopManager_;
274  toolbox::BSem stateMachineSemaphore_;
275  WorkLoopManager infoRequestWorkLoopManager_;
276  toolbox::BSem infoRequestSemaphore_;
277 
278  std::string activeStateMachineName_; // when multiple state machines, this is the
279  // name of the state machine which executed the
280  // configure transition
281  std::string activeStateMachineWindowName_;
282  std::pair<std::string /*group name*/, TableGroupKey>
283  theConfigurationTableGroup_; // used to track the active configuration group at
284  // states after the configure state
285 
286  Iterator theIterator_;
287  std::mutex stateMachineAccessMutex_; // for sharing state machine access with
288  // iterator thread
289  std::string stateMachineLastCommandInput_;
290 
291  enum
292  {
293  VERBOSE_MUTEX = 0
294  };
295 
296  CodeEditor codeEditor_;
297 
298  std::mutex broadcastCommandMessageIndexMutex_, broadcastIterationsDoneMutex_;
299  unsigned int broadcastCommandMessageIndex_;
300  bool broadcastIterationsDone_;
301  std::mutex broadcastIterationBreakpointMutex_;
302  unsigned int broadcastIterationBreakpoint_; // pause transition when iteration index
303  // matches breakpoint index
304 
305  // temporary member variable to avoid redeclaration in repetitive functions
306  char tmpStringForConversions_[100];
307 
308  // Trash tests
309  void wait(int milliseconds, std::string who = "") const;
310  unsigned long long counterTest_;
311  std::vector<int> vectorTest_;
312  std::string securityType_;
313 };
314 // clang-format on
315 
316 } // namespace ots
317 
318 #endif