14 from __future__
import print_function
15 from collections.abc
import Iterable
22 if run_number
is None and smk
is None and isRun2
is None:
23 raise RuntimeError(
"Cannot determine if trigger db is run 1 or 2")
26 return smk >= 2000
and smk<3000
27 elif run_number
is not None :
28 return run_number > 249000
34 if run_number
is None and smk
is None and lhcRun
is None:
35 raise RuntimeError(
"Cannot determine the triggerDBAlias as no info is given")
38 if lhcRun==1
or lhcRun==2:
39 return f
"TRIGGERDB_RUN{lhcRun}"
41 return "TRIGGERDBDEV1_I8" if (smk
is not None and smk<3000)
else "TRIGGERDB_RUN3"
46 return "TRIGGERDB_RUN1"
49 return "TRIGGERDB_RUN2"
51 return "TRIGGERDB_RUN3"
55 if run_number > 405800:
56 return "TRIGGERDB_RUN3"
57 if run_number > 378000:
58 return "TRIGGERDBDEV1_I8"
59 elif run_number > 249000:
60 return "TRIGGERDB_RUN2"
62 return "TRIGGERDB_RUN1"
66 from xml.dom
import minidom
67 import os, re, logging
68 log = logging.getLogger( __name__ )
71 def __init__(self, name, counter, lowername="", lowercounter=-1, forshow=False, forselect=False, level=0):
74 self.
lowername =
"" if lowername==
"~" else lowername
83 return "TC:"+self.
name
87 """Find <filename> with rights <access> through <pathlist>."""
90 if os.path.dirname( filename ):
91 if os.access( filename, access ):
96 f = os.path.join( path, filename )
97 if os.access( f, access ):
106 """looks for filename in local directory and then in all paths specified in environment variable 'pathenv'
107 returns path/filename if existing, otherwise None
109 log = logging.getLogger(
"TrigConfigSvcUtils.py" )
110 if os.path.exists(filename):
111 log.info(
"Using local file %s", filename)
114 pathlist = os.getenv(pathenv,
'').
split(os.pathsep)
115 resolvedfilename =
FindFile(filename, pathlist, os.R_OK)
117 return resolvedfilename
119 log.fatal(
"No file %s found locally nor in %s" % (filename, os.getenv(
'CORAL_DBLOOKUP_PATH')) )
124 log = logging.getLogger(
"TrigConfigSvcUtils.py" )
126 connectionServices =
None
129 if dblookupfilename
is None:
132 doc = minidom.parse(dblookupfilename)
133 for ls
in doc.getElementsByTagName(
'logicalservice'):
134 if ls.attributes[
'name'].value != alias:
136 connectionServices = [
str(s.attributes[
'name'].value)
for s
in ls.getElementsByTagName(
'service')]
139 log.info(
"For alias '%s' found list of connections %r", (alias,connectionServices) )
140 if connectionServices
is None:
141 print(
"ERROR: Trigger connection alias '%s' is not defined in %s" % (alias,dblookupfilename))
142 return connectionServices
146 """ read authentication.xml, first from local directory, then from all paths specified in CORAL_AUTH_PATH
147 returns dictionary d with d[connection] -> (user,pw)
152 if dbauthfilename
is None:
155 doc = minidom.parse(dbauthfilename)
156 for cn
in doc.getElementsByTagName(
'connection'):
159 svc = cn.attributes[
'name'].value
160 for p
in cn.getElementsByTagName(
'parameter'):
161 if p.attributes[
'name'].value ==
'user':
162 user = p.attributes[
'value'].value
163 elif p.attributes[
'name'].value ==
'password':
164 pw = p.attributes[
'value'].value
165 authDict[svc] = (user,pw)
172 log = logging.getLogger(
"TrigConfigSvcUtils.py" )
173 connection =
str(connection)
174 connectionParameters = {}
176 if connection.startswith(
"sqlite_file:"):
177 filename = connection[connection.find(
':')+1:]
178 connectionParameters[
"techno"] =
"sqlite"
179 connectionParameters[
"filename"] = filename
if os.path.exists(filename)
else None
181 elif connection.startswith(
"oracle://"):
182 if connection.count(
';') == 2:
183 pattern =
"(.*)://(.*)/(.*);username=(.*);password=(.*)"
184 m = re.match(pattern,connection)
187 log.fatal(
"connection string '%s' doesn't match the pattern '%s'?" % (connection,pattern))
188 (techno, server, schema, user, passwd) = m.groups()
194 pattern =
"oracle://(.*)/(.*)"
195 m = re.match(pattern,connection)
197 log.fatal(
"connection string '%s' doesn't match the pattern '%s'?" % (connection,pattern))
198 (server, schema) = m.groups()
199 (user,passwd) = authDict[connection]
201 connectionParameters[
"techno"] =
'oracle'
202 connectionParameters[
"server"] =
str(server)
203 connectionParameters[
"schema"] =
str(schema)
204 connectionParameters[
"user" ] =
str(user)
205 connectionParameters[
"passwd"] =
str(passwd)
207 elif connection.startswith(
"mysql://"):
208 pattern =
"mysql://(.*);dbname=(.*);user=(.*);passwd=(.*);"
209 m = re.match(pattern,connection)
211 log.fatal(
"connection string '%s' doesn't match the pattern '%s'?" % (connection,pattern) )
212 (server, dbname, user, passwd) = m.groups()
213 connectionParameters[
"techno"] =
'mysql'
214 connectionParameters[
"server"] = server
215 connectionParameters[
"dbname"] = dbname
216 connectionParameters[
"user" ] = user
217 connectionParameters[
"passwd"] = passwd
219 elif connection.startswith(
"frontier://"):
220 pattern =
r"frontier://ATLF/\(\)/(.*)"
221 m = re.match(pattern,connection)
223 log.fatal(
"connection string '%s' doesn't match the pattern '%s'?" % (connection,pattern) )
224 (schema, ) = m.groups()
225 connectionParameters[
"techno"] =
'frontier'
226 connectionParameters[
"schema"] = schema
228 return connectionParameters
237 log.info(
"Specified connection string '%s'", connection)
246 connectionParameters = {}
247 connection =
str(connection)
250 if ':' in connection:
252 return connectionParameters
255 connectionParameters[
"alias"] = connection
257 return connectionParameters
260 if connectionServices
is None:
261 return connectionParameters
264 if os.getenv(
'TRIGGER_USE_FRONTIER',
False):
265 connectionServices =
filter(
lambda conn:
not conn.startswith(
"sqlite_file"), connectionServices)
266 if 'ATLAS_TRIGGERDB_FORCESQLITE' in os.environ:
267 log.fatal(
"Inconsistent setup: environment variable ATLAS_TRIGGERDB_FORCESQLITE is defined and use of Frontier is requested" )
270 sqliteconnections = [conn
for conn
in connectionServices
if conn.startswith(
"sqlite_file")]
271 if len(sqliteconnections)>0:
272 for conn
in sqliteconnections:
274 if connectionParameters[
"filename"]
is not None:
276 if connectionParameters[
"filename"]
is not None:
277 log.info(
"Using sqlite connection %s", connectionParameters)
278 return connectionParameters
280 if 'ATLAS_TRIGGERDB_FORCESQLITE' in os.environ:
281 log.fatal(
"environment ATLAS_TRIGGERDB_FORCESQLITE is defined but non of the sqlite files defined in dblookup.xml exists" )
283 if 'ATLAS_TRIGGERDB_FORCESQLITE' in os.environ:
284 log.fatal(
"environment ATLAS_TRIGGERDB_FORCESQLITE is defined but no sqlite connection defined in dblookup.xml" )
286 from CoolConvUtilities.AtlCoolLib
import replicaList
287 serverlist=[
'ATLAS_CONFIG' if s==
'ATLAS_COOLPROD' else s
for s
in replicaList()]
288 log.info(
"Trying these servers in order %r", serverlist)
289 for server
in serverlist:
290 log.info(
"Trying server %s", server)
293 if not os.getenv(
'TRIGGER_USE_FRONTIER',
False):
295 frontierconnections = [conn
for conn
in connectionServices
if conn.startswith(
"frontier")]
296 if len(frontierconnections) == 0:
297 log.debug(
"FroNTier connection not defined for alias %s in dblookup", connection )
299 log.info(
"Environment FRONTIER_SERVER: %s", os.getenv(
'FRONTIER_SERVER',
'not defined'))
300 frontierServer = os.getenv(
'FRONTIER_SERVER',
None)
301 if not frontierServer:
302 log.debug(
"No environment variable FRONTIER_SERVER" )
305 connectionParameters[
'url'] = frontierServer
306 log.info(
"Using frontier connection %s", frontierconnections[0])
309 elif server==
'atlas_dd':
312 oracleconnections = [conn
for conn
in connectionServices
if conn.startswith(
"oracle://%s/" % server)]
313 if len(oracleconnections) == 0:
314 log.debug(
"Oracle connection not defined for server %s in dblookup", server )
317 log.info(
"Using oracle connection %s", oracleconnections[0])
320 return connectionParameters
327 raise RuntimeError (
"ERROR: Can't import sqlite3?")
329 connection = sqlite3.connect(filename)
330 return connection.cursor()
334 from getpass
import getpass
335 passwd = getpass(
"[Oracle] database password for %s@%s: " % (user, tns))
337 from cx_Oracle
import connect
339 raise RuntimeError (
"ERROR: Can't import cx_Oracle?")
340 connection = connect (user, passwd, tns, threaded=
True)
341 return connection.cursor()
346 from getpass
import getpass
347 passwd = getpass(
"[MySQL] `%s' database password for %s@%s: " % (db, user, host))
349 from MySQLdb
import connect
351 raise RuntimeError (
"ERROR: Can't import MySQLdb")
352 connection =
connect(host=host, user=user, passwd=passwd, db=db, connect_timeout=10)
353 return connection.cursor()
358 global __cursor_schema
359 if dbAlias
in __cursor_schema:
360 return __cursor_schema[dbAlias]
363 technology = connectionParameters[
"techno"]
365 if technology ==
'sqlite':
369 elif technology ==
'oracle':
370 cursor =
_get_oracle_cursor(connectionParameters[
"server"], connectionParameters[
"user"], connectionParameters[
"passwd"])
371 schema = connectionParameters[
"schema"].rstrip(
'.') +
'.'
373 elif technology ==
'frontier':
374 from TrigConfigSvc.TrigConfFrontier
import getFrontierCursor
375 cursor =
getFrontierCursor(connectionParameters[
"url"], connectionParameters[
"schema"], logging.getLogger(
"TrigConfigSvcUtils.py").level)
376 schema = connectionParameters[
"schema"].rstrip(
'.') +
'.'
378 elif technology ==
'mysql':
379 cursor =
_get_mysql_cursor(connectionParameters[
"server"], connectionParameters[
"dbname"], connectionParameters[
"user"], connectionParameters[
"passwd"]),
''
382 __cursor_schema[dbAlias] = (cursor,schema)
384 return __cursor_schema[dbAlias]
389 dbAlias =
triggerDBAlias(run_number = run_number, smk = smk, lhcRun = lhcRun)
394 schemaname = schemaname.rstrip(
'.')+
'.'
397 usedtables.add(o.split(
'.')[0])
400 if '.' in p
and '\'' not in p:
401 usedtables.add(p.split(
'.')[0])
402 return [
"%s%s %s" % (schemaname,tables[t],t)
for t
in usedtables]
405 def executeQuery(cursor, output, condition, schemaname, tables, bindvars=()):
406 query =
'select distinct %s from %s where %s' % (
409 ' and '.
join(condition)
412 cursor.execute(
str(query))
414 cursor.execute(
str(query),bindvars)
416 return cursor.fetchall()
419 def getL1PskNames(psk, dbAlias = None, run_number = None , smk = None , lhcRun = None ):
420 if not isinstance(psk, Iterable):
423 keyslist =
','.
join([
str(k)
for k
in psk
if k])
428 tables = {
'L' :
'L1_PRESCALE_SET' }
429 output = [
'L.L1PS_ID',
'L.L1PS_NAME' ]
430 condition = [
"L.L1PS_ID in (%s)" % keyslist ]
432 if dbAlias
is not None:
435 cursor, schema =
getTriggerDBCursor(run_number = run_number, smk = smk, lhcRun = lhcRun )
437 res =
executeQuery(cursor, output, condition, schema, tables)
443 def getHLTPskNames(psk, dbAlias = None, run_number = None , smk = None , lhcRun = None ):
444 if not isinstance(psk, Iterable):
447 keyslist =
','.
join([
str(k)
for k
in psk
if k])
451 tables = {
'L' :
'HLT_PRESCALE_SET' }
452 output = [
'L.HPS_ID',
'L.HPS_NAME']
453 condition = [
"L.HPS_ID in (%s)" % keyslist ]
455 if dbAlias
is not None:
458 cursor,schema =
getTriggerDBCursor(run_number = run_number, smk = smk, lhcRun = lhcRun )
460 res =
executeQuery( cursor, output, condition, schema, tables)
467 takes a single SMK or a list of SMKs
468 returns a map from SMK to (name,version,comment)
470 if not isinstance(smks, Iterable):
473 keyslist =
','.
join([
str(k)
for k
in smks
if k])
477 tables = {
'S' :
'SUPER_MASTER_TABLE' }
478 output = [
'S.SMT_ID',
'S.SMT_NAME',
'S.SMT_VERSION',
'S.SMT_COMMENT']
479 condition = [
"S.SMT_ID in (%s)" % keyslist ]
482 res =
executeQuery( cursor, output, condition, schema, tables)
484 return dict([ (r[0],(r[1],r[2],r[3]))
for r
in res])
490 if smk
is None or smk==0:
494 output = [
'TC.HTC_NAME',
'TC.HTC_CHAIN_COUNTER',
'TC.HTC_LOWER_CHAIN_NAME' ]
496 output = [
'TC.HTC_NAME',
'TC.HTC_CHAIN_COUNTER',
'TC.HTC_LOWER_CHAIN_NAME',
'TC.HTC_L2_OR_EF' ]
499 'SM' :
'SUPER_MASTER_TABLE',
500 'HM' :
'HLT_MASTER_TABLE',
501 'M2C' :
'HLT_TM_TO_TC',
502 'TC' :
'HLT_TRIGGER_CHAIN'
506 'SM.SMT_HLT_MASTER_TABLE_ID = HM.HMT_ID',
507 'HM.HMT_TRIGGER_MENU_ID = M2C.HTM2TC_TRIGGER_MENU_ID',
508 'M2C.HTM2TC_TRIGGER_CHAIN_ID = TC.HTC_ID'
510 bindvars = {
"smk": smk }
513 res =
executeQuery( cursor, output, condition, schema, tables, bindvars)
519 if len(r)==4
and r[3]==
'L2':
524 return l2chains, efchains
530 if smk
is None or smk==0:
537 'SM' :
'SUPER_MASTER_TABLE',
538 'M' :
'L1_MASTER_TABLE',
539 'M2I' :
'L1_TM_TO_TI',
540 'TI' :
'L1_TRIGGER_ITEM'
544 'SM.SMT_L1_MASTER_TABLE_ID = M.L1MT_ID',
545 'M.L1MT_TRIGGER_MENU_ID = M2I.L1TM2TI_TRIGGER_MENU_ID',
546 'M2I.L1TM2TI_TRIGGER_ITEM_ID = TI.L1TI_ID'
548 bindvars = {
"smk": smk }
551 res =
executeQuery( cursor, output, condition, schema, tables, bindvars)
554 items = maxNumberItems*[
None]
564 maxNumberItems = 512
if isTriggerRun2( run_number = run_number )
else 256
566 tables = {
'L' :
'L1_PRESCALE_SET' }
567 output = [
'L.L1PS_VAL%i' % i
for i
in range( 1, maxNumberItems + 1)]
568 condition = [
"L.L1PS_ID = :psk" ]
569 bindvars = {
"psk": l1prescalekey }
572 res =
executeQuery(cursor, output, condition, schema, tables, bindvars)
574 return res[0][0:maxNumberItems]
586 'H' :
'HLT_PRESCALE_SET',
591 'P.HPR_CHAIN_COUNTER',
593 'P.HPR_PASS_THROUGH_RATE'
596 "P.HPR_PRESCALE_SET_ID = :psk",
597 "P.HPR_L2_OR_EF not like 'express'"
599 bindvars = {
"psk": hltprescalekey }
602 res =
executeQuery(cursor, output, condition, schema, tables, bindvars)
607 elif (r[0]==
'EF' or r[0]==
'HLT' or r[0]==
'HL'):
619 return (
'n.a.',
'n.a.')
622 'S' :
'SUPER_MASTER_TABLE',
623 'M' :
'L1_MASTER_TABLE',
627 output = [
'R.L1R_CUT0',
'R.L1R_CUT1',
'R.L1R_CUT2',
'R.L1R_CUT3' ]
629 output = [
'R.L1R_RATE1',
'R.L1R_RATE2' ]
631 condition = [
"S.SMT_ID=:smk",
"S.SMT_L1_MASTER_TABLE_ID=M.L1MT_ID",
"M.L1MT_RANDOM_ID=R.L1R_ID" ]
633 bindvars = {
"smk": smk }
636 res =
executeQuery(cursor, output, condition, schema, tables, bindvars)
643 if __name__==
"__main__":