otsdaq  v2_00_00
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  cfgMgr->loadConfigurationGroup(
368  groupPair.first.first,
369  groupPair.first.second,
370  true,&memberMap/*memberMap*/,0,&accumulateErrors);
371  }
372  catch(std::runtime_error& e)
373  {
374 
375  std::cout << __COUT_HDR_FL__ << "Error was caught loading members for " <<
376  groupPair.first.first <<
377  "(" << groupPair.first.second << ")" <<
378  std::endl;
379  std::cout << __COUT_HDR_FL__ << e.what() << std::endl;
380  errDetected = true;
381  }
382  catch(...)
383  {
384  std::cout << __COUT_HDR_FL__ << "Error was caught loading members for " <<
385  groupPair.first.first <<
386  "(" << groupPair.first.second << ")" <<
387  std::endl;
388  errDetected = true;
389  }
390 
391  //=========================
392 
393  //if(count == 2) break;
394 
395 
396  //handle directory swap
397  std::cout << __COUT_HDR_FL__ << "Moving current directory: \t" << currentDir << std::endl;
398  std::cout << __COUT_HDR_FL__ << "\t... to: \t\t" << moveToDir << std::endl;
399  if(rename(currentDir.c_str(),moveToDir.c_str()) < 0)
400  {
401  __SS__ << "Problem!" << std::endl;
402  throw std::runtime_error(ss.str());
403  }
404 
405  if(pathToSwapIn != "")
406  {
407  std::cout << __COUT_HDR_FL__ << "Swapping in directory: \t" << pathToSwapIn << std::endl;
408  std::cout << __COUT_HDR_FL__ << "\t.. to: \t\t" << currentDir << std::endl;
409  if(rename(pathToSwapIn.c_str(),currentDir.c_str()) < 0)
410  {
411  __SS__ << "Problem!" << std::endl;
412  throw std::runtime_error(ss.str());
413  }
414  }
415  else if(count) //if not first time, replace from temporarily holding area
416  {
417  std::cout << __COUT_HDR_FL__ << "Moving temporary directory: \t" << (moveToDir+"_tmp") << std::endl;
418  std::cout << __COUT_HDR_FL__ << "\t.. to current directory: \t\t" << currentDir << std::endl;
419  if(rename((moveToDir+"_tmp").c_str(),currentDir.c_str()) < 0)
420  {
421  __SS__ << "Problem!" << std::endl;
422  throw std::runtime_error(ss.str());
423  }
424  }
425 
426 
427  //exit loop if any (loading) failure
428  if(errDetected)
429  {
430  //goto CLEAN_UP;
431 
432  //power on if group failed
433  // and record error
434 
435  groupErrors.insert(std::pair<
436  std::pair<std::string,ConfigurationGroupKey>,
437  std::string> (
438  std::pair<std::string,ConfigurationGroupKey>(
439  groupPair.first.first,
440  groupPair.first.second),
441  "Error caught loading the group."));
442  continue;
443  }
444 
445 
446 
447 
448  //=========================
449  //save group and its tables with new key and versions!
450  try
451  {
452  //saving tables
453  for(auto &memberPair:memberMap)
454  {
455  std::cout << __COUT_HDR_FL__ << memberPair.first << ":v" << memberPair.second << std::endl;
456 
457  //check if table has already been modified by a previous group
458  // (i.e. two groups using the same version of a table)
459  if(modifiedTables.find(std::pair<std::string,ConfigurationVersion>(
460  memberPair.first,
461  memberPair.second
462  )) != modifiedTables.end())
463  {
464 
465  std::cout << __COUT_HDR_FL__ << "Table was already modified!" << std::endl;
466  memberPair.second = modifiedTables[std::pair<std::string,ConfigurationVersion>(
467  memberPair.first,
468  memberPair.second
469  )];
470  std::cout << __COUT_HDR_FL__ << "\t to...\t" <<
471  memberPair.first << ":v" << memberPair.second << std::endl;
472  continue;
473  }
474 
475  //change the version of the active view to flatVersion and save it
476  config = cfgMgr->getConfigurationByName(memberPair.first);
477  cfgView = config->getViewP();
478  cfgView->setVersion(ConfigurationVersion(flatVersion));
479  theInterface_->saveActiveVersion(config);
480 
481  //set it back for the table so that future groups can re-use cached version
482  cfgView->setVersion(memberPair.second); //IMPORTANT
483 
484  memberPair.second = flatVersion; //change version in the member map
485 
486  std::cout << __COUT_HDR_FL__ << "\t to...\t" <<
487  memberPair.first << ":v" << memberPair.second << std::endl;
488 
489  //save new version to modifiedTables
490  modifiedTables.insert(std::pair<
491  std::pair<std::string,ConfigurationVersion>,
493  std::pair<std::string,ConfigurationVersion>(
494  memberPair.first,
495  memberPair.second),
496  ConfigurationVersion(flatVersion))
497  );
498  }
499 
500  //memberMap should now consist of members with new flat version, so save
501  theInterface_->saveConfigurationGroup(memberMap,
502  ConfigurationGroupKey::getFullGroupString(
503  groupPair.first.first,
504  ConfigurationGroupKey(flatVersion)));
505 
506  //and modify groupSet and activeGroupKeys keys
507  groupPair.second = ConfigurationGroupKey(flatVersion);
508 
509  //if this is an active group, save key change
510  if(activeGroupKeys.find(groupPair.first.first) != activeGroupKeys.end() &&
511  activeGroupKeys[groupPair.first.first].first == groupPair.first.second)
512  activeGroupKeys[groupPair.first.first].second =
513  ConfigurationGroupKey(flatVersion);
514  }
515  catch(std::runtime_error& e)
516  {
517  std::cout << __COUT_HDR_FL__ << "Error was caught saving group " <<
518  groupPair.first.first <<
519  " (" << groupPair.first.second << ") " <<
520  std::endl;
521  std::cout << __COUT_HDR_FL__ << e.what() << std::endl;
522 
523  groupErrors.insert(std::pair<
524  std::pair<std::string,ConfigurationGroupKey>,
525  std::string> (
526  std::pair<std::string,ConfigurationGroupKey>(
527  groupPair.first.first,
528  groupPair.first.second),
529  "Error caught saving the group."));
530  }
531  catch(...)
532  {
533  std::cout << __COUT_HDR_FL__ << "Error was caught saving group " <<
534  groupPair.first.first <<
535  " (" << groupPair.first.second << ") " <<
536  std::endl;
537 
538  groupErrors.insert(std::pair<
539  std::pair<std::string,ConfigurationGroupKey>,
540  std::string> (
541  std::pair<std::string,ConfigurationGroupKey>(
542  groupPair.first.first,
543  groupPair.first.second),
544  "Error caught saving the group."));
545  }
546  //=========================
547 
548 
549  //increment flat version
550  ++flatVersion;
551  ++count;
552  }
553 
554  //record in readme for moveto
555  {
556  FILE *fp = fopen((moveToDir + "/README_otsdaq_flatten.txt").c_str(),"a");
557  if(!fp)
558  std::cout << __COUT_HDR_FL__ << "\tError opening README file!" << std::endl;
559  else
560  {
561  time_t rawtime;
562  struct tm * timeinfo;
563  char buffer [200];
564 
565  time (&rawtime);
566  timeinfo = localtime (&rawtime);
567  strftime (buffer,200,"%b %d, %Y %I:%M%p %Z",timeinfo);
568 
569  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",
570  currentDir.c_str(),moveToDir.c_str(),time(0),buffer);
571 
572  fclose(fp);
573  }
574  }
575 
576 
577  //record in readme for swapin
578  {
579  FILE *fp = fopen((currentDir + "/README_otsdaq_flatten.txt").c_str(),"a");
580 
581  if(!fp)
582  std::cout << __COUT_HDR_FL__ << "\tError opening README file!" << std::endl;
583  else
584  {
585  time_t rawtime;
586  struct tm * timeinfo;
587  char buffer [200];
588 
589  time (&rawtime);
590  timeinfo = localtime (&rawtime);
591  strftime (buffer,200,"%b %d, %Y %I:%M:%S%p %Z",timeinfo);
592 
593  fprintf(fp,"This database was moved from...\t %s \t to...\t %s at this time \t %lu \t %s\n\n",
594  pathToSwapIn.c_str(),currentDir.c_str(),time(0),buffer);
595  fclose(fp);
596  }
597  }
598 
599 // //print resulting all groups
600 //
601 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups:" << std::endl;
602 // for(const auto &group: groupSet)
603 // std::cout << __COUT_HDR_FL__ << group.first.first << ": " <<
604 // group.first.second << " => " << group.second << std::endl;
605 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups end." << std::endl;
606 //
607 //
608 // //print resulting active groups
609 //
610 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups:" << std::endl;
611 // for(const auto &activeGroup: activeGroupKeys)
612 // std::cout << __COUT_HDR_FL__ << activeGroup.first << ": " <<
613 // activeGroup.second.first << " => " << activeGroup.second.second << std::endl;
614 //
615 // std::cout << __COUT_HDR_FL__ << activeBackboneGroupName << " is the " <<
616 // ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE << "." << std::endl;
617 // std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups end." << std::endl;
618 
619 
620 
621 
622 
623  //reload the active backbone (using activeGroupKeys)
624  // modify group aliases and table aliases properly based on groupSet and modifiedTables
625  // save new backbone with flatVersion to new DB
626 
627  if(activeBackboneGroupName == "")
628  {
629  std::cout << __COUT_HDR_FL__ << "No active Backbone table identified." << std::endl;
630  goto CLEAN_UP;
631  }
632 
633  std::cout << "\n\n" << __COUT_HDR_FL__ <<
634  "Modifying the active Backbone table to reflect new table versions and group keys." <<
635  std::endl;
636 
637  {
638  cfgMgr->loadConfigurationGroup(
639  activeBackboneGroupName,
640  activeGroupKeys[activeBackboneGroupName].second,
641  true,&memberMap,0,&accumulateErrors);
642 
643  //modify GroupAliasesConfiguration and VersionAliasesConfiguration to point
644  // at DEFAULT and flatVersion respectively
645 
646  const std::string groupAliasesName = "GroupAliasesConfiguration";
647  const std::string versionAliasesName = "VersionAliasesConfiguration";
648 
649 
650  std::map<std::string, ConfigurationVersion> activeMap = cfgMgr->getActiveVersions();
651 
652  //modify GroupAliasesConfiguration
653  if(activeMap.find(groupAliasesName) != activeMap.end())
654  {
655  std::cout << __COUT_HDR_FL__ << "\n\nModifying " << groupAliasesName << std::endl;
656  config = cfgMgr->getConfigurationByName(groupAliasesName);
657  cfgView = config->getViewP();
658 
659  unsigned int col1 = cfgView->findCol("GroupName");
660  unsigned int col2 = cfgView->findCol("GroupKey");
661 
662  //cfgView->print();
663 
664  //change all key entries found to the new key and delete rows for groups not found
665  bool found;
666  for(unsigned int row = 0; row<cfgView->getNumberOfRows(); ++row )
667  {
668  found = false;
669  for(const auto &group: groupSet)
670  if(group.second.isInvalid()) continue;
671  else if(cfgView->getDataView()[row][col1] == group.first.first &&
672  cfgView->getDataView()[row][col2] == group.first.second.toString())
673  {
674  //found a matching group/key pair
675  std::cout << __COUT_HDR_FL__ <<
676  "Changing row " << row << " for " <<
677  cfgView->getDataView()[row][col1] << " key=" <<
678  cfgView->getDataView()[row][col2] << " to NEW key=" <<
679  group.second << std::endl;
680  cfgView->setValue(
681  group.second.toString(),
682  row,col2);
683  found = true;
684  break;
685  }
686 
687  if(!found) //delete row
688  cfgView->deleteRow(row--);
689  }
690  //cfgView->print();
691  }
692 
693  //modify VersionAliasesConfiguration
694  if(activeMap.find(versionAliasesName) != activeMap.end())
695  {
696  std::cout << __COUT_HDR_FL__ << "\n\nModifying " << versionAliasesName << std::endl;
697  config = cfgMgr->getConfigurationByName(versionAliasesName);
698  cfgView = config->getViewP();
699  unsigned int col1 = cfgView->findCol("ConfigurationName");
700  unsigned int col2 = cfgView->findCol("Version");
701 
702  //change all version entries to the new version and delete rows with no match
703  bool found;
704  for(unsigned int row = 0; row<cfgView->getNumberOfRows(); ++row )
705  {
706  found = false;
707  for(const auto &table:modifiedTables)
708  if(cfgView->getDataView()[row][col1] == table.first.first &&
709  cfgView->getDataView()[row][col2] == table.first.second.toString())
710  {
711  //found a matching group/key pair
712  std::cout << __COUT_HDR_FL__ << "Changing row " << row << " for " <<
713  cfgView->getDataView()[row][col1] << " version=" <<
714  cfgView->getDataView()[row][col2] << " to NEW version=" <<
715  table.second << std::endl;
716  cfgView->setValue(table.second.toString(),row,col2);
717  found = true;
718  break;
719  }
720 
721  if(!found) //delete row
722  cfgView->deleteRow(row--);
723  }
724  }
725 
726 
727 
728  //save new "GroupAliasesConfiguration" and "VersionAliasesConfiguration"
729 
730  std::cout << __COUT_HDR_FL__ << groupAliasesName << ":v" <<
731  memberMap[groupAliasesName] << std::endl;
732  //change the version of the active view to flatVersion and save it
733  config = cfgMgr->getConfigurationByName(groupAliasesName);
734  cfgView = config->getViewP();
735  cfgView->setVersion(ConfigurationVersion(flatVersion));
736  theInterface_->saveActiveVersion(config);
737 
738  memberMap[groupAliasesName] = flatVersion; //change version in the member map
739 
740  std::cout << __COUT_HDR_FL__ << "\t to...\t" <<
741  groupAliasesName << ":v" << memberMap[groupAliasesName] << std::endl;
742 
743 
744 
745  std::cout << __COUT_HDR_FL__ << versionAliasesName << ":v" <<
746  memberMap[versionAliasesName] << std::endl;
747  //change the version of the active view to flatVersion and save it
748  config = cfgMgr->getConfigurationByName(versionAliasesName);
749  cfgView = config->getViewP();
750  cfgView->setVersion(ConfigurationVersion(flatVersion));
751  theInterface_->saveActiveVersion(config);
752 
753  memberMap[versionAliasesName] = flatVersion; //change version in the member map
754 
755  std::cout << __COUT_HDR_FL__ << "\t to...\t" <<
756  versionAliasesName << ":v" << memberMap[versionAliasesName] << std::endl;
757 
758  //memberMap should now consist of members with new flat version, so save
759  theInterface_->saveConfigurationGroup(memberMap,
760  ConfigurationGroupKey::getFullGroupString(
761  activeBackboneGroupName,
762  ConfigurationGroupKey(flatVersion)));
763 
764  activeGroupKeys[activeBackboneGroupName].second =
765  ConfigurationGroupKey(flatVersion);
766 
767  std::cout << __COUT_HDR_FL__ << "New to-be-active backbone group " << activeBackboneGroupName <<
768  ":v" << activeGroupKeys[activeBackboneGroupName].second << std::endl;
769  }
770 
771 
772 
773  //backup the file ConfigurationManager::ACTIVE_GROUP_FILENAME with time
774  // and change the ConfigurationManager::ACTIVE_GROUP_FILENAME
775  // to reflect new group names/keys
776 
777  {
778  std::cout << "\n\n" << __COUT_HDR_FL__ << "Manipulating the Active Groups file..." << std::endl;
779 
780  //check if original active file exists
781  FILE *fp = fopen(ConfigurationManager::ACTIVE_GROUP_FILENAME.c_str(),"r");
782  if(!fp)
783  {
784  __SS__ << "Original active groups file '" << ConfigurationManager::ACTIVE_GROUP_FILENAME
785  << "' not found." << std::endl;
786  goto CLEAN_UP;
787  }
788 
789  std::cout << __COUT_HDR_FL__ << "Backing up file: " << ConfigurationManager::ACTIVE_GROUP_FILENAME
790  << std::endl;
791 
792  fclose(fp);
793 
794  std::string renameFile = ConfigurationManager::ACTIVE_GROUP_FILENAME + "." + nowTime;
795  rename(ConfigurationManager::ACTIVE_GROUP_FILENAME.c_str(),
796  renameFile.c_str());
797 
798  std::cout << __COUT_HDR_FL__ << "Backup file name: " << renameFile
799  << std::endl;
800 
801  ConfigurationGroupKey *theConfigurationGroupKey_, *theContextGroupKey_, *theBackboneGroupKey_, *theIterateGroupKey_;
802  std::string theConfigurationGroup_, theContextGroup_, theBackboneGroup_, theIterateGroup_;
803 
804  theConfigurationGroup_ = activeConfigGroupName;
805  theConfigurationGroupKey_ = &(activeGroupKeys[activeConfigGroupName].second);
806 
807  theContextGroup_ = activeContextGroupName;
808  theContextGroupKey_ = &(activeGroupKeys[activeContextGroupName].second);
809 
810  theBackboneGroup_ = activeBackboneGroupName;
811  theBackboneGroupKey_ = &(activeGroupKeys[activeBackboneGroupName].second);
812 
813  theIterateGroup_ = activeIterateGroupName;
814  theIterateGroupKey_ = &(activeGroupKeys[activeIterateGroupName].second);
815 
816 
817  //the following is copied from ConfigurationManagerRW::activateConfigurationGroup
818  {
819  std::cout << __COUT_HDR_FL__ << "Updating persistent active groups to " <<
820  ConfigurationManager::ACTIVE_GROUP_FILENAME << " ..." << std::endl;
821 
822  std::string fn = ConfigurationManager::ACTIVE_GROUP_FILENAME;
823  FILE *fp = fopen(fn.c_str(),"w");
824  if(!fp) return;
825 
826  fprintf(fp,"%s\n",theContextGroup_.c_str());
827  fprintf(fp,"%s\n",theContextGroupKey_?theContextGroupKey_->toString().c_str():"-1");
828  fprintf(fp,"%s\n",theBackboneGroup_.c_str());
829  fprintf(fp,"%s\n",theBackboneGroupKey_?theBackboneGroupKey_->toString().c_str():"-1");
830  fprintf(fp,"%s\n",theConfigurationGroup_.c_str());
831  fprintf(fp,"%s\n",theConfigurationGroupKey_?theConfigurationGroupKey_->toString().c_str():"-1");
832  fprintf(fp,"%s\n",theIterateGroup_.c_str());
833  fprintf(fp,"%s\n",theIterateGroupKey_?theIterateGroupKey_->toString().c_str():"-1");
834  fclose(fp);
835  }
836  }
837 
838  //print resulting all groups
839 
840  std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups:" << std::endl;
841  for(const auto &group: groupSet)
842  std::cout << __COUT_HDR_FL__ << "\t" << group.first.first << ": " <<
843  group.first.second << " => " << group.second << std::endl;
844  std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Groups end." << std::endl;
845 
846 
847  //print resulting active groups
848 
849  std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups:" << std::endl;
850  for(const auto &activeGroup: activeGroupKeys)
851  std::cout << __COUT_HDR_FL__ << "\t" << activeGroup.first << ": " <<
852  activeGroup.second.first << " => " << activeGroup.second.second << std::endl;
853 
854  std::cout << __COUT_HDR_FL__ << activeBackboneGroupName << " is the " <<
855  ConfigurationManager::ACTIVE_GROUP_NAME_BACKBONE << "." << std::endl;
856  std::cout << "\n\n" << __COUT_HDR_FL__ << "Resulting Active Groups end." << std::endl;
857 
858 
859 CLEAN_UP:
860  //==============================================================================
861  std::cout << "\n\n" << __COUT_HDR_FL__ << "End of Flattening Active Configuration Groups!\n\n\n" << std::endl;
862 
863 
864 
865  std::cout << __COUT_HDR_FL__ << "****************************" << std::endl;
866  std::cout << __COUT_HDR_FL__ << "There were " << groupSet.size() <<
867  " groups considered, and there were errors handling " << groupErrors.size() <<
868  " of those groups." << std::endl;
869  std::cout << __COUT_HDR_FL__ << "The following errors were found handling the groups:" << std::endl;
870  for(auto& groupErr:groupErrors)
871  std::cout << __COUT_HDR_FL__ << "\t" << groupErr.first.first << " " << groupErr.first.second <<
872  ": \t" << groupErr.second << std::endl;
873  std::cout << __COUT_HDR_FL__ << "End of errors.\n\n" << std::endl;
874 
875 
876  std::cout << __COUT_HDR_FL__ << "Run the following to return to your previous database structure:" <<
877  std::endl;
878  std::cout << __COUT_HDR_FL__ << "\t otsdaq_flatten_system_aliases -1 " << moveToDir <<
879  "\n\n" << std::endl;
880 
881 
882  return;
883 }
884 
885 int main(int argc, char* argv[])
886 {
887  FlattenActiveSystemAliasConfigurationGroups(argc,argv);
888  return 0;
889 }
890 //BOOST_AUTO_TEST_SUITE_END()
891 
892