CMS 3D CMS Logo

SiStripPayloadHandler.cc
Go to the documentation of this file.
6 
7 #include <iostream>
8 #include <sstream>
9 #include <typeinfo>
10 #include <openssl/sha.h>
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 
55 };
56 
57 template <typename SiStripPayload>
59  : m_connectionPool(),
60  m_cfgMapSchemaName(iConfig.getUntrackedParameter<std::string>("cfgMapSchemaName", "CMS_COND_O2O")),
61  m_cfgMapTableName(iConfig.getUntrackedParameter<std::string>("cfgMapTableName", "STRIP_CONFIG_TO_PAYLOAD_MAP")),
62  m_condDb(iConfig.getParameter<std::string>("conditionDatabase")),
63  m_localCondDbFile(iConfig.getParameter<std::string>("condDbFile")),
64  m_targetTag(iConfig.getParameter<std::string>("targetTag")),
65  m_since(iConfig.getParameter<uint32_t>("since")),
66  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
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;
111  if (typeid(SiStripPayload) == typeid(SiStripApvGain)) {
112  // special treatment for ApvGain : provide last payload in DB
113  condObjBuilder->setLastIovGain(condDbSession.fetchPayload<SiStripApvGain>(last_hash));
114  }
115  condObjBuilder->getValue(obj);
116  payloadToUpload = std::shared_ptr<SiStripPayload>(obj);
117  std::cout << "@@@[FastO2O:false]@@@" << std::endl;
118  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
119  << " ... New payload has been created.";
120  }
121  condDbSession.transaction().commit();
122 
123  // write payload and iov in the local file
124  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
125  << "Write payload to local sqlite file: " << m_localCondDbFile;
126  cond::persistency::Session localFileSession = m_connectionPool.createSession(m_localCondDbFile, true);
127  localFileSession.transaction().start(false);
128  // write the payload
129  cond::Hash thePayloadHash = localFileSession.storePayload<SiStripPayload>(*payloadToUpload);
130  cond::persistency::IOVEditor iovEditor = localFileSession.createIov<SiStripPayload>(m_targetTag, cond::runnumber);
131  iovEditor.setDescription("New IOV");
132  // inserting the iov
133  iovEditor.insert(m_since, thePayloadHash);
134  iovEditor.flush();
135  localFileSession.transaction().commit();
136  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
137  << "Payload " << thePayloadHash << " inserted to sqlite with IOV " << m_since;
138 
139  // last step, update the configMap if required
140  if (!mapUpToDate) {
141  updateConfigMap(configHash, thePayloadHash);
142  }
143 
144  // finish the extra work: Compare the new payload with last IOV
145  if (last_hash == thePayloadHash) {
146  std::cout << "@@@[PayloadChange:false]@@@" << last_hash << std::endl;
147  } else {
148  std::cout << "@@@[PayloadChange:true]@@@" << last_hash << " -> " << thePayloadHash << std::endl;
149  }
150 }
151 
152 template <typename SiStripPayload>
154 
155 template <typename SiStripPayload>
157  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
158  << "Convert config string to SHA-1 hash for " << p_type
159  << "\n... config: " << p_cfgstr;
160 
161  // calcuate SHA-1 hash using openssl
162  // adapted from cond::persistency::makeHash() in CondCore/CondDB/src/IOVSchema.cc
163  SHA_CTX ctx;
164  if (!SHA1_Init(&ctx)) {
165  throw cms::Exception("SHA1 initialization error.");
166  }
167  if (!SHA1_Update(&ctx, p_type.c_str(), p_type.size())) {
168  throw cms::Exception("SHA1 processing error (1).");
169  }
170  if (!SHA1_Update(&ctx, p_cfgstr.c_str(), p_cfgstr.size())) {
171  throw cms::Exception("SHA1 processing error (2).");
172  }
173  unsigned char hash[SHA_DIGEST_LENGTH];
174  if (!SHA1_Final(hash, &ctx)) {
175  throw cms::Exception("SHA1 finalization error.");
176  }
177 
178  char tmp[SHA_DIGEST_LENGTH * 2 + 1];
179  // re-write bytes in hex
180  for (unsigned int i = 0; i < SHA_DIGEST_LENGTH; i++) {
181  ::sprintf(&tmp[i * 2], "%02x", hash[i]);
182  }
183  tmp[SHA_DIGEST_LENGTH * 2] = 0;
184 
185  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__
186  << "] "
187  "... hash: "
188  << tmp;
189  return tmp;
190 }
191 
192 template <typename SiStripPayload>
194  if (m_configMapDb.empty())
195  return ""; // return empty string if m_configMapDb is not specified
196 
197  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
198  << "Query " << m_configMapDb << " to see if the payload is already in DB.";
199 
200  auto cmDbSession = m_connectionPool.createCoralSession(m_configMapDb);
201  // query the STRIP_CONFIG_TO_PAYLOAD_MAP table
202  cmDbSession->transaction().start(true);
203  coral::ITable& cmTable = cmDbSession->schema(m_cfgMapSchemaName).tableHandle(m_cfgMapTableName);
204  std::unique_ptr<coral::IQuery> query(cmTable.newQuery());
205  query->addToOutputList("PAYLOAD_HASH");
206  query->defineOutputType("PAYLOAD_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
207  // also print these for debugging
208  query->addToOutputList("PAYLOAD_TYPE");
209  query->addToOutputList("CONFIG_STRING");
210  query->addToOutputList("INSERTION_TIME");
211  std::string whereClause("CONFIG_HASH = :CONFIG_HASH");
212  coral::AttributeList whereData;
213  whereData.extend<std::string>("CONFIG_HASH");
214  whereData.begin()->data<std::string>() = configHash;
215  query->setCondition(whereClause, whereData);
216  coral::ICursor& cursor = query->execute();
217  std::string p_hash;
218  if (cursor.next()) {
219  // the payload has been found ( fast O2O case )
220  p_hash = cursor.currentRow()["PAYLOAD_HASH"].data<std::string>();
221  edm::LogInfo("SiStripPayloadHandler")
222  << "[SiStripPayloadHandler::" << __func__ << "] "
223  << "Found associated payload hash " << p_hash
224  << "\n... type=" << cursor.currentRow()["PAYLOAD_TYPE"].data<std::string>()
225  << "\n... config=" << cursor.currentRow()["CONFIG_STRING"].data<std::string>()
226  << "\n... insertion_time=" << cursor.currentRow()["INSERTION_TIME"].data<coral::TimeStamp>().toString();
227  }
228  cmDbSession->transaction().commit();
229 
230  return p_hash;
231 }
232 
233 template <typename SiStripPayload>
235  if (m_cfgMapDbFile.empty())
236  return; // skip this if m_cfgMapDbFile is not set
237 
238  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
239  << "Updating the config to payload hash map to " << m_cfgMapDbFile;
240 
241  // create a writable transaction
242  auto cmSQLiteSession = m_connectionPool.createCoralSession(m_cfgMapDbFile, true);
243  cmSQLiteSession->transaction().start(false);
244 
245  if (!cmSQLiteSession->nominalSchema().existsTable(m_cfgMapTableName)) {
246  // create the table if it does not exist
247  coral::TableDescription mapTable;
248  mapTable.setName(m_cfgMapTableName);
249  mapTable.insertColumn("CONFIG_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
250  mapTable.insertColumn("PAYLOAD_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
251  mapTable.insertColumn("PAYLOAD_TYPE", coral::AttributeSpecification::typeNameForType<std::string>());
252  mapTable.insertColumn("CONFIG_STRING", coral::AttributeSpecification::typeNameForType<std::string>());
253  mapTable.insertColumn("INSERTION_TIME", coral::AttributeSpecification::typeNameForType<coral::TimeStamp>());
254  mapTable.setPrimaryKey("CONFIG_HASH");
255  mapTable.setNotNullConstraint("CONFIG_HASH");
256  mapTable.setNotNullConstraint("PAYLOAD_HASH");
257  mapTable.setNotNullConstraint("PAYLOAD_TYPE");
258  mapTable.setNotNullConstraint("CONFIG_STRING");
259  mapTable.setNotNullConstraint("INSERTION_TIME");
260  cmSQLiteSession->nominalSchema().createTable(mapTable);
261  }
262 
263  coral::ITable& cmTable = cmSQLiteSession->nominalSchema().tableHandle(m_cfgMapTableName);
264  coral::AttributeList insertData;
265  insertData.extend<std::string>("CONFIG_HASH");
266  insertData.extend<std::string>("PAYLOAD_HASH");
267  // also insert these for bookkeeping
268  insertData.extend<std::string>("PAYLOAD_TYPE");
269  insertData.extend<std::string>("CONFIG_STRING");
270  insertData.extend<coral::TimeStamp>("INSERTION_TIME");
271  insertData["CONFIG_HASH"].data<std::string>() = configHash;
272  insertData["PAYLOAD_HASH"].data<std::string>() = payloadHash;
273  insertData["PAYLOAD_TYPE"].data<std::string>() = p_type;
274  insertData["CONFIG_STRING"].data<std::string>() = p_cfgstr;
275  insertData["INSERTION_TIME"].data<coral::TimeStamp>() = coral::TimeStamp::now(); // UTC time
276  cmTable.dataEditor().insertRow(insertData);
277  cmSQLiteSession->transaction().commit();
278  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
279  << "Updated with mapping (configHash : payloadHash)" << configHash << " : "
280  << payloadHash;
281 }
282 
283 // -------------------------------------------------------
284 
287 
290 
293 
296 
299 
302 
T getParameter(std::string const &) const
edm::Service< SiStripCondObjBuilderFromDb > condObjBuilder
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:190
std::unique_ptr< T > fetchPayload(const cond::Hash &payloadHash)
Definition: Session.h:224
void setDescription(const std::string &description)
Definition: IOVEditor.cc:111
void analyze(const edm::Event &evt, const edm::EventSetup &evtSetup) override
Transaction & transaction()
Definition: Session.cc:43
SiStripPayloadHandler< SiStripPedestals > SiStripO2OPedestals
void setParameters(const edm::ParameterSet &connectionPset)
Definition: query.py:1
IOVProxy readIov(const std::string &tag, bool full=false)
Definition: Session.cc:54
SiStripPayloadHandler< SiStripBadStrip > SiStripO2OBadStrip
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
unsigned long long Time_t
Definition: Time.h:14
SiStripPayloadHandler< SiStripApvGain > SiStripO2OApvGain
std::string toString(const char *format,...)
Definition: xdaq_compat.cc:4
void getValue(SiStripFedCabling *&val)
Hash payloadId
Definition: Types.h:55
Session createSession(const std::string &connectionString, bool writeCapable=false)
void setLastIovGain(std::shared_ptr< SiStripApvGain > gain)
std::string Hash
Definition: Types.h:43
cond::persistency::ConnectionPool m_connectionPool
void insert(cond::Time_t since, const cond::Hash &payloadHash, bool checkType=false)
Definition: IOVEditor.cc:136
SiStripPayloadHandler(const edm::ParameterSet &iConfig)
cond::Hash storePayload(const T &payload, const boost::posix_time::ptime &creationTime=boost::posix_time::microsec_clock::universal_time())
Definition: Session.h:197
Definition: plugin.cc:23
SiStripPayloadHandler< SiStripThreshold > SiStripO2OThreshold
SiStripPayloadHandler< SiStripLatency > SiStripO2OLatency
tmp
align.sh
Definition: createJobs.py:716
std::shared_ptr< coral::ISessionProxy > createCoralSession(const std::string &connectionString, bool writeCapable=false)