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 
58 template<typename SiStripPayload>
61  m_cfgMapSchemaName( iConfig.getUntrackedParameter< std::string >("cfgMapSchemaName", "CMS_COND_O2O") ),
62  m_cfgMapTableName( iConfig.getUntrackedParameter< std::string >("cfgMapTableName", "STRIP_CONFIG_TO_PAYLOAD_MAP") ),
63  m_condDb( iConfig.getParameter< std::string >("conditionDatabase") ),
64  m_localCondDbFile( iConfig.getParameter< std::string >("condDbFile") ),
65  m_targetTag( iConfig.getParameter< std::string >("targetTag") ),
66  m_since( iConfig.getParameter< uint32_t >("since") ),
67  p_type( cond::demangledName(typeid(SiStripPayload)) ),
68  p_cfgstr( condObjBuilder->getConfigString(typeid(SiStripPayload)) )
69 {
70  if (iConfig.exists("configMapDatabase"))
71  m_configMapDb = iConfig.getParameter< std::string >("configMapDatabase");
72  if (iConfig.exists("cfgMapDbFile"))
73  m_cfgMapDbFile = iConfig.getParameter< std::string >("cfgMapDbFile");
76 }
77 
78 template<typename SiStripPayload>
80 }
81 
82 template<typename SiStripPayload>
84 
85  // some extra work: Getting the payload hash of the last IOV from condDb
86  // Will be compared with the new payload and reported
88  condDbSession.transaction().start( true );
89  cond::persistency::IOVProxy iovProxy = condDbSession.readIov( m_targetTag );
90  cond::Hash last_hash = iovProxy.getLast().payloadId;
91 
92  // that's the final goal: obtain the payload to store into the sqlite file for the upload into the DB
93  std::shared_ptr<SiStripPayload> payloadToUpload;
94  // first compute the hash of the configuration
95  std::string configHash = makeConfigHash();
96  // query the configMap DB to find the corresponding payload hash
97  std::string mappedPayloadHash = queryConfigMap(configHash);
98  bool mapUpToDate = false;
99 
100  if ( !mappedPayloadHash.empty() ){
101  // the payload has been found ( fast O2O case )
102  // copy the payload from condtition database
103  mapUpToDate = true;
104  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
105  << "Try retrieving payload from " << m_condDb;
106  payloadToUpload = condDbSession.fetchPayload<SiStripPayload>( mappedPayloadHash );
107  std::cout << "@@@[FastO2O:true]@@@" << std::endl;
108  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
109  << " ... Payload is copied from offline condition database.";
110  }else {
111  // start the long O2O...
112  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
113  << "NO mapping payload hash found. Will run the long O2O. ";
114  SiStripPayload *obj = nullptr;
115  if (typeid(SiStripPayload) == typeid(SiStripApvGain)){
116  // special treatment for ApvGain : provide last payload in DB
117  condObjBuilder->setLastIovGain(condDbSession.fetchPayload<SiStripApvGain>( last_hash ));
118  }
119  condObjBuilder->getValue(obj);
120  payloadToUpload = std::shared_ptr<SiStripPayload>(obj);
121  std::cout << "@@@[FastO2O:false]@@@" << std::endl;
122  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
123  << " ... New payload has been created.";
124  }
125  condDbSession.transaction().commit();
126 
127  // write payload and iov in the local file
128  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
129  << "Write payload to local sqlite file: " << m_localCondDbFile;
130  cond::persistency::Session localFileSession = m_connectionPool.createSession( m_localCondDbFile, true );
131  localFileSession.transaction().start( false );
132  // write the payload
133  cond::Hash thePayloadHash = localFileSession.storePayload<SiStripPayload>( *payloadToUpload );
134  cond::persistency::IOVEditor iovEditor = localFileSession.createIov<SiStripPayload>( m_targetTag, cond::runnumber );
135  iovEditor.setDescription( "New IOV" );
136  // inserting the iov
137  iovEditor.insert( m_since, thePayloadHash );
138  iovEditor.flush();
139  localFileSession.transaction().commit();
140  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
141  << "Payload " << thePayloadHash << " inserted to sqlite with IOV " << m_since;
142 
143  // last step, update the configMap if required
144  if( !mapUpToDate ){
145  updateConfigMap(configHash, thePayloadHash);
146  }
147 
148  // finish the extra work: Compare the new payload with last IOV
149  if (last_hash == thePayloadHash){
150  std::cout << "@@@[PayloadChange:false]@@@" << last_hash << std::endl;
151  }else {
152  std::cout << "@@@[PayloadChange:true]@@@" << last_hash << " -> " << thePayloadHash << std::endl;
153  }
154 
155 }
156 
157 template<typename SiStripPayload>
159 }
160 
161 template<typename SiStripPayload>
163 
164  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
165  << "Convert config string to SHA-1 hash for " << p_type
166  << "\n... config: " << p_cfgstr;
167 
168  // calcuate SHA-1 hash using openssl
169  // adapted from cond::persistency::makeHash() in CondCore/CondDB/src/IOVSchema.cc
170  SHA_CTX ctx;
171  if( !SHA1_Init( &ctx ) ){
172  throw cms::Exception("SHA1 initialization error.");
173  }
174  if( !SHA1_Update( &ctx, p_type.c_str(), p_type.size() ) ){
175  throw cms::Exception("SHA1 processing error (1).");
176  }
177  if( !SHA1_Update( &ctx, p_cfgstr.c_str(), p_cfgstr.size() ) ){
178  throw cms::Exception("SHA1 processing error (2).");
179  }
180  unsigned char hash[SHA_DIGEST_LENGTH];
181  if( !SHA1_Final(hash, &ctx) ){
182  throw cms::Exception("SHA1 finalization error.");
183  }
184 
185  char tmp[SHA_DIGEST_LENGTH*2+1];
186  // re-write bytes in hex
187  for (unsigned int i = 0; i < SHA_DIGEST_LENGTH; i++) {
188  ::sprintf(&tmp[i * 2], "%02x", hash[i]);
189  }
190  tmp[SHA_DIGEST_LENGTH*2] = 0;
191 
192  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
193  "... hash: " << tmp;
194  return tmp;
195 
196 }
197 
198 template<typename SiStripPayload>
200  if (m_configMapDb.empty()) 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  auto cmDbSession = m_connectionPool.createCoralSession( m_configMapDb );
206  // query the STRIP_CONFIG_TO_PAYLOAD_MAP table
207  cmDbSession->transaction().start( true );
208  coral::ITable& cmTable = cmDbSession->schema( m_cfgMapSchemaName ).tableHandle( m_cfgMapTableName );
209  std::unique_ptr<coral::IQuery> query( cmTable.newQuery() );
210  query->addToOutputList( "PAYLOAD_HASH" );
211  query->defineOutputType( "PAYLOAD_HASH", coral::AttributeSpecification::typeNameForType<std::string>() );
212  // also print these for debugging
213  query->addToOutputList( "PAYLOAD_TYPE" );
214  query->addToOutputList( "CONFIG_STRING" );
215  query->addToOutputList( "INSERTION_TIME" );
216  std::string whereClause( "CONFIG_HASH = :CONFIG_HASH" );
217  coral::AttributeList whereData;
218  whereData.extend<std::string>( "CONFIG_HASH" );
219  whereData.begin()->data< std::string >() = configHash;
220  query->setCondition( whereClause, whereData );
221  coral::ICursor& cursor = query->execute();
222  std::string p_hash;
223  if( cursor.next() ){
224  // the payload has been found ( fast O2O case )
225  p_hash = cursor.currentRow()["PAYLOAD_HASH"].data<std::string>();
226  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
227  << "Found associated payload hash " << p_hash
228  << "\n... type=" << cursor.currentRow()["PAYLOAD_TYPE"].data<std::string>()
229  << "\n... config=" << cursor.currentRow()["CONFIG_STRING"].data<std::string>()
230  << "\n... insertion_time=" << cursor.currentRow()["INSERTION_TIME"].data<coral::TimeStamp>().toString();
231  }
232  cmDbSession->transaction().commit();
233 
234  return p_hash;
235 }
236 
237 template<typename SiStripPayload>
239  if (m_cfgMapDbFile.empty()) return; // skip this if m_cfgMapDbFile is not set
240 
241  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
242  << "Updating the config to payload hash map to " << m_cfgMapDbFile;
243 
244  // create a writable transaction
245  auto cmSQLiteSession = m_connectionPool.createCoralSession( m_cfgMapDbFile, true );
246  cmSQLiteSession->transaction().start( false );
247 
248  if (!cmSQLiteSession->nominalSchema().existsTable( m_cfgMapTableName )){
249  // create the table if it does not exist
250  coral::TableDescription mapTable;
251  mapTable.setName(m_cfgMapTableName);
252  mapTable.insertColumn("CONFIG_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
253  mapTable.insertColumn("PAYLOAD_HASH", coral::AttributeSpecification::typeNameForType<std::string>());
254  mapTable.insertColumn("PAYLOAD_TYPE", coral::AttributeSpecification::typeNameForType<std::string>());
255  mapTable.insertColumn("CONFIG_STRING", coral::AttributeSpecification::typeNameForType<std::string>());
256  mapTable.insertColumn("INSERTION_TIME", coral::AttributeSpecification::typeNameForType<coral::TimeStamp>());
257  mapTable.setPrimaryKey("CONFIG_HASH");
258  mapTable.setNotNullConstraint("CONFIG_HASH");
259  mapTable.setNotNullConstraint("PAYLOAD_HASH");
260  mapTable.setNotNullConstraint("PAYLOAD_TYPE");
261  mapTable.setNotNullConstraint("CONFIG_STRING");
262  mapTable.setNotNullConstraint("INSERTION_TIME");
263  cmSQLiteSession->nominalSchema().createTable(mapTable);
264  }
265 
266  coral::ITable& cmTable = cmSQLiteSession->nominalSchema().tableHandle( m_cfgMapTableName );
267  coral::AttributeList insertData;
268  insertData.extend<std::string>( "CONFIG_HASH" );
269  insertData.extend<std::string>( "PAYLOAD_HASH" );
270  // also insert these for bookkeeping
271  insertData.extend<std::string>( "PAYLOAD_TYPE" );
272  insertData.extend<std::string>( "CONFIG_STRING" );
273  insertData.extend<coral::TimeStamp>( "INSERTION_TIME" );
274  insertData["CONFIG_HASH"].data<std::string>() = configHash;
275  insertData["PAYLOAD_HASH"].data<std::string>() = payloadHash;
276  insertData["PAYLOAD_TYPE"].data<std::string>() = p_type;
277  insertData["CONFIG_STRING"].data<std::string>() = p_cfgstr;
278  insertData["INSERTION_TIME"].data<coral::TimeStamp>() = coral::TimeStamp::now(); // UTC time
279  cmTable.dataEditor().insertRow( insertData );
280  cmSQLiteSession->transaction().commit();
281  edm::LogInfo("SiStripPayloadHandler") << "[SiStripPayloadHandler::" << __func__ << "] "
282  << "Updated with mapping (configHash : payloadHash)" << configHash << " : " << payloadHash;
283 }
284 
285 // -------------------------------------------------------
286 
289 
292 
295 
298 
301 
304 
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:22
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:188
std::unique_ptr< T > fetchPayload(const cond::Hash &payloadHash)
Definition: Session.h:218
void setDescription(const std::string &description)
Definition: IOVEditor.cc:128
void analyze(const edm::Event &evt, const edm::EventSetup &evtSetup) override
Transaction & transaction()
Definition: Session.cc:66
def query(query_str, verbose=False)
Definition: das.py:6
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:81
SiStripPayloadHandler< SiStripBadStrip > SiStripO2OBadStrip
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
unsigned long long Time_t
Definition: Time.h:16
SiStripPayloadHandler< SiStripApvGain > SiStripO2OApvGain
void getValue(SiStripFedCabling *&val)
Hash payloadId
Definition: Types.h:57
Session createSession(const std::string &connectionString, bool writeCapable=false)
void setLastIovGain(std::shared_ptr< SiStripApvGain > gain)
std::string Hash
Definition: Types.h:45
std::string toString(const std::pair< T, T > &aT)
Definition: CaloEllipse.h:72
cond::persistency::ConnectionPool m_connectionPool
void insert(cond::Time_t since, const cond::Hash &payloadHash, bool checkType=false)
Definition: IOVEditor.cc:152
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:192
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
Definition: plugin.cc:24
SiStripPayloadHandler< SiStripThreshold > SiStripO2OThreshold
SiStripPayloadHandler< SiStripLatency > SiStripO2OLatency
std::shared_ptr< coral::ISessionProxy > createCoralSession(const std::string &connectionString, bool writeCapable=false)