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 if dbAlias
in __cursor_schema:
358 return __cursor_schema[dbAlias]
361 technology = connectionParameters[
"techno"]
363 if technology ==
'sqlite':
367 elif technology ==
'oracle':
368 cursor =
_get_oracle_cursor(connectionParameters[
"server"], connectionParameters[
"user"], connectionParameters[
"passwd"])
369 schema = connectionParameters[
"schema"].rstrip(
'.') +
'.'
371 elif technology ==
'frontier':
372 from TrigConfigSvc.TrigConfFrontier
import getFrontierCursor
373 cursor =
getFrontierCursor(connectionParameters[
"url"], connectionParameters[
"schema"], logging.getLogger(
"TrigConfigSvcUtils.py").level)
374 schema = connectionParameters[
"schema"].rstrip(
'.') +
'.'
376 elif technology ==
'mysql':
377 cursor =
_get_mysql_cursor(connectionParameters[
"server"], connectionParameters[
"dbname"], connectionParameters[
"user"], connectionParameters[
"passwd"]),
''
380 __cursor_schema[dbAlias] = (cursor,schema)
382 return __cursor_schema[dbAlias]
387 dbAlias =
triggerDBAlias(run_number = run_number, smk = smk, lhcRun = lhcRun)
392 schemaname = schemaname.rstrip(
'.')+
'.'
395 usedtables.add(o.split(
'.')[0])
398 if '.' in p
and '\'' not in p:
399 usedtables.add(p.split(
'.')[0])
400 return [
"%s%s %s" % (schemaname,tables[t],t)
for t
in usedtables]
403 def executeQuery(cursor, output, condition, schemaname, tables, bindvars=()):
404 query =
'select distinct %s from %s where %s' % (
407 ' and '.
join(condition)
410 cursor.execute(
str(query))
412 cursor.execute(
str(query),bindvars)
414 return cursor.fetchall()
417 def getL1PskNames(psk, dbAlias = None, run_number = None , smk = None , lhcRun = None ):
418 if not isinstance(psk, Iterable):
421 keyslist =
','.
join([
str(k)
for k
in psk
if k])
426 tables = {
'L' :
'L1_PRESCALE_SET' }
427 output = [
'L.L1PS_ID',
'L.L1PS_NAME' ]
428 condition = [
"L.L1PS_ID in (%s)" % keyslist ]
430 if dbAlias
is not None:
433 cursor, schema =
getTriggerDBCursor(run_number = run_number, smk = smk, lhcRun = lhcRun )
435 res =
executeQuery(cursor, output, condition, schema, tables)
441 def getHLTPskNames(psk, dbAlias = None, run_number = None , smk = None , lhcRun = None ):
442 if not isinstance(psk, Iterable):
445 keyslist =
','.
join([
str(k)
for k
in psk
if k])
449 tables = {
'L' :
'HLT_PRESCALE_SET' }
450 output = [
'L.HPS_ID',
'L.HPS_NAME']
451 condition = [
"L.HPS_ID in (%s)" % keyslist ]
453 if dbAlias
is not None:
456 cursor,schema =
getTriggerDBCursor(run_number = run_number, smk = smk, lhcRun = lhcRun )
458 res =
executeQuery( cursor, output, condition, schema, tables)
465 takes a single SMK or a list of SMKs
466 returns a map from SMK to (name,version,comment)
468 if not isinstance(smks, Iterable):
471 keyslist =
','.
join([
str(k)
for k
in smks
if k])
475 tables = {
'S' :
'SUPER_MASTER_TABLE' }
476 output = [
'S.SMT_ID',
'S.SMT_NAME',
'S.SMT_VERSION',
'S.SMT_COMMENT']
477 condition = [
"S.SMT_ID in (%s)" % keyslist ]
480 res =
executeQuery( cursor, output, condition, schema, tables)
482 return dict([ (r[0],(r[1],r[2],r[3]))
for r
in res])
488 if smk
is None or smk==0:
492 output = [
'TC.HTC_NAME',
'TC.HTC_CHAIN_COUNTER',
'TC.HTC_LOWER_CHAIN_NAME' ]
494 output = [
'TC.HTC_NAME',
'TC.HTC_CHAIN_COUNTER',
'TC.HTC_LOWER_CHAIN_NAME',
'TC.HTC_L2_OR_EF' ]
497 'SM' :
'SUPER_MASTER_TABLE',
498 'HM' :
'HLT_MASTER_TABLE',
499 'M2C' :
'HLT_TM_TO_TC',
500 'TC' :
'HLT_TRIGGER_CHAIN'
504 'SM.SMT_HLT_MASTER_TABLE_ID = HM.HMT_ID',
505 'HM.HMT_TRIGGER_MENU_ID = M2C.HTM2TC_TRIGGER_MENU_ID',
506 'M2C.HTM2TC_TRIGGER_CHAIN_ID = TC.HTC_ID'
508 bindvars = {
"smk": smk }
511 res =
executeQuery( cursor, output, condition, schema, tables, bindvars)
517 if len(r)==4
and r[3]==
'L2':
522 return l2chains, efchains
528 if smk
is None or smk==0:
535 'SM' :
'SUPER_MASTER_TABLE',
536 'M' :
'L1_MASTER_TABLE',
537 'M2I' :
'L1_TM_TO_TI',
538 'TI' :
'L1_TRIGGER_ITEM'
542 'SM.SMT_L1_MASTER_TABLE_ID = M.L1MT_ID',
543 'M.L1MT_TRIGGER_MENU_ID = M2I.L1TM2TI_TRIGGER_MENU_ID',
544 'M2I.L1TM2TI_TRIGGER_ITEM_ID = TI.L1TI_ID'
546 bindvars = {
"smk": smk }
549 res =
executeQuery( cursor, output, condition, schema, tables, bindvars)
552 items = maxNumberItems*[
None]
562 maxNumberItems = 512
if isTriggerRun2( run_number = run_number )
else 256
564 tables = {
'L' :
'L1_PRESCALE_SET' }
565 output = [
'L.L1PS_VAL%i' % i
for i
in range( 1, maxNumberItems + 1)]
566 condition = [
"L.L1PS_ID = :psk" ]
567 bindvars = {
"psk": l1prescalekey }
570 res =
executeQuery(cursor, output, condition, schema, tables, bindvars)
572 return res[0][0:maxNumberItems]
584 'H' :
'HLT_PRESCALE_SET',
589 'P.HPR_CHAIN_COUNTER',
591 'P.HPR_PASS_THROUGH_RATE'
594 "P.HPR_PRESCALE_SET_ID = :psk",
595 "P.HPR_L2_OR_EF not like 'express'"
597 bindvars = {
"psk": hltprescalekey }
600 res =
executeQuery(cursor, output, condition, schema, tables, bindvars)
605 elif (r[0]==
'EF' or r[0]==
'HLT' or r[0]==
'HL'):
617 return (
'n.a.',
'n.a.')
620 'S' :
'SUPER_MASTER_TABLE',
621 'M' :
'L1_MASTER_TABLE',
625 output = [
'R.L1R_CUT0',
'R.L1R_CUT1',
'R.L1R_CUT2',
'R.L1R_CUT3' ]
627 output = [
'R.L1R_RATE1',
'R.L1R_RATE2' ]
629 condition = [
"S.SMT_ID=:smk",
"S.SMT_L1_MASTER_TABLE_ID=M.L1MT_ID",
"M.L1MT_RANDOM_ID=R.L1R_ID" ]
631 bindvars = {
"smk": smk }
634 res =
executeQuery(cursor, output, condition, schema, tables, bindvars)
641 if __name__==
"__main__":