CMS 3D CMS Logo

CondDBESSource.cc
Go to the documentation of this file.
1 //
2 // Package: CondCore/ESSources
3 // Module: CondDBESSource
4 //
5 // Description: <one line class summary>
6 //
7 // Implementation:
8 // <Notes on implementation>
9 //
10 // Author: Zhen Xie
11 // Fixes and other changes: Giacomo Govi
12 //
13 #include "CondDBESSource.h"
14 
15 #include <boost/algorithm/string.hpp>
20 
23 
29 #include <exception>
30 
31 #include <iomanip>
32 
33 #include <nlohmann/json.hpp>
34 
36 
37 namespace {
38  /* utility ot build the name of the plugin corresponding to a given record
39  se ESSources
40  */
41  std::string buildName(std::string const& iRecordName) { return iRecordName + std::string("@NewProxy"); }
42 
43  std::string joinRecordAndLabel(std::string const& iRecordName, std::string const& iLabelName) {
44  return iRecordName + std::string("@") + iLabelName;
45  }
46 
47  /* utility class to return a IOVs associated to a given "name"
48  This implementation return the IOV associated to a record...
49  It is essentialy a workaround to get the full IOV out of the tag colector
50  that is not accessible as hidden in the ESSource
51  FIXME: need to support label??
52  */
53  class CondGetterFromESSource : public cond::persistency::CondGetter {
54  public:
55  CondGetterFromESSource(CondDBESSource::ResolverMap const& ip) : m_resolvers(ip) {}
56  ~CondGetterFromESSource() override {}
57 
58  cond::persistency::IOVProxy get(std::string name) const override {
59  CondDBESSource::ResolverMap::const_iterator p = m_resolvers.find(name);
60  if (p != m_resolvers.end())
61  return (*p).second->iovProxy();
63  }
64 
65  CondDBESSource::ResolverMap const& m_resolvers;
66  };
67 
68  // This needs to be re-design and implemented...
69  // dump the state of a ProductResolver
70  void dumpInfo(std::ostream& out, std::string const& recName, cond::ProductResolverWrapperBase const& proxy) {
71  //cond::SequenceState state(proxy.proxy()->iov().state());
72  out << recName << " / " << proxy.label() << ": " << proxy.connString() << ", " << proxy.tag()
73  << "\n "
74  // << state.size() << ", " << state.revision() << ", "
75  // << cond::time::to_boost(state.timestamp()) << "\n "
76  // << state.comment()
77  << "\n "
78  // << "refresh " << proxy.proxy()->stats.nRefresh
79  // << "/" << proxy.proxy()->stats.nArefresh
80  // << ", reconnect " << proxy.proxy()->stats.nReconnect
81  // << "/" << proxy.proxy()->stats.nAreconnect
82  // << ", make " << proxy.proxy()->stats.nMake
83  // << ", load " << proxy.proxy()->stats.nLoad
84  ;
85  //if ( proxy.proxy()->stats.nLoad>0) {
86  out << "Time look up, payloadIds:" << std::endl;
87  const auto& pids = *proxy.requests();
88  for (const auto& id : pids)
89  out << " " << id.since << " - " << id.till << " : " << id.payloadId << std::endl;
90  }
91 
92  void dumpInfoJson(json& jsonData, const std::string& recName, cond::ProductResolverWrapperBase const& proxy) {
93  json recordData;
94  recordData["label"] = proxy.label();
95  recordData["connectionString"] = proxy.connString();
96  recordData["tag"] = proxy.tag();
97 
98  // Code to fill the JSON structure
99 
100  recordData["timeLookupPayloadIds"] = json::array();
101  const auto& pids = *proxy.requests();
102  for (const auto& id : pids) {
103  json payloadIdData;
104  payloadIdData["since"] = id.since;
105  payloadIdData["till"] = id.till;
106  payloadIdData["payloadId"] = id.payloadId;
107  recordData["timeLookupPayloadIds"].push_back(payloadIdData);
108  }
109 
110  jsonData[recName].push_back(recordData);
111  }
112 
113 } // namespace
114 
115 /*
116  * config Param
117  * RefreshEachRun: if true will refresh the IOV at each new run (or lumiSection)
118  * DumpStat: if true dump the statistics of all ProductResolver (currently on cout)
119  * DBParameters: configuration set of the connection
120  * globaltag: The GlobalTag
121  * toGet: list of record label tag connection-string to add/overwrite the content of the global-tag
122  */
124  : m_jsonDumpFilename(iConfig.getUntrackedParameter<std::string>("JsonDumpFileName", "")),
125  m_connection(),
126  m_connectionString(""),
127  m_frontierKey(""),
128  m_lastRun(0), // for the stat
129  m_lastLumi(0), // for the stat
130  m_policy(NOREFRESH),
131  m_doDump(iConfig.getUntrackedParameter<bool>("DumpStat", false)) {
132  if (iConfig.getUntrackedParameter<bool>("RefreshAlways", false)) {
134  }
135  if (iConfig.getUntrackedParameter<bool>("RefreshOpenIOVs", false)) {
137  }
138  if (iConfig.getUntrackedParameter<bool>("RefreshEachRun", false)) {
140  }
141  if (iConfig.getUntrackedParameter<bool>("ReconnectEachRun", false)) {
143  }
144 
145  Stats s = {0, 0, 0, 0, 0, 0, 0, 0};
146  m_stats = s;
147 
148  /*parameter set parsing
149  */
151  if (iConfig.exists("globaltag")) {
152  globaltag = iConfig.getParameter<std::string>("globaltag");
153  // the global tag _requires_ a connection string
154  m_connectionString = iConfig.getParameter<std::string>("connect");
155 
156  if (!globaltag.empty()) {
158  if (siteLocalConfig.isAvailable()) {
159  if (siteLocalConfig->useLocalConnectString()) {
160  std::string const& localConnectPrefix = siteLocalConfig->localConnectPrefix();
161  std::string const& localConnectSuffix = siteLocalConfig->localConnectSuffix();
162  m_connectionString = localConnectPrefix + globaltag + localConnectSuffix;
163  }
164  }
165  }
166  } else if (iConfig.exists("connect")) // default connection string
167  m_connectionString = iConfig.getParameter<std::string>("connect");
168 
169  // frontier key
170  m_frontierKey = iConfig.getUntrackedParameter<std::string>("frontierKey", "");
171 
172  // snapshot
173  boost::posix_time::ptime snapshotTime;
174  if (iConfig.exists("snapshotTime")) {
175  std::string snapshotTimeString = iConfig.getParameter<std::string>("snapshotTime");
176  if (!snapshotTimeString.empty())
177  snapshotTime = boost::posix_time::time_from_string(snapshotTimeString);
178  }
179 
180  // connection configuration
181  if (iConfig.exists("DBParameters")) {
182  edm::ParameterSet connectionPset = iConfig.getParameter<edm::ParameterSet>("DBParameters");
183  m_connection.setParameters(connectionPset);
184  }
186 
187  // load specific record/tag info - it will overwrite the global tag ( if any )
188  std::map<std::string, cond::GTEntry_t> replacements;
189  std::map<std::string, boost::posix_time::ptime> specialSnapshots;
190  if (iConfig.exists("toGet")) {
191  typedef std::vector<edm::ParameterSet> Parameters;
192  Parameters toGet = iConfig.getParameter<Parameters>("toGet");
193  for (Parameters::iterator itToGet = toGet.begin(); itToGet != toGet.end(); ++itToGet) {
194  std::string recordname = itToGet->getParameter<std::string>("record");
195  if (recordname.empty())
196  throw cond::Exception("ESSource: The record name has not been provided in a \"toGet\" entry.");
197  std::string labelname = itToGet->getUntrackedParameter<std::string>("label", "");
198  std::string pfn("");
199  if (m_connectionString.empty() || itToGet->exists("connect"))
200  pfn = itToGet->getParameter<std::string>("connect");
201  std::string tag("");
202  std::string fqTag("");
203  if (itToGet->exists("tag")) {
204  tag = itToGet->getParameter<std::string>("tag");
206  }
207  boost::posix_time::ptime tagSnapshotTime =
208  boost::posix_time::time_from_string(std::string(cond::time::MAX_TIMESTAMP));
209  if (itToGet->exists("snapshotTime"))
210  tagSnapshotTime = boost::posix_time::time_from_string(itToGet->getParameter<std::string>("snapshotTime"));
211  if (itToGet->exists("refreshTime")) {
212  cond::Time_t refreshTime = itToGet->getParameter<unsigned long long>("refreshTime");
213  m_refreshTimeForRecord.insert(std::make_pair(recordname, std::make_pair(refreshTime, true)));
214  }
215 
216  std::string recordLabelKey = joinRecordAndLabel(recordname, labelname);
217  replacements.insert(
218  std::make_pair(recordLabelKey, cond::GTEntry_t(std::make_tuple(recordname, labelname, fqTag))));
219  specialSnapshots.insert(std::make_pair(recordLabelKey, tagSnapshotTime));
220  }
221  }
222 
223  // get the global tag, merge with "replacement" store in "tagCollection"
224  std::vector<std::string> globaltagList;
225  std::vector<std::string> connectList;
226  std::vector<std::string> pfnPrefixList;
227  std::vector<std::string> pfnPostfixList;
228  if (!globaltag.empty()) {
229  std::string pfnPrefix(iConfig.getUntrackedParameter<std::string>("pfnPrefix", ""));
230  std::string pfnPostfix(iConfig.getUntrackedParameter<std::string>("pfnPostfix", ""));
231  boost::split(globaltagList, globaltag, boost::is_any_of("|"), boost::token_compress_off);
232  fillList(m_connectionString, connectList, globaltagList.size(), "connection");
233  fillList(pfnPrefix, pfnPrefixList, globaltagList.size(), "pfnPrefix");
234  fillList(pfnPostfix, pfnPostfixList, globaltagList.size(), "pfnPostfix");
235  }
236 
237  cond::GTMetadata_t gtMetadata;
238  fillTagCollectionFromDB(connectList, pfnPrefixList, pfnPostfixList, globaltagList, replacements, gtMetadata);
239  // if no job specific setting has been found, use the GT timestamp
240  if (snapshotTime.is_not_a_date_time())
241  snapshotTime = gtMetadata.snapshotTime;
242 
243  TagCollection::iterator it;
244  TagCollection::iterator itBeg = m_tagCollection.begin();
245  TagCollection::iterator itEnd = m_tagCollection.end();
246 
247  std::map<std::string, cond::persistency::Session> sessions;
248 
249  /* load ProductResolver Plugin (it is strongly typed due to EventSetup ideosyncrasis)
250  * construct proxy
251  * contrary to EventSetup the "object-name" is not used as identifier: multiple entries in a record are
252  * dinstinguished only by their label...
253  * done in two step: first create ResolverWrapper loading ALL required dictionaries
254  * this will allow to initialize POOL in one go for each "database"
255  * The real initialization of the Data-Resolvers is done in the second loop
256  */
257  std::vector<std::unique_ptr<cond::ProductResolverWrapperBase>> resolverWrappers(m_tagCollection.size());
258  size_t ipb = 0;
259  for (it = itBeg; it != itEnd; ++it) {
260  size_t ind = ipb++;
261  resolverWrappers[ind] = std::unique_ptr<cond::ProductResolverWrapperBase>{
262  cond::ProductResolverFactory::get()->tryToCreate(buildName(it->second.recordName()))};
263  if (!resolverWrappers[ind].get()) {
264  edm::LogWarning("CondDBESSource") << "Plugin for Record " << it->second.recordName() << " has not been found.";
265  }
266  }
267 
268  // now all required libraries have been loaded
269  // init sessions and DataResolvers
270  ipb = 0;
271  for (it = itBeg; it != itEnd; ++it) {
273  std::string tag = it->second.tagName();
274  std::pair<std::string, std::string> tagParams = cond::persistency::parseTag(it->second.tagName());
275  if (!tagParams.second.empty()) {
276  connStr = tagParams.second;
277  tag = tagParams.first;
278  }
279  std::map<std::string, cond::persistency::Session>::iterator p = sessions.find(connStr);
281  if (p == sessions.end()) {
283  std::tuple<std::string, std::string, std::string> connPars =
285  std::string dbService = std::get<1>(connPars);
286  std::string dbAccount = std::get<2>(connPars);
287  if ((dbService == "cms_orcon_prod" || dbService == "cms_orcon_adg") && dbAccount != "CMS_CONDITIONS")
288  edm::LogWarning("CondDBESSource")
289  << "[WARNING] You are reading tag \"" << tag << "\" from V1 account \"" << connStr
290  << "\". The concerned Conditions might be out of date." << std::endl;
291  //open db get tag info (i.e. the IOV token...)
292  nsess = m_connection.createReadOnlySession(connStr, "");
293  sessions.insert(std::make_pair(connStr, nsess));
294  } else
295  nsess = (*p).second;
296 
297  // ownership...
298  ResolverP resolver(std::move(resolverWrappers[ipb++]));
299  // instert in the map
300  if (resolver.get()) {
301  m_resolvers.insert(std::make_pair(it->second.recordName(), resolver));
302  // initialize
303  boost::posix_time::ptime tagSnapshotTime = snapshotTime;
304  auto tagSnapshotIter = specialSnapshots.find(it->first);
305  if (tagSnapshotIter != specialSnapshots.end())
306  tagSnapshotTime = tagSnapshotIter->second;
307  // finally, if the snapshot is set to infinity, reset the snapshot to null, to take the full iov set...
308  if (tagSnapshotTime == boost::posix_time::time_from_string(std::string(cond::time::MAX_TIMESTAMP)))
309  tagSnapshotTime = boost::posix_time::ptime();
310 
311  resolver->lateInit(nsess, tag, tagSnapshotTime, it->second.recordLabel(), connStr, &m_queue, &m_mutex);
312  }
313  }
314 
315  // one loaded expose all other tags to the Proxy!
316  CondGetterFromESSource visitor(m_resolvers);
317  ResolverMap::iterator b = m_resolvers.begin();
318  ResolverMap::iterator e = m_resolvers.end();
319  for (; b != e; b++) {
320  (*b).second->proxy(0)->loadMore(visitor);
321 
324  if (recordKey.type() != EventSetupRecordKey::TypeTag()) {
325  findingRecordWithKey(recordKey);
326  usingRecordWithKey(recordKey);
327  }
328  }
329 
330  m_stats.nData = m_resolvers.size();
331 }
332 
333 void CondDBESSource::fillList(const std::string& stringList,
334  std::vector<std::string>& listToFill,
335  const unsigned int listSize,
336  const std::string& type) {
337  boost::split(listToFill, stringList, boost::is_any_of("|"), boost::token_compress_off);
338  // If it is one clone it for each GT
339  if (listToFill.size() == 1) {
340  for (unsigned int i = 1; i < listSize; ++i) {
341  listToFill.push_back(stringList);
342  }
343  }
344  // else if they don't match the number of GTs throw an exception
345  else if (listSize != listToFill.size()) {
346  throw cond::Exception(
347  std::string("ESSource: number of global tag components does not match number of " + type + " strings"));
348  }
349 }
350 
352  std::cout << "CondDBESSource Statistics\n"
353  << "DataProxy " << stats.nData << " setInterval " << stats.nSet << " Runs " << stats.nRun << " Lumis "
354  << stats.nLumi << " Refresh " << stats.nRefresh << " Actual Refresh " << stats.nActualRefresh
355  << " Reconnect " << stats.nReconnect << " Actual Reconnect " << stats.nActualReconnect << std::endl;
356 }
357 
358 void saveJsonToFile(const json& jsonData, const std::string& filename) {
359  std::ofstream outputFile(filename);
360  if (outputFile.is_open()) {
361  outputFile << jsonData.dump(2) << std::endl;
362  std::cout << "JSON data saved in file '" << filename << "'" << std::endl;
363  } else {
364  std::cerr << "Error opening file to write JSON data." << std::endl;
365  }
366 }
367 
369  //dump info FIXME: find a more suitable place...
370  if (m_doDump) {
371  //Output CondDBESSource Statistics to the console
373 
374  ResolverMap::iterator b = m_resolvers.begin();
375  ResolverMap::iterator e = m_resolvers.end();
376  for (; b != e; b++) {
377  dumpInfo(std::cout, (*b).first, *(*b).second);
378  std::cout << "\n" << std::endl;
379  }
380  }
381  //if filename was provided for iConfig by process.GlobalTag.JsonDumpFileName =cms.untracked.string("CondDBESSource.json")
382  if (!m_jsonDumpFilename.empty()) {
383  json jsonData;
384 
385  for (const auto& entry : m_resolvers) {
386  std::string recName = entry.first;
387  const auto& proxy = *entry.second;
388  dumpInfoJson(jsonData, recName, proxy);
389  }
390  //Save the dump data to a file in JSON format
392  }
393  // FIXME
394  // We shall eventually close transaction and session...
395 }
396 
397 //
398 // invoked by EventSetUp: for a given record return the smallest IOV for which iTime is valid
399 // limit to next run/lumisection of Refresh is required
400 //
402  const edm::IOVSyncValue& iTime,
403  edm::ValidityInterval& oInterval) {
404  std::string recordname = iKey.name();
405 
406  edm::LogInfo("CondDBESSource") << "Getting data for record \"" << recordname
407  << "\" to be consumed on Run: " << iTime.eventID().run()
408  << " - Lumiblock:" << iTime.luminosityBlockNumber()
409  << " - Timestamp: " << iTime.time().value() << "; from CondDBESSource::setIntervalFor";
410 
411  std::lock_guard<std::mutex> guard(m_mutex);
412  m_stats.nSet++;
413 
414  if (iTime.eventID().run() != m_lastRun) {
415  m_lastRun = iTime.eventID().run();
416  m_stats.nRun++;
417  }
418  if (iTime.luminosityBlockNumber() != m_lastLumi) {
420  m_stats.nLumi++;
421  }
422 
423  bool doRefresh = false;
424  cond::Time_t defaultIovSize = cond::time::MAX_VAL;
425  bool refreshThisRecord = false;
426  bool reconnectThisRecord = false;
427 
428  auto iR = m_refreshTimeForRecord.find(recordname);
429  refreshThisRecord = iR != m_refreshTimeForRecord.end();
430  if (refreshThisRecord) {
431  defaultIovSize = iR->second.first;
432  reconnectThisRecord = iR->second.second;
433  iR->second.second = false;
434  }
435 
437  // find out the last run number for the proxy of the specified record
438  std::map<std::string, unsigned int>::iterator iRec = m_lastRecordRuns.find(recordname);
439  if (iRec != m_lastRecordRuns.end()) {
440  cond::Time_t lastRecordRun = iRec->second;
441  if (lastRecordRun != m_lastRun) {
442  // a refresh is required!
443  doRefresh = true;
444  iRec->second = m_lastRun;
445  edm::LogInfo("CondDBESSource") << "Preparing refresh for record \"" << recordname
446  << "\" since there has been a transition from run/lumi " << lastRecordRun
447  << " to run/lumi " << m_lastRun << "; from CondDBESSource::setIntervalFor";
448  }
449  } else {
450  doRefresh = true;
451  m_lastRecordRuns.insert(std::make_pair(recordname, m_lastRun));
452  edm::LogInfo("CondDBESSource") << "Preparing refresh for record \"" << recordname << "\" for " << iTime.eventID()
453  << ", timestamp: " << iTime.time().value()
454  << "; from CondDBESSource::setIntervalFor";
455  }
456  if (!doRefresh)
457  edm::LogInfo("CondDBESSource") << "Though enabled, refresh not needed for record \"" << recordname << "\" for "
458  << iTime.eventID() << ", timestamp: " << iTime.time().value()
459  << "; from CondDBESSource::setIntervalFor";
460  } else if (m_policy == REFRESH_ALWAYS || m_policy == REFRESH_OPEN_IOVS) {
461  doRefresh = true;
462  edm::LogInfo("CondDBESSource") << "Forcing refresh for record \"" << recordname << "\" for " << iTime.eventID()
463  << ", timestamp: " << iTime.time().value()
464  << "; from CondDBESSource::setIntervalFor";
465  }
466 
468 
469  // compute the smallest interval (assume all objects have the same timetype....)
470  cond::ValidityInterval recordValidity(1, cond::TIMELIMIT);
471  cond::TimeType timetype = cond::TimeType::invalid;
472  bool userTime = true;
473 
474  //FIXME use equal_range
475  ResolverMap::const_iterator pmBegin = m_resolvers.lower_bound(recordname);
476  ResolverMap::const_iterator pmEnd = m_resolvers.upper_bound(recordname);
477  if (pmBegin == pmEnd) {
478  edm::LogInfo("CondDBESSource") << "No ProductResolver (Pluging) found for record \"" << recordname
479  << "\"; from CondDBESSource::setIntervalFor";
480  return;
481  }
482 
483  for (ResolverMap::const_iterator pmIter = pmBegin; pmIter != pmEnd; ++pmIter) {
484  edm::LogInfo("CondDBESSource") << "Processing record \"" << recordname << "\" and label \""
485  << pmIter->second->label() << "\" for " << iTime.eventID()
486  << ", timestamp: " << iTime.time().value()
487  << "; from CondDBESSource::setIntervalFor";
488 
489  timetype = (*pmIter).second->timeType();
490 
492  userTime = (0 == abtime);
493 
494  if (userTime)
495  return; // oInterval invalid to avoid that make is called...
496 
497  if (doRefresh || refreshThisRecord) {
498  std::string recKey = joinRecordAndLabel(recordname, pmIter->second->label());
499  TagCollection::const_iterator tcIter = m_tagCollection.find(recKey);
500  if (tcIter == m_tagCollection.end()) {
501  edm::LogInfo("CondDBESSource") << "No Tag found for record \"" << recordname << "\" and label \""
502  << pmIter->second->label() << "\"; from CondDBESSource::setIntervalFor";
503  return;
504  }
505 
506  // first reconnect if required
507  if (m_policy == RECONNECT_EACH_RUN || reconnectThisRecord) {
508  edm::LogInfo("CondDBESSource")
509  << "Checking if the session must be closed and re-opened for getting correct conditions"
510  << "; from CondDBESSource::setIntervalFor";
511  std::string transId;
512  if (!reconnectThisRecord) {
513  transId = std::to_string(abtime);
514  } else {
515  transId = cond::time::transactionIdForLumiTime(abtime, defaultIovSize, m_frontierKey);
516  }
518  std::pair<std::string, std::string> tagParams = cond::persistency::parseTag(tcIter->second.tagName());
519  if (!tagParams.second.empty())
520  connStr = tagParams.second;
521  std::map<std::string, std::pair<cond::persistency::Session, std::string>>* sessionPool = &m_sessionPool;
522  if (refreshThisRecord) {
523  sessionPool = &m_sessionPoolForLumiConditions;
524  }
525  auto iSess = sessionPool->find(connStr);
526  bool reopen = false;
527  if (iSess != sessionPool->end()) {
528  if (iSess->second.second != transId) {
529  // the available session is open for a different run: reopen
530  reopen = true;
531  iSess->second.second = transId;
532  }
533  } else {
534  // no available session: probably first run analysed...
535  iSess =
536  sessionPool->insert(std::make_pair(connStr, std::make_pair(cond::persistency::Session(), transId))).first;
537  reopen = true;
538  }
539  if (reopen) {
540  iSess->second.first = m_connection.createReadOnlySession(connStr, transId);
541  edm::LogInfo("CondDBESSource") << "Re-opening the session with connection string " << connStr
542  << " and new transaction Id " << transId
543  << "; from CondDBESSource::setIntervalFor";
544  }
545 
546  edm::LogInfo("CondDBESSource") << "Reconnecting to \"" << connStr << "\" for getting new payload for record \""
547  << recordname << "\" and label \"" << pmIter->second->label()
548  << "\" from IOV tag \"" << tcIter->second.tagName() << "\" to be consumed by "
549  << iTime.eventID() << ", timestamp: " << iTime.time().value()
550  << "; from CondDBESSource::setIntervalFor";
551  pmIter->second->session() = iSess->second.first;
552  pmIter->second->reload();
554  } else {
555  edm::LogInfo("CondDBESSource") << "Refreshing IOV sequence labeled by tag \"" << tcIter->second.tagName()
556  << "\" for getting new payload for record \"" << recordname << "\" and label \""
557  << pmIter->second->label() << "\" to be consumed by " << iTime.eventID()
558  << ", timestamp: " << iTime.time().value()
559  << "; from CondDBESSource::setIntervalFor";
560  pmIter->second->reload();
561  m_stats.nRefresh++;
562  }
563  }
564 
565  //query the IOVSequence
566  cond::ValidityInterval validity = (*pmIter).second->setIntervalFor(abtime);
567 
568  edm::LogInfo("CondDBESSource") << "Validity coming from IOV sequence for record \"" << recordname
569  << "\" and label \"" << pmIter->second->label() << "\": (" << validity.first << ", "
570  << validity.second << ") for time (type: " << cond::timeTypeNames(timetype) << ") "
571  << abtime << "; from CondDBESSource::setIntervalFor";
572 
573  recordValidity.first = std::max(recordValidity.first, validity.first);
574  recordValidity.second = std::min(recordValidity.second, validity.second);
575  if (refreshThisRecord && recordValidity.second == cond::TIMELIMIT) {
576  iR->second.second = true;
577  if (defaultIovSize)
578  recordValidity.second = cond::time::tillTimeForIOV(abtime, defaultIovSize, timetype);
579  else {
580  recordValidity.second = 0;
581  }
582  }
583  }
584 
585  if (m_policy == REFRESH_OPEN_IOVS) {
586  doRefresh = (recordValidity.second == cond::timeTypeSpecs[timetype].endValue);
587  edm::LogInfo("CondDBESSource") << "Validity for record \"" << recordname
588  << "\" and the corresponding label(s) coming from Condition DB: ("
589  << recordValidity.first << ", " << recordValidity.first
590  << ") as the last IOV element in the IOV sequence is infinity"
591  << "; from CondDBESSource::setIntervalFor";
592  }
593 
594  // to force refresh we set end-value to the minimum such an IOV can extend to: current run or lumiblock
595  if ((!userTime) && recordValidity.second != 0) {
596  edm::IOVSyncValue start = cond::time::toIOVSyncValue(recordValidity.first, timetype, true);
598  : cond::time::toIOVSyncValue(recordValidity.second, timetype, false);
599 
602  }
603  oInterval = edm::ValidityInterval(start, stop);
604  }
605 
606  edm::LogInfo("CondDBESSource") << "Setting validity for record \"" << recordname
607  << "\" and corresponding label(s): starting at " << oInterval.first().eventID()
608  << ", timestamp: " << oInterval.first().time().value() << ", ending at "
609  << oInterval.last().eventID() << ", timestamp: " << oInterval.last().time().value()
610  << ", for " << iTime.eventID() << ", timestamp: " << iTime.time().value()
611  << "; from CondDBESSource::setIntervalFor";
612 }
613 
614 //required by EventSetup System
616  const EventSetupRecordKey& iRecordKey, unsigned int iovIndex) {
617  KeyedResolversVector keyedResolversVector;
618 
619  std::string recordname = iRecordKey.name();
620 
621  ResolverMap::const_iterator b = m_resolvers.lower_bound(recordname);
622  ResolverMap::const_iterator e = m_resolvers.upper_bound(recordname);
623  if (b == e) {
624  edm::LogInfo("CondDBESSource") << "No ProductResolver (Pluging) found for record \"" << recordname
625  << "\"; from CondDBESSource::registerResolvers";
626  return keyedResolversVector;
627  }
628 
629  for (ResolverMap::const_iterator p = b; p != e; ++p) {
630  if (nullptr != (*p).second.get()) {
631  edm::eventsetup::TypeTag type = (*p).second->type();
632  DataKey key(type, edm::eventsetup::IdTags((*p).second->label().c_str()));
633  keyedResolversVector.emplace_back(key, (*p).second->esResolver(iovIndex));
634  }
635  }
636  return keyedResolversVector;
637 }
638 
639 void CondDBESSource::initConcurrentIOVs(const EventSetupRecordKey& key, unsigned int nConcurrentIOVs) {
640  std::string recordname = key.name();
641  ResolverMap::const_iterator b = m_resolvers.lower_bound(recordname);
642  ResolverMap::const_iterator e = m_resolvers.upper_bound(recordname);
643  for (ResolverMap::const_iterator p = b; p != e; ++p) {
644  if (p->second) {
645  p->second->initConcurrentIOVs(nConcurrentIOVs);
646  }
647  }
648 }
649 
650 // Fills tag collection from the given globaltag
652  const std::string& prefix,
653  const std::string& postfix,
654  const std::string& roottag,
655  std::set<cond::GTEntry_t>& tagcoll,
656  cond::GTMetadata_t& gtMetadata) {
657  if (!roottag.empty()) {
658  if (connectionString.empty())
659  throw cond::Exception(std::string("ESSource: requested global tag ") + roottag +
660  std::string(" but not connection string given"));
661  std::tuple<std::string, std::string, std::string> connPars =
663  if (std::get<2>(connPars) == "CMS_COND_31X_GLOBALTAG") {
664  edm::LogWarning("CondDBESSource")
665  << "[WARNING] You are reading Global Tag \"" << roottag
666  << "\" from V1 account \"CMS_COND_31X_GLOBALTAG\". The concerned Conditions might be out of date."
667  << std::endl;
668  } else if (roottag.rfind("::All") != std::string::npos && std::get<2>(connPars) == "CMS_CONDITIONS") {
669  edm::LogWarning("CondDBESSource") << "[WARNING] You are trying to read Global Tag \"" << roottag
670  << "\" - postfix \"::All\" should not be used for V2." << std::endl;
671  }
673  session.transaction().start(true);
674  cond::persistency::GTProxy gtp = session.readGlobalTag(roottag, prefix, postfix);
675  gtMetadata.snapshotTime = gtp.snapshotTime();
676  for (const auto& gte : gtp) {
677  tagcoll.insert(gte);
678  }
679  session.transaction().commit();
680  }
681 }
682 
683 // fills tagcollection merging with replacement
684 // Note: it assumem the coraldbList and roottagList have the same length. This checked in the constructor that prepares the two lists before calling this method.
685 void CondDBESSource::fillTagCollectionFromDB(const std::vector<std::string>& connectionStringList,
686  const std::vector<std::string>& prefixList,
687  const std::vector<std::string>& postfixList,
688  const std::vector<std::string>& roottagList,
689  std::map<std::string, cond::GTEntry_t>& replacement,
690  cond::GTMetadata_t& gtMetadata) {
691  std::set<cond::GTEntry_t> tagcoll;
692 
693  auto connectionString = connectionStringList.begin();
694  auto prefix = prefixList.begin();
695  auto postfix = postfixList.begin();
696  for (auto roottag = roottagList.begin(); roottag != roottagList.end();
697  ++roottag, ++connectionString, ++prefix, ++postfix) {
698  fillTagCollectionFromGT(*connectionString, *prefix, *postfix, *roottag, tagcoll, gtMetadata);
699  }
700 
701  std::set<cond::GTEntry_t>::iterator tagCollIter;
702  std::set<cond::GTEntry_t>::iterator tagCollBegin = tagcoll.begin();
703  std::set<cond::GTEntry_t>::iterator tagCollEnd = tagcoll.end();
704 
705  // FIXME the logic is a bit perverse: can be surely linearized (at least simplified!) ....
706  for (tagCollIter = tagCollBegin; tagCollIter != tagCollEnd; ++tagCollIter) {
707  std::string recordLabelKey = joinRecordAndLabel(tagCollIter->recordName(), tagCollIter->recordLabel());
708  std::map<std::string, cond::GTEntry_t>::iterator fid = replacement.find(recordLabelKey);
709  if (fid != replacement.end()) {
710  if (!fid->second.tagName().empty()) {
711  cond::GTEntry_t tagMetadata(
712  std::make_tuple(tagCollIter->recordName(), tagCollIter->recordLabel(), fid->second.tagName()));
713  m_tagCollection.insert(std::make_pair(recordLabelKey, tagMetadata));
714  edm::LogInfo("CondDBESSource") << "Replacing tag \"" << tagCollIter->tagName() << "\" for record \""
715  << tagMetadata.recordName() << "\" and label \"" << tagMetadata.recordLabel()
716  << "\" with tag " << tagMetadata.tagName()
717  << "\"; from CondDBESSource::fillTagCollectionFromDB";
718  } else {
719  m_tagCollection.insert(std::make_pair(recordLabelKey, *tagCollIter));
720  }
721  replacement.erase(fid);
722  } else {
723  m_tagCollection.insert(std::make_pair(recordLabelKey, *tagCollIter));
724  }
725  }
726  std::map<std::string, cond::GTEntry_t>::iterator replacementIter;
727  std::map<std::string, cond::GTEntry_t>::iterator replacementBegin = replacement.begin();
728  std::map<std::string, cond::GTEntry_t>::iterator replacementEnd = replacement.end();
729  for (replacementIter = replacementBegin; replacementIter != replacementEnd; ++replacementIter) {
730  if (replacementIter->second.tagName().empty()) {
731  std::stringstream msg;
732  msg << "ESSource: no tag provided for record " << replacementIter->second.recordName();
733  if (!replacementIter->second.recordLabel().empty())
734  msg << " and label " << replacementIter->second.recordLabel();
735  throw cond::Exception(msg.str());
736  }
737  m_tagCollection.insert(*replacementIter);
738  }
739 }
740 
741 // backward compatibility for configuration files
743 public:
744  explicit PoolDBESSource(const edm::ParameterSet& ps) : CondDBESSource(ps) {}
745 };
746 
748 //define this as a plug-in
persistency::Exception Exception
Definition: Exception.h:25
const std::string & recordName() const
Definition: Types.h:120
const TimeTypeSpecs timeTypeSpecs[]
Definition: Time.cc:16
Definition: start.py:1
const IOVSyncValue & last() const
std::map< std::string, std::pair< cond::Time_t, bool > > m_refreshTimeForRecord
ResolverMap m_resolvers
std::tuple< std::string, std::string, std::string > parseConnectionString(const std::string &connectionString)
Definition: Utils.h:95
std::mutex m_mutex
LuminosityBlockNumber_t luminosityBlockNumber() const
Definition: IOVSyncValue.h:41
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
const IOVSyncValue & first() const
void saveJsonToFile(const json &jsonData, const std::string &filename)
Base exception class for the object to relational access.
Definition: Exception.h:11
std::multimap< std::string, ResolverP > ResolverMap
void start(bool readOnly=true)
Definition: Session.cc:18
std::shared_ptr< cond::ProductResolverWrapperBase > ResolverP
void usingRecordWithKey(const EventSetupRecordKey &key)
bool exists(std::string const &parameterName) const
checks if a parameter exists
void setIntervalFor(const EventSetupRecordKey &, const edm::IOVSyncValue &, edm::ValidityInterval &) override
boost::posix_time::ptime snapshotTime
Definition: Types.h:106
static constexpr const char *const MAX_TIMESTAMP
Definition: Time.h:26
std::pair< Time_t, Time_t > ValidityInterval
Definition: Time.h:17
std::map< std::string, std::pair< cond::persistency::Session, std::string > > m_sessionPool
void printStatistics(const Stats &stats) const
RefreshPolicy m_policy
Transaction & transaction()
Definition: Session.cc:52
std::string const & label() const
std::string transactionIdForLumiTime(Time_t time, unsigned int iovSize, const std::string &secretKey)
Definition: Time.cc:150
std::string const & connString() const
static std::string to_string(const XMLCh *ch)
TimeType
Definition: Time.h:19
void setParameters(const edm::ParameterSet &connectionPset)
nlohmann::json json
void fillTagCollectionFromGT(const std::string &connectionString, const std::string &prefix, const std::string &postfix, const std::string &roottag, std::set< cond::GTEntry_t > &tagcoll, cond::GTMetadata_t &gtMetadata)
Time_t tillTimeForIOV(Time_t since, unsigned int iovSize, TimeType timeType)
Definition: Time.cc:54
T getUntrackedParameter(std::string const &, T const &) const
Time_t fromIOVSyncValue(edm::IOVSyncValue const &time, TimeType timetype)
Definition: Time.cc:97
edm::SerialTaskQueue m_queue
std::string const & timeTypeNames(int)
Definition: Time.cc:11
unsigned long long Time_t
Definition: Time.h:14
std::string convertoToOracleConnection(const std::string &input)
Definition: Utils.h:120
std::pair< std::string, std::string > parseTag(const std::string &tag)
Definition: GTProxy.cc:14
static const IOVSyncValue & beginOfTime()
Definition: IOVSyncValue.cc:88
cond::persistency::ConnectionPool m_connection
edm::IOVSyncValue toIOVSyncValue(cond::Time_t time, TimeType timetype, bool startOrStop)
Definition: Time.cc:79
Session createSession(const std::string &connectionString, bool writeCapable=false)
key
prepare the HTCondor submission files and eventually submit them
void initConcurrentIOVs(const EventSetupRecordKey &key, unsigned int nConcurrentIOVs) override
std::string fullyQualifiedTag(const std::string &tag, const std::string &connectionString)
Definition: GTProxy.cc:8
void fillList(const std::string &pfn, std::vector< std::string > &pfnList, const unsigned int listSize, const std::string &type)
def dumpInfo(run)
Definition: getInfo.py:88
boost::posix_time::ptime snapshotTime() const
Definition: GTProxy.cc:135
std::map< std::string, std::pair< cond::persistency::Session, std::string > > m_sessionPoolForLumiConditions
std::shared_ptr< std::vector< Iov_t > > const & requests() const
Log< level::Info, false > LogInfo
RunNumber_t run() const
Definition: EventID.h:38
const std::string & tagName() const
Definition: Types.h:122
#define DEFINE_FWK_EVENTSETUP_SOURCE(type)
Definition: SourceFactory.h:92
PoolDBESSource(const edm::ParameterSet &ps)
TimeValue_t value() const
Definition: Timestamp.h:38
TagCollection m_tagCollection
const Time_t TIMELIMIT(std::numeric_limits< Time_t >::max())
double b
Definition: hdecay.h:120
~CondDBESSource() override
tuple msg
Definition: mps_check.py:286
std::string m_jsonDumpFilename
std::vector< std::pair< DataKey, std::shared_ptr< ESProductResolver > >> KeyedResolversVector
std::string const & tag() const
void fillTagCollectionFromDB(const std::vector< std::string > &connectionStringList, const std::vector< std::string > &prefixList, const std::vector< std::string > &postfixList, const std::vector< std::string > &roottagList, std::map< std::string, cond::GTEntry_t > &replacement, cond::GTMetadata_t &gtMetadata)
const EventID & eventID() const
Definition: IOVSyncValue.h:40
std::vector< AlignmentParameters * > Parameters
Definition: Utilities.h:32
heterocontainer::HCTypeTag TypeTag
std::string m_connectionString
const Timestamp & time() const
Definition: IOVSyncValue.h:42
unsigned int m_lastRun
static const ValidityInterval & invalidInterval()
Session createReadOnlySession(const std::string &connectionString, const std::string &transactionId)
std::string m_frontierKey
edm::IOVSyncValue limitedIOVSyncValue(Time_t time, TimeType timetype)
Definition: Time.cc:113
#define get
Log< level::Warning, false > LogWarning
Time_t endValue
Definition: Time.h:42
CondDBESSource(const edm::ParameterSet &)
GTProxy readGlobalTag(const std::string &name)
Definition: Session.cc:163
std::map< std::string, unsigned int > m_lastRecordRuns
KeyedResolversVector registerResolvers(const EventSetupRecordKey &, unsigned int iovIndex) override
const std::string & recordLabel() const
Definition: Types.h:121
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
unsigned int m_lastLumi
const Time_t MAX_VAL(std::numeric_limits< Time_t >::max())
def move(src, dest)
Definition: eostools.py:511
void findingRecordWithKey(const eventsetup::EventSetupRecordKey &)
static const IOVSyncValue & invalidIOVSyncValue()
Definition: IOVSyncValue.cc:78
static HCTypeTag findType(char const *iTypeName)
find a type based on the types name, if not found will return default HCTypeTag
Definition: HCTypeTag.cc:121