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