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