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