otsdaq  v1_01_02
 All Classes Namespaces Functions
otsdaq_flatten_active_to_version.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_active_to_version <flatVersion> <pathToSwapIn (optional)>
13 //
14 // if flatVersion 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 FlattenActiveConfigurationGroups(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 Configuration Groups!" << std::endl;
26 
27  std::cout << "\n\nusage: Two arguments:\n\t pathToSwapIn <flatVersion> <pathToSwapIn (optional)> \n\n" <<
28  "\t Default values: flatVersion = 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 flatVersion 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 
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  //also xdaq envs for XDAQContextConfiguration
84  setenv("XDAQ_CONFIGURATION_DATA_PATH",(std::string(getenv("USER_DATA")) + "/XDAQConfigurations").c_str(),1);
85  setenv("XDAQ_CONFIGURATION_XML","otsConfigurationNoRU_CMake",1);
87 
88  //==============================================================================
89  //get prepared with initial source db
90 
91  //ConfigurationManager instance immediately loads active groups
92  ConfigurationManagerRW cfgMgrInst("flatten_admin");
93  ConfigurationManagerRW *cfgMgr = &cfgMgrInst;
94 
95  std::cout << __COUT_HDR_FL__ << "\n\n\nLoading activeGroupsMap..." << std::endl;
96 
97  //save group members to reform groups
98  std::map<std::string, std::pair<std::string, ConfigurationGroupKey> > activeGroupsMap =
99  cfgMgr->getActiveConfigurationGroups();
100 
101  std::map<std::string, std::map<std::string, ConfigurationVersion> > activeGroupMembersMap;
102  for(auto &activeGroupPair: activeGroupsMap)
103  {
104  if(activeGroupPair.second.second.isInvalid())
105  {
106  std::cout << __COUT_HDR_FL__ << "Skipping invalid " <<
107  activeGroupPair.first << std::endl;
108  continue;
109  }
110 
111  std::cout << __COUT_HDR_FL__ << "Loading members for " <<
112  activeGroupPair.first << "\t" <<
113  activeGroupPair.second.first << "(" << activeGroupPair.second.second << ")" <<
114  std::endl;
115 
116  activeGroupMembersMap[activeGroupPair.second.first] =
117  cfgMgr->getConfigurationInterface()->getConfigurationGroupMembers(
118  ConfigurationGroupKey::getFullGroupString(
119  activeGroupPair.second.first,activeGroupPair.second.second));
120  }
121 
122 
123  //==============================================================================
124  //manipulate directories
125  std::string currentDir = getenv("ARTDAQ_DATABASE_URI");
126 
127  if(currentDir.find("filesystemdb://") != 0)
128  throw std::runtime_error("filesystemdb:// was not found in $ARTDAQ_DATABASE_URI!");
129 
130  currentDir = currentDir.substr(std::string("filesystemdb://").length());
131  while(currentDir.length() && currentDir[currentDir.length()-1] == '/') //remove trailing '/'s
132  currentDir = currentDir.substr(0,currentDir.length()-1);
133  std::string moveToDir = currentDir + "_" + std::to_string(time(0));
134 
135  std::cout << __COUT_HDR_FL__ << "Moving current directory: \t" << currentDir << std::endl;
136  std::cout << __COUT_HDR_FL__ << "\t... to: \t\t" << moveToDir << std::endl;
137 
138  if(argc < 2)
139  throw std::runtime_error("Aborting move! Must at least give version argument to flatten to!");
140 
141  rename(currentDir.c_str(),moveToDir.c_str());
142  FILE *fp = fopen((moveToDir + "/README_otsdaq_flatten.txt").c_str(),"a");
143  if(!fp)
144  std::cout << __COUT_HDR_FL__ << "\tError opening README file!" << std::endl;
145  else
146  {
147  time_t rawtime;
148  struct tm * timeinfo;
149  char buffer [200];
150 
151  time (&rawtime);
152  timeinfo = localtime (&rawtime);
153  strftime (buffer,200,"%b %d, %Y %I:%M%p %Z",timeinfo);
154 
155  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",
156  currentDir.c_str(),moveToDir.c_str(),time(0),buffer);
157 
158  fclose(fp);
159  }
160 
161  if(pathToSwapIn != "")
162  {
163  DIR *dp;
164  if((dp = opendir(pathToSwapIn.c_str())) == 0)
165  {
166  std::cout << __COUT_HDR_FL__<< "ERROR:(" << errno << "). Can't open directory: " << pathToSwapIn << std::endl;
167  exit(0);
168  }
169  closedir(dp);
170 
171  std::cout << __COUT_HDR_FL__ << "Swapping in directory: \t" << pathToSwapIn << std::endl;
172  std::cout << __COUT_HDR_FL__ << "\t.. to: \t\t" << currentDir << std::endl;
173 
174  rename(pathToSwapIn.c_str(),currentDir.c_str());
175  FILE *fp = fopen((currentDir + "/README_otsdaq_flatten.txt").c_str(),"a");
176  if(!fp)
177  std::cout << __COUT_HDR_FL__ << "\tError opening README file!" << std::endl;
178  else
179  {
180  time_t rawtime;
181  struct tm * timeinfo;
182  char buffer [200];
183 
184  time (&rawtime);
185  timeinfo = localtime (&rawtime);
186  strftime (buffer,200,"%b %d, %Y %I:%M:%S%p %Z",timeinfo);
187 
188  fprintf(fp,"This database was moved from...\t %s \t to...\t %s at this time \t %lu \t %s\n\n",
189  pathToSwapIn.c_str(),currentDir.c_str(),time(0),buffer);
190  fclose(fp);
191  }
192  }
193 
194 
195  //==============================================================================
196  //save current active versions with flatVersion
197  // Note: do not try this at home kids.
198  ConfigurationInterface* theInterface_ = ConfigurationInterface::getInstance(false); //true for File interface, false for artdaq database;
199  ConfigurationView* cfgView;
200  ConfigurationBase* config;
201 
202  std::map<std::string, ConfigurationVersion> activeMap = cfgMgr->getActiveVersions();
203 
204 
205  //modify GroupAliasesConfiguration and VersionAliasesConfiguration to point
206  // at DEFAULT and flatVersion respectively
207 
208  const std::string groupAliasesName = "GroupAliasesConfiguration";
209  const std::string versionAliasesName = "VersionAliasesConfiguration";
210 
211 
212  //don't do anything more if flatVersion is not persistent
213  if(ConfigurationVersion(flatVersion).isInvalid() ||
214  ConfigurationVersion(flatVersion).isTemporaryVersion())
215  {
216  std::cout << __COUT_HDR_FL__ << "\n\nflatVersion " << ConfigurationVersion(flatVersion) <<
217  " is an invalid or temporary version. Skipping to end!" << std::endl;
218  goto CLEAN_UP;
219  }
220 
221 
222  //modify GroupAliasesConfiguration
223  if(activeMap.find(groupAliasesName) != activeMap.end())
224  {
225  std::cout << __COUT_HDR_FL__ << "\n\nModifying " << groupAliasesName << std::endl;
226  config = cfgMgr->getConfigurationByName(groupAliasesName);
227  cfgView = config->getViewP();
228 
229  unsigned int col1 = cfgView->findCol("GroupName");
230  unsigned int col2 = cfgView->findCol("GroupKey");
231 
232  //change all key entries to active groups to DEFAULT
233  for(unsigned int row = 0; row<cfgView->getNumberOfRows(); ++row )
234  for(auto &activeGroupPair: activeGroupsMap)
235  if(activeGroupPair.second.second.isInvalid()) continue;
236  else if(cfgView->getDataView()[row][col1] == activeGroupPair.second.first &&
237  cfgView->getDataView()[row][col2] == activeGroupPair.second.second.toString())
238  {
239  //found a matching group/key pair
240  std::cout << __COUT_HDR_FL__ <<
241  "Changing row " << row << " for " <<
242  cfgView->getDataView()[row][col1] << " key=" <<
243  cfgView->getDataView()[row][col2] << " to DEFAULT=" <<
244  ConfigurationGroupKey(ConfigurationGroupKey::getDefaultKey()) << std::endl;
245  cfgView->setValue(
246  ConfigurationGroupKey(ConfigurationGroupKey::getDefaultKey()).toString(),
247  row,col2);
248  break;
249  }
250 
251  }
252 
253  //modify VersionAliasesConfiguration
254  if(activeMap.find(versionAliasesName) != activeMap.end())
255  {
256  std::cout << __COUT_HDR_FL__ << "\n\nModifying " << versionAliasesName << std::endl;
257  config = cfgMgr->getConfigurationByName(versionAliasesName);
258  cfgView = config->getViewP();
259  unsigned int col1 = cfgView->findCol("ConfigurationName");
260  unsigned int col2 = cfgView->findCol("Version");
261 
262  //change all version entries to active tables to flatVersion
263  for(unsigned int row = 0; row<cfgView->getNumberOfRows(); ++row )
264  for(auto &activePair:activeMap)
265  if(cfgView->getDataView()[row][col1] == activePair.first &&
266  cfgView->getDataView()[row][col2] == activePair.second.toString())
267  {
268  //found a matching group/key pair
269  std::cout << __COUT_HDR_FL__ << "Changing row " << row << " for " <<
270  cfgView->getDataView()[row][col1] << " version=" <<
271  cfgView->getDataView()[row][col2] << " to flatVersion=" <<
272  ConfigurationVersion(flatVersion) << std::endl;
273  cfgView->setValue(ConfigurationVersion(flatVersion).toString(),row,col2);
274  break;
275  }
276  }
277 
278  std::cout << __COUT_HDR_FL__ << "\n\nChanging versions... " << std::endl;
279 
280  for(auto &activePair:activeMap)
281  {
282  std::cout << __COUT_HDR_FL__ << activePair.first << ":v" << activePair.second << std::endl;
283  //change the version of the active view to flatVersion and save it
284  config = cfgMgr->getConfigurationByName(activePair.first);
285  cfgView = config->getViewP();
286  cfgView->setVersion(ConfigurationVersion(flatVersion));
287  theInterface_->saveActiveVersion(config);
288  }
289 
290  //==============================================================================
291  //save the active groups with the new member flatVersions
292  // Note: do not try this at home kids.
293  for(auto &activeGroupMembersPair: activeGroupMembersMap)
294  {
295  std::cout << __COUT_HDR_FL__ << "Group " << activeGroupMembersPair.first << std::endl;
296 
297  for(auto &groupMemberPair: activeGroupMembersPair.second)
298  {
299  std::cout << __COUT_HDR_FL__ << "\t from...\t" <<
300  groupMemberPair.first << ":v" << groupMemberPair.second << std::endl;
301  groupMemberPair.second = flatVersion;
302  }
303 
304  for(auto &groupMemberPair: activeGroupMembersPair.second)
305  {
306  std::cout << __COUT_HDR_FL__ << "\t to...\t" <<
307  groupMemberPair.first << ":v" << groupMemberPair.second << std::endl;
308  }
309 
310  theInterface_->saveConfigurationGroup(activeGroupMembersPair.second,
311  ConfigurationGroupKey::getFullGroupString(
312  activeGroupMembersPair.first,
313  ConfigurationGroupKey(ConfigurationGroupKey::getDefaultKey())));
314  }
315 
316 CLEAN_UP:
317  //==============================================================================
318  std::cout << __COUT_HDR_FL__ << "\n\nEnd of Flattening Active Configuration Groups!\n\n\n" << std::endl;
319 
320 
321  std::cout << __COUT_HDR_FL__ << "Run the following to return to your previous database structure:" <<
322  std::endl;
323  std::cout << __COUT_HDR_FL__ << "\t otsdaq_flatten_active_to_version -1 " << moveToDir <<
324  "\n\n" << std::endl;
325 
326 
327  return;
328 }
329 
330 int main(int argc, char* argv[])
331 {
332  FlattenActiveConfigurationGroups(argc,argv);
333  return 0;
334 }
335 //BOOST_AUTO_TEST_SUITE_END()
336