1 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
2 #include "otsdaq-core/ConfigurationInterface/ConfigurationInterface.h"
3 #include "otsdaq-core/ProgressBar/ProgressBar.h"
7 #include "otsdaq-core/TableCore/TableGroupKey.h"
12 #define __MF_SUBJECT__ "ConfigurationManager"
14 const std::string ConfigurationManager::READONLY_USER =
"READONLY_USER";
16 const std::string ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME =
"XDAQContextTable";
17 const std::string ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME =
18 "XDAQApplicationTable";
19 const std::string ConfigurationManager::GROUP_ALIASES_TABLE_NAME =
"GroupAliasesTable";
20 const std::string ConfigurationManager::VERSION_ALIASES_TABLE_NAME =
21 "VersionAliasesTable";
24 const std::string ConfigurationManager::ACTIVE_GROUPS_FILENAME =
25 ((getenv(
"SERVICE_DATA_PATH") == NULL)
26 ? (std::string(getenv(
"USER_DATA")) +
"/ServiceData")
27 : (std::string(getenv(
"SERVICE_DATA_PATH")))) +
28 "/ActiveTableGroups.cfg";
29 const std::string ConfigurationManager::ALIAS_VERSION_PREAMBLE =
"ALIAS:";
30 const std::string ConfigurationManager::SCRATCH_VERSION_ALIAS =
"Scratch";
32 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT =
"Context";
33 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE =
"Backbone";
34 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_ITERATE =
"Iterate";
35 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION =
"Configuration";
36 const std::string ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN =
"Unknown";
38 const uint8_t ConfigurationManager::METADATA_COL_ALIASES = 1;
39 const uint8_t ConfigurationManager::METADATA_COL_COMMENT = 2;
40 const uint8_t ConfigurationManager::METADATA_COL_AUTHOR = 3;
41 const uint8_t ConfigurationManager::METADATA_COL_TIMESTAMP = 4;
43 const std::set<std::string> ConfigurationManager::contextMemberNames_ = {
44 ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME,
45 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME,
46 "XDAQApplicationPropertyTable",
48 "MessageFacilityTable",
49 "GatewaySupervisorTable",
51 "DesktopWindowParameterTable"};
52 const std::set<std::string> ConfigurationManager::backboneMemberNames_ = {
53 ConfigurationManager::GROUP_ALIASES_TABLE_NAME,
54 ConfigurationManager::VERSION_ALIASES_TABLE_NAME};
55 const std::set<std::string> ConfigurationManager::iterateMemberNames_ = {
58 "IterationTargetTable",
59 "IterationCommandBeginLabelTable",
60 "IterationCommandChooseFSMTable",
61 "IterationCommandConfigureAliasTable",
62 "IterationCommandConfigureGroupTable",
63 "IterationCommandExecuteFEMacroTable",
64 "IterationCommandExecuteMacroTable",
65 "IterationCommandMacroDimensionalLoopTable",
66 "IterationCommandMacroDimensionalLoopParameterTable",
67 "IterationCommandModifyGroupTable",
68 "IterationCommandRepeatLabelTable",
69 "IterationCommandRunTable"};
72 ConfigurationManager::ConfigurationManager()
75 , theConfigurationTableGroupKey_(0)
76 , theContextTableGroupKey_(0)
77 , theBackboneTableGroupKey_(0)
78 , theConfigurationTableGroup_(
"")
79 , theContextTableGroup_(
"")
80 , theBackboneTableGroup_(
"")
82 theInterface_ = ConfigurationInterface::getInstance(
false);
98 groupMetadataTable_.setTableName(
99 ConfigurationInterface::GROUP_METADATA_TABLE_NAME);
100 std::vector<TableViewColumnInfo>* colInfo =
101 groupMetadataTable_.getMockupViewP()->getColumnsInfoP();
104 TableViewColumnInfo::TYPE_UID,
107 TableViewColumnInfo::DATATYPE_NUMBER,
113 TableViewColumnInfo::DATATYPE_STRING,
117 TableViewColumnInfo::TYPE_COMMENT,
118 "CommentDescription",
119 "COMMENT_DESCRIPTION",
120 TableViewColumnInfo::DATATYPE_STRING,
124 TableViewColumnInfo::TYPE_AUTHOR,
127 TableViewColumnInfo::DATATYPE_STRING,
132 "GROUP_CREATION_TIME",
133 TableViewColumnInfo::DATATYPE_TIME,
136 auto tmpVersion = groupMetadataTable_.createTemporaryView();
137 groupMetadataTable_.setActiveView(tmpVersion);
139 groupMetadataTable_.getViewP()->addRow();
146 ConfigurationManager::ConfigurationManager(
const std::string& username)
149 username_ = username;
153 ConfigurationManager::~ConfigurationManager() { destroy(); }
159 void ConfigurationManager::init(std::string* accumulatedErrors)
161 if(accumulatedErrors)
162 *accumulatedErrors =
"";
171 restoreActiveTableGroups(accumulatedErrors ?
true :
false);
173 catch(std::runtime_error& e)
175 if(accumulatedErrors)
176 *accumulatedErrors = e.what();
188 void ConfigurationManager::restoreActiveTableGroups(
189 bool throwErrors,
const std::string& pathToActiveGroupsFile)
191 destroyTableGroup(
"",
true);
194 pathToActiveGroupsFile ==
"" ? ACTIVE_GROUPS_FILENAME : pathToActiveGroupsFile;
195 FILE* fp = fopen(fn.c_str(),
"r");
197 __COUT__ <<
"ACTIVE_GROUPS_FILENAME = " << fn << __E__;
198 __COUT__ <<
"ARTDAQ_DATABASE_URI = " << std::string(getenv(
"ARTDAQ_DATABASE_URI"))
203 __COUT_WARN__ <<
"No active groups file found at " << fn << __E__;
212 std::string groupName;
213 std::string errorStr =
"";
218 while(fgets(tmp, 500, fp))
223 sscanf(tmp,
"%s", strVal);
224 for(
unsigned int j = 0; j < strlen(strVal); ++j)
225 if(!((strVal[j] >=
'a' && strVal[j] <=
'z') ||
226 (strVal[j] >=
'A' && strVal[j] <=
'Z') ||
227 (strVal[j] >=
'0' && strVal[j] <=
'9')))
230 __COUT_INFO__ <<
"Illegal character found, so skipping!" << __E__;
241 sscanf(tmp,
"%s", strVal);
243 for(
unsigned int j = 0; j < strlen(strVal); ++j)
244 if(!((strVal[j] >=
'0' && strVal[j] <=
'9')))
248 if(groupName.size() > 3)
250 <<
"Skipping active group with illegal character in name."
262 TableGroupKey::getFullGroupString(groupName,
TableGroupKey(strVal));
266 __COUT__ <<
"illegal group according to TableGroupKey::getFullGroupString..."
279 catch(std::runtime_error& e)
281 ss <<
"Failed to load group in ConfigurationManager::init() with name '"
282 << groupName <<
"(" << strVal <<
")'" << __E__;
283 ss << e.what() << __E__;
285 errorStr += ss.str();
289 ss <<
"Failed to load group in ConfigurationManager::init() with name '"
290 << groupName <<
"(" << strVal <<
")'" << __E__;
292 errorStr += ss.str();
298 if(throwErrors && errorStr !=
"")
300 __COUT_INFO__ <<
"\n" << ss.str();
303 else if(errorStr !=
"")
304 __COUT_INFO__ <<
"\n" << ss.str();
313 void ConfigurationManager::destroyTableGroup(
const std::string& theGroup,
317 bool isContext = theGroup ==
"" || theGroup == theContextTableGroup_;
318 bool isBackbone = theGroup ==
"" || theGroup == theBackboneTableGroup_;
319 bool isIterate = theGroup ==
"" || theGroup == theIterateTableGroup_;
320 bool isConfiguration = theGroup ==
"" || theGroup == theConfigurationTableGroup_;
322 if(!isContext && !isBackbone && !isIterate && !isConfiguration)
324 __SS__ <<
"Invalid configuration group to destroy: " << theGroup << __E__;
325 __COUT_ERR__ << ss.str();
329 std::string dbgHeader = onlyDeactivate ?
"Deactivating" :
"Destroying";
333 __COUT__ << dbgHeader <<
" Context group: " << theGroup << __E__;
335 __COUT__ << dbgHeader <<
" Backbone group: " << theGroup << __E__;
337 __COUT__ << dbgHeader <<
" Iterate group: " << theGroup << __E__;
339 __COUT__ << dbgHeader <<
" Configuration group: " << theGroup << __E__;
342 std::set<std::string>::const_iterator contextFindIt, backboneFindIt, iterateFindIt;
343 for(
auto it = nameToTableMap_.begin(); it != nameToTableMap_.end();
346 contextFindIt = contextMemberNames_.find(it->first);
347 backboneFindIt = backboneMemberNames_.find(it->first);
348 iterateFindIt = iterateMemberNames_.find(it->first);
350 ((isContext && contextFindIt != contextMemberNames_.end()) ||
351 (isBackbone && backboneFindIt != backboneMemberNames_.end()) ||
352 (isIterate && iterateFindIt != iterateMemberNames_.end()) ||
353 (!isContext && !isBackbone && contextFindIt == contextMemberNames_.end() &&
354 backboneFindIt == backboneMemberNames_.end() &&
355 iterateFindIt == iterateMemberNames_.end())))
363 it->second->deactivate();
369 nameToTableMap_.erase(it++);
378 theConfigurationTableGroup_ =
"";
379 if(theConfigurationTableGroupKey_ != 0)
381 __COUT__ <<
"Destroying Configuration Key: "
382 << *theConfigurationTableGroupKey_ << __E__;
383 theConfigurationTableGroupKey_.reset();
390 theBackboneTableGroup_ =
"";
391 if(theBackboneTableGroupKey_ != 0)
393 __COUT__ <<
"Destroying Backbone Key: " << *theBackboneTableGroupKey_
395 theBackboneTableGroupKey_.reset();
400 theIterateTableGroup_ =
"";
401 if(theIterateTableGroupKey_ != 0)
403 __COUT__ <<
"Destroying Iterate Key: " << *theIterateTableGroupKey_ << __E__;
404 theIterateTableGroupKey_.reset();
409 theContextTableGroup_ =
"";
410 if(theContextTableGroupKey_ != 0)
412 __COUT__ <<
"Destroying Context Key: " << *theContextTableGroupKey_ << __E__;
413 theContextTableGroupKey_.reset();
419 void ConfigurationManager::destroy(
void)
434 const std::string& ConfigurationManager::convertGroupTypeIdToName(
int groupTypeId)
436 return groupTypeId == CONTEXT_TYPE
437 ? ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT
438 : (groupTypeId == BACKBONE_TYPE
439 ? ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE
440 : (groupTypeId == ITERATE_TYPE
441 ? ConfigurationManager::ACTIVE_GROUP_NAME_ITERATE
442 : ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION));
452 int ConfigurationManager::getTypeOfGroup(
453 const std::map<std::string /*name*/, TableVersion /*version*/>& memberMap)
455 bool isContext =
true;
456 bool isBackbone =
true;
457 bool isIterate =
true;
459 bool inContext =
false;
460 bool inBackbone =
false;
461 bool inIterate =
false;
462 unsigned int matchCount = 0;
464 for(
auto& memberPair : memberMap)
469 for(
auto& contextMemberString : contextMemberNames_)
470 if(memberPair.first == contextMemberString)
482 __SS__ <<
"This group is an incomplete match to a Context group.\n";
483 __COUT_ERR__ <<
"\n" << ss.str();
484 ss <<
"\nTo be a Context group, the members must exactly match "
485 <<
"the following members:\n";
487 for(
const auto& memberName : contextMemberNames_)
488 ss << ++i <<
". " << memberName <<
"\n";
489 ss <<
"\nThe members are as follows::\n";
491 for(
const auto& memberPairTmp : memberMap)
492 ss << ++i <<
". " << memberPairTmp.first <<
"\n";
499 for(
auto& backboneMemberString : backboneMemberNames_)
500 if(memberPair.first == backboneMemberString)
512 __SS__ <<
"This group is an incomplete match to a Backbone group.\n";
513 __COUT_ERR__ <<
"\n" << ss.str();
514 ss <<
"\nTo be a Backbone group, the members must exactly match "
515 <<
"the following members:\n";
517 for(
auto& memberName : backboneMemberNames_)
518 ss << ++i <<
". " << memberName <<
"\n";
519 ss <<
"\nThe members are as follows::\n";
521 for(
const auto& memberPairTmp : memberMap)
522 ss << ++i <<
". " << memberPairTmp.first <<
"\n";
530 for(
auto& iterateMemberString : iterateMemberNames_)
531 if(memberPair.first == iterateMemberString)
543 __SS__ <<
"This group is an incomplete match to a Iterate group.\n";
544 __COUT_ERR__ <<
"\n" << ss.str();
545 ss <<
"\nTo be a Iterate group, the members must exactly match "
546 <<
"the following members:\n";
548 for(
auto& memberName : iterateMemberNames_)
549 ss << ++i <<
". " << memberName <<
"\n";
550 ss <<
"\nThe members are as follows::\n";
552 for(
const auto& memberPairTmp : memberMap)
553 ss << ++i <<
". " << memberPairTmp.first <<
"\n";
560 if(isContext && matchCount != contextMemberNames_.size())
562 __SS__ <<
"This group is an incomplete match to a Context group: "
563 <<
" Size=" << matchCount <<
" but should be "
564 << contextMemberNames_.size() << __E__;
565 __COUT_ERR__ <<
"\n" << ss.str();
566 ss <<
"\nThe members currently are...\n";
568 for(
auto& memberPair : memberMap)
569 ss << ++i <<
". " << memberPair.first <<
"\n";
570 ss <<
"\nThe expected Context members are...\n";
572 for(
auto& memberName : contextMemberNames_)
573 ss << ++i <<
". " << memberName <<
"\n";
578 if(isBackbone && matchCount != backboneMemberNames_.size())
580 __SS__ <<
"This group is an incomplete match to a Backbone group: "
581 <<
" Size=" << matchCount <<
" but should be "
582 << backboneMemberNames_.size() << __E__;
583 __COUT_ERR__ <<
"\n" << ss.str();
584 ss <<
"\nThe members currently are...\n";
586 for(
auto& memberPair : memberMap)
587 ss << ++i <<
". " << memberPair.first <<
"\n";
588 ss <<
"\nThe expected Backbone members are...\n";
590 for(
auto& memberName : backboneMemberNames_)
591 ss << ++i <<
". " << memberName <<
"\n";
596 if(isIterate && matchCount != iterateMemberNames_.size())
598 __SS__ <<
"This group is an incomplete match to a Iterate group: "
599 <<
" Size=" << matchCount <<
" but should be "
600 << backboneMemberNames_.size() << __E__;
601 __COUT_ERR__ <<
"\n" << ss.str();
602 ss <<
"\nThe members currently are...\n";
604 for(
auto& memberPair : memberMap)
605 ss << ++i <<
". " << memberPair.first <<
"\n";
606 ss <<
"\nThe expected Iterate members are...\n";
608 for(
auto& memberName : iterateMemberNames_)
609 ss << ++i <<
". " << memberName <<
"\n";
614 return isContext ? CONTEXT_TYPE
615 : (isBackbone ? BACKBONE_TYPE
616 : (isIterate ? ITERATE_TYPE : CONFIGURATION_TYPE));
622 const std::string& ConfigurationManager::getTypeNameOfGroup(
623 const std::map<std::string /*name*/, TableVersion /*version*/>& memberMap)
625 return convertGroupTypeIdToName(getTypeOfGroup(memberMap));
634 void ConfigurationManager::dumpActiveConfiguration(
const std::string& filePath,
635 const std::string& dumpType)
637 time_t rawtime = time(0);
638 __COUT__ <<
"filePath = " << filePath << __E__;
639 __COUT__ <<
"dumpType = " << dumpType << __E__;
642 fs.open(filePath, std::fstream::out | std::fstream::trunc);
653 __SS__ <<
"Invalid file path to dump active configuration. File " << filePath
654 <<
" could not be opened!" << __E__;
655 __COUT_ERR__ << ss.str();
661 (*out) <<
"#################################" << __E__;
662 (*out) <<
"This is an ots configuration dump.\n\n" << __E__;
663 (*out) <<
"Source database is $ARTDAQ_DATABASE_URI = \t"
664 << getenv(
"ARTDAQ_DATABASE_URI") << __E__;
665 (*out) <<
"\nOriginal location of dump: \t" << filePath << __E__;
666 (*out) <<
"Type of dump: \t" << dumpType << __E__;
667 (*out) <<
"Linux time for dump: \t" << rawtime << __E__;
670 struct tm* timeinfo = localtime(&rawtime);
672 strftime(buffer, 100,
"%c %Z", timeinfo);
673 (*out) <<
"Display time for dump: \t" << buffer << __E__;
684 std::map<std::string, std::pair<std::string, TableGroupKey>> activeGroups =
685 cfgMgr->getActiveTableGroups();
687 (*out) <<
"\n\n************************" << __E__;
688 (*out) <<
"Active Groups:" << __E__;
689 for(
auto& group : activeGroups)
691 (*out) <<
"\t" << group.first <<
" := " << group.second.first <<
" ("
692 << group.second.second <<
")" << __E__;
698 std::map<std::string, TableVersion> activeTables = cfgMgr->getActiveVersions();
700 (*out) <<
"\n\n************************" << __E__;
701 (*out) <<
"Active Tables:" << __E__;
702 (*out) <<
"Active Tables count = " << activeTables.size() << __E__;
705 for(
auto& table : activeTables)
707 (*out) <<
"\t" << ++i <<
". " << table.first <<
"-v" << table.second << __E__;
713 std::map<std::string, std::pair<std::string, TableGroupKey>> activeGroups =
714 cfgMgr->getActiveTableGroups();
715 (*out) <<
"\n\n************************" << __E__;
716 (*out) <<
"Active Group Members:" << __E__;
718 for(
auto& group : activeGroups)
720 (*out) <<
"\t" << group.first <<
" := " << group.second.first <<
" ("
721 << group.second.second <<
")" << __E__;
723 if(group.second.first ==
"")
726 <<
"Empty group name. Assuming no active group." << __E__;
731 std::map<std::string , std::string > groupAliases;
732 std::string groupComment;
733 std::string groupAuthor;
734 std::string groupCreateTime;
735 time_t groupCreateTime_t;
737 cfgMgr->loadTableGroup(group.second.first,
750 (*out) <<
"\t\tGroup Comment: \t" << groupComment << __E__;
751 (*out) <<
"\t\tGroup Author: \t" << groupAuthor << __E__;
753 sscanf(groupCreateTime.c_str(),
"%ld", &groupCreateTime_t);
754 (*out) <<
"\t\tGroup Create Time: \t" << ctime(&groupCreateTime_t) << __E__;
755 (*out) <<
"\t\tGroup Aliases: \t" << StringMacros::mapToString(groupAliases)
758 (*out) <<
"\t\tMember table count = " << memberMap.size() << __E__;
759 tableCount += memberMap.size();
762 for(
auto& member : memberMap)
764 (*out) <<
"\t\t\t" << ++i <<
". " << member.first <<
"-v" << member.second
768 (*out) <<
"\nActive Group Members total table count = " << tableCount << __E__;
773 std::map<std::string, TableVersion> activeTables = cfgMgr->getActiveVersions();
775 (*out) <<
"\n\n************************" << __E__;
776 (*out) <<
"Active Table Contents (table count = " << activeTables.size()
779 for(
auto& table : activeTables)
781 (*out) <<
"\n\n=============================================================="
784 (*out) <<
"=================================================================="
787 (*out) <<
"\t" << ++i <<
". " << table.first <<
"-v" << table.second << __E__;
789 cfgMgr->nameToTableMap_.find(table.first)->second->print(*out);
793 if(dumpType ==
"GroupKeys")
795 localDumpActiveGroups(
this, out);
797 else if(dumpType ==
"TableVersions")
799 localDumpActiveTables(
this, out);
801 else if(dumpType ==
"GroupKeysAndTableVersions")
803 localDumpActiveGroups(
this, out);
804 localDumpActiveTables(
this, out);
806 else if(dumpType ==
"All")
808 localDumpActiveGroups(
this, out);
809 localDumpActiveGroupMembers(
this, out);
810 localDumpActiveTables(
this, out);
811 localDumpActiveTableContents(
this, out);
816 <<
"Invalid dump type '" << dumpType
817 <<
"' given during dumpActiveConfiguration(). Valid types are as follows:\n"
825 <<
"GroupsKeysAndTableVersions"
830 "\n\nPlease change the State Machine configuration to a valid dump type."
843 void ConfigurationManager::loadMemberMap(
844 const std::map<std::string /*name*/, TableVersion /*version*/>& memberMap)
849 for(
auto& memberPair : memberMap)
860 tmpConfigBasePtr = 0;
861 if(nameToTableMap_.find(memberPair.first) != nameToTableMap_.end())
862 tmpConfigBasePtr = nameToTableMap_[memberPair.first];
864 theInterface_->get(tmpConfigBasePtr,
873 nameToTableMap_[memberPair.first] = tmpConfigBasePtr;
874 if(nameToTableMap_[memberPair.first]->getViewP())
881 __SS__ << nameToTableMap_[memberPair.first]->getTableName()
882 <<
": View version not activated properly!";
904 void ConfigurationManager::loadTableGroup(
905 const std::string& groupName,
908 std::map<std::string, TableVersion>* groupMembers,
910 std::string* accumulatedTreeErrors,
911 std::string* groupComment,
912 std::string* groupAuthor,
913 std::string* groupCreateTime,
914 bool doNotLoadMember ,
915 std::string* groupTypeString,
916 std::map<std::string /*name*/, std::string /*alias*/>* groupAliases)
try
920 *groupComment =
"NO COMMENT FOUND";
922 *groupAuthor =
"NO AUTHOR FOUND";
924 *groupCreateTime =
"0";
926 *groupTypeString =
"UNKNOWN";
957 theInterface_->getTableGroupMembers(
958 TableGroupKey::getFullGroupString(groupName, groupKey),
960 std::map<std::string , std::string > aliasMap;
966 auto metaTablePair = memberMap.find(groupMetadataTable_.getTableName());
967 if(metaTablePair != memberMap.end())
971 memberMap.erase(metaTablePair);
974 while(groupMetadataTable_.getView().getNumberOfRows())
975 groupMetadataTable_.getViewP()->deleteRow(0);
980 theInterface_->fill(&groupMetadataTable_, metaTablePair->second);
982 catch(
const std::runtime_error& e)
984 __COUT_WARN__ <<
"Ignoring metadata error: " << e.what() << __E__;
988 __COUT_WARN__ <<
"Ignoring unknown metadata error. " << __E__;
992 if(groupMetadataTable_.getView().getNumberOfRows() != 1)
995 *groupMembers = memberMap;
997 groupMetadataTable_.print();
998 __SS__ <<
"Ignoring that groupMetadataTable_ has wrong number of rows! Must "
999 "be 1. Going with anonymous defaults."
1001 __COUT_ERR__ <<
"\n" << ss.str();
1004 while(groupMetadataTable_.getViewP()->getNumberOfRows() > 1)
1005 groupMetadataTable_.getViewP()->deleteRow(0);
1006 if(groupMetadataTable_.getViewP()->getNumberOfRows() == 0)
1007 groupMetadataTable_.getViewP()->addRow();
1010 *groupComment =
"NO COMMENT FOUND";
1012 *groupAuthor =
"NO AUTHOR FOUND";
1014 *groupCreateTime =
"0";
1019 groupType = getTypeOfGroup(memberMap);
1020 *groupTypeString = convertGroupTypeIdToName(groupType);
1028 StringMacros::getMapFromString(groupMetadataTable_.getView().getValueAsString(
1029 0, ConfigurationManager::METADATA_COL_ALIASES),
1032 *groupAliases = aliasMap;
1034 *groupComment = groupMetadataTable_.getView().getValueAsString(
1035 0, ConfigurationManager::METADATA_COL_COMMENT);
1037 *groupAuthor = groupMetadataTable_.getView().getValueAsString(
1038 0, ConfigurationManager::METADATA_COL_AUTHOR);
1040 *groupCreateTime = groupMetadataTable_.getView().getValueAsString(
1041 0, ConfigurationManager::METADATA_COL_TIMESTAMP);
1045 std::map<std::string , std::map<std::string ,
TableVersion>>
1049 __COUTV__(StringMacros::mapToString(aliasMap));
1050 versionAliases = ConfigurationManager::getVersionAliases();
1051 __COUTV__(StringMacros::mapToString(versionAliases));
1055 for(
auto& aliasPair : aliasMap)
1058 if(memberMap.find(aliasPair.first) != memberMap.end())
1060 __COUT__ <<
"Group member '" << aliasPair.first
1061 <<
"' was found in group member map!" << __E__;
1062 __COUT__ <<
"Looking for alias '" << aliasPair.second
1063 <<
"' in active version aliases..." << __E__;
1065 if(versionAliases.find(aliasPair.first) == versionAliases.end() ||
1066 versionAliases[aliasPair.first].find(aliasPair.second) ==
1067 versionAliases[aliasPair.first].end())
1069 __SS__ <<
"Group '" << groupName <<
"(" << groupKey
1070 <<
")' requires table version alias '" << aliasPair.first
1071 <<
":" << aliasPair.second
1072 <<
",' which was not found in the active Backbone!"
1077 memberMap[aliasPair.first] =
1078 versionAliases[aliasPair.first][aliasPair.second];
1079 __COUT__ <<
"Version alias translated to " << aliasPair.first
1087 *groupMembers = memberMap;
1090 progressBar->step();
1099 groupType = getTypeOfGroup(memberMap);
1100 *groupTypeString = convertGroupTypeIdToName(groupType);
1119 if(!groupTypeString)
1120 groupType = getTypeOfGroup(memberMap);
1123 __COUT__ <<
"------------------------------------- init start \t [for all "
1125 << convertGroupTypeIdToName(groupType) <<
" group '" << groupName
1126 <<
"(" << groupKey <<
")"
1131 std::string groupToDeactivate =
1132 groupType == ConfigurationManager::CONTEXT_TYPE
1133 ? theContextTableGroup_
1134 : (groupType == ConfigurationManager::BACKBONE_TYPE
1135 ? theBackboneTableGroup_
1136 : (groupType == ConfigurationManager::ITERATE_TYPE
1137 ? theIterateTableGroup_
1138 : theConfigurationTableGroup_));
1141 if(groupToDeactivate !=
"")
1145 destroyTableGroup(groupToDeactivate,
true);
1166 progressBar->step();
1170 loadMemberMap(memberMap);
1173 progressBar->step();
1175 if(accumulatedTreeErrors)
1179 getChildren(&memberMap, accumulatedTreeErrors);
1180 if(*accumulatedTreeErrors !=
"")
1182 __COUT_ERR__ <<
"Errors detected while loading Table Group: " << groupName
1183 <<
"(" << groupKey <<
"). Aborting." << __E__;
1189 progressBar->step();
1194 for(
auto& memberPair : memberMap)
1197 if(ConfigurationInterface::isVersionTrackingEnabled() &&
1198 memberPair.second.isScratchVersion())
1200 __SS__ <<
"Error while activating member Table '"
1201 << nameToTableMap_[memberPair.first]->getTableName() <<
"-v"
1202 << memberPair.second <<
" for Table Group '" << groupName
1204 <<
")'. When version tracking is enabled, Scratch views"
1205 <<
" are not allowed! Please only use unique, persistent "
1206 "versions when version tracking is enabled."
1208 __COUT_ERR__ <<
"\n" << ss.str();
1216 nameToTableMap_[memberPair.first]->init(
this);
1218 catch(std::runtime_error& e)
1220 __SS__ <<
"Error detected calling "
1221 << nameToTableMap_[memberPair.first]->getTableName()
1222 <<
".init()!\n\n " << e.what() << __E__;
1227 __SS__ <<
"Unknown Error detected calling "
1228 << nameToTableMap_[memberPair.first]->getTableName()
1229 <<
".init()!\n\n " << __E__;
1235 progressBar->step();
1244 if(groupType == ConfigurationManager::CONTEXT_TYPE)
1250 theContextTableGroup_ = groupName;
1251 theContextTableGroupKey_ =
1252 std::shared_ptr<TableGroupKey>(
new TableGroupKey(groupKey));
1254 else if(groupType == ConfigurationManager::BACKBONE_TYPE)
1259 theBackboneTableGroup_ = groupName;
1260 theBackboneTableGroupKey_ =
1261 std::shared_ptr<TableGroupKey>(
new TableGroupKey(groupKey));
1263 else if(groupType == ConfigurationManager::ITERATE_TYPE)
1269 theIterateTableGroup_ = groupName;
1270 theIterateTableGroupKey_ =
1271 std::shared_ptr<TableGroupKey>(
new TableGroupKey(groupKey));
1278 theConfigurationTableGroup_ = groupName;
1279 theConfigurationTableGroupKey_ =
1280 std::shared_ptr<TableGroupKey>(
new TableGroupKey(groupKey));
1285 progressBar->step();
1288 __COUT__ <<
"------------------------------------- init complete \t [for all "
1290 << convertGroupTypeIdToName(groupType) <<
" group '" << groupName
1291 <<
"(" << groupKey <<
")"
1297 lastFailedGroupLoad_[convertGroupTypeIdToName(groupType)] =
1298 std::pair<std::string, TableGroupKey>(groupName,
TableGroupKey(groupKey));
1304 catch(
const std::runtime_error& e)
1306 __SS__ <<
"Error occurred while loading table group '" << groupName <<
"("
1307 << groupKey <<
")': \n"
1308 << e.what() << __E__;
1309 __COUT_WARN__ << ss.str();
1310 if(accumulatedTreeErrors)
1311 *accumulatedTreeErrors += ss.str();
1317 __SS__ <<
"An unknown error occurred while loading table group '" << groupName
1318 <<
"(" << groupKey <<
")." << __E__;
1319 __COUT_WARN__ << ss.str();
1320 if(accumulatedTreeErrors)
1321 *accumulatedTreeErrors += ss.str();
1332 lastFailedGroupLoad_[ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN] =
1333 std::pair<std::string, TableGroupKey>(groupName,
TableGroupKey(groupKey));
1339 catch(
const std::runtime_error& e)
1341 __SS__ <<
"Error occurred while loading table group: " << e.what() << __E__;
1342 __COUT_WARN__ << ss.str();
1343 if(accumulatedTreeErrors)
1344 *accumulatedTreeErrors += ss.str();
1350 __SS__ <<
"An unknown error occurred while loading table group." << __E__;
1351 __COUT_WARN__ << ss.str();
1352 if(accumulatedTreeErrors)
1353 *accumulatedTreeErrors += ss.str();
1365 std::map<std::string, std::pair<std::string, TableGroupKey>>
1366 ConfigurationManager::getActiveTableGroups(
void)
const
1369 std::map<std::string, std::pair<std::string, TableGroupKey>> retMap;
1371 retMap[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT] =
1372 std::pair<std::string, TableGroupKey>(
1373 theContextTableGroup_,
1374 theContextTableGroupKey_ ? *theContextTableGroupKey_ :
TableGroupKey());
1375 retMap[ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE] =
1376 std::pair<std::string, TableGroupKey>(
1377 theBackboneTableGroup_,
1378 theBackboneTableGroupKey_ ? *theBackboneTableGroupKey_ :
TableGroupKey());
1379 retMap[ConfigurationManager::ACTIVE_GROUP_NAME_ITERATE] =
1380 std::pair<std::string, TableGroupKey>(
1381 theIterateTableGroup_,
1382 theIterateTableGroupKey_ ? *theIterateTableGroupKey_ :
TableGroupKey());
1383 retMap[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION] =
1384 std::pair<std::string, TableGroupKey>(theConfigurationTableGroup_,
1385 theConfigurationTableGroupKey_
1386 ? *theConfigurationTableGroupKey_
1392 const std::string& ConfigurationManager::getActiveGroupName(
const std::string& type)
const
1394 if(type ==
"" || type == ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION)
1395 return theConfigurationTableGroup_;
1396 if(type == ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT)
1397 return theContextTableGroup_;
1398 if(type == ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE)
1399 return theBackboneTableGroup_;
1400 if(type == ConfigurationManager::ACTIVE_GROUP_NAME_ITERATE)
1401 return theIterateTableGroup_;
1403 __SS__ <<
"Invalid type requested '" << type <<
"'" << __E__;
1404 __COUT_ERR__ << ss.str();
1409 TableGroupKey ConfigurationManager::getActiveGroupKey(
const std::string& type)
const
1411 if(type ==
"" || type == ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION)
1412 return theConfigurationTableGroupKey_ ? *theConfigurationTableGroupKey_
1414 if(type == ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT)
1415 return theContextTableGroupKey_ ? *theContextTableGroupKey_ :
TableGroupKey();
1416 if(type == ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE)
1417 return theBackboneTableGroupKey_ ? *theBackboneTableGroupKey_ :
TableGroupKey();
1418 if(type == ConfigurationManager::ACTIVE_GROUP_NAME_ITERATE)
1419 return theIterateTableGroupKey_ ? *theIterateTableGroupKey_ :
TableGroupKey();
1421 __SS__ <<
"Invalid type requested '" << type <<
"'" << __E__;
1422 __COUT_ERR__ << ss.str();
1428 const std::string& contextUID,
const std::string& applicationUID)
const
1430 return getNode(
"/" + getTableByName(XDAQ_CONTEXT_TABLE_NAME)->getTableName() +
"/" +
1436 const std::string& contextUID,
const std::string& applicationUID)
const
1438 return getNode(
"/" + getTableByName(XDAQ_CONTEXT_TABLE_NAME)->getTableName() +
"/" +
1439 contextUID +
"/LinkToApplicationTable/" + applicationUID);
1444 const std::string& contextUID,
const std::string& applicationUID)
const
1446 return getNode(
"/" + getTableByName(XDAQ_CONTEXT_TABLE_NAME)->getTableName() +
"/" +
1447 contextUID +
"/LinkToApplicationTable/" + applicationUID +
1448 "/LinkToSupervisorTable");
1453 bool doNotThrowOnBrokenUIDLinks)
const
1458 if(nodeString.length() < 1)
1460 __SS__ << (
"Invalid empty node name") << __E__;
1461 __COUT_ERR__ << ss.str();
1466 unsigned int startingIndex = 0;
1467 while(startingIndex < nodeString.length() && nodeString[startingIndex] ==
'/')
1470 std::string nodeName = nodeString.substr(
1471 startingIndex, nodeString.find(
'/', startingIndex) - startingIndex);
1473 if(nodeName.length() < 1)
1483 std::string childPath = nodeString.substr(nodeName.length() + startingIndex);
1489 if(childPath.length() > 1)
1490 return configTree.getNode(childPath, doNotThrowOnBrokenUIDLinks);
1497 std::string ConfigurationManager::getFirstPathToNode(
const ConfigurationTree& node,
1498 const std::string& startPath)
const
1502 std::string path =
"/";
1512 std::vector<std::pair<std::string, ConfigurationTree>> ConfigurationManager::getChildren(
1513 std::map<std::string, TableVersion>* memberMap,
1514 std::string* accumulatedTreeErrors)
const
1516 std::vector<std::pair<std::string, ConfigurationTree>> retMap;
1517 if(accumulatedTreeErrors)
1518 *accumulatedTreeErrors =
"";
1520 if(!memberMap || memberMap->empty())
1522 for(
auto& configPair : nameToTableMap_)
1527 if(configPair.second->isActive())
1531 if(accumulatedTreeErrors)
1535 std::vector<std::pair<std::string, ConfigurationTree>>
1536 newNodeChildren = newNode.getChildren();
1537 for(
auto& newNodeChild : newNodeChildren)
1539 std::vector<std::pair<std::string, ConfigurationTree>>
1540 twoDeepChildren = newNodeChild.second.getChildren();
1542 for(
auto& twoDeepChild : twoDeepChildren)
1547 if(twoDeepChild.second.isLinkNode() &&
1548 twoDeepChild.second.isDisconnected() &&
1549 twoDeepChild.second.getDisconnectedTableName() !=
1550 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
1551 *accumulatedTreeErrors +=
1552 "\n\nAt node '" + configPair.first +
1553 "' with entry UID '" + newNodeChild.first +
1554 "' there is a disconnected child node at link "
1556 twoDeepChild.first +
"'" +
1557 " that points to table named '" +
1558 twoDeepChild.second.getDisconnectedTableName() +
1563 catch(std::runtime_error& e)
1565 *accumulatedTreeErrors +=
1566 "\n\nAt node '" + configPair.first +
1567 "' error detected descending through children:\n" + e.what();
1572 std::pair<std::string, ConfigurationTree>(configPair.first, newNode));
1580 for(
auto& memberPair : *memberMap)
1582 auto mapIt = nameToTableMap_.find(memberPair.first);
1583 if(mapIt == nameToTableMap_.end())
1585 __SS__ <<
"Get Children with member map requires a child '"
1586 << memberPair.first <<
"' that is not present!" << __E__;
1589 if(!(*mapIt).second->isActive())
1591 __SS__ <<
"Get Children with member map requires a child '"
1592 << memberPair.first <<
"' that is not active!" << __E__;
1598 if(accumulatedTreeErrors)
1602 std::vector<std::pair<std::string, ConfigurationTree>>
1603 newNodeChildren = newNode.getChildren();
1604 for(
auto& newNodeChild : newNodeChildren)
1606 std::vector<std::pair<std::string, ConfigurationTree>>
1607 twoDeepChildren = newNodeChild.second.getChildren();
1609 for(
auto& twoDeepChild : twoDeepChildren)
1613 if(twoDeepChild.second.isLinkNode() &&
1614 twoDeepChild.second.isDisconnected() &&
1615 twoDeepChild.second.getDisconnectedTableName() !=
1616 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
1618 *accumulatedTreeErrors +=
1619 "\n\nAt node '" + memberPair.first +
1620 "' with entry UID '" + newNodeChild.first +
1621 "' there is a disconnected child node at link column "
1623 twoDeepChild.first +
"'" +
1624 " that points to table named '" +
1625 twoDeepChild.second.getDisconnectedTableName() +
1632 for(
auto& searchMemberPair : *memberMap)
1633 if(searchMemberPair.first ==
1634 twoDeepChild.second.getDisconnectedTableName())
1640 *accumulatedTreeErrors +=
1642 "\nNote: It may be safe to ignore this "
1644 "since the link's target table " +
1645 twoDeepChild.second.getDisconnectedTableName() +
1646 " is not a member of this group (and may not be "
1652 catch(std::runtime_error& e)
1654 *accumulatedTreeErrors +=
1655 "\n\nAt node '" + memberPair.first +
1656 "' error detected descending through children:\n" + e.what();
1661 std::pair<std::string, ConfigurationTree>(memberPair.first, newNode));
1673 const TableBase* ConfigurationManager::getTableByName(
const std::string& tableName)
const
1675 std::map<std::string, TableBase*>::const_iterator it;
1676 if((it = nameToTableMap_.find(tableName)) == nameToTableMap_.end())
1678 __SS__ <<
"\n\nCan not find configuration named '" << tableName
1679 <<
"'\n\n\n\nYou need to load the configuration before it can be used."
1680 <<
" It probably is missing from the member list of the Table "
1681 "Group that was loaded.\n"
1682 <<
"\nYou may need to enter wiz mode to remedy the situation, use the "
1684 <<
"\n\t StartOTS.sh --wiz"
1700 TableGroupKey ConfigurationManager::loadConfigurationBackbone()
1702 if(!theBackboneTableGroupKey_)
1704 __COUT_WARN__ <<
"getTableGroupKey() Failed! No active backbone currently."
1710 loadTableGroup(theBackboneTableGroup_, *theBackboneTableGroupKey_);
1712 return *theBackboneTableGroupKey_;
1728 std::pair<std::string, TableGroupKey> ConfigurationManager::getTableGroupFromAlias(
1729 std::string systemAlias,
ProgressBar* progressBar)
1739 progressBar->step();
1741 if(systemAlias.find(
"GROUP:") == 0)
1744 progressBar->step();
1746 unsigned int i = strlen(
"GROUP:");
1747 unsigned int j = systemAlias.find(
':', i);
1750 progressBar->step();
1752 return std::pair<std::string, TableGroupKey>(
1753 systemAlias.substr(i, j - i),
TableGroupKey(systemAlias.substr(j + 1)));
1755 return std::pair<std::string, TableGroupKey>(
"",
TableGroupKey());
1758 loadConfigurationBackbone();
1761 progressBar->step();
1767 getNode(ConfigurationManager::GROUP_ALIASES_TABLE_NAME).getNode(systemAlias);
1770 progressBar->step();
1772 return std::pair<std::string, TableGroupKey>(
1773 entry.getNode(
"GroupName").getValueAsString(),
1774 TableGroupKey(entry.getNode(
"GroupKey").getValueAsString()));
1783 progressBar->step();
1785 return std::pair<std::string, TableGroupKey>(
"",
TableGroupKey());
1789 std::map<std::string , std::pair<std::string ,
TableGroupKey>>
1790 ConfigurationManager::getActiveGroupAliases(
void)
1792 restoreActiveTableGroups();
1796 std::map<std::string ,
1800 std::vector<std::pair<std::string, ConfigurationTree>> entries =
1801 getNode(ConfigurationManager::GROUP_ALIASES_TABLE_NAME).getChildren();
1802 for(
auto& entryPair : entries)
1804 retMap[entryPair.first] = std::pair<std::string, TableGroupKey>(
1805 entryPair.second.getNode(
"GroupName").getValueAsString(),
1806 TableGroupKey(entryPair.second.getNode(
"GroupKey").getValueAsString()));
1814 std::map<std::string ,
1816 ConfigurationManager::getVersionAliases(
void)
const
1820 std::map<std::string ,
1824 std::map<std::string, TableVersion> activeVersions = getActiveVersions();
1825 std::string versionAliasesTableName =
1826 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
1827 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
1829 __SS__ <<
"Active version of VersionAliases missing!"
1830 <<
"Make sure you have a valid active Backbone Group." << __E__;
1831 __COUT_WARN__ <<
"\n" << ss.str();
1835 __COUT__ <<
"activeVersions[\"" << versionAliasesTableName
1836 <<
"\"]=" << activeVersions[versionAliasesTableName] << __E__;
1838 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
1839 getNode(versionAliasesTableName).getChildren();
1844 std::string tableName, versionAlias;
1845 for(
auto& aliasNodePair : aliasNodePairs)
1847 tableName = aliasNodePair.second.getNode(
"TableName").getValueAsString();
1848 versionAlias = aliasNodePair.second.getNode(
"VersionAlias").getValueAsString();
1850 if(retMap.find(tableName) != retMap.end() &&
1851 retMap[tableName].find(versionAlias) != retMap[tableName].end())
1856 retMap[tableName][versionAlias] =
1857 TableVersion(aliasNodePair.second.getNode(
"Version").getValueAsString());
1865 std::map<std::string, TableVersion> ConfigurationManager::getActiveVersions(
void)
const
1867 std::map<std::string, TableVersion> retMap;
1868 for(
auto& config : nameToTableMap_)
1873 if(config.second && config.second->isActive())
1877 retMap.insert(std::pair<std::string, TableVersion>(
1878 config.first, config.second->getViewVersion()));
1907 std::shared_ptr<TableGroupKey> ConfigurationManager::makeTheTableGroupKey(
1910 if(theConfigurationTableGroupKey_)
1912 if(*theConfigurationTableGroupKey_ != key)
1913 destroyTableGroup();
1915 return theConfigurationTableGroupKey_;
1917 return std::shared_ptr<TableGroupKey>(
new TableGroupKey(key));
1921 std::string ConfigurationManager::encodeURIComponent(
const std::string& sourceStr)
1923 std::string retStr =
"";
1925 for(
const auto& c : sourceStr)
1926 if((c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z') || (c >=
'0' && c <=
'9'))
1930 sprintf(encodeStr,
"%%%2.2X", c);
1931 retStr += encodeStr;
1937 const std::set<std::string>& ConfigurationManager::getContextMemberNames()
1939 return ConfigurationManager::contextMemberNames_;
1942 const std::set<std::string>& ConfigurationManager::getBackboneMemberNames()
1944 return ConfigurationManager::backboneMemberNames_;
1947 const std::set<std::string>& ConfigurationManager::getIterateMemberNames()
1949 return ConfigurationManager::iterateMemberNames_;