otsdaq  v1_01_02
 All Classes Namespaces Functions
ConfigurationManager.cc
1 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
2 #include "otsdaq-core/ConfigurationInterface/ConfigurationInterface.h"//All configurable objects are included here
3 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationGroupKey.h"
4 #include "otsdaq-core/ProgressBar/ProgressBar.h"
5 
6 #include <fstream> // std::ofstream
7 
8 
9 using namespace ots;
10 
11 
12 #undef __MF_SUBJECT__
13 #define __MF_SUBJECT__ "ConfigurationManager"
14 
15 const std::string ConfigurationManager::READONLY_USER = "READONLY_USER";
16 
17 const std::string ConfigurationManager::XDAQ_CONTEXT_CONFIG_NAME = "XDAQContextConfiguration";
18 
19 //added env check for otsdaq_flatten_active_to_version to function
20 const std::string ConfigurationManager::ACTIVE_GROUP_FILENAME = ((getenv("SERVICE_DATA_PATH") == NULL)?(std::string(getenv("USER_DATA"))+"/ServiceData"):(std::string(getenv("SERVICE_DATA_PATH")))) + "/ActiveConfigurationGroups.cfg";
21 const std::string ConfigurationManager::ALIAS_VERSION_PREAMBLE = "ALIAS:";
22 const std::string ConfigurationManager::SCRATCH_VERSION_ALIAS = "Scratch";
23 
24 #define CORE_TABLE_INFO_FILENAME ((getenv("SERVICE_DATA_PATH") == NULL)?(std::string(getenv("USER_DATA"))+"/ServiceData"):(std::string(getenv("SERVICE_DATA_PATH")))) + "/CoreTableInfoNames.dat"
25 
26 
27 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT = "Context";
28 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE = "Backbone";
29 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION = "Configuration";
30 
31 
32 //==============================================================================
33 ConfigurationManager::ConfigurationManager()
34 : username_ (ConfigurationManager::READONLY_USER)
35 , theInterface_ (0)
36 , theConfigurationGroupKey_ (0)
37 , theContextGroupKey_ (0)
38 , theBackboneGroupKey_ (0)
39 , theConfigurationGroup_ ("")
40 , theContextGroup_ ("")
41 , theBackboneGroup_ ("")
42 , contextMemberNames_ ({XDAQ_CONTEXT_CONFIG_NAME,"XDAQApplicationConfiguration","DesktopIconConfiguration","MessageFacilityConfiguration","TheSupervisorConfiguration","StateMachineConfiguration","DesktopWindowParameterConfiguration"})
43 , backboneMemberNames_ ({"GroupAliasesConfiguration","VersionAliasesConfiguration"})
44 {
45  theInterface_ = ConfigurationInterface::getInstance(false); //false to use artdaq DB
46  //NOTE: in ConfigurationManagerRW using false currently.. think about consistency! FIXME
47 
48  //initialize special group metadata table
49  {
50  //Note: "ConfigurationGroupMetadata" should never be in conflict
51  // because all other tables end in "...Configuration"
52 
53  //This is a table called ConfigurationGroupMetadata
54  // with 3 fields:
55  // - GroupAuthor
56  // - GroupCreationTime
57  // - CommentDescription
58 
59  groupMetadataTable_.setConfigurationName(ConfigurationInterface::GROUP_METADATA_TABLE_NAME);
60  //ConfigurationView* mockup = configurationGroupMetadataTable_.getMockupViewP();
61  std::vector<ViewColumnInfo>* colInfo =
62  groupMetadataTable_.getMockupViewP()->getColumnsInfoP();
63 
64 
65  colInfo->push_back(ViewColumnInfo(
66  ViewColumnInfo::TYPE_UID, //just to make init() happy
67  "UnusedUID",
68  "UNUSED_UID",
69  ViewColumnInfo::DATATYPE_NUMBER,
70  "",0
71  ));
72  colInfo->push_back(ViewColumnInfo(
73  ViewColumnInfo::TYPE_COMMENT, //just to make init() happy
74  "CommentDescription",
75  "COMMENT_DESCRIPTION",
76  ViewColumnInfo::DATATYPE_STRING,
77  "",0
78  ));
79  colInfo->push_back(ViewColumnInfo(
80  ViewColumnInfo::TYPE_AUTHOR, //just to make init() happy
81  "GroupAuthor",
82  "AUTHOR",
83  ViewColumnInfo::DATATYPE_STRING,
84  "",0
85  ));
86  colInfo->push_back(ViewColumnInfo(
87  ViewColumnInfo::TYPE_TIMESTAMP,
88  "GroupCreationTime",
89  "GROUP_CREATION_TIME",
90  ViewColumnInfo::DATATYPE_TIME,
91  "",0
92  ));
93  auto tmpVersion = groupMetadataTable_.createTemporaryView();
94  groupMetadataTable_.setActiveView(tmpVersion);
95  //only need this one and only row for all time
96  groupMetadataTable_.getViewP()->addRow();
97  }
98 
99  //dump names of core tables (so UpdateOTS.sh can copy core tables for user)
100  {
101  FILE * fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(),"w");
102  if(fp)
103  {
104  for(const auto &name:contextMemberNames_)
105  fprintf(fp,"%s\n",name.c_str());
106  for(const auto &name:backboneMemberNames_)
107  fprintf(fp,"%s\n",name.c_str());
108  fclose(fp);
109  }
110  else
111  __MOUT__ << "Failed to open core table info file: " << CORE_TABLE_INFO_FILENAME << std::endl;
112  }
113 
114  init();
115 }
116 
117 //==============================================================================
118 ConfigurationManager::ConfigurationManager(const std::string& username)
120 {
121  username_ = username;
122 }
123 
124 //==============================================================================
125 ConfigurationManager::~ConfigurationManager()
126 {
127  destroy();
128 }
129 
130 //==============================================================================
131 //init
132 // if accumulatedErrors is not null.. fill it with errors
133 // else throw errors (but do not ask restoreActiveConfigurationGroups to throw errors)
134 void ConfigurationManager::init(std::string *accumulatedErrors)
135 {
136  if(accumulatedErrors) *accumulatedErrors = "";
137 
138  //destroy();
139 
140  // once Interface is false (using artdaq db) .. then can call
141  if(theInterface_->getMode() == false)
142  {
143  try
144  {
145  restoreActiveConfigurationGroups(accumulatedErrors?true:false);
146  }
147  catch(std::runtime_error &e)
148  {
149  if(accumulatedErrors) *accumulatedErrors = e.what();
150  else throw;
151  }
152  }
153 }
154 
155 //==============================================================================
156 //restoreActiveConfigurationGroups
157 // load the active groups from file
158 // Note: this should be used by the Supervisor to maintain
159 // the same configurationGroups surviving software system restarts
160 void ConfigurationManager::restoreActiveConfigurationGroups(bool throwErrors)
161 {
162  destroyConfigurationGroup("",true); //deactivate all
163 
164  std::string fn = ACTIVE_GROUP_FILENAME;
165  FILE *fp = fopen(fn.c_str(),"r");
166 
167  __MOUT__ << "ACTIVE_GROUP_FILENAME = " << ACTIVE_GROUP_FILENAME << std::endl;
168 
169  if(!fp) return;
170 
171  __MOUT__ << "throwErrors: " << throwErrors << std::endl;
172 
173  char tmp[500];
174  char strVal[500];
175 
176  std::string groupName;
177  std::string errorStr = "";
178 
179  for(int i=0;i<3;++i)
180  {
181  fgets(tmp,500,fp);
182  sscanf(tmp,"%s",strVal); //sscanf to remove '\n'
183  groupName = strVal;
184  fgets(tmp,500,fp);
185  sscanf(tmp,"%s",strVal); //sscanf to remove '\n'
186  try
187  {
188  //load and doActivate
189  loadConfigurationGroup(groupName,ConfigurationGroupKey(strVal),true);
190  }
191  catch(std::runtime_error &e)
192  {
193  __SS__ << "Failed to load config group in ConfigurationManager::init() with name '" <<
194  groupName << "_v" << strVal << "'" << std::endl;
195  ss << e.what() << std::endl;
196 
197  __MOUT_INFO__ << "\n" << ss.str();
198  errorStr += ss.str();
199  }
200  catch(...)
201  {
202  __SS__ << "Failed to load config group in ConfigurationManager::init() with name '" <<
203  groupName << "_v" << strVal << "'" << std::endl;
204 
205  __MOUT_INFO__ << "\n" << ss.str();
206  errorStr += ss.str();
207  }
208  }
209 
210  fclose(fp);
211 
212  if(throwErrors && errorStr != "")
213  throw std::runtime_error(errorStr);
214 }
215 
216 //==============================================================================
217 //destroyConfigurationGroup
218 // destroy all if theGroup == ""
219 // else destroy that group
220 // if onlyDeactivate, then don't delete, just deactivate view
221 void ConfigurationManager::destroyConfigurationGroup(const std::string& theGroup, bool onlyDeactivate)
222 {
223  //delete
224  bool isContext = theGroup == "" || theGroup == theContextGroup_;
225  bool isBackbone = theGroup == "" || theGroup == theBackboneGroup_;
226  bool isConfiguration = theGroup == "" || theGroup == theConfigurationGroup_;
227 
228  if(!isContext && !isBackbone && !isConfiguration)
229  {
230  __MOUT__ << "Invalid configuration group to destroy: " << theGroup << std::endl;
231  throw std::runtime_error("Invalid configuration group to destroy!");
232  }
233 
234  std::string dbgHeader = onlyDeactivate?"Deactivating":"Destroying";
235  if(isContext)
236  __MOUT__ << dbgHeader << " Context group: " << theGroup << std::endl;
237  if(isBackbone)
238  __MOUT__ << dbgHeader << " Backbone group: " << theGroup << std::endl;
239  if(isConfiguration)
240  __MOUT__ << dbgHeader << " Configuration group: " << theGroup << std::endl;
241 
242 
243  std::set<std::string>::const_iterator contextFindIt, backboneFindIt;
244  for(auto it = nameToConfigurationMap_.begin(); it != nameToConfigurationMap_.end(); /*no increment*/)
245  {
246  contextFindIt = contextMemberNames_.find(it->first);
247  backboneFindIt = backboneMemberNames_.find(it->first);
248  if(theGroup == "" || ( (isContext && contextFindIt != contextMemberNames_.end()) ||
249  (isBackbone && backboneFindIt != backboneMemberNames_.end()) ||
250  (!isContext && !isBackbone &&
251  contextFindIt == contextMemberNames_.end() &&
252  backboneFindIt == backboneMemberNames_.end())))
253  {
254  //__MOUT__ << "\t" << it->first << std::endl;
255  //if(it->second->isActive())
256  // __MOUT__ << "\t\t..._v" << it->second->getViewVersion() << std::endl;
257 
258 
259  if(onlyDeactivate) //only deactivate
260  {
261  it->second->deactivate();
262  ++it;
263  }
264  else //else, delete/erase
265  {
266  delete it->second;
267  nameToConfigurationMap_.erase(it++);
268  }
269  }
270  else
271  ++it;
272  }
273 
274  if(isConfiguration)
275  {
276  theConfigurationGroup_ = "";
277  if(theConfigurationGroupKey_ != 0)
278  {
279  __MOUT__ << "Destroying Configuration Key: " << *theConfigurationGroupKey_ << std::endl;
280  theConfigurationGroupKey_.reset();
281  }
282 
283  // theDACStreams_.clear();
284  }
285  if(isBackbone)
286  {
287  theBackboneGroup_ = "";
288  if(theBackboneGroupKey_ != 0)
289  {
290  __MOUT__ << "Destroying Backbone Key: " << *theBackboneGroupKey_ << std::endl;
291  theBackboneGroupKey_.reset();
292  }
293  }
294  if(isContext)
295  {
296  theContextGroup_ = "";
297  if(theContextGroupKey_ != 0)
298  {
299  __MOUT__ << "Destroying Context Key: " << *theContextGroupKey_ << std::endl;
300  theContextGroupKey_.reset();
301  }
302  }
303 }
304 
305 //==============================================================================
306 void ConfigurationManager::destroy(void)
307 {
308  //NOTE: Moved to ConfigurationGUISupervisor [FIXME is this correct?? should we use shared_ptr??]
309  // if( ConfigurationInterface::getInstance(true) != 0 )
310  // delete theInterface_;
311  destroyConfigurationGroup();
312 }
313 
314 
315 //==============================================================================
316 //convertGroupTypeIdToName
317 // return translation:
318 // 0 for context
319 // 1 for backbone
320 // 2 for configuration (others)
321 const std::string& ConfigurationManager::convertGroupTypeIdToName(int groupTypeId)
322 {
323  return groupTypeId==CONTEXT_TYPE?
324  ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT:
325  (groupTypeId==BACKBONE_TYPE?
326  ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE:
327  ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION);
328 }
329 
330 //==============================================================================
331 //getTypeOfGroup
332 // return
333 // 0 for context
334 // 1 for backbone
335 // 2 for configuration (others)
336 int ConfigurationManager::getTypeOfGroup(
337  const std::string &configGroupName,
338  ConfigurationGroupKey configGroupKey,
339  const std::map<std::string /*name*/, ConfigurationVersion /*version*/> &memberMap)
340 {
341 
342  bool isContext = true;
343  bool isBackbone = true;
344  bool inGroup;
345  bool inContext = false;
346  bool inBackbone = false;
347  unsigned int matchCount = 0;
348 
349  for(auto &memberPair:memberMap)
350  {
351  //__MOUT__ << "Member name: = "<< memberPair.first << std::endl;
352  inGroup = false; //check context
353  for(auto &contextMemberString:contextMemberNames_)
354  //if(!isContext) break;
355  //else
356  if(memberPair.first == contextMemberString)
357  {
358  inGroup = true;
359  inContext = true;
360  ++matchCount;
361  break;
362  }
363  if(!inGroup)
364  {
365  isContext = false;
366  if(inContext) //there was a member in context!
367  {
368  __SS__ << "This group is an incomplete match to contextMemberNames_: " +
369  configGroupName + "(" + configGroupKey.toString() + ")\n";
370  ss << "\nTo be a Context group, the members must exactly match" <<
371  "the following members:\n";
372  int i = 0;
373  for(auto &memberName:contextMemberNames_)
374  ss << ++i << ". " << memberName << "\n";
375  __MOUT_ERR__ << "\n" << ss.str();
376  throw std::runtime_error(ss.str());
377  }
378  }
379 
380  inGroup = false; //check backbone
381  for(auto &backboneMemberString:backboneMemberNames_)
382  //if(!isBackbone) break;
383  //else
384  if(memberPair.first == backboneMemberString)
385  {
386  inGroup = true;
387  inBackbone = true;
388  ++matchCount;
389  break;
390  }
391  if(!inGroup)
392  {
393  isBackbone = false;
394  if(inBackbone) //there was a member in backbone!
395  {
396  __SS__ << "This group is an incomplete match to backboneMemberNames_: " +
397  configGroupName + "(" + configGroupKey.toString() + ")\n";
398  ss << "\nTo be a Backbone group, the members must exactly match" <<
399  "the following members:\n";
400  int i = 0;
401  for(auto &memberName:backboneMemberNames_)
402  ss << ++i << ". " << memberName << "\n";
403  __MOUT_ERR__ << "\n" << ss.str();
404  throw std::runtime_error(ss.str());
405  }
406  }
407 
408  }
409 
410  if(isContext && matchCount != contextMemberNames_.size())
411  {
412  __SS__ << "This group is an incomplete match to contextMemberNames_: " +
413  configGroupName + "(" + configGroupKey.toString() + ")" +
414  " Size=" << matchCount << " but should be " << contextMemberNames_.size() <<
415  std::endl;
416  ss << "\nThe members currently are...\n";
417  int i = 0;
418  for(auto &memberPair:memberMap)
419  ss << ++i << ". " << memberPair.first << "\n";
420  ss << "\nThe expected Context members are...\n";
421  i = 0;
422  for(auto &memberName:contextMemberNames_)
423  ss << ++i << ". " << memberName << "\n";
424  __MOUT_ERR__ << "\n" << ss.str();
425  throw std::runtime_error(ss.str());
426  }
427 
428  if(isBackbone && matchCount != backboneMemberNames_.size())
429  {
430  __SS__ << "This group is an incomplete match to backboneMemberNames_: " +
431  configGroupName + "(" + configGroupKey.toString() + ")" +
432  " Size=" << matchCount << " but should be " << backboneMemberNames_.size() <<
433  std::endl;
434  ss << "\nThe members currently are...\n";
435  int i = 0;
436  for(auto &memberPair:memberMap)
437  ss << ++i << ". " << memberPair.first << "\n";
438  ss << "\nThe expected Backbone members are...\n";
439  i = 0;
440  for(auto &memberName:backboneMemberNames_)
441  ss << ++i << ". " << memberName << "\n";
442  __MOUT_ERR__ << "\n" << ss.str();
443  throw std::runtime_error(ss.str());
444  }
445 
446  return isContext?CONTEXT_TYPE:(isBackbone?BACKBONE_TYPE:CONFIGURATION_TYPE);
447 }
448 
449 //==============================================================================
450 //getTypeNameOfGroup
451 // return
452 // 0 for context
453 // 1 for backbone
454 // 2 for configuration (others)
455 const std::string& ConfigurationManager::getTypeNameOfGroup(
456  const std::string &configGroupName,
457  ConfigurationGroupKey configGroupKey,
458  const std::map<std::string /*name*/, ConfigurationVersion /*version*/> &memberMap)
459 {
460  return convertGroupTypeIdToName(getTypeOfGroup(configGroupName, configGroupKey, memberMap));
461 }
462 //==============================================================================
463 //loadMemberMap
464 // loads tables given by name/version pairs in memberMap
465 // Note: does not activate them.
466 void ConfigurationManager::dumpActiveConfiguration(
467  const std::string &filePath, const std::string &dumpType) const
468 {
469  time_t rawtime = time(0);
470  __MOUT__ << "filePath = " << filePath << std::endl;
471  __MOUT__ << "dumpType = " << dumpType << std::endl;
472 
473 
474  std::ofstream fs;
475  fs.open(filePath, std::fstream::out | std::fstream::trunc);
476 
477  std::ostream *out;
478 
479  //if file was valid use it, else default to cout
480  if(fs.is_open())
481  out = &fs;
482  else
483  out = &(std::cout);
484 
485 
486  (*out) << "#################################" << std::endl;
487  (*out) << "This is an ots configuration dump.\n\n" << std::endl;
488  (*out) << "Source database is $ARTDAQ_DATABASE_URI = \t" << getenv("ARTDAQ_DATABASE_URI") << std::endl;
489  (*out) << "\nOriginal location of dump: \t" << filePath << std::endl;
490  (*out) << "Type of dump: \t" << dumpType << std::endl;
491  (*out) << "Linux time for dump: \t" << rawtime << std::endl;
492 
493  {
494  struct tm * timeinfo = localtime (&rawtime);
495  char buffer [100];
496  strftime(buffer,100,"%c %Z",timeinfo);
497  (*out) << "Display time for dump: \t" << buffer << std::endl;
498  }
499 
500 
501  //define local "lambda" functions
502  // active groups
503  // active tables
504  // active group members
505  // active table contents
506 
507  auto localDumpActiveGroups = [](const ConfigurationManager *cfgMgr, std::ostream *out) {
508  std::map<std::string, std::pair<std::string, ConfigurationGroupKey>> activeGroups =
509  cfgMgr->getActiveConfigurationGroups();
510 
511  (*out) << "\n\n************************" << std::endl;
512  (*out) << "Active Groups:" << std::endl;
513  for(auto &group:activeGroups)
514  {
515  (*out) << "\t" << group.first << " := " <<
516  group.second.first << " (" <<
517  group.second.second << ")" << std::endl;
518  }
519  };
520 
521  auto localDumpActiveTables = [](const ConfigurationManager *cfgMgr, std::ostream *out) {
522  std::map<std::string, ConfigurationVersion> activeTables =
523  cfgMgr->getActiveVersions();
524 
525  (*out) << "\n\n************************" << std::endl;
526  (*out) << "Active Tables:" << std::endl;
527  (*out) << "Active Tables count = " << activeTables.size() << std::endl;
528  for(auto &table:activeTables)
529  {
530  (*out) << "\t" << table.first << "-v" <<
531  table.second << std::endl;
532  }
533  };
534 
535  auto localDumpActiveGroupMembers = [](const ConfigurationManager *cfgMgr, std::ostream *out) {
536  std::map<std::string, std::pair<std::string, ConfigurationGroupKey>> activeGroups =
537  cfgMgr->getActiveConfigurationGroups();
538  (*out) << "\n\n************************" << std::endl;
539  (*out) << "Active Group Members:" << std::endl;
540  int tableCount = 0;
541  for(auto &group:activeGroups)
542  {
543  (*out) << "\t" << group.first << " := " <<
544  group.second.first << " (" <<
545  group.second.second << ")" << std::endl;
546 
547  std::map<std::string /*name*/, ConfigurationVersion /*version*/> memberMap =
548  cfgMgr->theInterface_->getConfigurationGroupMembers(
549  ConfigurationGroupKey::getFullGroupString(
550  group.second.first,
551  group.second.second));
552 
553  (*out) << "\tMember count = " << memberMap.size() << std::endl;
554  tableCount += memberMap.size();
555 
556  for(auto &member:memberMap)
557  {
558  (*out) << "\t\t" << member.first << "-v" <<
559  member.second << std::endl;
560  }
561  }
562  (*out) << "Active Group Members total count = " << tableCount << std::endl;
563  };
564 
565  auto localDumpActiveTableContents = [](const ConfigurationManager *cfgMgr, std::ostream *out) {
566  std::map<std::string, ConfigurationVersion> activeTables =
567  cfgMgr->getActiveVersions();
568 
569  (*out) << "\n\n************************" << std::endl;
570  (*out) << "Active Table Contents:" << std::endl;
571  for(auto &table:activeTables)
572  {
573  (*out) << "\t" << table.first << "-v" <<
574  table.second << std::endl;
575 
576  cfgMgr->nameToConfigurationMap_.find(table.first)->second->print(*out);
577  }
578  };
579 
580 
581 
582  if(dumpType == "GroupKeys")
583  {
584  localDumpActiveGroups(this,out);
585  }
586  else if(dumpType == "TableVersions")
587  {
588  localDumpActiveTables(this,out);
589  }
590  else if(dumpType == "GroupKeysAndTableVersions")
591  {
592  localDumpActiveGroups(this,out);
593  localDumpActiveTables(this,out);
594  }
595  else if(dumpType == "All")
596  {
597  localDumpActiveGroups(this,out);
598  localDumpActiveGroupMembers(this,out);
599  localDumpActiveTables(this,out);
600  localDumpActiveTableContents(this,out);
601  }
602  else
603  {
604  __SS__ << "Invalid dump type '" << dumpType <<
605  "' given during dumpActiveConfiguration(). Valid types are as follows:\n" <<
606 
607  //List all choices
608  "GroupKeys" << ", " <<
609  "TableVersions" << ", " <<
610  "GroupsKeysAndTableVersions" << ", " <<
611  "All" <<
612 
613  "\n\nPlease change the State Machine configuration to a valid dump type." <<
614  std::endl;
615  throw std::runtime_error(ss.str());
616  }
617 
618  if(fs.is_open())
619  fs.close();
620 }
621 
622 //==============================================================================
623 //loadMemberMap
624 // loads tables given by name/version pairs in memberMap
625 // Note: does not activate them.
626 void ConfigurationManager::loadMemberMap(
627  const std::map<std::string /*name*/, ConfigurationVersion /*version*/> &memberMap)
628 {
629  ConfigurationBase *tmpConfigBasePtr;
630  // for each member
631  // get()
632  for(auto &memberPair:memberMap)
633  {
634  //__MOUT__ << "\tMember config " << memberPair.first << ":" <<
635  // memberPair.second << std::endl;
636 
637  //get the proper temporary pointer
638  // use 0 if doesn't exist yet.
639  // Note: do not want to give nameToConfigurationMap_[memberPair.first]
640  // in case there is failure in get... (exceptions may be thrown)
641  //Note: Default constructor is called by Map, i.e. nameToConfigurationMap_[memberPair.first] = 0; //create pointer and set to 0
642  tmpConfigBasePtr = 0;
643  if(nameToConfigurationMap_.find(memberPair.first) != nameToConfigurationMap_.end())
644  tmpConfigBasePtr = nameToConfigurationMap_[memberPair.first];
645 
646  theInterface_->get(tmpConfigBasePtr, //configurationPtr
647  memberPair.first, //configurationName
648  0, //ConfigurationGroupKey
649  0, //configurations
650  false, //dontFill=false to fill
651  memberPair.second, //version
652  false //resetConfiguration
653  );
654 
655  nameToConfigurationMap_[memberPair.first] = tmpConfigBasePtr;
656  if(nameToConfigurationMap_[memberPair.first]->getViewP())
657  {
658  //__MOUT__ << "\t\tActivated version: " << nameToConfigurationMap_[memberPair.first]->getViewVersion() << std::endl;
659  }
660  else
661  {
662  __SS__ << nameToConfigurationMap_[memberPair.first]->getConfigurationName() <<
663  ": View version not activated properly!";
664  throw std::runtime_error(ss.str());
665  }
666  }
667 }
668 
669 //==============================================================================
670 //loadConfigurationGroup
671 // load all members of configuration group
672 // if doActivate
673 // DOES NOT theConfigurationGroup_, theContextGroup_, or theBackboneGroup_ on success
674 // this happens with ConfigurationManagerRW::activateConfigurationGroup
675 // for each member
676 // configBase->init()
677 //
678 // if progressBar != 0, then do step handling, for finer granularity
679 //
680 // if(doNotLoadMember) return memberMap; //this is useful if just getting group metadata
681 //
682 // throws exception on failure.
683 // map<name , ConfigurationVersion >
684 std::map<std::string, ConfigurationVersion> ConfigurationManager::loadConfigurationGroup(
685  const std::string &configGroupName,
686  ConfigurationGroupKey configGroupKey,
687  bool doActivate,
688  ProgressBar *progressBar,
689  std::string *accumulatedTreeErrors,
690  std::string *groupComment,
691  std::string *groupAuthor,
692  std::string *groupCreateTime,
693  bool doNotLoadMember)
694 {
695  if(accumulatedTreeErrors) *accumulatedTreeErrors = "";
696  if(groupComment) *groupComment = "";
697  if(groupAuthor) *groupAuthor = "";
698  if(groupCreateTime) *groupCreateTime = "";
699 
700  // load all members of configuration group
701  // if doActivate
702  // determine the type configuration
703  // deactivate all of that type (invalidate active view)
704  //
705  // for each member
706  // get()
707  // if doActivate, configBase->init()
708  //
709  // if doActivate
710  // set theConfigurationGroup_, theContextGroup_, or theBackboneGroup_ on success
711 
712  __MOUT_INFO__ << "Loading Configuration Group: " << configGroupName <<
713  "(" << configGroupKey << ")" << std::endl;
714 
715  std::map<std::string /*name*/, ConfigurationVersion /*version*/> memberMap =
716  theInterface_->getConfigurationGroupMembers(
717  ConfigurationGroupKey::getFullGroupString(configGroupName,configGroupKey),
718  true); //include meta data table
719 
720 
721  if(progressBar) progressBar->step();
722 
723  //remove meta data table and extract info
724  auto metaTablePair = memberMap.find(groupMetadataTable_.getConfigurationName());
725  if(metaTablePair !=
726  memberMap.end())
727  {
728  __MOUT__ << "Found group meta data. v" <<
729  metaTablePair->second << std::endl;
730  //clear table
731  while(groupMetadataTable_.getView().getNumberOfRows())
732  groupMetadataTable_.getViewP()->deleteRow(0);
733  theInterface_->fill(&groupMetadataTable_,metaTablePair->second);
734  //check that there is only 1 row
735  if(groupMetadataTable_.getView().getNumberOfRows() != 1)
736  {
737  groupMetadataTable_.print();
738  __SS__ << "groupMetadataTable_ has wrong number of rows! Must be 1." << std::endl;
739  __MOUT_ERR__ << "\n" << ss.str();
740  throw std::runtime_error(ss.str());
741  }
742  //groupMetadataTable_.print();
743 
744  memberMap.erase(metaTablePair);
745 
746  //extract fields
747  if(groupComment) *groupComment = groupMetadataTable_.getView().getValueAsString(0,1);
748  if(groupAuthor) *groupAuthor = groupMetadataTable_.getView().getValueAsString(0,2);
749  if(groupCreateTime) *groupCreateTime = groupMetadataTable_.getView().getValueAsString(0,3);
750  }
751 
752  if(progressBar) progressBar->step();
753 
754  __MOUT__ << "memberMap loaded size = " << memberMap.size() << std::endl;
755 
756  if(doNotLoadMember) return memberMap; //this is useful if just getting group metadata
757 
758  int groupType = -1;
759  if(doActivate)
760  {
761  //determine the type configuration group
762  groupType = getTypeOfGroup(configGroupName,configGroupKey,memberMap);
763 
764  std::string groupToDeactivate =
765  groupType==CONTEXT_TYPE?theContextGroup_:
766  (groupType==BACKBONE_TYPE?theBackboneGroup_:theConfigurationGroup_);
767 
768  // deactivate all of that type (invalidate active view)
769  if(groupToDeactivate != "") //deactivate only if pre-existing group
770  {
771  __MOUT__ << "groupToDeactivate '" << groupToDeactivate << "'" << std::endl;
772  destroyConfigurationGroup(groupToDeactivate,true);
773  }
774 // else
775 // {
776 // //Getting here, is kind of strange:
777 // // - this group may have only been partially loaded before
778 // //Solution: destroy en by targeting member map
779 //
780 // }
781  }
782 
783  if(progressBar) progressBar->step();
784 
785  __MOUT__ << "Activating chosen group:" << std::endl;
786 
787 
788  loadMemberMap(memberMap);
789 
790  if(progressBar) progressBar->step();
791 
792  if(accumulatedTreeErrors)
793  {
794  __MOUT__ << "Checking chosen group for tree errors..." << std::endl;
795 
796  getChildren(&memberMap, accumulatedTreeErrors);
797  if(*accumulatedTreeErrors != "")
798  {
799  __MOUT_ERR__ << "Errors detected while loading Configuration Group: " << configGroupName <<
800  "(" << configGroupKey << "). Aborting." << std::endl;
801  return memberMap; //return member name map to version
802  }
803  }
804 
805  if(progressBar) progressBar->step();
806 
807  // for each member
808  // if doActivate, configBase->init()
809  if(doActivate)
810  for(auto &memberPair:memberMap)
811  {
812  //do NOT allow activating Scratch versions if tracking is ON!
813  if(ConfigurationInterface::isVersionTrackingEnabled() &&
814  memberPair.second.isScratchVersion())
815  {
816  __SS__ << "Error while activating member Table '" <<
817  nameToConfigurationMap_[memberPair.first]->getConfigurationName() <<
818  "-v" << memberPair.second <<
819  " for Configuration Group '" << configGroupName <<
820  "(" << configGroupKey << ")'. When version tracking is enabled, Scratch views" <<
821  " are not allowed! Please only use unique, persistent versions when version tracking is enabled."
822  << std::endl;
823  __MOUT_ERR__ << "\n" << ss.str();
824  throw std::runtime_error(ss.str());
825  }
826 
827 
828  //attempt to init using the configuration's specific init
829  // this could be risky user code, try and catch
830  try
831  {
832  nameToConfigurationMap_[memberPair.first]->init(this);
833  }
834  catch(std::runtime_error& e)
835  {
836  __SS__ << "Error detected calling " <<
837  nameToConfigurationMap_[memberPair.first]->getConfigurationName() <<
838  ".init()!\n\n " << e.what() << std::endl;
839  throw std::runtime_error(ss.str());
840  }
841  catch(...)
842  {
843  __SS__ << "Error detected calling " <<
844  nameToConfigurationMap_[memberPair.first]->getConfigurationName() <<
845  ".init()!\n\n " << std::endl;
846  throw std::runtime_error(ss.str());
847  }
848 
849  }
850 
851  if(progressBar) progressBar->step();
852 
853 
854  // if doActivate
855  // set theConfigurationGroup_, theContextGroup_, or theBackboneGroup_ on success
856 
857  if(doActivate)
858  {
859  if(groupType == CONTEXT_TYPE) //
860  {
861  __MOUT_INFO__ << "Context Configuration Group loaded: " << configGroupName <<
862  "(" << configGroupKey << ")" << std::endl;
863  theContextGroup_ = configGroupName;
864  theContextGroupKey_ = std::shared_ptr<ConfigurationGroupKey>(new ConfigurationGroupKey(configGroupKey));
865  }
866  else if(groupType == BACKBONE_TYPE)
867  {
868  __MOUT_INFO__ << "Backbone Configuration Group loaded: " << configGroupName <<
869  "(" << configGroupKey << ")" << std::endl;
870  theBackboneGroup_ = configGroupName;
871  theBackboneGroupKey_ = std::shared_ptr<ConfigurationGroupKey>(new ConfigurationGroupKey(configGroupKey));
872  }
873  else //is theConfigurationGroup_
874  {
875  __MOUT_INFO__ << "The Configuration Group loaded: " << configGroupName <<
876  "(" << configGroupKey << ")" << std::endl;
877  theConfigurationGroup_ = configGroupName;
878  theConfigurationGroupKey_ = std::shared_ptr<ConfigurationGroupKey>(new ConfigurationGroupKey(configGroupKey));
879  }
880  }
881 
882  if(progressBar) progressBar->step();
883  __MOUT__ << "Load complete." << std::endl;
884  return memberMap;
885 }
886 
887 
888 //==============================================================================
889 //setActiveGlobalConfiguration
890 // get theActiveGlobalConfig_
891 // map<type, pair <groupName , ConfigurationGroupKey> >
892 //
893 // Note: invalid ConfigurationGroupKey means no active group currently
894 std::map<std::string, std::pair<std::string, ConfigurationGroupKey> > ConfigurationManager::getActiveConfigurationGroups(void) const
895 {
896  // map<type, pair <groupName , ConfigurationGroupKey> >
897  std::map<std::string, std::pair<std::string, ConfigurationGroupKey> > retMap;
898 
899  retMap[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT] =
900  std::pair<std::string,ConfigurationGroupKey>(theContextGroup_ ,theContextGroupKey_ ?*theContextGroupKey_ : ConfigurationGroupKey());
901  retMap[ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE] =
902  std::pair<std::string,ConfigurationGroupKey>(theBackboneGroup_ ,theBackboneGroupKey_ ?*theBackboneGroupKey_ : ConfigurationGroupKey());
903  retMap[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION] =
904  std::pair<std::string,ConfigurationGroupKey>(theConfigurationGroup_,theConfigurationGroupKey_?*theConfigurationGroupKey_: ConfigurationGroupKey());
905  return retMap;
906 }
907 
908 //==============================================================================
909 ConfigurationTree ConfigurationManager::getSupervisorConfigurationNode(
910  const std::string &contextUID, const std::string &applicationUID) const
911 {
912  return getNode(
913  "/" + getConfigurationByName(XDAQ_CONTEXT_CONFIG_NAME)->getConfigurationName() +
914  "/" + contextUID +
915  "/LinkToApplicationConfiguration/" + applicationUID +
916  "/LinkToSupervisorConfiguration");
917 }
918 
919 //==============================================================================
920 ConfigurationTree ConfigurationManager::getNode(const std::string& nodeString) const
921 {
922  //__MOUT__ << "nodeString=" << nodeString << " " << nodeString.length() << std::endl;
923 
924  //get nodeName (in case of / syntax)
925  if(nodeString.length() < 1) throw std::runtime_error("Invalid empty node name");
926 
927  bool startingSlash = (nodeString[0] == '/');
928 
929  std::string nodeName = nodeString.substr(startingSlash?1:0, nodeString.find('/',1)-(startingSlash?1:0));
930  //__MOUT__ << "nodeName=" << nodeName << " " << nodeName.length() << std::endl;
931  if(nodeName.length() < 1) throw std::runtime_error("Invalid node name: " + nodeName);
932 
933  std::string childPath = nodeString.substr(nodeName.length() + (startingSlash?1:0));
934 
935  //__MOUT__ << "childPath=" << childPath << " " << childPath.length() << std::endl;
936 
937  ConfigurationTree configTree(this, getConfigurationByName(nodeName));
938  if(childPath.length() > 1)
939  return configTree.getNode(childPath);
940  else
941  return configTree;
942 }
943 
944 //==============================================================================
945 //getFirstPathToNode
946 std::string ConfigurationManager::getFirstPathToNode(const ConfigurationTree &node, const std::string &startPath) const
947 //void ConfigurationManager::getFirstPathToNode(const ConfigurationTree &node, const ConfigurationTree &startNode) const
948 {
949  std::string path = "/";
950  return path;
951 }
952 
953 //==============================================================================
954 //getChildren
955 // if memberMap is passed then only consider children in the map
956 //
957 // if accumulatedTreeErrors is non null, check for disconnects occurs.
958 // check is 2 levels deep which should get to the links starting at tables.
959 std::vector<std::pair<std::string,ConfigurationTree> > ConfigurationManager::getChildren(
960  std::map<std::string, ConfigurationVersion> *memberMap,
961  std::string *accumulatedTreeErrors) const
962 {
963  std::vector<std::pair<std::string,ConfigurationTree> > retMap;
964  if(accumulatedTreeErrors) *accumulatedTreeErrors = "";
965 
966  if(!memberMap || memberMap->empty()) //return all present active members
967  {
968  for(auto &configPair:nameToConfigurationMap_)
969  {
970  //__MOUT__ << configPair.first << " " << (int)(configPair.second?1:0) << std::endl;
971 
972  if(configPair.second->isActive()) //only consider if active
973  {
974  ConfigurationTree newNode(this, configPair.second);
975 
976 
977  if(accumulatedTreeErrors) //check for disconnects
978  {
979  try
980  {
981  std::vector<std::pair<std::string,ConfigurationTree> > newNodeChildren =
982  newNode.getChildren();
983  for(auto &newNodeChild: newNodeChildren)
984  {
985  std::vector<std::pair<std::string,ConfigurationTree> > twoDeepChildren =
986  newNodeChild.second.getChildren();
987 
988  for(auto &twoDeepChild: twoDeepChildren)
989  {
990  //__MOUT__ << configPair.first << " " << newNodeChild.first << " " <<
991  // twoDeepChild.first << std::endl;
992  if(twoDeepChild.second.isLinkNode() &&
993  twoDeepChild.second.isDisconnected() &&
994  twoDeepChild.second.getDisconnectedTableName() !=
995  ViewColumnInfo::DATATYPE_LINK_DEFAULT)
996  *accumulatedTreeErrors += "\n\nAt node '" +
997  configPair.first + "' with entry UID '" +
998  newNodeChild.first + "' there is a disconnected child node at link column '" +
999  twoDeepChild.first + "'" +
1000  " that points to table named '" +
1001  twoDeepChild.second.getDisconnectedTableName() +
1002  "' ...";
1003  }
1004  }
1005  }
1006  catch(std::runtime_error &e)
1007  {
1008  *accumulatedTreeErrors += "\n\nAt node '" +
1009  configPair.first + "' error detected descending through children:\n" +
1010  e.what();
1011  }
1012  }
1013 
1014  retMap.push_back(std::pair<std::string,ConfigurationTree>(configPair.first,
1015  newNode));
1016  }
1017 
1018  //__MOUT__ << configPair.first << std::endl;
1019  }
1020  }
1021  else //return only members from the member map (they must be present and active!)
1022  {
1023 
1024  for(auto &memberPair: *memberMap)
1025  {
1026  auto mapIt = nameToConfigurationMap_.find(memberPair.first);
1027  if(mapIt == nameToConfigurationMap_.end())
1028  {
1029  __SS__ << "Get Children with member map requires a child '" <<
1030  memberPair.first << "' that is not present!" << std::endl;
1031  throw std::runtime_error(ss.str());
1032  }
1033  if(!(*mapIt).second->isActive())
1034  {
1035  __SS__ << "Get Children with member map requires a child '" <<
1036  memberPair.first << "' that is not active!" << std::endl;
1037  throw std::runtime_error(ss.str());
1038  }
1039 
1040  ConfigurationTree newNode(this, (*mapIt).second);
1041 
1042  if(accumulatedTreeErrors) //check for disconnects
1043  {
1044  try
1045  {
1046  std::vector<std::pair<std::string,ConfigurationTree> > newNodeChildren =
1047  newNode.getChildren();
1048  for(auto &newNodeChild: newNodeChildren)
1049  {
1050  std::vector<std::pair<std::string,ConfigurationTree> > twoDeepChildren =
1051  newNodeChild.second.getChildren();
1052 
1053  for(auto &twoDeepChild: twoDeepChildren)
1054  {
1055  //__MOUT__ << memberPair.first << " " << newNodeChild.first << " " <<
1056  // twoDeepChild.first << std::endl;
1057  if(twoDeepChild.second.isLinkNode() &&
1058  twoDeepChild.second.isDisconnected() &&
1059  twoDeepChild.second.getDisconnectedTableName() !=
1060  ViewColumnInfo::DATATYPE_LINK_DEFAULT)
1061  {
1062  *accumulatedTreeErrors += "\n\nAt node '" +
1063  memberPair.first + "' with entry UID '" +
1064  newNodeChild.first + "' there is a disconnected child node at link column '" +
1065  twoDeepChild.first + "'" +
1066  " that points to table named '" +
1067  twoDeepChild.second.getDisconnectedTableName() +
1068  "' ...";
1069 
1070  //check if disconnected table is in group, if not software error
1071 
1072  bool found = false;
1073  for(auto &searchMemberPair: *memberMap)
1074  if(searchMemberPair.first ==
1075  twoDeepChild.second.getDisconnectedTableName())
1076  { found = true; break;}
1077  if(!found)
1078  *accumulatedTreeErrors +=
1079  std::string("\nNote: It may be safe to ignore this error ") +
1080  "since the link's target table " +
1081  twoDeepChild.second.getDisconnectedTableName() +
1082  " is not a member of this group (and may not be loaded yet).";
1083  }
1084  }
1085  }
1086  }
1087  catch(std::runtime_error &e)
1088  {
1089  *accumulatedTreeErrors += "\n\nAt node '" +
1090  memberPair.first + "' error detected descending through children:\n" +
1091  e.what();
1092  }
1093  }
1094 
1095  retMap.push_back(std::pair<std::string,ConfigurationTree>(memberPair.first,
1096  newNode));
1097  }
1098  }
1099 
1100  return retMap;
1101 }
1102 
1103 //==============================================================================
1104 //getConfigurationByName
1105 // Get read-only pointer to configuration.
1106 // If Read/Write access is needed use ConfigurationManagerWithWriteAccess
1107 // (For general use, Write access should be avoided)
1108 const ConfigurationBase* ConfigurationManager::getConfigurationByName(const std::string &configurationName) const
1109 {
1110  std::map<std::string, ConfigurationBase*>::const_iterator it;
1111  if((it = nameToConfigurationMap_.find(configurationName)) == nameToConfigurationMap_.end())
1112  {
1113  __SS__ << "\n\nCan not find configuration named '" <<
1114  configurationName <<
1115  "'\n\n\n\nYou need to load the configuration before it can be used." <<
1116  " It probably is missing from the member list of the Configuration Group that was loaded.\n" <<
1117  "\nYou may need to enter wiz mode to remedy the situation, use the following:\n" <<
1118  "\n\t StartOTS.sh --wiz" <<
1119  "\n\n\n\n"
1120  << std::endl;
1121  throw std::runtime_error(ss.str());
1122  }
1123  return it->second;
1124 }
1125 
1126 //==============================================================================
1127 //loadConfigurationBackbone
1128 // loads the active backbone configuration group
1129 // returns the active group key that was loaded
1130 ConfigurationGroupKey ConfigurationManager::loadConfigurationBackbone()
1131 {
1132  if(!theBackboneGroupKey_) //no active backbone
1133  {
1134  __MOUT_WARN__ << "getConfigurationGroupKey() Failed! No active backbone currently." << std::endl;
1135  return ConfigurationGroupKey();
1136  }
1137 
1138  //may already be loaded, but that's ok, load anyway to be sure
1139  loadConfigurationGroup(theBackboneGroup_,*theBackboneGroupKey_);
1140 
1141  return *theBackboneGroupKey_;
1142 }
1143 
1144 //=============================================================ConfigurationManager=================
1145 // verifies that all backbone members are loaded and have the same version
1147 //ConfigurationVersion ConfigurationManager::getConfigurationBackboneVersion(void)
1148 //{
1149 // //check versions match
1150 // //check all except version aliases since it is always latest
1151 // ConfigurationVersion v = getConfigurationByName(*(backboneMemberNames_.begin()))->getViewVersion();
1152 // for(const auto& name : backboneMemberNames_)
1153 // {
1154 // if(name == "VersionAliases" )
1155 // break;
1156 // if(v != getConfigurationByName(name)->getViewVersion())
1157 // {
1158 // __MOUT__ << "Backbone Versions do no match! " << v << " vs " <<
1159 // name << ":" <<
1160 // getConfigurationByName(name)->getViewVersion() << std::endl;
1161 // throw std::runtime_error("Backbone Versions do no match!");
1162 // }
1163 // }
1164 // return v;
1165 //}
1166 
1167 
1168 
1169 
1170 //Getters
1171 //==============================================================================
1172 //getConfigurationGroupKey
1173 // use backbone to determine default key for runType.
1174 // - runType translates to group key alias,
1175 // which maps to a group name and key pair
1176 // set
1177 //
1178 // return INVALID on failure
1179 // pair<group name , ConfigurationGroupKey>
1180 std::pair<std::string, ConfigurationGroupKey> ConfigurationManager::getConfigurationGroupFromAlias(std::string runType, ProgressBar* progressBar)
1181 {
1182  //steps
1183  // load active backbone
1184  // find runType in GroupAliasesConfiguration
1185  // return key
1186 
1187  if(progressBar) progressBar->step();
1188 
1189  loadConfigurationBackbone();
1190 
1191  if(progressBar) progressBar->step();
1192 
1193  try
1194  {
1195  // find runType in GroupAliasesConfiguration
1196  ConfigurationTree entry = getNode("GroupAliasesConfiguration").getNode(runType);
1197  return std::pair<std::string, ConfigurationGroupKey>(entry.getNode("GroupName").getValueAsString(), ConfigurationGroupKey(entry.getNode("GroupKey").getValueAsString()));
1198  }
1199  catch(...)
1200  {}
1201 
1202  if(progressBar) progressBar->step();
1203 
1204  return std::pair<std::string, ConfigurationGroupKey>("",ConfigurationGroupKey());
1205 }
1206 
1207 //==============================================================================
1208 // map<alias , pair<group name, ConfigurationGroupKey> >
1209 std::map<std::string, std::pair<std::string, ConfigurationGroupKey> > ConfigurationManager::getGroupAliasesConfiguration(void)
1210 {
1211  restoreActiveConfigurationGroups(); //make sure the active configuration backbone is loaded!
1212  //loadConfigurationBackbone();
1213 
1214  std::map<std::string /*alias*/,
1215  std::pair<std::string /*group name*/, ConfigurationGroupKey> > retMap;
1216 
1217  std::vector<std::pair<std::string,ConfigurationTree> > entries = getNode("GroupAliasesConfiguration").getChildren();
1218  for(auto &entryPair: entries)
1219  {
1220  retMap[entryPair.first] = std::pair<std::string, ConfigurationGroupKey>(
1221  entryPair.second.getNode("GroupName").getValueAsString(),
1222  ConfigurationGroupKey(entryPair.second.getNode("GroupKey").getValueAsString()));
1223 
1224  }
1225  return retMap;
1226 }
1227 
1228 //==============================================================================
1229 //getActiveVersions
1230 std::map<std::string, ConfigurationVersion> ConfigurationManager::getActiveVersions(void) const
1231 {
1232  std::map<std::string, ConfigurationVersion> retMap;
1233  for(auto &config:nameToConfigurationMap_)
1234  {
1235  //__MOUT__ << config.first << std::endl;
1236 
1237  //check configuration pointer is not null and that there is an active view
1238  if(config.second && config.second->isActive())
1239  {
1240  //__MOUT__ << config.first << "_v" << config.second->getViewVersion() << std::endl;
1241  retMap.insert(std::pair<std::string, ConfigurationVersion>(config.first, config.second->getViewVersion()));
1242  }
1243  }
1244  return retMap;
1245 }
1246 
1248 //const DACStream& ConfigurationManager::getDACStream(std::string fecName)
1249 //{
1250 //
1251 // //fixme/todo this is called before setupAll so it breaks!
1252 // //====================================================
1253 // const DetectorConfiguration* detectorConfiguration = __GET_CONFIG__(DetectorConfiguration);
1254 // for(auto& type : detectorConfiguration->getDetectorTypes())
1255 // theDACsConfigurations_[type] = (DACsConfigurationBase*)(getConfigurationByName(type + "DACsConfiguration"));
1256 // //====================================================
1257 //
1258 // theDACStreams_[fecName].makeStream(fecName,
1259 // __GET_CONFIG__(DetectorConfiguration),
1260 // __GET_CONFIG__(DetectorToFEConfiguration),
1261 // theDACsConfigurations_,
1262 // __GET_CONFIG__(MaskConfiguration));//, theTrimConfiguration_);
1263 //
1264 // __MOUT__ << "Done with DAC stream!" << std::endl;
1265 // return theDACStreams_[fecName];
1266 //}
1267 
1268 //==============================================================================
1269 std::shared_ptr<ConfigurationGroupKey> ConfigurationManager::makeTheConfigurationGroupKey(ConfigurationGroupKey key)
1270 {
1271  if(theConfigurationGroupKey_)
1272  {
1273  if(*theConfigurationGroupKey_ != key)
1274  destroyConfigurationGroup();
1275  else
1276  return theConfigurationGroupKey_;
1277  }
1278  return std::shared_ptr<ConfigurationGroupKey>(new ConfigurationGroupKey(key));
1279 }
1280 
1281 //==============================================================================
1282 std::string ConfigurationManager::encodeURIComponent(const std::string &sourceStr)
1283 {
1284  std::string retStr = "";
1285  char encodeStr[4];
1286  for(const auto &c:sourceStr)
1287  if(
1288  (c >= 'a' && c <= 'z') ||
1289  (c >= 'A' && c <= 'Z') ||
1290  (c >= '0' && c <= '9') )
1291  retStr += c;
1292  else
1293  {
1294  sprintf(encodeStr,"%%%2.2X",c);
1295  retStr += encodeStr;
1296  }
1297  return retStr;
1298 }
1299 
1300 
1301 
1302 
1303 
1304 
1305 
1306 
1307 
1308