CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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:
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
164  SHA_CTX ctx;
165  if (!SHA1_Init(&ctx)) {
166  throw cms::Exception("SHA1 initialization error.");
167  }
168  if (!SHA1_Update(&ctx, p_type.c_str(), p_type.size())) {
169  throw cms::Exception("SHA1 processing error (1).");
170  }
171  if (!SHA1_Update(&ctx, p_cfgstr.c_str(), p_cfgstr.size())) {
172  throw cms::Exception("SHA1 processing error (2).");
173  }
174  unsigned char hash[SHA_DIGEST_LENGTH];
175  if (!SHA1_Final(hash, &ctx)) {
176  throw cms::Exception("SHA1 finalization error.");
177  }
178 
179  char tmp[SHA_DIGEST_LENGTH * 2 + 1];
180  // re-write bytes in hex
181  for (unsigned int i = 0; i < SHA_DIGEST_LENGTH; i++) {
182  ::sprintf(&tmp[i * 2], "%02x", hash[i]);
183  }
184  tmp[SHA_DIGEST_LENGTH * 2] = 0;
185 
186  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__
187  << "] "
188  "... hash: "
189  << tmp;
190  return tmp;
191 }
192 
193 template <typename SiStripPayload>
195  if (m_configMapDb.empty())
196  return ""; // return empty string if m_configMapDb is not specified
197 
198  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
199  << "Query " << m_configMapDb << " to see if the payload is already in DB.";
200 
201  auto cmDbSession = m_connectionPool.createCoralSession(m_configMapDb);
202  // query the STRIP_CONFIG_TO_PAYLOAD_MAP table
203  cmDbSession->transaction().start(true);
204  coral::ITable& cmTable = cmDbSession->schema(m_cfgMapSchemaName).tableHandle(m_cfgMapTableName);
205  std::unique_ptr<coral::IQuery> query(cmTable.newQuery());
206  query->addToOutputList("PAYLOAD_HASH");
207  query->defineOutputType("PAYLOAD_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
208  // also print these for debugging
209  query->addToOutputList("PAYLOAD_TYPE");
210  query->addToOutputList("CONFIG_STRING");
211  query->addToOutputList("INSERTION_TIME");
212  std::string whereClause("CONFIG_HASH = :CONFIG_HASH");
213  coral::AttributeList whereData;
214  whereData.extend<std::string>("CONFIG_HASH");
215  whereData.begin()->data<std::string>() = configHash;
216  query->setCondition(whereClause, whereData);
217  coral::ICursor& cursor = query->execute();
218  std::string p_hash;
219  if (cursor.next()) {
220  // the payload has been found ( fast O2O case )
221  p_hash = cursor.currentRow()["PAYLOAD_HASH"].data<std::string>();
222  edm::LogInfo("SiStripPayloadHandler")
223  << "[SiStripPayloadHandler::" << __func__ << "] "
224  << "Found associated payload hash " << p_hash
225  << "\n... type=" << cursor.currentRow()["PAYLOAD_TYPE"].data<std::string>()
226  << "\n... config=" << cursor.currentRow()["CONFIG_STRING"].data<std::string>()
227  << "\n... insertion_time=" << cursor.currentRow()["INSERTION_TIME"].data<coral::TimeStamp>().toString();
228  }
229  cmDbSession->transaction().commit();
230 
231  return p_hash;
232 }
233 
234 template <typename SiStripPayload>
236  if (m_cfgMapDbFile.empty())
237  return; // skip this if m_cfgMapDbFile is not set
238 
239  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
240  << "Updating the config to payload hash map to " << m_cfgMapDbFile;
241 
242  // create a writable transaction
243  auto cmSQLiteSession = m_connectionPool.createCoralSession(m_cfgMapDbFile, true);
244  cmSQLiteSession->transaction().start(false);
245 
246  if (!cmSQLiteSession->nominalSchema().existsTable(m_cfgMapTableName)) {
247  // create the table if it does not exist
248  coral::TableDescription mapTable;
249  mapTable.setName(m_cfgMapTableName);
250  mapTable.insertColumn("CONFIG_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
251  mapTable.insertColumn("PAYLOAD_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
252  mapTable.insertColumn("PAYLOAD_TYPE", coral::AttributeSpecification::typeNameForType<std::string>());
253  mapTable.insertColumn("CONFIG_STRING", coral::AttributeSpecification::typeNameForType<std::string>());
254  mapTable.insertColumn("INSERTION_TIME", coral::AttributeSpecification::typeNameForType<coral::TimeStamp>());
255  mapTable.setPrimaryKey("CONFIG_HASH");
256  mapTable.setNotNullConstraint("CONFIG_HASH");
257  mapTable.setNotNullConstraint("PAYLOAD_HASH");
258  mapTable.setNotNullConstraint("PAYLOAD_TYPE");
259  mapTable.setNotNullConstraint("CONFIG_STRING");
260  mapTable.setNotNullConstraint("INSERTION_TIME");
261  cmSQLiteSession->nominalSchema().createTable(mapTable);
262  }
263 
264  coral::ITable& cmTable = cmSQLiteSession->nominalSchema().tableHandle(m_cfgMapTableName);
265  coral::AttributeList insertData;
266  insertData.extend<std::string>("CONFIG_HASH");
267  insertData.extend<std::string>("PAYLOAD_HASH");
268  // also insert these for bookkeeping
269  insertData.extend<std::string>("PAYLOAD_TYPE");
270  insertData.extend<std::string>("CONFIG_STRING");
271  insertData.extend<coral::TimeStamp>("INSERTION_TIME");
272  insertData["CONFIG_HASH"].data<std::string>() = configHash;
273  insertData["PAYLOAD_HASH"].data<std::string>() = payloadHash;
274  insertData["PAYLOAD_TYPE"].data<std::string>() = p_type;
275  insertData["CONFIG_STRING"].data<std::string>() = p_cfgstr;
276  insertData["INSERTION_TIME"].data<coral::TimeStamp>() = coral::TimeStamp::now(); // UTC time
277  cmTable.dataEditor().insertRow(insertData);
278  cmSQLiteSession->transaction().commit();
279  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
280  << "Updated with mapping (configHash : payloadHash)" << configHash << " : "
281  << payloadHash;
282 }
283 
284 // -------------------------------------------------------
285 
288 
291 
294 
297 
300 
303 
SiStripPayloadHandler< SiStripNoises > SiStripO2ONoises
SiStripPayloadHandler< SiStripFedCabling > SiStripO2OFedCabling
std::string queryConfigMap(std::string configHash)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
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
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
void setParameters(const edm::ParameterSet &connectionPset)
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
void getValue(SiStripFedCabling *&val)
Hash payloadId
Definition: Types.h:55
void setLastIovGain(std::shared_ptr< SiStripApvGain > gain)
std::string Hash
Definition: Types.h:43
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)
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
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
tuple cout
Definition: gather_cfg.py:144
SiStripPayloadHandler< SiStripThreshold > SiStripO2OThreshold
SiStripPayloadHandler< SiStripLatency > SiStripO2OLatency
tmp
align.sh
Definition: createJobs.py:716