otsdaq  v2_04_00
AllSupervisorInfo.cc
1 #include "otsdaq-core/SupervisorInfo/AllSupervisorInfo.h"
2 
3 #include "otsdaq-core/Macros/CoutMacros.h"
4 #include "otsdaq-core/MessageFacility/MessageFacility.h"
5 
6 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
7 #include "otsdaq-core/TablePluginDataFormats/XDAQContextTable.h"
8 
9 #include <iostream>
10 
11 using namespace ots;
12 
13 const bool AllSupervisorInfo::MACROMAKER_MODE =
14  (std::string(__ENV__("MACROMAKER_MODE")) == "1") ? true : false;
15 
16 //========================================================================================================================
17 AllSupervisorInfo::AllSupervisorInfo(void) : theSupervisorInfo_(0), theWizardInfo_(0) {}
18 
19 //========================================================================================================================
20 AllSupervisorInfo::AllSupervisorInfo(xdaq::ApplicationContext* applicationContext)
22 {
23  init(applicationContext);
24 }
25 
26 //========================================================================================================================
27 AllSupervisorInfo::~AllSupervisorInfo(void) { destroy(); }
28 
29 //========================================================================================================================
30 void AllSupervisorInfo::destroy(void)
31 {
32  allSupervisorInfo_.clear();
33  allFETypeSupervisorInfo_.clear();
34  allDMTypeSupervisorInfo_.clear();
35 
36  theSupervisorInfo_ = 0;
37  theWizardInfo_ = 0;
38 
39  SupervisorDescriptorInfoBase::destroy();
40 }
41 
42 //========================================================================================================================
43 void AllSupervisorInfo::init(xdaq::ApplicationContext* applicationContext)
44 {
45  __COUT__ << "Initializing info based on XDAQ context..." << __E__;
46 
47  AllSupervisorInfo::destroy();
48  SupervisorDescriptorInfoBase::init(applicationContext);
49 
50  auto allDescriptors = SupervisorDescriptorInfoBase::getAllDescriptors();
51  // ready.. loop through all descriptors, and organize
52 
53  // for(const auto& descriptor:allDescriptors)
54  // {
55  // SupervisorInfo tempSupervisorInfo(
56  // descriptor.second /* descriptor */,
57  // "" /* config app name */,"" /* config parent context name */
59  // );
60  //
61  // __COUT__ << "id " << descriptor.second->getLocalId() << " url " <<
62  // descriptor.second->getContextDescriptor()->getURL() << __E__;
63  //
64  // }
65  // __COUTV__(XDAQContextTable::GATEWAY_SUPERVISOR_CLASS);
66 
67  // Steps:
68  // 1. first pass, identify Wiz mode or not
69  // 2. second pass, organize supervisors
70 
71  bool isWizardMode = false;
72 
73  // first pass, identify Wiz mode or not
74  // accept first encountered (wizard or gateway) as the mode
75  for(const auto& descriptor : allDescriptors)
76  {
77  SupervisorInfo tempSupervisorInfo(
78  descriptor.second /* descriptor */,
79  "" /* config app name */,
80  "" /* config parent context name */ // skip configuration info
81  );
82 
83  // check for gateway supervisor
84  if(tempSupervisorInfo.isGatewaySupervisor())
85  {
86  // found normal mode, done with first pass
87  isWizardMode = false;
88  break;
89  }
90  else if(tempSupervisorInfo.isWizardSupervisor())
91  {
92  // found wiz mode, done with first pass
93  isWizardMode = true;
94  break;
95  }
96  }
97 
98  if(AllSupervisorInfo::MACROMAKER_MODE)
99  __COUT__ << "Initializing info for Macro Maker mode XDAQ context..." << __E__;
100  else if(isWizardMode)
101  __COUT__ << "Initializing info for Wiz mode XDAQ context..." << __E__;
102  else
103  __COUT__ << "Initializing info for Normal mode XDAQ context..." << __E__;
104  std::unique_ptr<ConfigurationManager> cfgMgr(
105  (isWizardMode || AllSupervisorInfo::MACROMAKER_MODE)
106  ? 0
107  : new ConfigurationManager());
108  const XDAQContextTable* contextConfig =
109  (isWizardMode || AllSupervisorInfo::MACROMAKER_MODE)
110  ? 0
111  : cfgMgr->__GET_CONFIG__(XDAQContextTable);
112 
113  // do not involve the Configuration Manager
114  // as it adds no valid information to the supervisors
115  // present in wiz mode
116  for(const auto& descriptor : allDescriptors)
117  {
118  auto /*<iterator,bool>*/ emplacePair =
119  allSupervisorInfo_.emplace(std::pair<unsigned int, SupervisorInfo>(
120  descriptor.second->getLocalId(), // descriptor.first,
122  descriptor.second /* descriptor */,
123  contextConfig
124  ? contextConfig->getApplicationUID(
125  descriptor.second->getContextDescriptor()->getURL(),
126  descriptor.second->getLocalId())
127  : "" /* config app name */,
128  contextConfig
129  ? contextConfig->getContextUID(
130  descriptor.second->getContextDescriptor()->getURL())
131  : "" /* config parent context name */
132  )));
133  if(!emplacePair.second)
134  {
135  __SS__ << "Error! Duplicate Application IDs are not allowed. ID ="
136  << descriptor.second->getLocalId() << __E__;
137  __SS_THROW__;
138  }
139 
141  // now organize new descriptor by class...
142 
143  // check for gateway supervisor
144  // note: necessarily exclusive to other Supervisor types
145  if(emplacePair.first->second.isGatewaySupervisor())
146  {
147  if(theSupervisorInfo_)
148  {
149  __SS__ << "Error! Multiple Gateway Supervisors of class "
150  << XDAQContextTable::GATEWAY_SUPERVISOR_CLASS
151  << " found. There can only be one. ID ="
152  << descriptor.second->getLocalId() << __E__;
153  __SS_THROW__;
154  }
155  // copy and erase from map
156  theSupervisorInfo_ = &(emplacePair.first->second);
157  continue;
158  }
159 
160  // check for wizard supervisor
161  // note: necessarily exclusive to other Supervisor types
162  if(emplacePair.first->second.isWizardSupervisor())
163  {
164  if(theWizardInfo_)
165  {
166  __SS__ << "Error! Multiple Wizard Supervisors of class "
167  << XDAQContextTable::WIZARD_SUPERVISOR_CLASS
168  << " found. There can only be one. ID ="
169  << descriptor.second->getLocalId() << __E__;
170  __SS_THROW__;
171  }
172  // copy and erase from map
173  theWizardInfo_ = &(emplacePair.first->second);
174  continue;
175  }
176 
177  // check for FE type, then add to FE group
178  // note: not necessarily exclusive to other Supervisor types
179  if(emplacePair.first->second.isTypeFESupervisor())
180  {
181  allFETypeSupervisorInfo_.emplace(
182  std::pair<unsigned int, const SupervisorInfo&>(
183  emplacePair.first->second.getId(), emplacePair.first->second));
184  }
185 
186  // check for DM type, then add to DM group
187  // note: not necessarily exclusive to other Supervisor types
188  if(emplacePair.first->second.isTypeDMSupervisor())
189  {
190  allDMTypeSupervisorInfo_.emplace(
191  std::pair<unsigned int, const SupervisorInfo&>(
192  emplacePair.first->second.getId(), emplacePair.first->second));
193  }
194 
195  // check for Logbook type, then add to Logbook group
196  // note: not necessarily exclusive to other Supervisor types
197  if(emplacePair.first->second.isTypeLogbookSupervisor())
198  {
199  allLogbookTypeSupervisorInfo_.emplace(
200  std::pair<unsigned int, const SupervisorInfo&>(
201  emplacePair.first->second.getId(), emplacePair.first->second));
202  }
203 
204  // check for MacroMaker type, then add to MacroMaker group
205  // note: not necessarily exclusive to other Supervisor types
206  if(emplacePair.first->second.isTypeMacroMakerSupervisor())
207  {
208  allMacroMakerTypeSupervisorInfo_.emplace(
209  std::pair<unsigned int, const SupervisorInfo&>(
210  emplacePair.first->second.getId(), emplacePair.first->second));
211  }
212 
213  } // end main extraction loop
214 
215  //} //end wiz mode extraction
216  // else
217  // {
218  // __COUT__ << "Initializing info for Normal mode XDAQ context..." << __E__;
219  //
220  //
221  // ConfigurationManager cfgMgr;
222  // const XDAQContextTable* contextConfig =
223  // cfgMgr.__GET_CONFIG__(XDAQContextTable);
224  //
225  //
226  // //second pass, organize supervisors
227  // auto allDescriptors = SupervisorDescriptorInfoBase::getAllDescriptors();
228  // for(const auto& descriptor:allDescriptors)
229  // {
230  // auto /*<iterator,bool>*/ emplacePair =
231  // allSupervisorInfo_.emplace(std::pair<unsigned int, SupervisorInfo>(
232  // descriptor.second->getLocalId(),//descriptor.first,
233  // SupervisorInfo(
234  // descriptor.second /* descriptor */,
235  // contextConfig->getApplicationUID
236  // (
237  // descriptor.second->getContextDescriptor()->getURL(),
238  // descriptor.second->getLocalId()
239  // ) /* name */,
240  // contextConfig->getContextUID(
241  // descriptor.second->getContextDescriptor()->getURL())
243  // )));
244  // if(!emplacePair.second)
245  // {
246  // __SS__ << "Error! Duplicate Application IDs are not allowed. ID =" <<
247  // descriptor.second->getLocalId() << __E__;
248  // __SS_THROW__;
249  // }
250  //
251  // /////////////////////////////////////////////
252  // // now organize new descriptor by class...
253  //
254  // //check for gateway supervisor
255  // // note: necessarily exclusive to other Supervisor types
256  // if(emplacePair.first->second.isGatewaySupervisor())
257  // {
258  // if(theSupervisorInfo_)
259  // {
260  // __SS__ << "Error! Multiple Gateway Supervisors of class " <<
261  // XDAQContextTable::GATEWAY_SUPERVISOR_CLASS << "
262  // found. There can only be one. ID =" <<
263  // descriptor.second->getLocalId() << __E__;
264  // __SS_THROW__;
265  // }
266  // //copy and erase from map
267  // theSupervisorInfo_ = &(emplacePair.first->second);
268  // continue;
269  // }
270  //
271  // //check for wizard supervisor
272  // // note: necessarily exclusive to other Supervisor types
273  // if(emplacePair.first->second.isWizardSupervisor())
274  // {
275  // if(theWizardInfo_)
276  // {
277  // __SS__ << "Error! Multiple Wizard Supervisors of class " <<
278  // XDAQContextTable::WIZARD_SUPERVISOR_CLASS <<
279  // " found. There can only be one. ID =" <<
280  // descriptor.second->getLocalId() << __E__;
281  // __SS_THROW__;
282  // }
283  // //copy and erase from map
284  // theWizardInfo_ = &(emplacePair.first->second);
285  // continue;
286  // }
287  //
288  //
289  // //check for FE type, then add to FE group
290  // // note: not necessarily exclusive to other Supervisor types
291  // if(emplacePair.first->second.isTypeFESupervisor())
292  // {
293  // allFETypeSupervisorInfo_.emplace(std::pair<unsigned int, const
294  // SupervisorInfo&>( emplacePair.first->second.getId(),
295  // emplacePair.first->second));
296  // }
297  //
298  // //check for DM type, then add to DM group
299  // // note: not necessarily exclusive to other Supervisor types
300  // if(emplacePair.first->second.isTypeDMSupervisor())
301  // {
302  // allDMTypeSupervisorInfo_.emplace(std::pair<unsigned int, const
303  // SupervisorInfo&>( emplacePair.first->second.getId(),
304  // emplacePair.first->second));
305  // }
306  //
307  // //check for Logbook type, then add to Logbook group
308  // // note: not necessarily exclusive to other Supervisor types
309  // if(emplacePair.first->second.isTypeLogbookSupervisor())
310  // {
311  // allLogbookTypeSupervisorInfo_.emplace(std::pair<unsigned int, const
312  // SupervisorInfo&>( emplacePair.first->second.getId(),
313  // emplacePair.first->second));
314  // }
315  //
316  // //check for MacroMaker type, then add to MacroMaker group
317  // // note: not necessarily exclusive to other Supervisor types
318  // if(emplacePair.first->second.isTypeMacroMakerSupervisor())
319  // {
320  // allMacroMakerTypeSupervisorInfo_.emplace(std::pair<unsigned int, const
321  // SupervisorInfo&>( emplacePair.first->second.getId(),
322  // emplacePair.first->second));
323  // }
324  //
325  // } //end main extraction loop
326  // } //end normal mode extraction
327 
328  if(AllSupervisorInfo::MACROMAKER_MODE)
329  {
330  if(theWizardInfo_ || theSupervisorInfo_)
331  {
332  __SS__ << "Error! For MacroMaker mode, must not have one "
333  << XDAQContextTable::GATEWAY_SUPERVISOR_CLASS << " OR one "
334  << XDAQContextTable::WIZARD_SUPERVISOR_CLASS
335  << " as part of the context configuration! "
336  << "One was found." << __E__;
337  __SS_THROW__;
338  }
339  }
340  else if((!theWizardInfo_ && !theSupervisorInfo_) ||
341  (theWizardInfo_ && theSupervisorInfo_))
342  {
343  __SS__ << "Error! Must have one " << XDAQContextTable::GATEWAY_SUPERVISOR_CLASS
344  << " OR one " << XDAQContextTable::WIZARD_SUPERVISOR_CLASS
345  << " as part of the context configuration! "
346  << "Neither (or both) were found." << __E__;
347  __SS_THROW__;
348  }
349 
350  SupervisorDescriptorInfoBase::destroy();
351 
352  __COUT__ << "Supervisor Info initialization complete!" << __E__;
353 
354  // for debugging
355  // getOrderedSupervisorDescriptors("Configure");
356 } // end init()
357 
358 //========================================================================================================================
359 const SupervisorInfo& AllSupervisorInfo::getSupervisorInfo(xdaq::Application* app) const
360 {
361  auto it = allSupervisorInfo_.find(app->getApplicationDescriptor()->getLocalId());
362  if(it == allSupervisorInfo_.end())
363  {
364  __SS__ << "Could not find: " << app->getApplicationDescriptor()->getLocalId()
365  << std::endl;
366  __SS_THROW__;
367  }
368  return it->second;
369 }
370 
371 //========================================================================================================================
372 void AllSupervisorInfo::setSupervisorStatus(xdaq::Application* app,
373  const std::string& status)
374 {
375  setSupervisorStatus(app->getApplicationDescriptor()->getLocalId(), status);
376 }
377 //========================================================================================================================
378 void AllSupervisorInfo::setSupervisorStatus(const SupervisorInfo& appInfo,
379  const std::string& status)
380 {
381  setSupervisorStatus(appInfo.getId(), status);
382 }
383 //========================================================================================================================
384 void AllSupervisorInfo::setSupervisorStatus(const unsigned int& id,
385  const std::string& status)
386 {
387  auto it = allSupervisorInfo_.find(id);
388  if(it == allSupervisorInfo_.end())
389  {
390  __SS__ << "Could not find: " << id << std::endl;
391  __SS_THROW__;
392  }
393  it->second.setStatus(status);
394 }
395 
396 //========================================================================================================================
397 const SupervisorInfo& AllSupervisorInfo::getGatewayInfo(void) const
398 {
399  if(!theSupervisorInfo_)
400  {
401  __SS__ << "AllSupervisorInfo was not initialized or no Application of type "
402  << XDAQContextTable::GATEWAY_SUPERVISOR_CLASS << " found!" << __E__;
403  __SS_THROW__;
404  }
405  return *theSupervisorInfo_;
406 }
407 //========================================================================================================================
408 XDAQ_CONST_CALL xdaq::ApplicationDescriptor* AllSupervisorInfo::getGatewayDescriptor(
409  void) const
410 {
411  return getGatewayInfo().getDescriptor();
412 }
413 
414 //========================================================================================================================
415 const SupervisorInfo& AllSupervisorInfo::getWizardInfo(void) const
416 {
417  if(!theWizardInfo_)
418  {
419  __SS__ << "AllSupervisorInfo was not initialized or no Application of type "
420  << XDAQContextTable::WIZARD_SUPERVISOR_CLASS << " found!" << __E__;
421  __SS_THROW__;
422  }
423  return *theWizardInfo_;
424 }
425 //========================================================================================================================
426 XDAQ_CONST_CALL xdaq::ApplicationDescriptor* AllSupervisorInfo::getWizardDescriptor(
427  void) const
428 {
429  return getWizardInfo().getDescriptor();
430 }
431 
432 //========================================================================================================================
433 std::vector<std::vector<const SupervisorInfo*>>
434 AllSupervisorInfo::getOrderedSupervisorDescriptors(
435  const std::string& stateMachineCommand) const
436 {
437  __COUT__ << "getOrderedSupervisorDescriptors" << __E__;
438 
439  std::map<uint64_t /*priority*/, std::vector<unsigned int /*appId*/>>
440  orderedByPriority;
441 
442  try
443  {
444  ConfigurationManager cfgMgr;
445  const std::vector<XDAQContextTable::XDAQContext>& contexts =
446  cfgMgr.__GET_CONFIG__(XDAQContextTable)->getContexts();
447 
448  for(const auto& context : contexts)
449  if(context.status_)
450  for(const auto& app : context.applications_)
451  {
452  if(!app.status_)
453  continue; // skip disabled apps
454 
455  auto it = app.stateMachineCommandPriority_.find(stateMachineCommand);
456  if(it == app.stateMachineCommandPriority_.end())
457  orderedByPriority[XDAQContextTable::XDAQApplication::
458  DEFAULT_PRIORITY]
459  .push_back(
460  app.id_); // if no priority, then default to
461  // XDAQContextTable::XDAQApplication::DEFAULT_PRIORITY
462  else // take value, and do not allow DEFAULT value of 0 -> force to
463  // XDAQContextTable::XDAQApplication::DEFAULT_PRIORITY
464  orderedByPriority[it->second ? it->second
465  : XDAQContextTable::XDAQApplication::
466  DEFAULT_PRIORITY]
467  .push_back(app.id_);
468 
469  //__COUT__ << "app.id_ " << app.id_ << __E__;
470  }
471  }
472  catch(...)
473  {
474  __COUT_ERR__ << "SupervisorDescriptorInfoBase could not access the XDAQ Context "
475  "and Application configuration through the Context Table "
476  "Group."
477  << __E__;
478  throw;
479  }
480 
481  __COUT__ << "Here is the order supervisors will be " << stateMachineCommand
482  << "'d:" << __E__;
483 
484  // return ordered set of supervisor infos
485  // skip over Gateway Supervisor,
486  // and other supervisors that do not need state transitions.
487  std::vector<std::vector<const SupervisorInfo*>> retVec;
488  bool createContainer;
489  for(const auto& priorityAppVector : orderedByPriority)
490  {
491  createContainer = true;
492 
493  for(const auto& priorityApp : priorityAppVector.second)
494  {
495  auto it = allSupervisorInfo_.find(priorityApp);
496  if(it == allSupervisorInfo_.end())
497  {
498  __SS__
499  << "Error! Was AllSupervisorInfo properly initialized? The app.id_ "
500  << priorityApp << " priority "
501  << (unsigned int)priorityAppVector.first
502  << " could not be found in AllSupervisorInfo." << __E__;
503  __SS_THROW__;
504  }
505 
506  //__COUT__ << it->second.getName() << " [" << it->second.getId() << "]: " << "
507  // priority? " << (unsigned int)priorityAppVector.first <<
508  //__E__;
509 
510  if(it->second.isGatewaySupervisor())
511  continue; // skip gateway supervisor
512  if(it->second.isTypeLogbookSupervisor())
513  continue; // skip logbook supervisor(s)
514  if(it->second.isTypeMacroMakerSupervisor())
515  continue; // skip macromaker supervisor(s)
516  if(it->second.isTypeConfigurationGUISupervisor())
517  continue; // skip configurationGUI supervisor(s)
518  if(it->second.isTypeChatSupervisor())
519  continue; // skip chat supervisor(s)
520  if(it->second.isTypeConsoleSupervisor())
521  continue; // skip console supervisor(s)
522 
523  if(createContainer) // create container first time
524  {
525  retVec.push_back(std::vector<const SupervisorInfo*>());
526 
527  // if default priority, create a new vector container for each entry
528  // so they happen in sequence by default
529  // if(priorityAppVector.first !=
530  // XDAQContextTable::XDAQApplication::DEFAULT_PRIORITY)
531  // createContainer = false;
532 
533  createContainer = false;
534  }
535  retVec[retVec.size() - 1].push_back(&(it->second));
536 
537  __COUT__ << it->second.getName() << " [LID=" << it->second.getId() << "]: "
538  << " priority " << (unsigned int)priorityAppVector.first << " count "
539  << retVec[retVec.size() - 1].size() << __E__;
540  }
541  } // end equal priority loop
542  return retVec;
543 }
void init(xdaq::ApplicationContext *applicationContext)