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