00001 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
00002 #include "otsdaq-core/ConfigurationInterface/ConfigurationInterface.h"
00003 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationGroupKey.h"
00004 #include "otsdaq-core/ProgressBar/ProgressBar.h"
00005
00006 #include <fstream>
00007
00008
00009 using namespace ots;
00010
00011
00012 #undef __MF_SUBJECT__
00013 #define __MF_SUBJECT__ "ConfigurationManager"
00014
00015 const std::string ConfigurationManager::READONLY_USER = "READONLY_USER";
00016
00017 const std::string ConfigurationManager::XDAQ_CONTEXT_CONFIG_NAME = "XDAQContextConfiguration";
00018
00019
00020 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";
00021 const std::string ConfigurationManager::ALIAS_VERSION_PREAMBLE = "ALIAS:";
00022 const std::string ConfigurationManager::SCRATCH_VERSION_ALIAS = "Scratch";
00023
00024 #define CORE_TABLE_INFO_FILENAME ((getenv("SERVICE_DATA_PATH") == NULL)?(std::string(getenv("USER_DATA"))+"/ServiceData"):(std::string(getenv("SERVICE_DATA_PATH")))) + "/CoreTableInfoNames.dat"
00025
00026
00027 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT = "Context";
00028 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE = "Backbone";
00029 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION = "Configuration";
00030
00031
00032
00033 ConfigurationManager::ConfigurationManager()
00034 : username_ (ConfigurationManager::READONLY_USER)
00035 , theInterface_ (0)
00036 , theConfigurationGroupKey_ (0)
00037 , theContextGroupKey_ (0)
00038 , theBackboneGroupKey_ (0)
00039 , theConfigurationGroup_ ("")
00040 , theContextGroup_ ("")
00041 , theBackboneGroup_ ("")
00042 , contextMemberNames_ ({XDAQ_CONTEXT_CONFIG_NAME,"XDAQApplicationConfiguration","DesktopIconConfiguration","MessageFacilityConfiguration","TheSupervisorConfiguration","StateMachineConfiguration","DesktopWindowParameterConfiguration"})
00043 , backboneMemberNames_ ({"GroupAliasesConfiguration","VersionAliasesConfiguration"})
00044 {
00045 theInterface_ = ConfigurationInterface::getInstance(false);
00046
00047
00048
00049 {
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 groupMetadataTable_.setConfigurationName(ConfigurationInterface::GROUP_METADATA_TABLE_NAME);
00060
00061 std::vector<ViewColumnInfo>* colInfo =
00062 groupMetadataTable_.getMockupViewP()->getColumnsInfoP();
00063
00064
00065 colInfo->push_back(ViewColumnInfo(
00066 ViewColumnInfo::TYPE_UID,
00067 "UnusedUID",
00068 "UNUSED_UID",
00069 ViewColumnInfo::DATATYPE_NUMBER,
00070 "",0
00071 ));
00072 colInfo->push_back(ViewColumnInfo(
00073 ViewColumnInfo::TYPE_COMMENT,
00074 "CommentDescription",
00075 "COMMENT_DESCRIPTION",
00076 ViewColumnInfo::DATATYPE_STRING,
00077 "",0
00078 ));
00079 colInfo->push_back(ViewColumnInfo(
00080 ViewColumnInfo::TYPE_AUTHOR,
00081 "GroupAuthor",
00082 "AUTHOR",
00083 ViewColumnInfo::DATATYPE_STRING,
00084 "",0
00085 ));
00086 colInfo->push_back(ViewColumnInfo(
00087 ViewColumnInfo::TYPE_TIMESTAMP,
00088 "GroupCreationTime",
00089 "GROUP_CREATION_TIME",
00090 ViewColumnInfo::DATATYPE_TIME,
00091 "",0
00092 ));
00093 auto tmpVersion = groupMetadataTable_.createTemporaryView();
00094 groupMetadataTable_.setActiveView(tmpVersion);
00095
00096 groupMetadataTable_.getViewP()->addRow();
00097 }
00098
00099
00100 {
00101 FILE * fp = fopen((CORE_TABLE_INFO_FILENAME).c_str(),"w");
00102 if(fp)
00103 {
00104 for(const auto &name:contextMemberNames_)
00105 fprintf(fp,"%s\n",name.c_str());
00106 for(const auto &name:backboneMemberNames_)
00107 fprintf(fp,"%s\n",name.c_str());
00108 fclose(fp);
00109 }
00110 else
00111 __MOUT__ << "Failed to open core table info file: " << CORE_TABLE_INFO_FILENAME << std::endl;
00112 }
00113
00114 init();
00115 }
00116
00117
00118 ConfigurationManager::ConfigurationManager(const std::string& username)
00119 : ConfigurationManager ()
00120 {
00121 username_ = username;
00122 }
00123
00124
00125 ConfigurationManager::~ConfigurationManager()
00126 {
00127 destroy();
00128 }
00129
00130
00131
00132
00133
00134 void ConfigurationManager::init(std::string *accumulatedErrors)
00135 {
00136 if(accumulatedErrors) *accumulatedErrors = "";
00137
00138
00139
00140
00141 if(theInterface_->getMode() == false)
00142 {
00143 try
00144 {
00145 restoreActiveConfigurationGroups(accumulatedErrors?true:false);
00146 }
00147 catch(std::runtime_error &e)
00148 {
00149 if(accumulatedErrors) *accumulatedErrors = e.what();
00150 else throw;
00151 }
00152 }
00153 }
00154
00155
00156
00157
00158
00159
00160 void ConfigurationManager::restoreActiveConfigurationGroups(bool throwErrors)
00161 {
00162 destroyConfigurationGroup("",true);
00163
00164 std::string fn = ACTIVE_GROUP_FILENAME;
00165 FILE *fp = fopen(fn.c_str(),"r");
00166
00167 __MOUT__ << "ACTIVE_GROUP_FILENAME = " << ACTIVE_GROUP_FILENAME << std::endl;
00168
00169 if(!fp) return;
00170
00171 __MOUT__ << "throwErrors: " << throwErrors << std::endl;
00172
00173 char tmp[500];
00174 char strVal[500];
00175
00176 std::string groupName;
00177 std::string errorStr = "";
00178
00179 for(int i=0;i<3;++i)
00180 {
00181 fgets(tmp,500,fp);
00182 sscanf(tmp,"%s",strVal);
00183 groupName = strVal;
00184 fgets(tmp,500,fp);
00185 sscanf(tmp,"%s",strVal);
00186 try
00187 {
00188
00189 loadConfigurationGroup(groupName,ConfigurationGroupKey(strVal),true);
00190 }
00191 catch(std::runtime_error &e)
00192 {
00193 __SS__ << "Failed to load config group in ConfigurationManager::init() with name '" <<
00194 groupName << "_v" << strVal << "'" << std::endl;
00195 ss << e.what() << std::endl;
00196
00197 __MOUT_INFO__ << "\n" << ss.str();
00198 errorStr += ss.str();
00199 }
00200 catch(...)
00201 {
00202 __SS__ << "Failed to load config group in ConfigurationManager::init() with name '" <<
00203 groupName << "_v" << strVal << "'" << std::endl;
00204
00205 __MOUT_INFO__ << "\n" << ss.str();
00206 errorStr += ss.str();
00207 }
00208 }
00209
00210 fclose(fp);
00211
00212 if(throwErrors && errorStr != "")
00213 throw std::runtime_error(errorStr);
00214 }
00215
00216
00217
00218
00219
00220
00221 void ConfigurationManager::destroyConfigurationGroup(const std::string& theGroup, bool onlyDeactivate)
00222 {
00223
00224 bool isContext = theGroup == "" || theGroup == theContextGroup_;
00225 bool isBackbone = theGroup == "" || theGroup == theBackboneGroup_;
00226 bool isConfiguration = theGroup == "" || theGroup == theConfigurationGroup_;
00227
00228 if(!isContext && !isBackbone && !isConfiguration)
00229 {
00230 __MOUT__ << "Invalid configuration group to destroy: " << theGroup << std::endl;
00231 throw std::runtime_error("Invalid configuration group to destroy!");
00232 }
00233
00234 std::string dbgHeader = onlyDeactivate?"Deactivating":"Destroying";
00235 if(isContext)
00236 __MOUT__ << dbgHeader << " Context group: " << theGroup << std::endl;
00237 if(isBackbone)
00238 __MOUT__ << dbgHeader << " Backbone group: " << theGroup << std::endl;
00239 if(isConfiguration)
00240 __MOUT__ << dbgHeader << " Configuration group: " << theGroup << std::endl;
00241
00242
00243 std::set<std::string>::const_iterator contextFindIt, backboneFindIt;
00244 for(auto it = nameToConfigurationMap_.begin(); it != nameToConfigurationMap_.end(); )
00245 {
00246 contextFindIt = contextMemberNames_.find(it->first);
00247 backboneFindIt = backboneMemberNames_.find(it->first);
00248 if(theGroup == "" || ( (isContext && contextFindIt != contextMemberNames_.end()) ||
00249 (isBackbone && backboneFindIt != backboneMemberNames_.end()) ||
00250 (!isContext && !isBackbone &&
00251 contextFindIt == contextMemberNames_.end() &&
00252 backboneFindIt == backboneMemberNames_.end())))
00253 {
00254
00255
00256
00257
00258
00259 if(onlyDeactivate)
00260 {
00261 it->second->deactivate();
00262 ++it;
00263 }
00264 else
00265 {
00266 delete it->second;
00267 nameToConfigurationMap_.erase(it++);
00268 }
00269 }
00270 else
00271 ++it;
00272 }
00273
00274 if(isConfiguration)
00275 {
00276 theConfigurationGroup_ = "";
00277 if(theConfigurationGroupKey_ != 0)
00278 {
00279 __MOUT__ << "Destroying Configuration Key: " << *theConfigurationGroupKey_ << std::endl;
00280 theConfigurationGroupKey_.reset();
00281 }
00282
00283
00284 }
00285 if(isBackbone)
00286 {
00287 theBackboneGroup_ = "";
00288 if(theBackboneGroupKey_ != 0)
00289 {
00290 __MOUT__ << "Destroying Backbone Key: " << *theBackboneGroupKey_ << std::endl;
00291 theBackboneGroupKey_.reset();
00292 }
00293 }
00294 if(isContext)
00295 {
00296 theContextGroup_ = "";
00297 if(theContextGroupKey_ != 0)
00298 {
00299 __MOUT__ << "Destroying Context Key: " << *theContextGroupKey_ << std::endl;
00300 theContextGroupKey_.reset();
00301 }
00302 }
00303 }
00304
00305
00306 void ConfigurationManager::destroy(void)
00307 {
00308
00309
00310
00311 destroyConfigurationGroup();
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321 const std::string& ConfigurationManager::convertGroupTypeIdToName(int groupTypeId)
00322 {
00323 return groupTypeId==CONTEXT_TYPE?
00324 ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT:
00325 (groupTypeId==BACKBONE_TYPE?
00326 ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE:
00327 ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION);
00328 }
00329
00330
00331
00332
00333
00334
00335
00336 int ConfigurationManager::getTypeOfGroup(
00337 const std::string &configGroupName,
00338 ConfigurationGroupKey configGroupKey,
00339 const std::map<std::string /*name*/, ConfigurationVersion /*version*/> &memberMap)
00340 {
00341
00342 bool isContext = true;
00343 bool isBackbone = true;
00344 bool inGroup;
00345 bool inContext = false;
00346 bool inBackbone = false;
00347 unsigned int matchCount = 0;
00348
00349 for(auto &memberPair:memberMap)
00350 {
00351
00352 inGroup = false;
00353 for(auto &contextMemberString:contextMemberNames_)
00354
00355
00356 if(memberPair.first == contextMemberString)
00357 {
00358 inGroup = true;
00359 inContext = true;
00360 ++matchCount;
00361 break;
00362 }
00363 if(!inGroup)
00364 {
00365 isContext = false;
00366 if(inContext)
00367 {
00368 __SS__ << "This group is an incomplete match to contextMemberNames_: " +
00369 configGroupName + "(" + configGroupKey.toString() + ")\n";
00370 ss << "\nTo be a Context group, the members must exactly match" <<
00371 "the following members:\n";
00372 int i = 0;
00373 for(auto &memberName:contextMemberNames_)
00374 ss << ++i << ". " << memberName << "\n";
00375 __MOUT_ERR__ << "\n" << ss.str();
00376 throw std::runtime_error(ss.str());
00377 }
00378 }
00379
00380 inGroup = false;
00381 for(auto &backboneMemberString:backboneMemberNames_)
00382
00383
00384 if(memberPair.first == backboneMemberString)
00385 {
00386 inGroup = true;
00387 inBackbone = true;
00388 ++matchCount;
00389 break;
00390 }
00391 if(!inGroup)
00392 {
00393 isBackbone = false;
00394 if(inBackbone)
00395 {
00396 __SS__ << "This group is an incomplete match to backboneMemberNames_: " +
00397 configGroupName + "(" + configGroupKey.toString() + ")\n";
00398 ss << "\nTo be a Backbone group, the members must exactly match" <<
00399 "the following members:\n";
00400 int i = 0;
00401 for(auto &memberName:backboneMemberNames_)
00402 ss << ++i << ". " << memberName << "\n";
00403 __MOUT_ERR__ << "\n" << ss.str();
00404 throw std::runtime_error(ss.str());
00405 }
00406 }
00407
00408 }
00409
00410 if(isContext && matchCount != contextMemberNames_.size())
00411 {
00412 __SS__ << "This group is an incomplete match to contextMemberNames_: " +
00413 configGroupName + "(" + configGroupKey.toString() + ")" +
00414 " Size=" << matchCount << " but should be " << contextMemberNames_.size() <<
00415 std::endl;
00416 ss << "\nThe members currently are...\n";
00417 int i = 0;
00418 for(auto &memberPair:memberMap)
00419 ss << ++i << ". " << memberPair.first << "\n";
00420 ss << "\nThe expected Context members are...\n";
00421 i = 0;
00422 for(auto &memberName:contextMemberNames_)
00423 ss << ++i << ". " << memberName << "\n";
00424 __MOUT_ERR__ << "\n" << ss.str();
00425 throw std::runtime_error(ss.str());
00426 }
00427
00428 if(isBackbone && matchCount != backboneMemberNames_.size())
00429 {
00430 __SS__ << "This group is an incomplete match to backboneMemberNames_: " +
00431 configGroupName + "(" + configGroupKey.toString() + ")" +
00432 " Size=" << matchCount << " but should be " << backboneMemberNames_.size() <<
00433 std::endl;
00434 ss << "\nThe members currently are...\n";
00435 int i = 0;
00436 for(auto &memberPair:memberMap)
00437 ss << ++i << ". " << memberPair.first << "\n";
00438 ss << "\nThe expected Backbone members are...\n";
00439 i = 0;
00440 for(auto &memberName:backboneMemberNames_)
00441 ss << ++i << ". " << memberName << "\n";
00442 __MOUT_ERR__ << "\n" << ss.str();
00443 throw std::runtime_error(ss.str());
00444 }
00445
00446 return isContext?CONTEXT_TYPE:(isBackbone?BACKBONE_TYPE:CONFIGURATION_TYPE);
00447 }
00448
00449
00450
00451
00452
00453
00454
00455 const std::string& ConfigurationManager::getTypeNameOfGroup(
00456 const std::string &configGroupName,
00457 ConfigurationGroupKey configGroupKey,
00458 const std::map<std::string /*name*/, ConfigurationVersion /*version*/> &memberMap)
00459 {
00460 return convertGroupTypeIdToName(getTypeOfGroup(configGroupName, configGroupKey, memberMap));
00461 }
00462
00463
00464
00465
00466 void ConfigurationManager::dumpActiveConfiguration(
00467 const std::string &filePath, const std::string &dumpType) const
00468 {
00469 time_t rawtime = time(0);
00470 __MOUT__ << "filePath = " << filePath << std::endl;
00471 __MOUT__ << "dumpType = " << dumpType << std::endl;
00472
00473
00474 std::ofstream fs;
00475 fs.open(filePath, std::fstream::out | std::fstream::trunc);
00476
00477 std::ostream *out;
00478
00479
00480 if(fs.is_open())
00481 out = &fs;
00482 else
00483 out = &(std::cout);
00484
00485
00486 (*out) << "#################################" << std::endl;
00487 (*out) << "This is an ots configuration dump.\n\n" << std::endl;
00488 (*out) << "Source database is $ARTDAQ_DATABASE_URI = \t" << getenv("ARTDAQ_DATABASE_URI") << std::endl;
00489 (*out) << "\nOriginal location of dump: \t" << filePath << std::endl;
00490 (*out) << "Type of dump: \t" << dumpType << std::endl;
00491 (*out) << "Linux time for dump: \t" << rawtime << std::endl;
00492
00493 {
00494 struct tm * timeinfo = localtime (&rawtime);
00495 char buffer [100];
00496 strftime(buffer,100,"%c %Z",timeinfo);
00497 (*out) << "Display time for dump: \t" << buffer << std::endl;
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507 auto localDumpActiveGroups = [](const ConfigurationManager *cfgMgr, std::ostream *out) {
00508 std::map<std::string, std::pair<std::string, ConfigurationGroupKey>> activeGroups =
00509 cfgMgr->getActiveConfigurationGroups();
00510
00511 (*out) << "\n\n************************" << std::endl;
00512 (*out) << "Active Groups:" << std::endl;
00513 for(auto &group:activeGroups)
00514 {
00515 (*out) << "\t" << group.first << " := " <<
00516 group.second.first << " (" <<
00517 group.second.second << ")" << std::endl;
00518 }
00519 };
00520
00521 auto localDumpActiveTables = [](const ConfigurationManager *cfgMgr, std::ostream *out) {
00522 std::map<std::string, ConfigurationVersion> activeTables =
00523 cfgMgr->getActiveVersions();
00524
00525 (*out) << "\n\n************************" << std::endl;
00526 (*out) << "Active Tables:" << std::endl;
00527 (*out) << "Active Tables count = " << activeTables.size() << std::endl;
00528 for(auto &table:activeTables)
00529 {
00530 (*out) << "\t" << table.first << "-v" <<
00531 table.second << std::endl;
00532 }
00533 };
00534
00535 auto localDumpActiveGroupMembers = [](const ConfigurationManager *cfgMgr, std::ostream *out) {
00536 std::map<std::string, std::pair<std::string, ConfigurationGroupKey>> activeGroups =
00537 cfgMgr->getActiveConfigurationGroups();
00538 (*out) << "\n\n************************" << std::endl;
00539 (*out) << "Active Group Members:" << std::endl;
00540 int tableCount = 0;
00541 for(auto &group:activeGroups)
00542 {
00543 (*out) << "\t" << group.first << " := " <<
00544 group.second.first << " (" <<
00545 group.second.second << ")" << std::endl;
00546
00547 std::map<std::string , ConfigurationVersion > memberMap =
00548 cfgMgr->theInterface_->getConfigurationGroupMembers(
00549 ConfigurationGroupKey::getFullGroupString(
00550 group.second.first,
00551 group.second.second));
00552
00553 (*out) << "\tMember count = " << memberMap.size() << std::endl;
00554 tableCount += memberMap.size();
00555
00556 for(auto &member:memberMap)
00557 {
00558 (*out) << "\t\t" << member.first << "-v" <<
00559 member.second << std::endl;
00560 }
00561 }
00562 (*out) << "Active Group Members total count = " << tableCount << std::endl;
00563 };
00564
00565 auto localDumpActiveTableContents = [](const ConfigurationManager *cfgMgr, std::ostream *out) {
00566 std::map<std::string, ConfigurationVersion> activeTables =
00567 cfgMgr->getActiveVersions();
00568
00569 (*out) << "\n\n************************" << std::endl;
00570 (*out) << "Active Table Contents:" << std::endl;
00571 for(auto &table:activeTables)
00572 {
00573 (*out) << "\t" << table.first << "-v" <<
00574 table.second << std::endl;
00575
00576 cfgMgr->nameToConfigurationMap_.find(table.first)->second->print(*out);
00577 }
00578 };
00579
00580
00581
00582 if(dumpType == "GroupKeys")
00583 {
00584 localDumpActiveGroups(this,out);
00585 }
00586 else if(dumpType == "TableVersions")
00587 {
00588 localDumpActiveTables(this,out);
00589 }
00590 else if(dumpType == "GroupKeysAndTableVersions")
00591 {
00592 localDumpActiveGroups(this,out);
00593 localDumpActiveTables(this,out);
00594 }
00595 else if(dumpType == "All")
00596 {
00597 localDumpActiveGroups(this,out);
00598 localDumpActiveGroupMembers(this,out);
00599 localDumpActiveTables(this,out);
00600 localDumpActiveTableContents(this,out);
00601 }
00602 else
00603 {
00604 __SS__ << "Invalid dump type '" << dumpType <<
00605 "' given during dumpActiveConfiguration(). Valid types are as follows:\n" <<
00606
00607
00608 "GroupKeys" << ", " <<
00609 "TableVersions" << ", " <<
00610 "GroupsKeysAndTableVersions" << ", " <<
00611 "All" <<
00612
00613 "\n\nPlease change the State Machine configuration to a valid dump type." <<
00614 std::endl;
00615 throw std::runtime_error(ss.str());
00616 }
00617
00618 if(fs.is_open())
00619 fs.close();
00620 }
00621
00622
00623
00624
00625
00626 void ConfigurationManager::loadMemberMap(
00627 const std::map<std::string /*name*/, ConfigurationVersion /*version*/> &memberMap)
00628 {
00629 ConfigurationBase *tmpConfigBasePtr;
00630
00631
00632 for(auto &memberPair:memberMap)
00633 {
00634
00635
00636
00637
00638
00639
00640
00641
00642 tmpConfigBasePtr = 0;
00643 if(nameToConfigurationMap_.find(memberPair.first) != nameToConfigurationMap_.end())
00644 tmpConfigBasePtr = nameToConfigurationMap_[memberPair.first];
00645
00646 theInterface_->get(tmpConfigBasePtr,
00647 memberPair.first,
00648 0,
00649 0,
00650 false,
00651 memberPair.second,
00652 false
00653 );
00654
00655 nameToConfigurationMap_[memberPair.first] = tmpConfigBasePtr;
00656 if(nameToConfigurationMap_[memberPair.first]->getViewP())
00657 {
00658
00659 }
00660 else
00661 {
00662 __SS__ << nameToConfigurationMap_[memberPair.first]->getConfigurationName() <<
00663 ": View version not activated properly!";
00664 throw std::runtime_error(ss.str());
00665 }
00666 }
00667 }
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 std::map<std::string, ConfigurationVersion> ConfigurationManager::loadConfigurationGroup(
00685 const std::string &configGroupName,
00686 ConfigurationGroupKey configGroupKey,
00687 bool doActivate,
00688 ProgressBar *progressBar,
00689 std::string *accumulatedTreeErrors,
00690 std::string *groupComment,
00691 std::string *groupAuthor,
00692 std::string *groupCreateTime,
00693 bool doNotLoadMember)
00694 {
00695 if(accumulatedTreeErrors) *accumulatedTreeErrors = "";
00696 if(groupComment) *groupComment = "";
00697 if(groupAuthor) *groupAuthor = "";
00698 if(groupCreateTime) *groupCreateTime = "";
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 __MOUT_INFO__ << "Loading Configuration Group: " << configGroupName <<
00713 "(" << configGroupKey << ")" << std::endl;
00714
00715 std::map<std::string , ConfigurationVersion > memberMap =
00716 theInterface_->getConfigurationGroupMembers(
00717 ConfigurationGroupKey::getFullGroupString(configGroupName,configGroupKey),
00718 true);
00719
00720
00721 if(progressBar) progressBar->step();
00722
00723
00724 auto metaTablePair = memberMap.find(groupMetadataTable_.getConfigurationName());
00725 if(metaTablePair !=
00726 memberMap.end())
00727 {
00728 __MOUT__ << "Found group meta data. v" <<
00729 metaTablePair->second << std::endl;
00730
00731 while(groupMetadataTable_.getView().getNumberOfRows())
00732 groupMetadataTable_.getViewP()->deleteRow(0);
00733 theInterface_->fill(&groupMetadataTable_,metaTablePair->second);
00734
00735 if(groupMetadataTable_.getView().getNumberOfRows() != 1)
00736 {
00737 groupMetadataTable_.print();
00738 __SS__ << "groupMetadataTable_ has wrong number of rows! Must be 1." << std::endl;
00739 __MOUT_ERR__ << "\n" << ss.str();
00740 throw std::runtime_error(ss.str());
00741 }
00742
00743
00744 memberMap.erase(metaTablePair);
00745
00746
00747 if(groupComment) *groupComment = groupMetadataTable_.getView().getValueAsString(0,1);
00748 if(groupAuthor) *groupAuthor = groupMetadataTable_.getView().getValueAsString(0,2);
00749 if(groupCreateTime) *groupCreateTime = groupMetadataTable_.getView().getValueAsString(0,3);
00750 }
00751
00752 if(progressBar) progressBar->step();
00753
00754 __MOUT__ << "memberMap loaded size = " << memberMap.size() << std::endl;
00755
00756 if(doNotLoadMember) return memberMap;
00757
00758 int groupType = -1;
00759 if(doActivate)
00760 {
00761
00762 groupType = getTypeOfGroup(configGroupName,configGroupKey,memberMap);
00763
00764 std::string groupToDeactivate =
00765 groupType==CONTEXT_TYPE?theContextGroup_:
00766 (groupType==BACKBONE_TYPE?theBackboneGroup_:theConfigurationGroup_);
00767
00768
00769 if(groupToDeactivate != "")
00770 {
00771 __MOUT__ << "groupToDeactivate '" << groupToDeactivate << "'" << std::endl;
00772 destroyConfigurationGroup(groupToDeactivate,true);
00773 }
00774
00775
00776
00777
00778
00779
00780
00781 }
00782
00783 if(progressBar) progressBar->step();
00784
00785 __MOUT__ << "Activating chosen group:" << std::endl;
00786
00787
00788 loadMemberMap(memberMap);
00789
00790 if(progressBar) progressBar->step();
00791
00792 if(accumulatedTreeErrors)
00793 {
00794 __MOUT__ << "Checking chosen group for tree errors..." << std::endl;
00795
00796 getChildren(&memberMap, accumulatedTreeErrors);
00797 if(*accumulatedTreeErrors != "")
00798 {
00799 __MOUT_ERR__ << "Errors detected while loading Configuration Group: " << configGroupName <<
00800 "(" << configGroupKey << "). Aborting." << std::endl;
00801 return memberMap;
00802 }
00803 }
00804
00805 if(progressBar) progressBar->step();
00806
00807
00808
00809 if(doActivate)
00810 for(auto &memberPair:memberMap)
00811 {
00812
00813 if(ConfigurationInterface::isVersionTrackingEnabled() &&
00814 memberPair.second.isScratchVersion())
00815 {
00816 __SS__ << "Error while activating member Table '" <<
00817 nameToConfigurationMap_[memberPair.first]->getConfigurationName() <<
00818 "-v" << memberPair.second <<
00819 " for Configuration Group '" << configGroupName <<
00820 "(" << configGroupKey << ")'. When version tracking is enabled, Scratch views" <<
00821 " are not allowed! Please only use unique, persistent versions when version tracking is enabled."
00822 << std::endl;
00823 __MOUT_ERR__ << "\n" << ss.str();
00824 throw std::runtime_error(ss.str());
00825 }
00826
00827
00828
00829
00830 try
00831 {
00832 nameToConfigurationMap_[memberPair.first]->init(this);
00833 }
00834 catch(std::runtime_error& e)
00835 {
00836 __SS__ << "Error detected calling " <<
00837 nameToConfigurationMap_[memberPair.first]->getConfigurationName() <<
00838 ".init()!\n\n " << e.what() << std::endl;
00839 throw std::runtime_error(ss.str());
00840 }
00841 catch(...)
00842 {
00843 __SS__ << "Error detected calling " <<
00844 nameToConfigurationMap_[memberPair.first]->getConfigurationName() <<
00845 ".init()!\n\n " << std::endl;
00846 throw std::runtime_error(ss.str());
00847 }
00848
00849 }
00850
00851 if(progressBar) progressBar->step();
00852
00853
00854
00855
00856
00857 if(doActivate)
00858 {
00859 if(groupType == CONTEXT_TYPE)
00860 {
00861 __MOUT_INFO__ << "Context Configuration Group loaded: " << configGroupName <<
00862 "(" << configGroupKey << ")" << std::endl;
00863 theContextGroup_ = configGroupName;
00864 theContextGroupKey_ = std::shared_ptr<ConfigurationGroupKey>(new ConfigurationGroupKey(configGroupKey));
00865 }
00866 else if(groupType == BACKBONE_TYPE)
00867 {
00868 __MOUT_INFO__ << "Backbone Configuration Group loaded: " << configGroupName <<
00869 "(" << configGroupKey << ")" << std::endl;
00870 theBackboneGroup_ = configGroupName;
00871 theBackboneGroupKey_ = std::shared_ptr<ConfigurationGroupKey>(new ConfigurationGroupKey(configGroupKey));
00872 }
00873 else
00874 {
00875 __MOUT_INFO__ << "The Configuration Group loaded: " << configGroupName <<
00876 "(" << configGroupKey << ")" << std::endl;
00877 theConfigurationGroup_ = configGroupName;
00878 theConfigurationGroupKey_ = std::shared_ptr<ConfigurationGroupKey>(new ConfigurationGroupKey(configGroupKey));
00879 }
00880 }
00881
00882 if(progressBar) progressBar->step();
00883 __MOUT__ << "Load complete." << std::endl;
00884 return memberMap;
00885 }
00886
00887
00888
00889
00890
00891
00892
00893
00894 std::map<std::string, std::pair<std::string, ConfigurationGroupKey> > ConfigurationManager::getActiveConfigurationGroups(void) const
00895 {
00896
00897 std::map<std::string, std::pair<std::string, ConfigurationGroupKey> > retMap;
00898
00899 retMap[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT] =
00900 std::pair<std::string,ConfigurationGroupKey>(theContextGroup_ ,theContextGroupKey_ ?*theContextGroupKey_ : ConfigurationGroupKey());
00901 retMap[ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE] =
00902 std::pair<std::string,ConfigurationGroupKey>(theBackboneGroup_ ,theBackboneGroupKey_ ?*theBackboneGroupKey_ : ConfigurationGroupKey());
00903 retMap[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION] =
00904 std::pair<std::string,ConfigurationGroupKey>(theConfigurationGroup_,theConfigurationGroupKey_?*theConfigurationGroupKey_: ConfigurationGroupKey());
00905 return retMap;
00906 }
00907
00908
00909 ConfigurationTree ConfigurationManager::getSupervisorConfigurationNode(
00910 const std::string &contextUID, const std::string &applicationUID) const
00911 {
00912 return getNode(
00913 "/" + getConfigurationByName(XDAQ_CONTEXT_CONFIG_NAME)->getConfigurationName() +
00914 "/" + contextUID +
00915 "/LinkToApplicationConfiguration/" + applicationUID +
00916 "/LinkToSupervisorConfiguration");
00917 }
00918
00919
00920 ConfigurationTree ConfigurationManager::getNode(const std::string& nodeString) const
00921 {
00922
00923
00924
00925 if(nodeString.length() < 1) throw std::runtime_error("Invalid empty node name");
00926
00927 bool startingSlash = (nodeString[0] == '/');
00928
00929 std::string nodeName = nodeString.substr(startingSlash?1:0, nodeString.find('/',1)-(startingSlash?1:0));
00930
00931 if(nodeName.length() < 1) throw std::runtime_error("Invalid node name: " + nodeName);
00932
00933 std::string childPath = nodeString.substr(nodeName.length() + (startingSlash?1:0));
00934
00935
00936
00937 ConfigurationTree configTree(this, getConfigurationByName(nodeName));
00938 if(childPath.length() > 1)
00939 return configTree.getNode(childPath);
00940 else
00941 return configTree;
00942 }
00943
00944
00945
00946 std::string ConfigurationManager::getFirstPathToNode(const ConfigurationTree &node, const std::string &startPath) const
00947
00948 {
00949 std::string path = "/";
00950 return path;
00951 }
00952
00953
00954
00955
00956
00957
00958
00959 std::vector<std::pair<std::string,ConfigurationTree> > ConfigurationManager::getChildren(
00960 std::map<std::string, ConfigurationVersion> *memberMap,
00961 std::string *accumulatedTreeErrors) const
00962 {
00963 std::vector<std::pair<std::string,ConfigurationTree> > retMap;
00964 if(accumulatedTreeErrors) *accumulatedTreeErrors = "";
00965
00966 if(!memberMap || memberMap->empty())
00967 {
00968 for(auto &configPair:nameToConfigurationMap_)
00969 {
00970
00971
00972 if(configPair.second->isActive())
00973 {
00974 ConfigurationTree newNode(this, configPair.second);
00975
00976
00977 if(accumulatedTreeErrors)
00978 {
00979 try
00980 {
00981 std::vector<std::pair<std::string,ConfigurationTree> > newNodeChildren =
00982 newNode.getChildren();
00983 for(auto &newNodeChild: newNodeChildren)
00984 {
00985 std::vector<std::pair<std::string,ConfigurationTree> > twoDeepChildren =
00986 newNodeChild.second.getChildren();
00987
00988 for(auto &twoDeepChild: twoDeepChildren)
00989 {
00990
00991
00992 if(twoDeepChild.second.isLinkNode() &&
00993 twoDeepChild.second.isDisconnected() &&
00994 twoDeepChild.second.getDisconnectedTableName() !=
00995 ViewColumnInfo::DATATYPE_LINK_DEFAULT)
00996 *accumulatedTreeErrors += "\n\nAt node '" +
00997 configPair.first + "' with entry UID '" +
00998 newNodeChild.first + "' there is a disconnected child node at link column '" +
00999 twoDeepChild.first + "'" +
01000 " that points to table named '" +
01001 twoDeepChild.second.getDisconnectedTableName() +
01002 "' ...";
01003 }
01004 }
01005 }
01006 catch(std::runtime_error &e)
01007 {
01008 *accumulatedTreeErrors += "\n\nAt node '" +
01009 configPair.first + "' error detected descending through children:\n" +
01010 e.what();
01011 }
01012 }
01013
01014 retMap.push_back(std::pair<std::string,ConfigurationTree>(configPair.first,
01015 newNode));
01016 }
01017
01018
01019 }
01020 }
01021 else
01022 {
01023
01024 for(auto &memberPair: *memberMap)
01025 {
01026 auto mapIt = nameToConfigurationMap_.find(memberPair.first);
01027 if(mapIt == nameToConfigurationMap_.end())
01028 {
01029 __SS__ << "Get Children with member map requires a child '" <<
01030 memberPair.first << "' that is not present!" << std::endl;
01031 throw std::runtime_error(ss.str());
01032 }
01033 if(!(*mapIt).second->isActive())
01034 {
01035 __SS__ << "Get Children with member map requires a child '" <<
01036 memberPair.first << "' that is not active!" << std::endl;
01037 throw std::runtime_error(ss.str());
01038 }
01039
01040 ConfigurationTree newNode(this, (*mapIt).second);
01041
01042 if(accumulatedTreeErrors)
01043 {
01044 try
01045 {
01046 std::vector<std::pair<std::string,ConfigurationTree> > newNodeChildren =
01047 newNode.getChildren();
01048 for(auto &newNodeChild: newNodeChildren)
01049 {
01050 std::vector<std::pair<std::string,ConfigurationTree> > twoDeepChildren =
01051 newNodeChild.second.getChildren();
01052
01053 for(auto &twoDeepChild: twoDeepChildren)
01054 {
01055
01056
01057 if(twoDeepChild.second.isLinkNode() &&
01058 twoDeepChild.second.isDisconnected() &&
01059 twoDeepChild.second.getDisconnectedTableName() !=
01060 ViewColumnInfo::DATATYPE_LINK_DEFAULT)
01061 {
01062 *accumulatedTreeErrors += "\n\nAt node '" +
01063 memberPair.first + "' with entry UID '" +
01064 newNodeChild.first + "' there is a disconnected child node at link column '" +
01065 twoDeepChild.first + "'" +
01066 " that points to table named '" +
01067 twoDeepChild.second.getDisconnectedTableName() +
01068 "' ...";
01069
01070
01071
01072 bool found = false;
01073 for(auto &searchMemberPair: *memberMap)
01074 if(searchMemberPair.first ==
01075 twoDeepChild.second.getDisconnectedTableName())
01076 { found = true; break;}
01077 if(!found)
01078 *accumulatedTreeErrors +=
01079 std::string("\nNote: It may be safe to ignore this error ") +
01080 "since the link's target table " +
01081 twoDeepChild.second.getDisconnectedTableName() +
01082 " is not a member of this group (and may not be loaded yet).";
01083 }
01084 }
01085 }
01086 }
01087 catch(std::runtime_error &e)
01088 {
01089 *accumulatedTreeErrors += "\n\nAt node '" +
01090 memberPair.first + "' error detected descending through children:\n" +
01091 e.what();
01092 }
01093 }
01094
01095 retMap.push_back(std::pair<std::string,ConfigurationTree>(memberPair.first,
01096 newNode));
01097 }
01098 }
01099
01100 return retMap;
01101 }
01102
01103
01104
01105
01106
01107
01108 const ConfigurationBase* ConfigurationManager::getConfigurationByName(const std::string &configurationName) const
01109 {
01110 std::map<std::string, ConfigurationBase*>::const_iterator it;
01111 if((it = nameToConfigurationMap_.find(configurationName)) == nameToConfigurationMap_.end())
01112 {
01113 __SS__ << "\n\nCan not find configuration named '" <<
01114 configurationName <<
01115 "'\n\n\n\nYou need to load the configuration before it can be used." <<
01116 " It probably is missing from the member list of the Configuration Group that was loaded.\n" <<
01117 "\nYou may need to enter wiz mode to remedy the situation, use the following:\n" <<
01118 "\n\t StartOTS.sh --wiz" <<
01119 "\n\n\n\n"
01120 << std::endl;
01121 throw std::runtime_error(ss.str());
01122 }
01123 return it->second;
01124 }
01125
01126
01127
01128
01129
01130 ConfigurationGroupKey ConfigurationManager::loadConfigurationBackbone()
01131 {
01132 if(!theBackboneGroupKey_)
01133 {
01134 __MOUT_WARN__ << "getConfigurationGroupKey() Failed! No active backbone currently." << std::endl;
01135 return ConfigurationGroupKey();
01136 }
01137
01138
01139 loadConfigurationGroup(theBackboneGroup_,*theBackboneGroupKey_);
01140
01141 return *theBackboneGroupKey_;
01142 }
01143
01144
01145
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180 std::pair<std::string, ConfigurationGroupKey> ConfigurationManager::getConfigurationGroupFromAlias(std::string runType, ProgressBar* progressBar)
01181 {
01182
01183
01184
01185
01186
01187 if(progressBar) progressBar->step();
01188
01189 loadConfigurationBackbone();
01190
01191 if(progressBar) progressBar->step();
01192
01193 try
01194 {
01195
01196 ConfigurationTree entry = getNode("GroupAliasesConfiguration").getNode(runType);
01197 return std::pair<std::string, ConfigurationGroupKey>(entry.getNode("GroupName").getValueAsString(), ConfigurationGroupKey(entry.getNode("GroupKey").getValueAsString()));
01198 }
01199 catch(...)
01200 {}
01201
01202 if(progressBar) progressBar->step();
01203
01204 return std::pair<std::string, ConfigurationGroupKey>("",ConfigurationGroupKey());
01205 }
01206
01207
01208
01209 std::map<std::string, std::pair<std::string, ConfigurationGroupKey> > ConfigurationManager::getGroupAliasesConfiguration(void)
01210 {
01211 restoreActiveConfigurationGroups();
01212
01213
01214 std::map<std::string ,
01215 std::pair<std::string , ConfigurationGroupKey> > retMap;
01216
01217 std::vector<std::pair<std::string,ConfigurationTree> > entries = getNode("GroupAliasesConfiguration").getChildren();
01218 for(auto &entryPair: entries)
01219 {
01220 retMap[entryPair.first] = std::pair<std::string, ConfigurationGroupKey>(
01221 entryPair.second.getNode("GroupName").getValueAsString(),
01222 ConfigurationGroupKey(entryPair.second.getNode("GroupKey").getValueAsString()));
01223
01224 }
01225 return retMap;
01226 }
01227
01228
01229
01230 std::map<std::string, ConfigurationVersion> ConfigurationManager::getActiveVersions(void) const
01231 {
01232 std::map<std::string, ConfigurationVersion> retMap;
01233 for(auto &config:nameToConfigurationMap_)
01234 {
01235
01236
01237
01238 if(config.second && config.second->isActive())
01239 {
01240
01241 retMap.insert(std::pair<std::string, ConfigurationVersion>(config.first, config.second->getViewVersion()));
01242 }
01243 }
01244 return retMap;
01245 }
01246
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269 std::shared_ptr<ConfigurationGroupKey> ConfigurationManager::makeTheConfigurationGroupKey(ConfigurationGroupKey key)
01270 {
01271 if(theConfigurationGroupKey_)
01272 {
01273 if(*theConfigurationGroupKey_ != key)
01274 destroyConfigurationGroup();
01275 else
01276 return theConfigurationGroupKey_;
01277 }
01278 return std::shared_ptr<ConfigurationGroupKey>(new ConfigurationGroupKey(key));
01279 }
01280
01281
01282 std::string ConfigurationManager::encodeURIComponent(const std::string &sourceStr)
01283 {
01284 std::string retStr = "";
01285 char encodeStr[4];
01286 for(const auto &c:sourceStr)
01287 if(
01288 (c >= 'a' && c <= 'z') ||
01289 (c >= 'A' && c <= 'Z') ||
01290 (c >= '0' && c <= '9') )
01291 retStr += c;
01292 else
01293 {
01294 sprintf(encodeStr,"%%%2.2X",c);
01295 retStr += encodeStr;
01296 }
01297 return retStr;
01298 }
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308