otsdaq  v1_01_04
 All Classes Namespaces Functions
otsdaq_flatten_system_aliases.cc
1 #include <string>
2 #include <iostream>
3 #include <memory>
4 #include <cassert>
5 #include <dirent.h>
6 #include "otsdaq-core/ConfigurationInterface/ConfigurationManagerRW.h"
7 #include "otsdaq-core/ConfigurationInterface/ConfigurationInterface.h"
8 //#include "artdaq-database/StorageProviders/FileSystemDB/provider_filedb_index.h"
9 //#include "artdaq-database/JsonDocument/JSONDocument.h"
10 
11 //usage:
12 // otsdaq_flatten_system_aliases <baseFlatVersion> <pathToSwapIn (optional)>
13 //
14 // if baseFlatVersion is invalid or temporary nothing is saved in the new db
15 // (Note: this can be used to swap dbs using pathToSwapIn)
16 
17 using namespace ots;
18 
19 
20 void FlattenActiveSystemAliasConfigurationGroups(int argc, char* argv[])
21 {
22  std::cout << "=================================================\n";
23  std::cout << "=================================================\n";
24  std::cout << "=================================================\n";
25  std::cout << __COUT_HDR_FL__ << "\nFlattening Active System Aliases!" << std::endl;
26 
27  std::cout << "\n\nusage: Two arguments:\n\t pathToSwapIn <baseFlatVersion> <pathToSwapIn (optional)> \n\n" <<
28  "\t Default values: baseFlatVersion = 0, pathToSwapIn = \"\" \n\n" <<
29  std::endl;
30 
31  std::cout << "\n\nNote: you can optionally just swap databases (and not modify their contents at all)" <<
32  " by providing an invalid baseFlatVersion of -1.\n\n" <<
33  std::endl;
34 
35  std::cout << "\n\nNote: This assumes artdaq db file type interface. " <<
36  "The current database/ will be moved to database_<linuxtime>/ " <<
37  "and if a pathToSwapIn is specified it will be copied to database/ " <<
38  "before saving the currently active groups.\n\n" <<
39  std::endl;
40 
41  std::cout << "argc = " << argc << std::endl;
42  for(int i = 0; i < argc; i++)
43  std::cout << "argv[" << i << "] = " << argv[i] << std::endl;
44 
45  if(argc < 2)
46  {
47  std::cout << "Must provide at least one parameter.";
48  return;
49  }
50 
51  //determine if "h"elp was first parameter
52  std::string flatVersionStr = argv[1];
53  if(flatVersionStr.find('h') != std::string::npos)
54  {
55  std::cout << "Recognized parameter 1. as a 'help' option. Usage was printed. Exiting." << std::endl;
56  return;
57  }
58 
59  int flatVersion = 0;
60  std::string pathToSwapIn = "";
61  if(argc >= 2)
62  sscanf(argv[1],"%d",&flatVersion);
63  if(argc >= 3)
64  pathToSwapIn = argv[2];
65 
66  std::cout << __COUT_HDR_FL__ << "flatVersion = " << flatVersion << std::endl;
67  std::cout << __COUT_HDR_FL__ << "pathToSwapIn = " << pathToSwapIn << std::endl;
68 
69  //return;
70  //==============================================================================
71  //Define environment variables
72  // Note: normally these environment variables are set by StartOTS.sh
73 
74  //These are needed by otsdaq/otsdaq-core/ConfigurationDataFormats/ConfigurationInfoReader.cc [207]
75  setenv("CONFIGURATION_TYPE","File",1); //Can be File, Database, DatabaseTest
76  setenv("CONFIGURATION_DATA_PATH",(std::string(getenv("USER_DATA")) + "/ConfigurationDataExamples").c_str(),1);
77  setenv("CONFIGURATION_INFO_PATH",(std::string(getenv("USER_DATA")) + "/ConfigurationInfo").c_str(),1);
79 
80  //Some configuration plug-ins use getenv("SERVICE_DATA_PATH") in init() so define it
81  setenv("SERVICE_DATA_PATH",(std::string(getenv("USER_DATA")) + "/ServiceData").c_str(),1);
82 
83  //Some configuration plug-ins use getenv("OTSDAQ_LIB") and getenv("OTSDAQ_UTILITIES_LIB") in init() so define it
84  // to a non-sense place is ok
85  setenv("OTSDAQ_LIB",(std::string(getenv("USER_DATA")) + "/").c_str(),1);
86  setenv("OTSDAQ_UTILITIES_LIB",(std::string(getenv("USER_DATA")) + "/").c_str(),1);
87 
88  //Some configuration plug-ins use getenv("OTS_MAIN_PORT") in init() so define it
89  setenv("OTS_MAIN_PORT","2015",1);
90 
91  //also xdaq envs for XDAQContextConfiguration
92  setenv("XDAQ_CONFIGURATION_DATA_PATH",(std::string(getenv("USER_DATA")) + "/XDAQConfigurations").c_str(),1);
93  setenv("XDAQ_CONFIGURATION_XML","otsConfigurationNoRU_CMake",1);
95 
96  //==============================================================================
97  //get prepared with initial source db
98 
99  //ConfigurationManager instance immediately loads active groups
100  std::cout << "\n\n\n" << __COUT_HDR_FL__ << "Loading active Aliases..." << std::endl;
101  ConfigurationManagerRW cfgMgrInst("flatten_admin");
102  ConfigurationManagerRW *cfgMgr = &cfgMgrInst;
103 
104 
105  //create set of groups to persist
106  // include active context
107  // include active backbone
108  // include active iterate group
109  // include active config group
110  // (keep key translation separate activeGroupKeys)
111  // include all groups with system aliases
112 
113  //for group in set
114  // load/activate group and flatten tables to flatVersion to new DB
115  // save new version to modifiedTables
116  // save group with flatVersion key to new DB
117  // save new key to groupSet
118  // ++flatVersion
119 
120  //reload the active backbone (using activeGroupKeys)
121  // modify group aliases and table aliases properly based on groupSet and modifiedTables
122  // save new backbone with flatVersion to new DB
123 
124  //backup the file ConfigurationManager::ACTIVE_GROUP_FILENAME with time
125  // and change the ConfigurationManager::ACTIVE_GROUP_FILENAME
126  // to reflect new group names/keys
127 
128 
129  /* map<<groupName, origKey>, newKey> */
130  std::map<std::pair<std::string,ConfigurationGroupKey>,
131  ConfigurationGroupKey> groupSet;
132  /* <tableName, <origVersion, newVersion> >*/
133  std::map<std::pair<std::string,ConfigurationVersion>,
134  ConfigurationVersion> modifiedTables;
135  std::map<std::string, std::pair<ConfigurationGroupKey,
136  ConfigurationGroupKey>> activeGroupKeys;
137  std::map<std::pair<std::string,ConfigurationGroupKey>,
138  std::string> groupErrors;
139 
140  std::string activeBackboneGroupName = "";
141  std::string activeContextGroupName = "";
142  std::string activeIterateGroupName = "";
143  std::string activeConfigGroupName = "";
144 
145  std::string nowTime = std::to_string(time(0));
146 
147  std::string thenTime = "";
148  if(pathToSwapIn != "") //get target then time
149  {
150  thenTime = pathToSwapIn.substr(pathToSwapIn.rfind('_')+1);
151  std::cout << __COUT_HDR_FL__<< "thenTime = " << thenTime << std::endl;
152  //return;
153  }
154 
155  //add active groups to set
156  std::map<std::string, std::pair<std::string, ConfigurationGroupKey>> activeGroupsMap =
157  cfgMgr->getActiveConfigurationGroups();
158 
159  for(const auto &activeGroup: activeGroupsMap)
160  {
161  groupSet.insert(std::pair<
162  std::pair<std::string,ConfigurationGroupKey>,
163  ConfigurationGroupKey> (
164  std::pair<std::string,ConfigurationGroupKey>(
165  activeGroup.second.first,
166  activeGroup.second.second),
167  ConfigurationGroupKey())
168  );
169  activeGroupKeys.insert(std::pair<
170  std::string,
171  std::pair<ConfigurationGroupKey,ConfigurationGroupKey>> (
172  activeGroup.second.first,
173  std::pair<ConfigurationGroupKey,ConfigurationGroupKey>(
174  activeGroup.second.second,
175  ConfigurationGroupKey()))
176  );
177 
178  if(activeGroup.first == ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE)
179  {
180  activeBackboneGroupName = activeGroup.second.first;
181  std::cout << __COUT_HDR_FL__<< "found activeBackboneGroupName = " <<
182  activeBackboneGroupName << std::endl;
183  }
184  else if(activeGroup.first == ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT)
185  {
186  activeContextGroupName = activeGroup.second.first;
187  std::cout << __COUT_HDR_FL__<< "found activeContextGroupName = " <<
188  activeContextGroupName << std::endl;
189  }
190  else if(activeGroup.first == ConfigurationManager::ACTIVE_GROUP_NAME_ITERATE)
191  {
192  activeIterateGroupName = activeGroup.second.first;
193  std::cout << __COUT_HDR_FL__<< "found activeIterateGroupName = " <<
194  activeIterateGroupName << std::endl;
195  }
196  else if(activeGroup.first == ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION)
197  {
198  activeConfigGroupName = activeGroup.second.first;
199  std::cout << __COUT_HDR_FL__<< "found activeConfigGroupName = " <<
200  activeConfigGroupName << std::endl;
201  }
202  }
203 
204  //add system alias groups to set
205  const std::string groupAliasesTableName = "GroupAliasesConfiguration";
206  std::map<std::string, ConfigurationVersion> activeVersions = cfgMgr->getActiveVersions();
207  if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
208  {
209  __SS__ << "\nActive version of GroupAliasesConfiguration missing! " <<
210  "GroupAliasesConfiguration is a required member of the Backbone configuration group." <<
211  "\n\nLikely you need to activate a valid Backbone group." <<
212  std::endl;
213  throw std::runtime_error(ss.str());
214  }
215 
216 
217  std::vector<std::pair<std::string,ConfigurationTree> > aliasNodePairs =
218  cfgMgr->getNode(groupAliasesTableName).getChildren();
219  for(auto& groupPair:aliasNodePairs)
220  groupSet.insert(std::pair<
221  std::pair<std::string,ConfigurationGroupKey>,
222  ConfigurationGroupKey> (
223  std::pair<std::string,ConfigurationGroupKey>(
224  groupPair.second.getNode("GroupName").getValueAsString(),
225  ConfigurationGroupKey(groupPair.second.getNode("GroupKey").getValueAsString())),
226  ConfigurationGroupKey())
227  );
228 
229  std::cout << __COUT_HDR_FL__<< "Identfied groups:" << std::endl;
230  for(auto& group:groupSet)
231  std::cout << __COUT_HDR_FL__<< group.first.first << " " << group.first.second << std::endl;
232  std::cout << __COUT_HDR_FL__<< std::endl;
233  std::cout << __COUT_HDR_FL__<< std::endl;
234 
235  //return;
236  //==============================================================================
237  //prepare to manipulate directories
238  std::string currentDir = getenv("ARTDAQ_DATABASE_URI");
239 
240  if(currentDir.find("filesystemdb://") != 0)
241  {
242  __SS__ << "filesystemdb:// was not found in $ARTDAQ_DATABASE_URI!" << std::endl;
243  __COUT_ERR__ << "\n" << ss.str();
244  throw std::runtime_error(ss.str());
245  }
246 
247  currentDir = currentDir.substr(std::string("filesystemdb://").length());
248  while(currentDir.length() && currentDir[currentDir.length()-1] == '/') //remove trailing '/'s
249  currentDir = currentDir.substr(0,currentDir.length()-1);
250  std::string moveToDir = currentDir + "_" + nowTime;
251  if(argc < 2)
252  {
253  __SS__ << ("Aborting move! Must at least give version argument to flatten to!") << std::endl;
254  __COUT_ERR__ << "\n" << ss.str();
255  throw std::runtime_error(ss.str());
256  }
257 
258  if(pathToSwapIn != "")
259  {
260  DIR *dp;
261  if((dp = opendir(pathToSwapIn.c_str())) == 0)
262  {
263  std::cout << __COUT_HDR_FL__<< "ERROR:(" << errno << "). Can't open directory: " << pathToSwapIn << std::endl;
264  exit(0);
265  }
266  closedir(dp);
267  }
268 
269  //handle directory swap
270  std::cout << __COUT_HDR_FL__ << "Moving current directory: \t" << currentDir << std::endl;
271  std::cout << __COUT_HDR_FL__ << "\t... to: \t\t" << moveToDir << std::endl;
272  //return;
273  rename(currentDir.c_str(),moveToDir.c_str());
274 
275  if(pathToSwapIn != "")
276  {
277  std::cout << __COUT_HDR_FL__ << "Swapping in directory: \t" << pathToSwapIn << std::endl;
278  std::cout << __COUT_HDR_FL__ << "\t.. to: \t\t" << currentDir << std::endl;
279  rename(pathToSwapIn.c_str(),currentDir.c_str());
280 
281  //also swap in active groups file
282  //check if original active file exists
283  std::string activeGroupsFile = ConfigurationManager::ACTIVE_GROUP_FILENAME + "." + thenTime;
284  FILE *fp = fopen(activeGroupsFile.c_str(),"r");
285  if(fp)
286  {
287  std::cout << __COUT_HDR_FL__ << "Swapping active groups file: \t" <<
288  activeGroupsFile << std::endl;
289  std::cout << __COUT_HDR_FL__ << "\t.. to: \t\t" <<
290  ConfigurationManager::ACTIVE_GROUP_FILENAME << std::endl;
291  rename(activeGroupsFile.c_str(),
292  ConfigurationManager::ACTIVE_GROUP_FILENAME.c_str());
293  }
294  }
295 
296 
297 
298 
299 
300  ConfigurationInterface* theInterface_ = ConfigurationInterface::getInstance(false); //true for File interface, false for artdaq database;
301  ConfigurationView* cfgView;
302  ConfigurationBase* config;
303 
304  bool errDetected;
305  std::string accumulateErrors = "";
306  std::map<std::string, ConfigurationVersion> memberMap;
307  int count = 0;
308 
309  //don't do anything more if flatVersion is not persistent
310  if(ConfigurationVersion(flatVersion).isInvalid() ||
311  ConfigurationVersion(flatVersion).isTemporaryVersion())
312  {
313  std::cout << __COUT_HDR_FL__ << "\n\nflatVersion " << ConfigurationVersion(flatVersion) <<
314  " is an invalid or temporary version. Skipping to end!" << std::endl;
315  goto CLEAN_UP;
316  }
317 
318 
319  for(auto& groupPair:groupSet)
320  {
321  errDetected = false;
322 
323  std::cout << __COUT_HDR_FL__ << "****************************" << std::endl;
324  std::cout << __COUT_HDR_FL__ << "Loading members for " <<
325  groupPair.first.first <<
326  "(" << groupPair.first.second << ")" <<
327  std::endl;
328  std::cout << __COUT_HDR_FL__ << "flatVersion = " << flatVersion << std::endl;
329 
330  //handle directory swap BACK
331  if(pathToSwapIn != "")
332  {
333  std::cout << __COUT_HDR_FL__ << "REVERT by Swapping back directory: \t" << currentDir << std::endl;
334  std::cout << __COUT_HDR_FL__ << "\t.. to: \t\t" << pathToSwapIn << std::endl;
335  if(rename(currentDir.c_str(),pathToSwapIn.c_str()) < 0)
336  {
337  __SS__ << "Problem!" << std::endl;
338  throw std::runtime_error(ss.str());
339  }
340 
341  }
342  else if(count) //if not first time, move currentDir to temporarily holding area
343  {
344  std::cout << __COUT_HDR_FL__ << "REVERT by Moving directory: \t" << currentDir << std::endl;
345  std::cout << __COUT_HDR_FL__ << "\t.. to temporary directory: \t\t" << (moveToDir+"_tmp") << std::endl;
346  if(rename(currentDir.c_str(),(moveToDir+"_tmp").c_str()) < 0)
347  {
348  __SS__ << "Problem!" << std::endl;
349  throw std::runtime_error(ss.str());
350  }
351  }
352 
353 
354  std::cout << __COUT_HDR_FL__ << "REVERT by Moving directory: \t" << moveToDir << std::endl;
355  std::cout << __COUT_HDR_FL__ << "\t... to: \t\t" << currentDir << std::endl;
356  if(rename(moveToDir.c_str(),currentDir.c_str()) < 0)
357  {
358  __SS__ << "Problem!" << std::endl;
359  throw std::runtime_error(ss.str());
360  }
361 
362 
363  //=========================
364  //load group and tables from original DB
365  try
366  {
367  memberMap =
368  cfgMgr->loadConfigurationGroup(
369  groupPair.first.first,
370  groupPair.first.second,
371  true,0,&accumulateErrors);
372  }
373  catch(std::runtime_error& e)
374  {
375 
376  std::cout << __COUT_HDR_FL__ << "Error was caught loading members for " <<
377  groupPair.first.first <<
378  "(" << groupPair.first.second << ")" <<
379  std::endl;
380  std::cout << __COUT_HDR_FL__ << e.what() << std::endl;
381  errDetected = true;
382  }
383  catch(...)
384  {
385  std::cout << __COUT_HDR_FL__ << "Error was caught loading members for " <<
386  groupPair.first.first <<
387  "(" << groupPair.first.second << ")" <<
388  std::endl;
389  errDetected = true;
390  }
391 
392  //=========================
393 
394  //if(count == 2) break;
395 
396 
397  //handle directory swap
398  std::cout << __COUT_HDR_FL__ << "Moving current directory: \t" << currentDir << std::endl;
399  std::cout << __COUT_HDR_FL__ << "\t... to: \t\t" << moveToDir << std::endl;
400  if(rename(currentDir.c_str(),moveToDir.c_str()) < 0)
401  {
402  __SS__ << "Problem!" << std::endl;
403  throw std::runtime_error(ss.str());
404  }
405 
406  if(pathToSwapIn != "")
407  {
408  std::cout << __COUT_HDR_FL__ << "Swapping in directory: \t" << pathToSwapIn << std::endl;
409  std::cout << __COUT_HDR_FL__ << "\t.. to: \t\t" << currentDir << std::endl;
410  if(rename(pathToSwapIn.c_str(),currentDir.c_str()) < 0)
411  {
412  __SS__ << "Problem!" << std::endl;
413  throw std::runtime_error(ss.str());
414  }
415  }
416  else if(count) //if not first time, replace from temporarily holding area
417  {
418  std::cout << __COUT_HDR_FL__ << "Moving temporary directory: \t" << (moveToDir+"_tmp") << std::endl;
419  std::cout << __COUT_HDR_FL__ << "\t.. to current directory: \t\t" << currentDir << std::endl;
420  if(rename((moveToDir+"_tmp").c_str(),currentDir.c_str()) < 0)
421  {
422  __SS__ << "Problem!" << std::endl;
423  throw std::runtime_error(ss.str());
424  }
425  }
426 
427 
428  //exit loop if any (loading) failure
429  if(errDetected)
430  {
431  //goto CLEAN_UP;
432 
433  //power on if group failed
434  // and record error
435 
436  groupErrors.insert(std::pair<
437  std::pair<std::string,ConfigurationGroupKey>,
438  std::string> (
439  std::pair<std::string,ConfigurationGroupKey>(
440  groupPair.first.first,
441  groupPair.first.second),
442  "Error caught loading the group."));
443  continue;
444  }
445 
446 
447 
448 
449  //=========================
450  //save group and its tables with new key and versions!
451  try
452  {
453  //saving tables
454  for(auto &memberPair:memberMap)
455  {
456  std::cout << __COUT_HDR_FL__ << memberPair.first << ":v" << memberPair.second << std::endl;
457 
458  //check if table has already been modified by a previous group
459  // (i.e. two groups using the same version of a table)
460  if(modifiedTables.find(std::pair<std::string,ConfigurationVersion>(
461  memberPair.first,
462  memberPair.second
463  )) != modifiedTables.end())
464  {
465 
466  std::cout << __COUT_HDR_FL__ << "Table was already modified!" << std::endl;
467  memberPair.second = modifiedTables[std::pair<std::string,ConfigurationVersion>(
468  memberPair.first,
469  memberPair.second
470  )];
471  std::cout << __COUT_HDR_FL__ << "\t to...\t" <<
472  memberPair.first << ":v" << memberPair.second << std::endl;
473  continue;
474  }
475 
476  //change the version of the active view to flatVersion and save it
477  config = cfgMgr->getConfigurationByName(memberPair.first);
478  cfgView = config->getViewP();
479  cfgView->setVersion(ConfigurationVersion(flatVersion));
480  theInterface_->saveActiveVersion(config);
481 
482  //set it back for the table so that future groups can re-use cached version
483  cfgView->setVersion(memberPair.second); //IMPORTANT
484 
485  memberPair.second = flatVersion; //change version in the member map
486 
487  std::cout << __COUT_HDR_FL__ << "\t to...\t" <<
488  memberPair.first << ":v" << memberPair.second << std::endl;
489 
490  //save new version to modifiedTables
491  modifiedTables.insert(std::pair<
492  std::pair<std::string,ConfigurationVersion>,
494  std::pair<std::string,ConfigurationVersion>(
495  memberPair.first,
496  memberPair.second),
497  ConfigurationVersion(flatVersion))
498  );
499  }
500 
501  //memberMap should now consist of members with new flat version, so save
502  theInterface_->saveConfigurationGroup(memberMap,
503  ConfigurationGroupKey::getFullGroupString(
504  groupPair.first.first,
505  ConfigurationGroupKey(flatVersion)));
506 
507  //and modify groupSet and activeGroupKeys keys
508  groupPair.second = ConfigurationGroupKey(flatVersion);
509 
510  //if this is an active group, save key change
511  if(activeGroupKeys.find(groupPair.first.first) != activeGroupKeys.end() &&
512  activeGroupKeys[groupPair.first.first].first == groupPair.first.second)
513  activeGroupKeys[groupPair.first.first].second =
514  ConfigurationGroupKey(flatVersion);
515  }
516  catch(std::runtime_error& e)
517  {
518  std::cout << __COUT_HDR_FL__ << "Error was caught saving group " <<
519  groupPair.first.first <<
520  " (" << groupPair.first.second << ") " <<
521  std::endl;
522  std::cout << __COUT_HDR_FL__ << e.what() << std::endl;
523 
524  groupErrors.insert(std::pair<
525  std::pair<std::string,ConfigurationGroupKey>,
526  std::string> (
527  std::pair<std::string,ConfigurationGroupKey>(
528  groupPair.first.first,
529  groupPair.first.second),
530  "Error caught saving the group."));
531  }
532  catch(...)
533  {
534  std::cout << __COUT_HDR_FL__ << "Error was caught saving group " <<
535  groupPair.first.first <<
536  " (" << groupPair.first.second << ") " <<
537  std::endl;
538 
539  groupErrors.insert(std::pair<
540  std::pair<std::string,ConfigurationGroupKey>,
541  std::string> (
542  std::pair<std::string,ConfigurationGroupKey>(
543  groupPair.first.first,
544  groupPair.first.second),
545  "Error caught saving the group."));
546  }
547  //=========================
548 
549 
550  //increment flat version
551  ++flatVersion;
552  ++count;
553  }
554 
555  //record in readme for moveto
556  {
557  FILE *fp = fopen((moveToDir + "/README_otsdaq_flatten.txt").c_str(),"a");
558  if(!fp)
559  std::cout << __COUT_HDR_FL__ << "\tError opening README file!" << std::endl;
560  else
561  {
562  time_t rawtime;
563  struct tm * timeinfo;
564  char buffer [200];
565 
566  time (&rawtime);
567  timeinfo = localtime (&rawtime);
568  strftime (buffer,200,"%b %d, %Y %I:%M%p %Z",timeinfo);
569 
570  fprintf(fp,"This database was moved from...\n\t %s \nto...\n\t %s \nat this time \n\t %lu \t %s\n\n\n",
571  currentDir.c_str(),moveToDir.c_str(),time(0),buffer);
572 
573  fclose(fp);
574  }
575  }
576 
577 
578  //record in readme for swapin
579  {
580  FILE *fp = fopen((currentDir + "/README_otsdaq_flatten.txt").c_str(),"a");
581 
582  if(!fp)
583  std::cout << __COUT_HDR_FL__ << "\tError opening README file!" << std::endl;
584  else
585  {
586  time_t rawtime;
587  struct tm * timeinfo;
588  char buffer [200];
589 
590  time (&rawtime);
591  timeinfo = localtime (&rawtime);
592  strftime (buffer,200,"%b %d, %Y %I:%M:%S%p %Z",timeinfo);
593 
594  fprintf(fp,"This database was moved from...\t %s \t to...\t %s at this time \t %lu \t %s\n\n",
595  pathToSwapIn.c_str(),currentDir.c_str(),time(0),buffer);
596  fclose(fp);
597  }
598  }
599 
600 // //print resulting all groups
601 //
602 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups:" << std::endl;
603 // for(const auto &group: groupSet)
604 // std::cout << __COUT_HDR_FL__ << group.first.first << ": " <<
605 // group.first.second << " => " << group.second << std::endl;
606 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups end." << std::endl;
607 //
608 //
609 // //print resulting active groups
610 //
611 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups:" << std::endl;
612 // for(const auto &activeGroup: activeGroupKeys)
613 // std::cout << __COUT_HDR_FL__ << activeGroup.first << ": " <<
614 // activeGroup.second.first << " => " << activeGroup.second.second << std::endl;
615 //
616 // std::cout << __COUT_HDR_FL__ << activeBackboneGroupName << " is the " <<
617 // ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE << "." << std::endl;
618 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups end." << std::endl;
619 
620 
621 
622 
623 
624  //reload the active backbone (using activeGroupKeys)
625  // modify group aliases and table aliases properly based on groupSet and modifiedTables
626  // save new backbone with flatVersion to new DB
627 
628  if(activeBackboneGroupName == "")
629  {
630  std::cout << __COUT_HDR_FL__ << "No active Backbone table identified." << std::endl;
631  goto CLEAN_UP;
632  }
633 
634  std::cout << "\n\n" << __COUT_HDR_FL__ <<
635  "Modifying the active Backbone table to reflect new table versions and group keys." <<
636  std::endl;
637 
638  {
639  memberMap =
640  cfgMgr->loadConfigurationGroup(
641  activeBackboneGroupName,
642  activeGroupKeys[activeBackboneGroupName].second,
643  true,0,&accumulateErrors);
644 
645  //modify GroupAliasesConfiguration and VersionAliasesConfiguration to point
646  // at DEFAULT and flatVersion respectively
647 
648  const std::string groupAliasesName = "GroupAliasesConfiguration";
649  const std::string versionAliasesName = "VersionAliasesConfiguration";
650 
651 
652  std::map<std::string, ConfigurationVersion> activeMap = cfgMgr->getActiveVersions();
653 
654  //modify GroupAliasesConfiguration
655  if(activeMap.find(groupAliasesName) != activeMap.end())
656  {
657  std::cout << __COUT_HDR_FL__ << "\n\nModifying " << groupAliasesName << std::endl;
658  config = cfgMgr->getConfigurationByName(groupAliasesName);
659  cfgView = config->getViewP();
660 
661  unsigned int col1 = cfgView->findCol("GroupName");
662  unsigned int col2 = cfgView->findCol("GroupKey");
663 
664  //cfgView->print();
665 
666  //change all key entries found to the new key and delete rows for groups not found
667  bool found;
668  for(unsigned int row = 0; row<cfgView->getNumberOfRows(); ++row )
669  {
670  found = false;
671  for(const auto &group: groupSet)
672  if(group.second.isInvalid()) continue;
673  else if(cfgView->getDataView()[row][col1] == group.first.first &&
674  cfgView->getDataView()[row][col2] == group.first.second.toString())
675  {
676  //found a matching group/key pair
677  std::cout << __COUT_HDR_FL__ <<
678  "Changing row " << row << " for " <<
679  cfgView->getDataView()[row][col1] << " key=" <<
680  cfgView->getDataView()[row][col2] << " to NEW key=" <<
681  group.second << std::endl;
682  cfgView->setValue(
683  group.second.toString(),
684  row,col2);
685  found = true;
686  break;
687  }
688 
689  if(!found) //delete row
690  cfgView->deleteRow(row--);
691  }
692  //cfgView->print();
693  }
694 
695  //modify VersionAliasesConfiguration
696  if(activeMap.find(versionAliasesName) != activeMap.end())
697  {
698  std::cout << __COUT_HDR_FL__ << "\n\nModifying " << versionAliasesName << std::endl;
699  config = cfgMgr->getConfigurationByName(versionAliasesName);
700  cfgView = config->getViewP();
701  unsigned int col1 = cfgView->findCol("ConfigurationName");
702  unsigned int col2 = cfgView->findCol("Version");
703 
704  //change all version entries to the new version and delete rows with no match
705  bool found;
706  for(unsigned int row = 0; row<cfgView->getNumberOfRows(); ++row )
707  {
708  found = false;
709  for(const auto &table:modifiedTables)
710  if(cfgView->getDataView()[row][col1] == table.first.first &&
711  cfgView->getDataView()[row][col2] == table.first.second.toString())
712  {
713  //found a matching group/key pair
714  std::cout << __COUT_HDR_FL__ << "Changing row " << row << " for " <<
715  cfgView->getDataView()[row][col1] << " version=" <<
716  cfgView->getDataView()[row][col2] << " to NEW version=" <<
717  table.second << std::endl;
718  cfgView->setValue(table.second.toString(),row,col2);
719  found = true;
720  break;
721  }
722 
723  if(!found) //delete row
724  cfgView->deleteRow(row--);
725  }
726  }
727 
728 
729 
730  //save new "GroupAliasesConfiguration" and "VersionAliasesConfiguration"
731 
732  std::cout << __COUT_HDR_FL__ << groupAliasesName << ":v" <<
733  memberMap[groupAliasesName] << std::endl;
734  //change the version of the active view to flatVersion and save it
735  config = cfgMgr->getConfigurationByName(groupAliasesName);
736  cfgView = config->getViewP();
737  cfgView->setVersion(ConfigurationVersion(flatVersion));
738  theInterface_->saveActiveVersion(config);
739 
740  memberMap[groupAliasesName] = flatVersion; //change version in the member map
741 
742  std::cout << __COUT_HDR_FL__ << "\t to...\t" <<
743  groupAliasesName << ":v" << memberMap[groupAliasesName] << std::endl;
744 
745 
746 
747  std::cout << __COUT_HDR_FL__ << versionAliasesName << ":v" <<
748  memberMap[versionAliasesName] << std::endl;
749  //change the version of the active view to flatVersion and save it
750  config = cfgMgr->getConfigurationByName(versionAliasesName);
751  cfgView = config->getViewP();
752  cfgView->setVersion(ConfigurationVersion(flatVersion));
753  theInterface_->saveActiveVersion(config);
754 
755  memberMap[versionAliasesName] = flatVersion; //change version in the member map
756 
757  std::cout << __COUT_HDR_FL__ << "\t to...\t" <<
758  versionAliasesName << ":v" << memberMap[versionAliasesName] << std::endl;
759 
760  //memberMap should now consist of members with new flat version, so save
761  theInterface_->saveConfigurationGroup(memberMap,
762  ConfigurationGroupKey::getFullGroupString(
763  activeBackboneGroupName,
764  ConfigurationGroupKey(flatVersion)));
765 
766  activeGroupKeys[activeBackboneGroupName].second =
767  ConfigurationGroupKey(flatVersion);
768 
769  std::cout << __COUT_HDR_FL__ << "New to-be-active backbone group " << activeBackboneGroupName <<
770  ":v" << activeGroupKeys[activeBackboneGroupName].second << std::endl;
771  }
772 
773 
774 
775  //backup the file ConfigurationManager::ACTIVE_GROUP_FILENAME with time
776  // and change the ConfigurationManager::ACTIVE_GROUP_FILENAME
777  // to reflect new group names/keys
778 
779  {
780  std::cout << "\n\n" << __COUT_HDR_FL__ << "Manipulating the Active Groups file..." << std::endl;
781 
782  //check if original active file exists
783  FILE *fp = fopen(ConfigurationManager::ACTIVE_GROUP_FILENAME.c_str(),"r");
784  if(!fp)
785  {
786  __SS__ << "Original active groups file '" << ConfigurationManager::ACTIVE_GROUP_FILENAME
787  << "' not found." << std::endl;
788  goto CLEAN_UP;
789  }
790 
791  std::cout << __COUT_HDR_FL__ << "Backing up file: " << ConfigurationManager::ACTIVE_GROUP_FILENAME
792  << std::endl;
793 
794  fclose(fp);
795 
796  std::string renameFile = ConfigurationManager::ACTIVE_GROUP_FILENAME + "." + nowTime;
797  rename(ConfigurationManager::ACTIVE_GROUP_FILENAME.c_str(),
798  renameFile.c_str());
799 
800  std::cout << __COUT_HDR_FL__ << "Backup file name: " << renameFile
801  << std::endl;
802 
803  ConfigurationGroupKey *theConfigurationGroupKey_, *theContextGroupKey_, *theBackboneGroupKey_, *theIterateGroupKey_;
804  std::string theConfigurationGroup_, theContextGroup_, theBackboneGroup_, theIterateGroup_;
805 
806  theConfigurationGroup_ = activeConfigGroupName;
807  theConfigurationGroupKey_ = &(activeGroupKeys[activeConfigGroupName].second);
808 
809  theContextGroup_ = activeContextGroupName;
810  theContextGroupKey_ = &(activeGroupKeys[activeContextGroupName].second);
811 
812  theBackboneGroup_ = activeBackboneGroupName;
813  theBackboneGroupKey_ = &(activeGroupKeys[activeBackboneGroupName].second);
814 
815  theIterateGroup_ = activeIterateGroupName;
816  theIterateGroupKey_ = &(activeGroupKeys[activeIterateGroupName].second);
817 
818 
819  //the following is copied from ConfigurationManagerRW::activateConfigurationGroup
820  {
821  std::cout << __COUT_HDR_FL__ << "Updating persistent active groups to " <<
822  ConfigurationManager::ACTIVE_GROUP_FILENAME << " ..." << std::endl;
823 
824  std::string fn = ConfigurationManager::ACTIVE_GROUP_FILENAME;
825  FILE *fp = fopen(fn.c_str(),"w");
826  if(!fp) return;
827 
828  fprintf(fp,"%s\n",theContextGroup_.c_str());
829  fprintf(fp,"%s\n",theContextGroupKey_?theContextGroupKey_->toString().c_str():"-1");
830  fprintf(fp,"%s\n",theBackboneGroup_.c_str());
831  fprintf(fp,"%s\n",theBackboneGroupKey_?theBackboneGroupKey_->toString().c_str():"-1");
832  fprintf(fp,"%s\n",theConfigurationGroup_.c_str());
833  fprintf(fp,"%s\n",theConfigurationGroupKey_?theConfigurationGroupKey_->toString().c_str():"-1");
834  fprintf(fp,"%s\n",theIterateGroup_.c_str());
835  fprintf(fp,"%s\n",theIterateGroupKey_?theIterateGroupKey_->toString().c_str():"-1");
836  fclose(fp);
837  }
838  }
839 
840  //print resulting all groups
841 
842  std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups:" << std::endl;
843  for(const auto &group: groupSet)
844  std::cout << __COUT_HDR_FL__ << "\t" << group.first.first << ": " <<
845  group.first.second << " => " << group.second << std::endl;
846  std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups end." << std::endl;
847 
848 
849  //print resulting active groups
850 
851  std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups:" << std::endl;
852  for(const auto &activeGroup: activeGroupKeys)
853  std::cout << __COUT_HDR_FL__ << "\t" << activeGroup.first << ": " <<
854  activeGroup.second.first << " => " << activeGroup.second.second << std::endl;
855 
856  std::cout << __COUT_HDR_FL__ << activeBackboneGroupName << " is the " <<
857  ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE << "." << std::endl;
858  std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups end." << std::endl;
859 
860 
861 CLEAN_UP:
862  //==============================================================================
863  std::cout << "\n\n" << __COUT_HDR_FL__ << "End of Flattening Active Configuration Groups!\n\n\n" << std::endl;
864 
865 
866 
867  std::cout << __COUT_HDR_FL__ << "****************************" << std::endl;
868  std::cout << __COUT_HDR_FL__ << "There were " << groupSet.size() <<
869  " groups considered, and there were errors handling " << groupErrors.size() <<
870  " of those groups." << std::endl;
871  std::cout << __COUT_HDR_FL__ << "The following errors were found handling the groups:" << std::endl;
872  for(auto& groupErr:groupErrors)
873  std::cout << __COUT_HDR_FL__ << "\t" << groupErr.first.first << " " << groupErr.first.second <<
874  ": \t" << groupErr.second << std::endl;
875  std::cout << __COUT_HDR_FL__ << "End of errors.\n\n" << std::endl;
876 
877 
878  std::cout << __COUT_HDR_FL__ << "Run the following to return to your previous database structure:" <<
879  std::endl;
880  std::cout << __COUT_HDR_FL__ << "\t otsdaq_flatten_system_aliases -1 " << moveToDir <<
881  "\n\n" << std::endl;
882 
883 
884  return;
885 }
886 
887 int main(int argc, char* argv[])
888 {
889  FlattenActiveSystemAliasConfigurationGroups(argc,argv);
890  return 0;
891 }
892 //BOOST_AUTO_TEST_SUITE_END()
893 
894