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 fprintf(fp,
"%s\n",theContextGroup_.c_str());
307 fprintf(fp,
"%s\n",theContextGroupKey_?theContextGroupKey_->toString().c_str():
"-1");
308 fprintf(fp,
"%s\n",theBackboneGroup_.c_str());
309 fprintf(fp,
"%s\n",theBackboneGroupKey_?theBackboneGroupKey_->toString().c_str():
"-1");
310 fprintf(fp,
"%s\n",theConfigurationGroup_.c_str());
311 fprintf(fp,
"%s\n",theConfigurationGroupKey_?theConfigurationGroupKey_->toString().c_str():
"-1");
321 __MOUT_INFO__ <<
"Creating temporary backbone view from version " <<
322 sourceViewVersion << std::endl;
327 auto backboneMemberNames = ConfigurationManager::getBackboneMemberNames();
328 for (
auto& name : backboneMemberNames)
330 retTmpVersion = ConfigurationManager::getConfigurationByName(name)->getNextTemporaryVersion();
331 if(retTmpVersion < tmpVersion)
332 tmpVersion = retTmpVersion;
335 __MOUT__ <<
"Common temporary backbone version found as " <<
336 tmpVersion << std::endl;
339 for (
auto& name : backboneMemberNames)
341 retTmpVersion = getConfigurationByName(name)->createTemporaryView(sourceViewVersion, tmpVersion);
342 if(retTmpVersion != tmpVersion)
344 __MOUT_ERR__ <<
"Failure! Temporary view requested was " <<
345 tmpVersion <<
". Mismatched temporary view created: " << retTmpVersion << std::endl;
346 throw std::runtime_error(
"Mismatched temporary view created!");
356 ConfigurationBase* ConfigurationManagerRW::getConfigurationByName(
const std::string &configurationName)
358 if(nameToConfigurationMap_.find(configurationName) == nameToConfigurationMap_.end())
360 __MOUT_ERR__ <<
"\nConfiguration not found with name: " << configurationName << std::endl;
361 throw std::runtime_error(
"Configuration not found with name '" + configurationName +
".'");
363 return nameToConfigurationMap_[configurationName];
371 ConfigurationBase* ConfigurationManagerRW::getVersionedConfigurationByName(
const std::string &configurationName,
374 auto it = nameToConfigurationMap_.find(configurationName);
375 if(it == nameToConfigurationMap_.end())
377 __SS__ <<
"\nCan not find configuration named '" <<
379 "'\n\n\n\nYou need to load the configuration before it can be used." <<
380 "It probably is missing from the member list of the Configuration Group that was loaded?\n\n\n\n\n"
382 throw std::runtime_error(ss.str());
385 theInterface_->get(configuration, configurationName, 0 , 0,
389 looseColumnMatching);
390 return configuration;
396 ConfigurationVersion ConfigurationManagerRW::saveNewConfiguration(
const std::string &configurationName,
403 config->getTemporaryView(temporaryVersion)->setAuthor(username_);
407 newVersion = theInterface_->saveNewVersion(config, temporaryVersion);
409 config->setActiveView(newVersion);
412 while(!newVersion.isScratchVersion() && allConfigurationInfo_[configurationName].versions_.find(newVersion) !=
413 allConfigurationInfo_[configurationName].versions_.end())
415 __MOUT_ERR__ <<
"What happenened!?? ERROR::: newVersion v" << newVersion <<
416 " already exists!? How is it possible? Retrace your steps and tell an admin." << std::endl;
419 temporaryVersion = config->createTemporaryView(newVersion);
421 if(newVersion.isTemporaryVersion())
422 newVersion = temporaryVersion;
424 newVersion = ConfigurationVersion::getNextVersion(newVersion);
426 __MOUT_WARN__ <<
"Attempting to recover and use v" << newVersion << std::endl;
430 newVersion = theInterface_->saveNewVersion(config, temporaryVersion, newVersion);
432 config->setActiveView(newVersion);
435 if(newVersion.isInvalid())
437 __SS__ <<
"Something went wrong saving the new version v" << newVersion <<
438 ". What happened?! (duplicates? database error?)" << std::endl;
439 __MOUT_ERR__ <<
"\n" << ss.str();
440 throw std::runtime_error(ss.str());
444 allConfigurationInfo_[configurationName].versions_.insert(newVersion);
446 __MOUT__ <<
"New version added to info " << newVersion << std::endl;
456 void ConfigurationManagerRW::eraseTemporaryVersion(
const std::string &configurationName,
461 config->trimTemporary(targetVersion);
464 if(allConfigurationInfo_.find(configurationName) ==
465 allConfigurationInfo_.end())
return;
468 if(targetVersion.isInvalid())
471 for(
auto it = allConfigurationInfo_[configurationName].versions_.begin();
472 it != allConfigurationInfo_[configurationName].versions_.end(); )
474 if(it->isTemporaryVersion())
476 __MOUT__ <<
"Removing version info: " << *it << std::endl;
477 allConfigurationInfo_[configurationName].versions_.erase(it++);
485 __MOUT__ <<
"Removing version info: " << targetVersion << std::endl;
486 auto it = allConfigurationInfo_[configurationName].versions_.find(targetVersion);
487 if(it == allConfigurationInfo_[configurationName].versions_.end())
489 __MOUT__ <<
"Target version was not found in info versions..." << std::endl;
492 allConfigurationInfo_[configurationName].versions_.erase(
493 allConfigurationInfo_[configurationName].versions_.find(targetVersion));
494 __MOUT__ <<
"Target version was erased from info." << std::endl;
503 void ConfigurationManagerRW::clearCachedVersions(
const std::string &configurationName)
507 config->trimCache(0);
515 void ConfigurationManagerRW::clearAllCachedVersions()
517 for(
auto configInfo: allConfigurationInfo_)
518 configInfo.second.configurationPtr_->trimCache(0);
523 ConfigurationVersion ConfigurationManagerRW::copyViewToCurrentColumns(
const std::string &configurationName,
526 getConfigurationByName(configurationName)->reset();
538 allConfigurationInfo_[configurationName].versions_.insert(newTemporaryVersion);
540 return newTemporaryVersion;
555 const std::map<std::string, ConfigurationVersion> &groupMemberMap)
557 std::set<std::string > groupNames =
558 theInterface_->getAllConfigurationGroupNames(groupName);
563 for(
auto &fullName: groupNames)
565 ConfigurationGroupKey::getGroupNameAndKey(fullName,name,key);
567 __MOUT__ << fullName <<
" has name " << name <<
" ==? " << groupName << std::endl;
568 if( name != groupName)
continue;
570 __MOUT__ << name <<
" == " << groupName << std::endl;
571 compareToMemberMap = theInterface_->getConfigurationGroupMembers(fullName);
574 for(
auto &memberPair: groupMemberMap)
576 __MOUT__ << memberPair.first <<
" - " << memberPair.second << std::endl;
577 if(compareToMemberMap.find(memberPair.first) == compareToMemberMap.end() ||
578 memberPair.second != compareToMemberMap[memberPair.first])
580 __MOUT__ <<
"mismatch found!" << std::endl;
585 if(isDifferent)
continue;
588 if(groupMemberMap.size() != compareToMemberMap.size())
continue;
590 __MOUT__ <<
"Found exact match with key: " << key << std::endl;
594 __MOUT__ <<
"no match found!" << std::endl;
607 ConfigurationGroupKey ConfigurationManagerRW::saveNewConfigurationGroup(
const std::string &groupName,
608 std::map<std::string, ConfigurationVersion> &groupMembers,
617 __MOUT__ << std::endl;
620 if(!previousVersion.isInvalid())
621 newKey = ConfigurationGroupKey::getNextKey(previousVersion);
624 std::set<ConfigurationGroupKey> keys = theInterface_->getKeys(groupName);
626 newKey = ConfigurationGroupKey::getNextKey(*(keys.crbegin()));
628 newKey = ConfigurationGroupKey::getDefaultKey();
631 __MOUT__ <<
"New Key for group: " << groupName <<
" found as " << newKey << std::endl;
635 std::map<std::string, ConfigurationInfo> allCfgInfo = getAllConfigurationInfo();
636 for(
auto &memberPair : groupMembers )
639 if(allCfgInfo.find(memberPair.first) == allCfgInfo.end())
641 __MOUT_ERR__ <<
"Group member \"" << memberPair.first <<
"\" not found in configuration!";
643 if(groupMetadataTable_.getConfigurationName() ==
646 __MOUT_WARN__ <<
"Looks like this is the groupMetadataTable_. " <<
647 "Note that this table is added to the member map when groups are saved." <<
648 "It should not be part of member map when calling this function." << std::endl;
649 __MOUT__ <<
"Attempting to recover." << std::endl;
650 groupMembers.erase(groupMembers.find(memberPair.first));
653 throw std::runtime_error(
"Group member not found!");
656 if(allCfgInfo[memberPair.first].versions_.find(memberPair.second) ==
657 allCfgInfo[memberPair.first].versions_.end())
659 __MOUT_ERR__ <<
"Group member \"" << memberPair.first <<
"\" version \"" <<
660 memberPair.second <<
"\" not found in configuration!";
661 throw std::runtime_error(
"Group member version not found!");
672 groupMetadataTable_.getViewP()->setValue(groupComment,0,1);
673 groupMetadataTable_.getViewP()->setValue(username_,0,2);
674 groupMetadataTable_.getViewP()->setValue(time(0),0,3);
677 groupMetadataTable_.getViewP()->setVersion(
678 ConfigurationVersion::getNextVersion(theInterface_->findLatestVersion(&groupMetadataTable_))
683 theInterface_->saveActiveVersion(&groupMetadataTable_);
686 groupMembers[groupMetadataTable_.getConfigurationName()] =
687 groupMetadataTable_.getViewVersion();
689 theInterface_->saveConfigurationGroup(groupMembers,
690 ConfigurationGroupKey::getFullGroupString(groupName,newKey));
691 __MOUT__ <<
"Created config group: " << groupName <<
":" << newKey << std::endl;
693 catch(std::runtime_error &e)
695 __MOUT_ERR__ <<
"Failed to create config group: " << groupName <<
":" << newKey << std::endl;
696 __MOUT_ERR__ <<
"\n\n" << e.what() << std::endl;
701 __MOUT_ERR__ <<
"Failed to create config group: " << groupName <<
":" << newKey << std::endl;
715 __MOUT_INFO__ <<
"Creating new backbone from temporary version " <<
716 temporaryVersion << std::endl;
721 auto backboneMemberNames = ConfigurationManager::getBackboneMemberNames();
722 for (
auto& name : backboneMemberNames)
724 retNewVersion = ConfigurationManager::getConfigurationByName(name)->getNextVersion();
725 __MOUT__ <<
"New version for backbone member (" << name <<
"): " <<
726 retNewVersion << std::endl;
727 if(retNewVersion > newVersion)
728 newVersion = retNewVersion;
731 __MOUT__ <<
"Common new backbone version found as " <<
732 newVersion << std::endl;
735 for (
auto& name : backboneMemberNames)
738 retNewVersion = getConfigurationInterface()->saveNewVersion(
739 getConfigurationByName(name), temporaryVersion, newVersion);
740 if(retNewVersion != newVersion)
742 __MOUT_ERR__ <<
"Failure! New view requested was " <<
743 newVersion <<
". Mismatched new view created: " << retNewVersion << std::endl;
744 throw std::runtime_error(
"Mismatched temporary view created!");
752 void ConfigurationManagerRW::testXDAQContext()
908 __MOUT__ <<
"Loading config..." << std::endl;
914 __MOUT__ << std::endl;
916 __MOUT__ <<
"Value: " << v << std::endl;
917 __MOUT__ <<
"Value index: " << t.getValue<
int>() << std::endl;
959 __MOUT__ <<
"Failed to load config..." << std::endl;