1 #include "otsdaq-core/ConfigurationInterface/ConfigurationManagerRW.h"
31 #define __MF_SUBJECT__ "ConfigurationManagerRW"
33 #define CONFIGURATION_INFO_PATH std::string(getenv("CONFIGURATION_INFO_PATH")) + "/"
34 #define CONFIGURATION_INFO_EXT "Info.xml"
38 ConfigurationManagerRW::ConfigurationManagerRW(std::string username)
41 __MOUT__ <<
"Using Config Mgr with Write Access! (for " << username <<
")" << std::endl;
45 theInterface_ = ConfigurationInterface::getInstance(
false);
55 const std::map<std::string, ConfigurationInfo>& ConfigurationManagerRW::getAllConfigurationInfo(
56 bool refresh, std::string *accumulatedErrors,
const std::string &errorFilterName)
60 if(accumulatedErrors) *accumulatedErrors =
"";
62 if(!refresh)
return allConfigurationInfo_;
65 allConfigurationInfo_.clear();
72 __MOUT__ <<
"Extracting list of Configuration tables" << std::endl;
75 std::string path = CONFIGURATION_INFO_PATH;
76 char fileExt[] = CONFIGURATION_INFO_EXT;
77 const unsigned char MIN_CONFIG_NAME_SZ = 3;
78 if( (pDIR=opendir( path.c_str() )) != 0 )
80 while((entry = readdir(pDIR)) != 0)
83 if(strlen(entry->d_name) < strlen(fileExt)+MIN_CONFIG_NAME_SZ)
88 &(entry->d_name[strlen(entry->d_name) - strlen(fileExt)]),
93 entry->d_name[strlen(entry->d_name) - strlen(fileExt)] =
'\0';
102 theInterface_->get(configuration,
107 catch(cet::exception)
109 if(configuration)
delete configuration;
112 __MOUT__ <<
"Skipping! No valid class found for... " << entry->d_name <<
"\n";
115 catch(std::runtime_error &e)
117 if(configuration)
delete configuration;
120 __MOUT__ <<
"Skipping! No valid class found for... " << entry->d_name <<
"\n";
121 __MOUT__ <<
"Error: " << e.what() << std::endl;
127 if(accumulatedErrors)
130 if(errorFilterName ==
"" ||
131 errorFilterName == entry->d_name)
133 *accumulatedErrors += std::string(
"\nIn table '") + entry->d_name +
136 __SS__ <<
"Attempting to allow illegal columns!" << std::endl;
137 *accumulatedErrors += ss.str();
141 __MOUT__ <<
"Attempting to allow illegal columns!" << std::endl;
144 std::string returnedAccumulatedErrors;
148 configuration =
new ConfigurationBase(entry->d_name, &returnedAccumulatedErrors);
152 __MOUT__ <<
"Skipping! Allowing illegal columns didn't work either... " <<
153 entry->d_name <<
"\n";
156 __MOUT__ <<
"Error (but allowed): " << returnedAccumulatedErrors << std::endl;
158 if(errorFilterName ==
"" ||
159 errorFilterName == entry->d_name)
160 *accumulatedErrors += std::string(
"\nIn table '") + entry->d_name +
161 "'..." + returnedAccumulatedErrors;
169 if(nameToConfigurationMap_[entry->d_name])
172 std::set<ConfigurationVersion> versions =
173 nameToConfigurationMap_[entry->d_name]->getStoredVersions();
174 for(
auto &version:versions)
175 if(version.isTemporaryVersion())
177 __MOUT__ <<
"copying tmp = " << version << std::endl;
181 nameToConfigurationMap_[entry->d_name]->setActiveView(version);
182 configuration->copyView(
183 nameToConfigurationMap_[entry->d_name]->getView(),
191 delete nameToConfigurationMap_[entry->d_name];
192 nameToConfigurationMap_[entry->d_name] = 0;
195 nameToConfigurationMap_[entry->d_name] = configuration;
197 allConfigurationInfo_[entry->d_name].configurationPtr_ = configuration;
198 allConfigurationInfo_[entry->d_name].versions_ = theInterface_->getVersions(configuration);
202 std::set<ConfigurationVersion> versions =
203 nameToConfigurationMap_[entry->d_name]->getStoredVersions();
204 for(
auto &version:versions)
205 if(version.isTemporaryVersion())
207 __MOUT__ <<
"surviving tmp = " << version << std::endl;
208 allConfigurationInfo_[entry->d_name].versions_.emplace(version);
213 __MOUT__ <<
"Extracting list of Configuration tables complete" << std::endl;
216 init(accumulatedErrors);
218 return allConfigurationInfo_;
224 std::map<std::string,std::map<std::string,ConfigurationVersion> >
225 ConfigurationManagerRW::getActiveVersionAliases(
void)
const
227 __MOUT__ <<
"getActiveVersionAliases()" << std::endl;
228 std::map<std::string,std::map<std::string,ConfigurationVersion> > retMap;
230 std::map<std::string, ConfigurationVersion> activeVersions = getActiveVersions();
231 std::string versionAliasesTableName =
"VersionAliasesConfiguration";
232 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
234 __SS__ <<
"Active version of VersionAliases missing!" <<
235 "Make sure you have a valid active Backbone Group." << std::endl;
236 __MOUT_WARN__ <<
"\n" << ss.str();
240 __MOUT__ <<
"activeVersions[\"VersionAliasesConfiguration\"]=" <<
241 activeVersions[versionAliasesTableName] << std::endl;
244 if(!ConfigurationInterface::isVersionTrackingEnabled())
245 for(
const auto &tableInfo:allConfigurationInfo_)
246 for(
const auto &version:tableInfo.second.versions_)
247 if(version.isScratchVersion())
248 retMap[tableInfo.first][ConfigurationManager::SCRATCH_VERSION_ALIAS] =
251 std::vector<std::pair<std::string,ConfigurationTree> > aliasNodePairs =
252 getNode(versionAliasesTableName).getChildren();
257 std::string configName, versionAlias;
258 for(
auto& aliasNodePair:aliasNodePairs)
260 configName = aliasNodePair.second.getNode(
261 "ConfigurationName").getValueAsString();
262 versionAlias = aliasNodePair.second.getNode(
263 "VersionAlias").getValueAsString();
265 if(retMap.find(configName) != retMap.end() &&
266 retMap[configName].find(versionAlias) != retMap[configName].end())
271 aliasNodePair.second.getNode(
"Version").getValueAsString());
281 void ConfigurationManagerRW::activateConfigurationGroup(
const std::string &configGroupName,
284 loadConfigurationGroup(configGroupName,configGroupKey,
287 accumulatedTreeErrors);
289 if(accumulatedTreeErrors &&
290 *accumulatedTreeErrors !=
"")
292 __MOUT_ERR__ <<
"Errors were accumulated so de-activating group: " <<
293 configGroupName <<
" (" << configGroupKey <<
")" << std::endl;
295 { destroyConfigurationGroup(configGroupName,
true); }
299 __MOUT_INFO__ <<
"Updating persistent active groups to " <<
300 ConfigurationManager::ACTIVE_GROUP_FILENAME <<
" ..." << std::endl;
302 std::string fn = ConfigurationManager::ACTIVE_GROUP_FILENAME;
303 FILE *fp = fopen(fn.c_str(),
"w");
306 __SS__ <<
"Fatal Error! Unable to open the file " <<
307 ConfigurationManager::ACTIVE_GROUP_FILENAME <<
" for editing! Is there a permissions problem?" << std::endl;
308 __MOUT_ERR__ << ss.str();
309 throw std::runtime_error(ss.str());
313 __MOUT__ << theContextGroup_ <<
"(" <<
314 (theContextGroupKey_?theContextGroupKey_->toString().c_str():
"-1") <<
")" << std::endl;
315 __MOUT__ << theBackboneGroup_ <<
"(" <<
316 (theBackboneGroupKey_?theBackboneGroupKey_->toString().c_str():
"-1") <<
")" << std::endl;
317 __MOUT__ << theConfigurationGroup_ <<
"(" <<
318 (theConfigurationGroupKey_?theConfigurationGroupKey_->toString().c_str():
"-1") <<
")" << std::endl;
320 fprintf(fp,
"%s\n",theContextGroup_.c_str());
321 fprintf(fp,
"%s\n",theContextGroupKey_?theContextGroupKey_->toString().c_str():
"-1");
322 fprintf(fp,
"%s\n",theBackboneGroup_.c_str());
323 fprintf(fp,
"%s\n",theBackboneGroupKey_?theBackboneGroupKey_->toString().c_str():
"-1");
324 fprintf(fp,
"%s\n",theConfigurationGroup_.c_str());
325 fprintf(fp,
"%s\n",theConfigurationGroupKey_?theConfigurationGroupKey_->toString().c_str():
"-1");
335 __MOUT_INFO__ <<
"Creating temporary backbone view from version " <<
336 sourceViewVersion << std::endl;
341 auto backboneMemberNames = ConfigurationManager::getBackboneMemberNames();
342 for (
auto& name : backboneMemberNames)
344 retTmpVersion = ConfigurationManager::getConfigurationByName(name)->getNextTemporaryVersion();
345 if(retTmpVersion < tmpVersion)
346 tmpVersion = retTmpVersion;
349 __MOUT__ <<
"Common temporary backbone version found as " <<
350 tmpVersion << std::endl;
353 for (
auto& name : backboneMemberNames)
355 retTmpVersion = getConfigurationByName(name)->createTemporaryView(sourceViewVersion, tmpVersion);
356 if(retTmpVersion != tmpVersion)
358 __MOUT_ERR__ <<
"Failure! Temporary view requested was " <<
359 tmpVersion <<
". Mismatched temporary view created: " << retTmpVersion << std::endl;
360 throw std::runtime_error(
"Mismatched temporary view created!");
370 ConfigurationBase* ConfigurationManagerRW::getConfigurationByName(
const std::string &configurationName)
372 if(nameToConfigurationMap_.find(configurationName) == nameToConfigurationMap_.end())
374 __SS__ <<
"\nConfiguration not found with name: " << configurationName << std::endl;
375 __MOUT_ERR__ <<
"\n" << ss.str();
376 throw std::runtime_error(ss.str());
378 return nameToConfigurationMap_[configurationName];
386 ConfigurationBase* ConfigurationManagerRW::getVersionedConfigurationByName(
const std::string &configurationName,
389 auto it = nameToConfigurationMap_.find(configurationName);
390 if(it == nameToConfigurationMap_.end())
392 __SS__ <<
"\nCan not find configuration named '" <<
394 "'\n\n\n\nYou need to load the configuration before it can be used." <<
395 "It probably is missing from the member list of the Configuration Group that was loaded?\n\n\n\n\n"
397 throw std::runtime_error(ss.str());
400 theInterface_->get(configuration, configurationName, 0 , 0,
404 looseColumnMatching);
405 return configuration;
411 ConfigurationVersion ConfigurationManagerRW::saveNewConfiguration(
const std::string &configurationName,
418 config->getTemporaryView(temporaryVersion)->setAuthor(username_);
422 newVersion = theInterface_->saveNewVersion(config, temporaryVersion);
424 config->setActiveView(newVersion);
427 while(!newVersion.isScratchVersion() && allConfigurationInfo_[configurationName].versions_.find(newVersion) !=
428 allConfigurationInfo_[configurationName].versions_.end())
430 __MOUT_ERR__ <<
"What happenened!?? ERROR::: newVersion v" << newVersion <<
431 " already exists!? How is it possible? Retrace your steps and tell an admin." << std::endl;
434 temporaryVersion = config->createTemporaryView(newVersion);
436 if(newVersion.isTemporaryVersion())
437 newVersion = temporaryVersion;
439 newVersion = ConfigurationVersion::getNextVersion(newVersion);
441 __MOUT_WARN__ <<
"Attempting to recover and use v" << newVersion << std::endl;
445 newVersion = theInterface_->saveNewVersion(config, temporaryVersion, newVersion);
447 config->setActiveView(newVersion);
450 if(newVersion.isInvalid())
452 __SS__ <<
"Something went wrong saving the new version v" << newVersion <<
453 ". What happened?! (duplicates? database error?)" << std::endl;
454 __MOUT_ERR__ <<
"\n" << ss.str();
455 throw std::runtime_error(ss.str());
459 allConfigurationInfo_[configurationName].versions_.insert(newVersion);
461 __MOUT__ <<
"New version added to info " << newVersion << std::endl;
471 void ConfigurationManagerRW::eraseTemporaryVersion(
const std::string &configurationName,
476 config->trimTemporary(targetVersion);
479 if(allConfigurationInfo_.find(configurationName) ==
480 allConfigurationInfo_.end())
return;
483 if(targetVersion.isInvalid())
486 for(
auto it = allConfigurationInfo_[configurationName].versions_.begin();
487 it != allConfigurationInfo_[configurationName].versions_.end(); )
489 if(it->isTemporaryVersion())
491 __MOUT__ <<
"Removing version info: " << *it << std::endl;
492 allConfigurationInfo_[configurationName].versions_.erase(it++);
500 __MOUT__ <<
"Removing version info: " << targetVersion << std::endl;
501 auto it = allConfigurationInfo_[configurationName].versions_.find(targetVersion);
502 if(it == allConfigurationInfo_[configurationName].versions_.end())
504 __MOUT__ <<
"Target version was not found in info versions..." << std::endl;
507 allConfigurationInfo_[configurationName].versions_.erase(
508 allConfigurationInfo_[configurationName].versions_.find(targetVersion));
509 __MOUT__ <<
"Target version was erased from info." << std::endl;
518 void ConfigurationManagerRW::clearCachedVersions(
const std::string &configurationName)
522 config->trimCache(0);
530 void ConfigurationManagerRW::clearAllCachedVersions()
532 for(
auto configInfo: allConfigurationInfo_)
533 configInfo.second.configurationPtr_->trimCache(0);
538 ConfigurationVersion ConfigurationManagerRW::copyViewToCurrentColumns(
const std::string &configurationName,
541 getConfigurationByName(configurationName)->reset();
553 allConfigurationInfo_[configurationName].versions_.insert(newTemporaryVersion);
555 return newTemporaryVersion;
570 const std::map<std::string, ConfigurationVersion> &groupMemberMap)
572 std::set<std::string > groupNames =
573 theInterface_->getAllConfigurationGroupNames(groupName);
578 for(
const std::string& fullName: groupNames)
580 ConfigurationGroupKey::getGroupNameAndKey(fullName,name,key);
583 if( name != groupName)
continue;
586 compareToMemberMap = theInterface_->getConfigurationGroupMembers(fullName);
589 for(
auto &memberPair: groupMemberMap)
592 if(compareToMemberMap.find(memberPair.first) == compareToMemberMap.end() ||
593 memberPair.second != compareToMemberMap[memberPair.first])
600 if(isDifferent)
continue;
603 if(groupMemberMap.size() != compareToMemberMap.size())
continue;
605 __MOUT__ <<
"Found exact match with key: " << key << std::endl;
609 __MOUT__ <<
"No match found - this group is new!" << std::endl;
622 ConfigurationGroupKey ConfigurationManagerRW::saveNewConfigurationGroup(
const std::string &groupName,
623 std::map<std::string, ConfigurationVersion> &groupMembers,
634 if(!previousVersion.isInvalid())
635 newKey = ConfigurationGroupKey::getNextKey(previousVersion);
638 std::set<ConfigurationGroupKey> keys = theInterface_->getKeys(groupName);
640 newKey = ConfigurationGroupKey::getNextKey(*(keys.crbegin()));
642 newKey = ConfigurationGroupKey::getDefaultKey();
645 __MOUT__ <<
"New Key for group: " << groupName <<
" found as " << newKey << std::endl;
649 std::map<std::string, ConfigurationInfo> allCfgInfo = getAllConfigurationInfo();
650 for(
auto &memberPair : groupMembers )
653 if(allCfgInfo.find(memberPair.first) == allCfgInfo.end())
655 __MOUT_ERR__ <<
"Group member \"" << memberPair.first <<
"\" not found in configuration!";
657 if(groupMetadataTable_.getConfigurationName() ==
660 __MOUT_WARN__ <<
"Looks like this is the groupMetadataTable_. " <<
661 "Note that this table is added to the member map when groups are saved." <<
662 "It should not be part of member map when calling this function." << std::endl;
663 __MOUT__ <<
"Attempting to recover." << std::endl;
664 groupMembers.erase(groupMembers.find(memberPair.first));
667 throw std::runtime_error(
"Group member not found!");
670 if(allCfgInfo[memberPair.first].versions_.find(memberPair.second) ==
671 allCfgInfo[memberPair.first].versions_.end())
673 __MOUT_ERR__ <<
"Group member \"" << memberPair.first <<
"\" version \"" <<
674 memberPair.second <<
"\" not found in configuration!";
675 throw std::runtime_error(
"Group member version not found!");
686 groupMetadataTable_.getViewP()->setValue(groupComment,0,1);
687 groupMetadataTable_.getViewP()->setValue(username_,0,2);
688 groupMetadataTable_.getViewP()->setValue(time(0),0,3);
691 groupMetadataTable_.getViewP()->setVersion(
692 ConfigurationVersion::getNextVersion(theInterface_->findLatestVersion(&groupMetadataTable_))
697 theInterface_->saveActiveVersion(&groupMetadataTable_);
700 groupMembers[groupMetadataTable_.getConfigurationName()] =
701 groupMetadataTable_.getViewVersion();
703 theInterface_->saveConfigurationGroup(groupMembers,
704 ConfigurationGroupKey::getFullGroupString(groupName,newKey));
705 __MOUT__ <<
"Created config group: " << groupName <<
":" << newKey << std::endl;
707 catch(std::runtime_error &e)
709 __MOUT_ERR__ <<
"Failed to create config group: " << groupName <<
":" << newKey << std::endl;
710 __MOUT_ERR__ <<
"\n\n" << e.what() << std::endl;
715 __MOUT_ERR__ <<
"Failed to create config group: " << groupName <<
":" << newKey << std::endl;
729 __MOUT_INFO__ <<
"Creating new backbone from temporary version " <<
730 temporaryVersion << std::endl;
735 auto backboneMemberNames = ConfigurationManager::getBackboneMemberNames();
736 for (
auto& name : backboneMemberNames)
738 retNewVersion = ConfigurationManager::getConfigurationByName(name)->getNextVersion();
739 __MOUT__ <<
"New version for backbone member (" << name <<
"): " <<
740 retNewVersion << std::endl;
741 if(retNewVersion > newVersion)
742 newVersion = retNewVersion;
745 __MOUT__ <<
"Common new backbone version found as " <<
746 newVersion << std::endl;
749 for (
auto& name : backboneMemberNames)
752 retNewVersion = getConfigurationInterface()->saveNewVersion(
753 getConfigurationByName(name), temporaryVersion, newVersion);
754 if(retNewVersion != newVersion)
756 __MOUT_ERR__ <<
"Failure! New view requested was " <<
757 newVersion <<
". Mismatched new view created: " << retNewVersion << std::endl;
758 throw std::runtime_error(
"Mismatched temporary view created!");
766 void ConfigurationManagerRW::testXDAQContext()
922 __MOUT__ <<
"Loading config..." << std::endl;
928 __MOUT__ << std::endl;
930 __MOUT__ <<
"Value: " << v << std::endl;
931 __MOUT__ <<
"Value index: " << t.getValue<
int>() << std::endl;
973 __MOUT__ <<
"Failed to load config..." << std::endl;