ATLAS Offline Software
TrigDBLoader.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include "./TrigDBHelper.h"
8 
9 #include "CoralBase/Exception.h"
10 #include "CoralBase/Blob.h"
11 
12 #include "RelationalAccess/ConnectionService.h"
13 #include "RelationalAccess/IConnectionServiceConfiguration.h"
14 #include "RelationalAccess/ISessionProxy.h"
15 #include "RelationalAccess/ISchema.h"
16 
17 #include "CrestApi/CrestApiBase.h"
18 #include "CrestApi/CrestRequest.h"
19 
20 #include "boost/property_tree/ptree.hpp"
21 #include <fstream>
22 #include <format>
23 
25 
26 TrigConf::TrigDBLoader::TrigDBLoader(const std::string & loaderName, const std::string & connection) :
27  TrigConfMessaging(loaderName),
28  m_connection(connection)
29 {
30 
31 
32 }
33 
34 // Destructor defined here because QueryDefinition is an incomplete type in the header
36 
37 size_t
38 TrigConf::TrigDBLoader::schemaVersion(coral::ISessionProxy* session) const {
39 
40  static const std::string versionTagPrefix("Trigger-Run3-Schema-v");
41 
42  // if database has no schema version, then we return 0
43  if(! session->nominalSchema().existsTable("TRIGGER_SCHEMA") ) {
44  throw std::runtime_error( "Trigger schema has no schema version table" );
45  }
46 
48  // tables
49  qdef.addToTableList ( "TRIGGER_SCHEMA" );
50  // attributes
51  qdef.extendOutput<std::string>( "TS_TAG" );
52 
53  auto query = qdef.createQuery( session );
54  auto & cursor = query->execute();
55  if ( ! cursor.next() ) {
56  throw std::runtime_error( "Trigger schema has schema version table but it is empty" );
57  }
58 
59  const coral::AttributeList& row = cursor.currentRow();
60  std::string versionTag = row["TS_TAG"].data<std::string>();
61  if( ! versionTag.starts_with(versionTagPrefix)) {
62  throw std::runtime_error(std::format("Tag format error: Trigger schema version tag {} does not start with {}", versionTag, versionTagPrefix));
63  }
64 
65  std::string vstr = versionTag.substr(versionTagPrefix.size()); // the part of the string containing the version
66  size_t schemaVersion{0};
67  try {
68  schemaVersion = std::stoi(vstr);
69  }
70  catch (const std::invalid_argument& ia) {
71  TRG_MSG_ERROR("Invalid argument when interpreting the version part " << vstr << " of schema tag " << versionTag << ". " << ia.what());
72  throw;
73  }
74 
75  TRG_MSG_INFO("TriggerDB schema version: " << schemaVersion);
76  return schemaVersion;
77 }
78 
79 void
80 TrigConf::TrigDBLoader::setCrestConnection(const std::string & server, const std::string & version) {
81  // server
82  m_crestServer = server;
83  if(m_crestServer.ends_with('/')) { // remove trailing '/'
84  m_crestServer.pop_back();
85  }
86 
87  // use crest flag
88  m_useCrest = ! m_crestServer.empty();
89 
90  // version
91  if(version.empty()) {
92  m_crestVersion = DEFAULT_CREST_API_VERSION; // defined in CrestApi/CrestApiBase.h
93  } else {
94  m_crestVersion = version;
95  }
96  if(!m_crestVersion.starts_with('/')) { // prepend '/' if not existent
97  m_crestVersion = "/" + m_crestVersion;
98  }
99 }
100 
101 void
102 TrigConf::TrigDBLoader::setCrestTrigDB(const std::string & crestTrigDB) {
103  m_crestTrigDb = crestTrigDB;
104 }
105 
106 std::unique_ptr<coral::ISessionProxy>
108 
109  coral::ConnectionService connSvc;
110  coral::IConnectionServiceConfiguration& csc = connSvc.configuration();
111  csc.setConnectionRetrialPeriod( m_retrialPeriod );
112  csc.setConnectionRetrialTimeOut( m_retrialTimeout );
113  csc.setConnectionTimeOut( m_connectionTimeout );
114 
115  /* TODO
116  if(csc.replicaSortingAlgorithm() == nullptr) { // likely to be standalone, create our own
117  TRG_MSG_INFO("Create own ReplicaSortingAlgorithm");
118  m_replicaSorter = new TrigConf::ReplicaSorter();
119  csc.setReplicaSortingAlgorithm(*m_replicaSorter);
120  }
121  */
122 
123  TRG_MSG_INFO("Connecting to " << m_connection);
124 
125  auto proxy = std::unique_ptr<coral::ISessionProxy>( connSvc.connect(m_connection, coral::AccessMode::ReadOnly) );
126 
127  TRG_MSG_INFO("Opened session " << m_connection << " with retrialPeriod/retrialTimeout/connectionTimeout: "
128  << m_retrialPeriod << "/" << m_retrialTimeout << "/" << m_connectionTimeout);
129 
130  return proxy;
131 }
132 
133 std::string
134 TrigConf::TrigDBLoader::getTrigDataCrest(const std::string & type, int key) const {
135  /*
136  To get the trigger data from the TriggerDB using CrestApi, it has been agreed to
137  use the API's payload query with a special specifier
138 
139  triggerdb://<TrigDBSpec>/<TypeSpec>/<DBKey>
140 
141  Possible TrigDBSpec: CONF_DATA_RUN3, CONF_MC_RUN3, CONF_REPR_RUN3
142  Possible TypeSpec: L1PS, HLTM, L1M, HLTPS, BGS, MGS, JO
143  */
144 
145  std::string url = m_crestServer + m_crestVersion;
146  std::string query = std::format("triggerdb://{}/{}/{}", m_crestTrigDb, type, key);
147 
148 #if 0
149  /*
150  the final implementation should be the code below
151  however, in the version used by 24.0 the function CrestApi.getPayload(hash) does not work
152  for the trigger: it includes a hash validation that is not applicable for the trigger
153  but only for conditions payload queries by hash
154  */
155  Crest::CrestApi capi = Crest::CrestApi(url);
156  std::string payload = capi.getPayload(query);
157 #else
158  /*
159  so for release 24.0 and until the access to the trigger payload is implemented in CrestApi
160  the CrestRequest is build manually. Luckily all needed functionality is accessible
161  (this code is a copy of CrestApi::getPayload() without the checkHash())
162  */
163  Crest::CrestRequest request = Crest::CrestRequest();
164  request.setUrl(url);
165  std::string current_path = "payloads/data?format=BLOB&hash=" + query;
166  nlohmann::json js = nullptr;
167  std::string payload = request.performRequest(current_path, Crest::Action::GET, js, "TrigDbLoader");
168 #endif
169 
170  return payload;
171 }
172 
175  const std::map<size_t, TrigConf::QueryDefinition> & queries) const
176 {
177  // find the largest version key in the map of defined queries that is <= the schemaVersion
178  size_t maxDefVersion = 0;
179  for(auto & entry : queries) {
180  size_t vkey = entry.first;
181  if(vkey>maxDefVersion and vkey<=schemaVersion) {
182  maxDefVersion = vkey;
183  }
184  }
185  // if nothing found, throw an error
186  if( maxDefVersion==0 ) {
187  TRG_MSG_ERROR("No query for schema version " << schemaVersion << " defined" );
188  throw TrigConf::NoQueryException(std::format("No query available for schema version {}", schemaVersion));
189  }
190  return queries.at(maxDefVersion);
191 }
192 
193 void
195  const std::string & outFileName, const std::string & description,
196  const std::string & query_type) const
197 {
198  std::string payload;
199  try {
200  payload = getTrigDataCrest(query_type, key);
201  }
202  catch(Crest::CrestException & ex) {
203  TRG_MSG_ERROR("When reading " << description << " for key " << key << " from crest a CrestException was caught ( " << ex.what() <<" )" );
204  throw TrigConf::CrestLoadingException(std::format("{}: {}", getName(), ex.what()));
205  }
206  if(!outFileName.empty()) {
208  TRG_MSG_INFO("Wrote file " << outFileName);
209  }
210  try {
212  }
213  catch(boost::property_tree::json_parser_error & ex) {
214  TRG_MSG_ERROR("When reading " << description << " for key " << key << " from crest a ptree json parser error was caught ( " << ex.what() <<" )" );
215  throw TrigConf::JsonParsingException(std::format("{}: {}", getName(), ex.what()));
216  }
217 }
218 
219 void
221  const std::string & outFileName, const std::string & description,
222  const std::map<size_t, QueryDefinition> & queries) const
223 {
224  auto session = createDBSession();
225  session->transaction().start( /*bool readonly=*/ true);
226  const size_t sv = schemaVersion(session.get());
227  QueryDefinition qdef = getQueryDefinition(sv, queries);
228  try {
229  qdef.setBoundValue<int>("key", key);
230  auto q = qdef.createQuery( session.get() );
231  auto & cursor = q->execute();
232  if ( ! cursor.next() ) {
233  TRG_MSG_ERROR("Tried reading " << description << ", but key " << key << " is not available" );
234  throw TrigConf::NoKeyException(std::format("{}: key {} not available", getName(), key));
235  }
236  const coral::AttributeList& row = cursor.currentRow();
237  const coral::Blob& dataBlob = row[qdef.dataName()].data<coral::Blob>();
238 
239  if(!outFileName.empty()) {
240  writeRawFile( dataBlob, outFileName );
241  TRG_MSG_INFO("Wrote file " << outFileName);
242  }
243  blobToPtree( dataBlob, pt );
244  }
245  catch(coral::QueryException & ex) {
246  TRG_MSG_ERROR("When reading " << description << " for key " << key << " a coral::QueryException was caught ( " << ex.what() <<" )" );
247  throw TrigConf::QueryException(std::format("{}: {}", getName(), ex.what()));
248  }
249  catch(boost::property_tree::json_parser_error & ex) {
250  TRG_MSG_ERROR("When reading " << description << " for key " << key << " a ptree json parser error was caught ( " << ex.what() <<" )" );
251  throw TrigConf::JsonParsingException(std::format("{}: {}", getName(), ex.what()));
252  }
253 }
TRG_MSG_ERROR
#define TRG_MSG_ERROR(x)
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStreamMacros.h:29
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:407
vtune_athena.format
format
Definition: vtune_athena.py:14
json
nlohmann::json json
Definition: HistogramDef.cxx:9
ptree
boost::property_tree::ptree ptree
Definition: TrigDBLoader.cxx:24
TrigConf::TrigDBLoader::schemaVersion
size_t schemaVersion(coral::ISessionProxy *session) const
access to TriggerDB schema version
Definition: TrigDBLoader.cxx:38
test_pyathena.pt
pt
Definition: test_pyathena.py:11
python.subdetectors.tile.Blob
Blob
Definition: tile.py:17
keylayer_zslicemap.row
row
Definition: keylayer_zslicemap.py:155
TrigConf::TrigDBLoader::loadFromCrest
void loadFromCrest(unsigned int key, boost::property_tree::ptree &pt, const std::string &outFileName, const std::string &description, const std::string &query_type) const
Definition: TrigDBLoader.cxx:194
TrigDBLoader.h
Loader class for Trigger configuration from the Trigger DB.
python.PyKernel.AttributeList
AttributeList
Definition: PyKernel.py:36
TrigConf::TrigDBLoader::setCrestConnection
void setCrestConnection(const std::string &server, const std::string &version="")
declare CREST as the source of the configuration An empty crest server makes it use Oracle
Definition: TrigDBLoader.cxx:80
TrigConf::QueryDefinition
Definition: TrigDBHelper.h:30
physics_parameters.url
string url
Definition: physics_parameters.py:27
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
dumpTruth.getName
getName
Definition: dumpTruth.py:34
TrigConf::QueryDefinition::extendOutput
void extendOutput(const std::string &fieldName)
Definition: TrigDBHelper.h:67
TrigConf::QueryDefinition::setBoundValue
void setBoundValue(const std::string &fieldName, const T &value)
Definition: TrigDBHelper.h:77
query
Definition: query.py:1
TrigConf::writeRawFile
void writeRawFile(const coral::Blob &data, const std::string &outFileName)
write coral data blob to file
Definition: TrigDBHelper.cxx:72
checkCorrelInHIST.cursor
cursor
Definition: checkCorrelInHIST.py:26
TrigConf::JsonParsingException
Definition: Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/Exceptions.h:62
TrigConf::TrigDBLoader::loadFromOracle
void loadFromOracle(unsigned int key, boost::property_tree::ptree &pt, const std::string &outFileName, const std::string &description, const std::map< size_t, QueryDefinition > &queries) const
Definition: TrigDBLoader.cxx:220
GET
#define GET(n)
Definition: MD5.cxx:153
TrigConf::TrigDBLoader::setCrestTrigDB
void setCrestTrigDB(const std::string &crestTrigDB)
set trigger db for the crest connection
Definition: TrigDBLoader.cxx:102
TrigConf::QueryDefinition::createQuery
std::unique_ptr< coral::IQuery > createQuery(coral::ISessionProxy *session)
Definition: TrigDBHelper.cxx:13
TrigConf::NoQueryException
Definition: Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/Exceptions.h:26
TRG_MSG_INFO
#define TRG_MSG_INFO(x)
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStreamMacros.h:27
TrigConf::NoKeyException
Definition: Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/Exceptions.h:31
python.getProblemFolderFromLogs.js
dictionary js
Definition: getProblemFolderFromLogs.py:80
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
ptree
boost::property_tree::ptree ptree
Definition: JsonFileLoader.cxx:16
TrigConf::stringToPtree
void stringToPtree(const std::string &json_string, boost::property_tree::ptree &pt)
Definition: TrigDBHelper.cxx:65
TrigConf::QueryException
Definition: Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/Exceptions.h:21
dumpNswErrorDb.outFileName
string outFileName
Definition: dumpNswErrorDb.py:131
TrigConf::TrigConfMessaging
Class to provide easy access to TrigConf::MsgStream for TrigConf classes.
Definition: TrigConfMessaging.h:28
PixelModuleFeMask_create_db.payload
string payload
Definition: PixelModuleFeMask_create_db.py:69
get_generator_info.version
version
Definition: get_generator_info.py:33
TrigConf::TrigDBLoader::getTrigDataCrest
std::string getTrigDataCrest(const std::string &type, int key) const
Get trigger configuration from the TriggerDB through Crest.
Definition: TrigDBLoader.cxx:134
index.query
query
Definition: index.py:72
TrigConf::blobToPtree
void blobToPtree(const coral::Blob &blob, boost::property_tree::ptree &pt)
Definition: TrigDBHelper.cxx:58
LArCellConditions.sv
bool sv
Definition: LArCellConditions.py:45
TrigConf::TrigDBLoader::~TrigDBLoader
virtual ~TrigDBLoader()
Destructor - cannot be defined here because QueryDefinition is an incomplete type.
extractSporadic.q
list q
Definition: extractSporadic.py:97
TrigDBHelper.h
TrigConf::QueryDefinition::dataName
const std::string & dataName()
Definition: TrigDBHelper.h:53
python.html.AtlRunQueryDQSummary.server
server
Definition: AtlRunQueryDQSummary.py:21
TrigConf::TrigDBLoader::createDBSession
std::unique_ptr< coral::ISessionProxy > createDBSession() const
create (if needed) DB session and return the session proxy
Definition: TrigDBLoader.cxx:107
TrigConf::CrestLoadingException
Definition: Trigger/TrigConfiguration/TrigConfIO/TrigConfIO/Exceptions.h:74
TrigConf::QueryDefinition::addToTableList
void addToTableList(const std::string &table, const std::string &table_short="")
Definition: TrigDBHelper.cxx:44
description
std::string description
glabal timer - how long have I taken so far?
Definition: hcg.cxx:88
TrigConf::TrigDBLoader::getQueryDefinition
QueryDefinition getQueryDefinition(size_t schemaVersion, const std::map< size_t, QueryDefinition > &queries) const
return query for given schemaVersion from possible queries
Definition: TrigDBLoader.cxx:174
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
TrigConf::TrigDBLoader::TrigDBLoader
TrigDBLoader(const std::string &loaderName, const std::string &connection)
Constructor.
Definition: TrigDBLoader.cxx:26