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