CMS 3D CMS Logo

SiStripPayloadHandler.cc
Go to the documentation of this file.
7 
8 #include <iostream>
9 #include <sstream>
10 #include <typeinfo>
11 
13 
14 #include "RelationalAccess/ITransaction.h"
15 #include "RelationalAccess/ISessionProxy.h"
16 #include "RelationalAccess/ISchema.h"
17 #include "RelationalAccess/ITable.h"
18 #include "RelationalAccess/IQuery.h"
19 #include "RelationalAccess/ICursor.h"
20 #include "RelationalAccess/ITableDataEditor.h"
21 #include "RelationalAccess/TableDescription.h"
22 #include "CoralBase/Attribute.h"
23 #include "CoralBase/AttributeList.h"
24 #include "CoralBase/TimeStamp.h"
25 
27 
28 template <typename SiStripPayload>
30 public:
31  explicit SiStripPayloadHandler(const edm::ParameterSet& iConfig);
32  ~SiStripPayloadHandler() override;
33  void analyze(const edm::Event& evt, const edm::EventSetup& evtSetup) override;
34  void endJob() override;
35 
36 private:
39  void updateConfigMap(std::string configHash, std::string payloadHash);
40 
41 private:
51 
54 };
55 
56 template <typename SiStripPayload>
58  : m_connectionPool(),
59  m_cfgMapSchemaName(iConfig.getUntrackedParameter<std::string>("cfgMapSchemaName", "CMS_COND_O2O")),
60  m_cfgMapTableName(iConfig.getUntrackedParameter<std::string>("cfgMapTableName", "STRIP_CONFIG_TO_PAYLOAD_MAP")),
61  m_condDb(iConfig.getParameter<std::string>("conditionDatabase")),
62  m_localCondDbFile(iConfig.getParameter<std::string>("condDbFile")),
63  m_targetTag(iConfig.getParameter<std::string>("targetTag")),
64  m_since(iConfig.getParameter<uint32_t>("since")),
65  p_type(cond::demangledName(typeid(SiStripPayload))) {
67  p_cfgstr = condObjBuilder->getConfigString(typeid(SiStripPayload));
68  if (iConfig.exists("configMapDatabase"))
69  m_configMapDb = iConfig.getParameter<std::string>("configMapDatabase");
70  if (iConfig.exists("cfgMapDbFile"))
71  m_cfgMapDbFile = iConfig.getParameter<std::string>("cfgMapDbFile");
74 }
75 
76 template <typename SiStripPayload>
78 
79 template <typename SiStripPayload>
81  // some extra work: Getting the payload hash of the last IOV from condDb
82  // Will be compared with the new payload and reported
83  cond::persistency::Session condDbSession = m_connectionPool.createSession(m_condDb);
84  condDbSession.transaction().start(true);
85  cond::persistency::IOVProxy iovProxy = condDbSession.readIov(m_targetTag);
86  cond::Hash last_hash = iovProxy.getLast().payloadId;
87 
88  // that's the final goal: obtain the payload to store into the sqlite file for the upload into the DB
89  std::shared_ptr<SiStripPayload> payloadToUpload;
90  // first compute the hash of the configuration
91  std::string configHash = makeConfigHash();
92  // query the configMap DB to find the corresponding payload hash
93  std::string mappedPayloadHash = queryConfigMap(configHash);
94  bool mapUpToDate = false;
95 
96  if (!mappedPayloadHash.empty()) {
97  // the payload has been found ( fast O2O case )
98  // copy the payload from condtition database
99  mapUpToDate = true;
100  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
101  << "Try retrieving payload from " << m_condDb;
102  payloadToUpload = condDbSession.fetchPayload<SiStripPayload>(mappedPayloadHash);
103  std::cout << "@@@[FastO2O:true]@@@" << std::endl;
104  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
105  << " ... Payload is copied from offline condition database.";
106  } else {
107  // start the long O2O...
108  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
109  << "NO mapping payload hash found. Will run the long O2O. ";
110  SiStripPayload* obj = nullptr;
112  if (typeid(SiStripPayload) == typeid(SiStripApvGain)) {
113  // special treatment for ApvGain : provide last payload in DB
114  condObjBuilder->setLastIovGain(condDbSession.fetchPayload<SiStripApvGain>(last_hash));
115  }
116  condObjBuilder->getValue(obj);
117  payloadToUpload = std::shared_ptr<SiStripPayload>(obj);
118  std::cout << "@@@[FastO2O:false]@@@" << std::endl;
119  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
120  << " ... New payload has been created.";
121  }
122  condDbSession.transaction().commit();
123 
124  // write payload and iov in the local file
125  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
126  << "Write payload to local sqlite file: " << m_localCondDbFile;
127  cond::persistency::Session localFileSession = m_connectionPool.createSession(m_localCondDbFile, true);
128  localFileSession.transaction().start(false);
129  // write the payload
130  cond::Hash thePayloadHash = localFileSession.storePayload<SiStripPayload>(*payloadToUpload);
131  cond::persistency::IOVEditor iovEditor = localFileSession.createIov<SiStripPayload>(m_targetTag, cond::runnumber);
132  iovEditor.setDescription("New IOV");
133  // inserting the iov
134  iovEditor.insert(m_since, thePayloadHash);
135  iovEditor.flush();
136  localFileSession.transaction().commit();
137  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
138  << "Payload " << thePayloadHash << " inserted to sqlite with IOV " << m_since;
139 
140  // last step, update the configMap if required
141  if (!mapUpToDate) {
142  updateConfigMap(configHash, thePayloadHash);
143  }
144 
145  // finish the extra work: Compare the new payload with last IOV
146  if (last_hash == thePayloadHash) {
147  std::cout << "@@@[PayloadChange:false]@@@" << last_hash << std::endl;
148  } else {
149  std::cout << "@@@[PayloadChange:true]@@@" << last_hash << " -> " << thePayloadHash << std::endl;
150  }
151 }
152 
153 template <typename SiStripPayload>
155 
156 template <typename SiStripPayload>
158  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
159  << "Convert config string to SHA-1 hash for " << p_type
160  << "\n... config: " << p_cfgstr;
161 
162  // calcuate SHA-1 hash using openssl
163  // adapted from cond::persistency::makeHash() in CondCore/CondDB/src/IOVSchema.cc
165  EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
166  const EVP_MD* md = EVP_get_digestbyname("SHA1");
167  if (!EVP_DigestInit_ex(mdctx, md, nullptr)) {
168  throw cms::Exception("SHA1 initialization error.");
169  }
170  if (!EVP_DigestUpdate(mdctx, p_type.c_str(), p_type.size())) {
171  throw cms::Exception("SHA1 processing error (1).");
172  }
173  if (!EVP_DigestUpdate(mdctx, p_cfgstr.c_str(), p_cfgstr.size())) {
174  throw cms::Exception("SHA1 processing error (2).");
175  }
176  unsigned char hash[EVP_MAX_MD_SIZE];
177  unsigned int md_len;
178  if (!EVP_DigestFinal_ex(mdctx, hash, &md_len)) {
179  throw cms::Exception("SHA1 finalization error.");
180  }
181  EVP_MD_CTX_free(mdctx);
182 
183  char tmp[EVP_MAX_MD_SIZE * 2 + 1];
184  // re-write bytes in hex
185  for (unsigned int i = 0; i < md_len; i++) {
186  ::sprintf(&tmp[i * 2], "%02x", hash[i]);
187  }
188  tmp[md_len * 2] = 0;
189 
190  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__
191  << "] "
192  "... hash: "
193  << tmp;
194  return tmp;
195 }
196 
197 template <typename SiStripPayload>
199  if (m_configMapDb.empty())
200  return ""; // return empty string if m_configMapDb is not specified
201 
202  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
203  << "Query " << m_configMapDb << " to see if the payload is already in DB.";
204 
205  // if dev/prep, use CMS_COND_STRIP
206  if (m_condDb.find("prep") != std::string::npos) {
207  m_cfgMapSchemaName = "CMS_COND_STRIP";
208  }
209  auto cmDbSession = m_connectionPool.createCoralSession(m_configMapDb);
210  // query the STRIP_CONFIG_TO_PAYLOAD_MAP table
211  cmDbSession->transaction().start(true);
212  coral::ITable& cmTable = cmDbSession->schema(m_cfgMapSchemaName).tableHandle(m_cfgMapTableName);
213  std::unique_ptr<coral::IQuery> query(cmTable.newQuery());
214  query->addToOutputList("PAYLOAD_HASH");
215  query->defineOutputType("PAYLOAD_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
216  // also print these for debugging
217  query->addToOutputList("PAYLOAD_TYPE");
218  query->addToOutputList("CONFIG_STRING");
219  query->addToOutputList("INSERTION_TIME");
220  std::string whereClause("CONFIG_HASH = :CONFIG_HASH");
221  coral::AttributeList whereData;
222  whereData.extend<std::string>("CONFIG_HASH");
223  whereData.begin()->data<std::string>() = configHash;
224  query->setCondition(whereClause, whereData);
225  coral::ICursor& cursor = query->execute();
226  std::string p_hash;
227  if (cursor.next()) {
228  // the payload has been found ( fast O2O case )
229  p_hash = cursor.currentRow()["PAYLOAD_HASH"].data<std::string>();
230  edm::LogInfo("SiStripPayloadHandler")
231  << "[SiStripPayloadHandler::" << __func__ << "] "
232  << "Found associated payload hash " << p_hash
233  << "\n... type=" << cursor.currentRow()["PAYLOAD_TYPE"].data<std::string>()
234  << "\n... config=" << cursor.currentRow()["CONFIG_STRING"].data<std::string>()
235  << "\n... insertion_time=" << cursor.currentRow()["INSERTION_TIME"].data<coral::TimeStamp>().toString();
236  }
237  cmDbSession->transaction().commit();
238 
239  return p_hash;
240 }
241 
242 template <typename SiStripPayload>
244  if (m_cfgMapDbFile.empty())
245  return; // skip this if m_cfgMapDbFile is not set
246 
247  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
248  << "Updating the config to payload hash map to " << m_cfgMapDbFile;
249 
250  // create a writable transaction
251  auto cmSQLiteSession = m_connectionPool.createCoralSession(m_cfgMapDbFile, true);
252  cmSQLiteSession->transaction().start(false);
253 
254  if (!cmSQLiteSession->nominalSchema().existsTable(m_cfgMapTableName)) {
255  // create the table if it does not exist
256  coral::TableDescription mapTable;
257  mapTable.setName(m_cfgMapTableName);
258  mapTable.insertColumn("CONFIG_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
259  mapTable.insertColumn("PAYLOAD_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
260  mapTable.insertColumn("PAYLOAD_TYPE", coral::AttributeSpecification::typeNameForType<std::string>());
261  mapTable.insertColumn("CONFIG_STRING", coral::AttributeSpecification::typeNameForType<std::string>());
262  mapTable.insertColumn("INSERTION_TIME", coral::AttributeSpecification::typeNameForType<coral::TimeStamp>());
263  mapTable.setPrimaryKey("CONFIG_HASH");
264  mapTable.setNotNullConstraint("CONFIG_HASH");
265  mapTable.setNotNullConstraint("PAYLOAD_HASH");
266  mapTable.setNotNullConstraint("PAYLOAD_TYPE");
267  mapTable.setNotNullConstraint("CONFIG_STRING");
268  mapTable.setNotNullConstraint("INSERTION_TIME");
269  cmSQLiteSession->nominalSchema().createTable(mapTable);
270  }
271 
272  coral::ITable& cmTable = cmSQLiteSession->nominalSchema().tableHandle(m_cfgMapTableName);
273  coral::AttributeList insertData;
274  insertData.extend<std::string>("CONFIG_HASH");
275  insertData.extend<std::string>("PAYLOAD_HASH");
276  // also insert these for bookkeeping
277  insertData.extend<std::string>("PAYLOAD_TYPE");
278  insertData.extend<std::string>("CONFIG_STRING");
279  insertData.extend<coral::TimeStamp>("INSERTION_TIME");
280  insertData["CONFIG_HASH"].data<std::string>() = configHash;
281  insertData["PAYLOAD_HASH"].data<std::string>() = payloadHash;
282  insertData["PAYLOAD_TYPE"].data<std::string>() = p_type;
283  insertData["CONFIG_STRING"].data<std::string>() = p_cfgstr;
284  insertData["INSERTION_TIME"].data<coral::TimeStamp>() = coral::TimeStamp::now(); // UTC time
285  cmTable.dataEditor().insertRow(insertData);
286  cmSQLiteSession->transaction().commit();
287  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
288  << "Updated with mapping (configHash : payloadHash)" << configHash << " : "
289  << payloadHash;
290 }
291 
292 // -------------------------------------------------------
293 
296 
299 
302 
305 
308 
311 
void openssl_init()
Definition: openssl_init.cc:5
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
SiStripPayloadHandler< SiStripNoises > SiStripO2ONoises
SiStripPayloadHandler< SiStripFedCabling > SiStripO2OFedCabling
std::string queryConfigMap(std::string configHash)
void start(bool readOnly=true)
Definition: Session.cc:18
bool exists(std::string const &parameterName) const
checks if a parameter exists
void updateConfigMap(std::string configHash, std::string payloadHash)
IOVEditor createIov(const std::string &tag, cond::TimeType timeType, cond::SynchronizationType synchronizationType=cond::SYNCH_ANY)
Definition: Session.h:179
std::unique_ptr< T > fetchPayload(const cond::Hash &payloadHash)
Definition: Session.h:213
~SiStripPayloadHandler() override
void setDescription(const std::string &description)
Definition: IOVEditor.cc:139
void analyze(const edm::Event &evt, const edm::EventSetup &evtSetup) override
Transaction & transaction()
Definition: Session.cc:52
SiStripPayloadHandler< SiStripPedestals > SiStripO2OPedestals
#define EVP_MD_CTX_free
Definition: openssl_init.h:7
void setParameters(const edm::ParameterSet &connectionPset)
Definition: query.py:1
SiStripPayloadHandler< SiStripBadStrip > SiStripO2OBadStrip
unsigned long long Time_t
Definition: Time.h:14
SiStripPayloadHandler< SiStripApvGain > SiStripO2OApvGain
std::string toString(const char *format,...)
Definition: xdaq_compat.cc:4
#define EVP_MD_CTX_new
Definition: openssl_init.h:6
void getValue(SiStripFedCabling *&val)
Hash payloadId
Definition: Types.h:55
void setLastIovGain(std::shared_ptr< SiStripApvGain > gain)
std::string Hash
Definition: Types.h:43
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
IOVProxy readIov(const std::string &tag)
Definition: Session.cc:63
cond::persistency::ConnectionPool m_connectionPool
Log< level::Info, false > LogInfo
void insert(cond::Time_t since, const cond::Hash &payloadHash, bool checkType=false)
Definition: IOVEditor.cc:159
SiStripPayloadHandler(const edm::ParameterSet &iConfig)
std::string getConfigString(const std::type_info &typeInfo)
cond::Hash storePayload(const T &payload, const boost::posix_time::ptime &creationTime=boost::posix_time::microsec_clock::universal_time())
Definition: Session.h:186
SiStripPayloadHandler< SiStripThreshold > SiStripO2OThreshold
SiStripPayloadHandler< SiStripLatency > SiStripO2OLatency
tmp
align.sh
Definition: createJobs.py:716