14 from collections.abc
import Iterable
21 if run_number
is None and smk
is None and isRun2
is None:
22 raise RuntimeError(
"Cannot determine if trigger db is run 1 or 2")
25 return smk >= 2000
and smk<3000
26 elif run_number
is not None :
27 return run_number > 249000
33 if run_number
is None and smk
is None and lhcRun
is None:
34 raise RuntimeError(
"Cannot determine the triggerDBAlias as no info is given")
37 if lhcRun==1
or lhcRun==2:
38 return f
"TRIGGERDB_RUN{lhcRun}"
40 return "TRIGGERDBDEV1_I8" if (smk
is not None and smk<3000)
else "TRIGGERDB_RUN3"
45 return "TRIGGERDB_RUN1"
48 return "TRIGGERDB_RUN2"
50 return "TRIGGERDB_RUN3"
54 if run_number > 405800:
55 return "TRIGGERDB_RUN3"
56 if run_number > 378000:
57 return "TRIGGERDBDEV1_I8"
58 elif run_number > 249000:
59 return "TRIGGERDB_RUN2"
61 return "TRIGGERDB_RUN1"
65 from xml.dom
import minidom
66 import os, re, logging
67 log = logging.getLogger( __name__ )
70 def __init__(self, name, counter, lowername="", lowercounter=-1, forshow=False, forselect=False, level=0):
73 self.
lowername =
"" if lowername==
"~" else lowername
82 return "TC:"+self.
name
86 """Find <filename> with rights <access> through <pathlist>."""
89 if os.path.dirname( filename ):
90 if os.access( filename, access ):
95 f = os.path.join( path, filename )
96 if os.access( f, access ):
105 """looks for filename in local directory and then in all paths specified in environment variable 'pathenv'
106 returns path/filename if existing, otherwise None
108 log = logging.getLogger(
"TrigConfigSvcUtils.py" )
109 if os.path.exists(filename):
110 log.info(
"Using local file %s", filename)
113 pathlist = os.getenv(pathenv,
'').
split(os.pathsep)
114 resolvedfilename =
FindFile(filename, pathlist, os.R_OK)
116 return resolvedfilename
118 log.fatal(
"No file %s found locally nor in %s" % (filename, os.getenv(
'CORAL_DBLOOKUP_PATH')) )
123 log = logging.getLogger(
"TrigConfigSvcUtils.py" )
125 connectionServices =
None
128 if dblookupfilename
is None:
131 doc = minidom.parse(dblookupfilename)
132 for ls
in doc.getElementsByTagName(
'logicalservice'):
133 if ls.attributes[
'name'].value != alias:
135 connectionServices = [
str(s.attributes[
'name'].value)
for s
in ls.getElementsByTagName(
'service')]
138 log.info(
"For alias '%s' found list of connections %r", alias, connectionServices )
139 if connectionServices
is None:
140 print(
"ERROR: Trigger connection alias '%s' is not defined in %s" % (alias,dblookupfilename))
141 return connectionServices
145 """ read authentication.xml, first from local directory, then from all paths specified in CORAL_AUTH_PATH
146 returns dictionary d with d[connection] -> (user,pw)
151 if dbauthfilename
is None:
154 doc = minidom.parse(dbauthfilename)
155 for cn
in doc.getElementsByTagName(
'connection'):
158 svc = cn.attributes[
'name'].value
159 for p
in cn.getElementsByTagName(
'parameter'):
160 if p.attributes[
'name'].value ==
'user':
161 user = p.attributes[
'value'].value
162 elif p.attributes[
'name'].value ==
'password':
163 pw = p.attributes[
'value'].value
164 authDict[svc] = (user,pw)
171 log = logging.getLogger(
"TrigConfigSvcUtils.py" )
172 connection =
str(connection)
173 connectionParameters = {}
175 if connection.startswith(
"sqlite_file:"):
176 filename = connection[connection.find(
':')+1:]
177 connectionParameters[
"techno"] =
"sqlite"
178 connectionParameters[
"filename"] = filename
if os.path.exists(filename)
else None
180 elif connection.startswith(
"oracle://"):
181 if connection.count(
';') == 2:
182 pattern =
"(.*)://(.*)/(.*);username=(.*);password=(.*)"
183 m = re.match(pattern,connection)
186 log.fatal(
"connection string '%s' doesn't match the pattern '%s'?" % (connection,pattern))
187 (techno, server, schema, user, passwd) = m.groups()
193 pattern =
"oracle://(.*)/(.*)"
194 m = re.match(pattern,connection)
196 log.fatal(
"connection string '%s' doesn't match the pattern '%s'?" % (connection,pattern))
197 (server, schema) = m.groups()
198 (user,passwd) = authDict[connection]
200 connectionParameters[
"techno"] =
'oracle'
201 connectionParameters[
"server"] =
str(server)
202 connectionParameters[
"schema"] =
str(schema)
203 connectionParameters[
"user" ] =
str(user)
204 connectionParameters[
"passwd"] =
str(passwd)
206 elif connection.startswith(
"mysql://"):
207 pattern =
"mysql://(.*);dbname=(.*);user=(.*);passwd=(.*);"
208 m = re.match(pattern,connection)
210 log.fatal(
"connection string '%s' doesn't match the pattern '%s'?" % (connection,pattern) )
211 (server, dbname, user, passwd) = m.groups()
212 connectionParameters[
"techno"] =
'mysql'
213 connectionParameters[
"server"] = server
214 connectionParameters[
"dbname"] = dbname
215 connectionParameters[
"user" ] = user
216 connectionParameters[
"passwd"] = passwd
218 elif connection.startswith(
"frontier://"):
219 pattern =
r"frontier://ATLF/\(\)/(.*)"
220 m = re.match(pattern,connection)
222 log.fatal(
"connection string '%s' doesn't match the pattern '%s'?" % (connection,pattern) )
223 (schema, ) = m.groups()
224 connectionParameters[
"techno"] =
'frontier'
225 connectionParameters[
"schema"] = schema
227 return connectionParameters
236 log.info(
"Specified connection string '%s'", connection)
245 connectionParameters = {}
246 connection =
str(connection)
249 if ':' in connection:
251 return connectionParameters
254 connectionParameters[
"alias"] = connection
256 return connectionParameters
259 if connectionServices
is None:
260 return connectionParameters
263 if os.getenv(
'TRIGGER_USE_FRONTIER',
False):
264 connectionServices =
filter(
lambda conn:
not conn.startswith(
"sqlite_file"), connectionServices)
265 if 'ATLAS_TRIGGERDB_FORCESQLITE' in os.environ:
266 log.fatal(
"Inconsistent setup: environment variable ATLAS_TRIGGERDB_FORCESQLITE is defined and use of Frontier is requested" )
269 sqliteconnections = [conn
for conn
in connectionServices
if conn.startswith(
"sqlite_file")]
270 if len(sqliteconnections)>0:
271 for conn
in sqliteconnections:
273 if connectionParameters[
"filename"]
is not None:
275 if connectionParameters[
"filename"]
is not None:
276 log.info(
"Using sqlite connection %s", connectionParameters)
277 return connectionParameters
279 if 'ATLAS_TRIGGERDB_FORCESQLITE' in os.environ:
280 log.fatal(
"environment ATLAS_TRIGGERDB_FORCESQLITE is defined but non of the sqlite files defined in dblookup.xml exists" )
282 if 'ATLAS_TRIGGERDB_FORCESQLITE' in os.environ:
283 log.fatal(
"environment ATLAS_TRIGGERDB_FORCESQLITE is defined but no sqlite connection defined in dblookup.xml" )
285 from CoolConvUtilities.AtlCoolLib
import replicaList
286 serverlist=[
'ATLAS_CONFIG' if s==
'ATLAS_COOLPROD' else s
for s
in replicaList()]
287 log.info(
"Trying these servers in order %r", serverlist)
288 for server
in serverlist:
289 log.info(
"Trying server %s", server)
292 if not os.getenv(
'TRIGGER_USE_FRONTIER',
False):
294 frontierconnections = [conn
for conn
in connectionServices
if conn.startswith(
"frontier")]
295 if len(frontierconnections) == 0:
296 log.debug(
"FroNTier connection not defined for alias %s in dblookup", connection )
298 log.info(
"Environment FRONTIER_SERVER: %s", os.getenv(
'FRONTIER_SERVER',
'not defined'))
299 frontierServer = os.getenv(
'FRONTIER_SERVER',
None)
300 if not frontierServer:
301 log.debug(
"No environment variable FRONTIER_SERVER" )
304 connectionParameters[
'url'] = frontierServer
305 log.info(
"Using frontier connection %s", frontierconnections[0])
308 elif server==
'atlas_dd':
311 oracleconnections = [conn
for conn
in connectionServices
if conn.startswith(
"oracle://%s/" % server)]
312 if len(oracleconnections) == 0:
313 log.debug(
"Oracle connection not defined for server %s in dblookup", server )
316 log.info(
"Using oracle connection %s", oracleconnections[0])
319 return connectionParameters
326 raise RuntimeError (
"ERROR: Can't import sqlite3?")
328 connection = sqlite3.connect(filename)
329 return connection.cursor()
333 from getpass
import getpass
334 passwd = getpass(
"[Oracle] database password for %s@%s: " % (user, tns))
336 from cx_Oracle
import connect
338 raise RuntimeError (
"ERROR: Can't import cx_Oracle?")
339 connection = connect (user, passwd, tns, threaded=
True)
340 return connection.cursor()
345 from getpass
import getpass
346 passwd = getpass(
"[MySQL] `%s' database password for %s@%s: " % (db, user, host))
348 from MySQLdb
import connect
350 raise RuntimeError (
"ERROR: Can't import MySQLdb")
351 connection =
connect(host=host, user=user, passwd=passwd, db=db, connect_timeout=10)
352 return connection.cursor()
357 global __cursor_schema
358 if dbAlias
in __cursor_schema:
359 return __cursor_schema[dbAlias]
362 technology = connectionParameters[
"techno"]
364 if technology ==
'sqlite':
368 elif technology ==
'oracle':
369 cursor =
_get_oracle_cursor(connectionParameters[
"server"], connectionParameters[
"user"], connectionParameters[
"passwd"])
370 schema = connectionParameters[
"schema"].rstrip(
'.') +
'.'
372 elif technology ==
'frontier':
373 from TrigConfigSvc.TrigConfFrontier
import getFrontierCursor
374 cursor =
getFrontierCursor(connectionParameters[
"url"], connectionParameters[
"schema"], logging.getLogger(
"TrigConfigSvcUtils.py").level)
375 schema = connectionParameters[
"schema"].rstrip(
'.') +
'.'
377 elif technology ==
'mysql':
378 cursor =
_get_mysql_cursor(connectionParameters[
"server"], connectionParameters[
"dbname"], connectionParameters[
"user"], connectionParameters[
"passwd"]),
''
381 __cursor_schema[dbAlias] = (cursor,schema)
383 return __cursor_schema[dbAlias]
388 dbAlias =
triggerDBAlias(run_number = run_number, smk = smk, lhcRun = lhcRun)
393 schemaname = schemaname.rstrip(
'.')+
'.'
396 usedtables.add(o.split(
'.')[0])
399 if '.' in p
and '\'' not in p:
400 usedtables.add(p.split(
'.')[0])
401 return [
"%s%s %s" % (schemaname,tables[t],t)
for t
in usedtables]
404 def executeQuery(cursor, output, condition, schemaname, tables, bindvars=()):
405 query =
'select distinct %s from %s where %s' % (
408 ' and '.
join(condition)
411 cursor.execute(
str(query))
413 cursor.execute(
str(query),bindvars)
415 return cursor.fetchall()
418 def getL1PskNames(psk, dbAlias = None, run_number = None , smk = None , lhcRun = None ):
419 if not isinstance(psk, Iterable):
422 keyslist =
','.
join([
str(k)
for k
in psk
if k])
427 tables = {
'L' :
'L1_PRESCALE_SET' }
428 output = [
'L.L1PS_ID',
'L.L1PS_NAME' ]
429 condition = [
"L.L1PS_ID in (%s)" % keyslist ]
431 if dbAlias
is not None:
434 cursor, schema =
getTriggerDBCursor(run_number = run_number, smk = smk, lhcRun = lhcRun )
436 res =
executeQuery(cursor, output, condition, schema, tables)
442 def getHLTPskNames(psk, dbAlias = None, run_number = None , smk = None , lhcRun = None ):
443 if not isinstance(psk, Iterable):
446 keyslist =
','.
join([
str(k)
for k
in psk
if k])
450 tables = {
'L' :
'HLT_PRESCALE_SET' }
451 output = [
'L.HPS_ID',
'L.HPS_NAME']
452 condition = [
"L.HPS_ID in (%s)" % keyslist ]
454 if dbAlias
is not None:
457 cursor,schema =
getTriggerDBCursor(run_number = run_number, smk = smk, lhcRun = lhcRun )
459 res =
executeQuery( cursor, output, condition, schema, tables)
466 takes a single SMK or a list of SMKs
467 returns a map from SMK to (name,version,comment)
469 if not isinstance(smks, Iterable):
472 keyslist =
','.
join([
str(k)
for k
in smks
if k])
476 tables = {
'S' :
'SUPER_MASTER_TABLE' }
477 output = [
'S.SMT_ID',
'S.SMT_NAME',
'S.SMT_VERSION',
'S.SMT_COMMENT']
478 condition = [
"S.SMT_ID in (%s)" % keyslist ]
481 res =
executeQuery( cursor, output, condition, schema, tables)
483 return dict([ (r[0],(r[1],r[2],r[3]))
for r
in res])
489 if smk
is None or smk==0:
493 output = [
'TC.HTC_NAME',
'TC.HTC_CHAIN_COUNTER',
'TC.HTC_LOWER_CHAIN_NAME' ]
495 output = [
'TC.HTC_NAME',
'TC.HTC_CHAIN_COUNTER',
'TC.HTC_LOWER_CHAIN_NAME',
'TC.HTC_L2_OR_EF' ]
498 'SM' :
'SUPER_MASTER_TABLE',
499 'HM' :
'HLT_MASTER_TABLE',
500 'M2C' :
'HLT_TM_TO_TC',
501 'TC' :
'HLT_TRIGGER_CHAIN'
505 'SM.SMT_HLT_MASTER_TABLE_ID = HM.HMT_ID',
506 'HM.HMT_TRIGGER_MENU_ID = M2C.HTM2TC_TRIGGER_MENU_ID',
507 'M2C.HTM2TC_TRIGGER_CHAIN_ID = TC.HTC_ID'
509 bindvars = {
"smk": smk }
512 res =
executeQuery( cursor, output, condition, schema, tables, bindvars)
518 if len(r)==4
and r[3]==
'L2':
523 return l2chains, efchains
529 if smk
is None or smk==0:
536 'SM' :
'SUPER_MASTER_TABLE',
537 'M' :
'L1_MASTER_TABLE',
538 'M2I' :
'L1_TM_TO_TI',
539 'TI' :
'L1_TRIGGER_ITEM'
543 'SM.SMT_L1_MASTER_TABLE_ID = M.L1MT_ID',
544 'M.L1MT_TRIGGER_MENU_ID = M2I.L1TM2TI_TRIGGER_MENU_ID',
545 'M2I.L1TM2TI_TRIGGER_ITEM_ID = TI.L1TI_ID'
547 bindvars = {
"smk": smk }
550 res =
executeQuery( cursor, output, condition, schema, tables, bindvars)
553 items = maxNumberItems*[
None]
563 maxNumberItems = 512
if isTriggerRun2( run_number = run_number )
else 256
565 tables = {
'L' :
'L1_PRESCALE_SET' }
566 output = [
'L.L1PS_VAL%i' % i
for i
in range( 1, maxNumberItems + 1)]
567 condition = [
"L.L1PS_ID = :psk" ]
568 bindvars = {
"psk": l1prescalekey }
571 res =
executeQuery(cursor, output, condition, schema, tables, bindvars)
573 return res[0][0:maxNumberItems]
585 'H' :
'HLT_PRESCALE_SET',
590 'P.HPR_CHAIN_COUNTER',
592 'P.HPR_PASS_THROUGH_RATE'
595 "P.HPR_PRESCALE_SET_ID = :psk",
596 "P.HPR_L2_OR_EF not like 'express'"
598 bindvars = {
"psk": hltprescalekey }
601 res =
executeQuery(cursor, output, condition, schema, tables, bindvars)
606 elif (r[0]==
'EF' or r[0]==
'HLT' or r[0]==
'HL'):
618 return (
'n.a.',
'n.a.')
621 'S' :
'SUPER_MASTER_TABLE',
622 'M' :
'L1_MASTER_TABLE',
626 output = [
'R.L1R_CUT0',
'R.L1R_CUT1',
'R.L1R_CUT2',
'R.L1R_CUT3' ]
628 output = [
'R.L1R_RATE1',
'R.L1R_RATE2' ]
630 condition = [
"S.SMT_ID=:smk",
"S.SMT_L1_MASTER_TABLE_ID=M.L1MT_ID",
"M.L1MT_RANDOM_ID=R.L1R_ID" ]
632 bindvars = {
"smk": smk }
635 res =
executeQuery(cursor, output, condition, schema, tables, bindvars)
642 if __name__==
"__main__":