33# Import stateless functions from DIRACCommon for backward compatibility
44from DIRACCommon .WorkloadManagementSystem .DB .JobDBUtils import *
55
6+ from DIRAC import S_OK
67from DIRAC .ConfigurationSystem .Client .Helpers .Operations import Operations
78from DIRAC .Core .Utilities .ObjectLoader import ObjectLoader
89from DIRAC .Core .Utilities .ReturnValues import returnValueOrRaise
910from DIRAC .WorkloadManagementSystem .Client .JobState .JobManifest import makeJobManifestConfig
11+ from DIRAC .WorkloadManagementSystem .DB .JobDB import JobDB
12+ from DIRAC .WorkloadManagementSystem .DB .JobParametersDB import JobParametersDB
1013
1114getDIRACPlatform = returnValueOrRaise (
1215 ObjectLoader ().loadObject ("ConfigurationSystem.Client.Helpers.Resources" , "getDIRACPlatform" )
1316)
1417
1518
16- def checkAndPrepareJob (
17- jobID , classAdJob , classAdReq , owner , ownerGroup , jobAttrs , vo
18- ): # pylint: disable=function-redefined
19+ def checkAndPrepareJob (jobID , classAdJob , classAdReq , owner , ownerGroup , jobAttrs , vo ): # pylint: disable=function-redefined
1920 from DIRACCommon .WorkloadManagementSystem .DB .JobDBUtils import checkAndPrepareJob
2021
2122 config = {
@@ -31,3 +32,63 @@ def checkAndAddOwner(jdl: str, owner: str, ownerGroup: str): # pylint: disable=
3132 from DIRACCommon .WorkloadManagementSystem .DB .JobDBUtils import checkAndAddOwner
3233
3334 return checkAndAddOwner (jdl , owner , ownerGroup , job_manifest_config = makeJobManifestConfig (ownerGroup ))
35+
36+
37+ def getJobParameters (jobIDs : list [int ], parName : str | None , vo : str = "" ) -> dict :
38+ """Utility to get a job parameter for a list of jobIDs pertaining to a VO.
39+ If the jobID is not in the JobParametersDB, it will be looked up in the JobDB.
40+
41+ Requires direct access to the JobParametersDB and JobDB.
42+
43+ :param jobIDs: list of jobIDs
44+ :param parName: name of the parameter to be retrieved
45+ :param vo: VO of the jobIDs
46+ :return: dictionary with jobID as key and the parameter as value
47+ :rtype: dict
48+ """
49+
50+ elasticJobParametersDB = JobParametersDB ()
51+ jobDB = JobDB ()
52+
53+ if vo : # a user is connecting, with a proxy
54+ res = elasticJobParametersDB .getJobParameters (jobIDs , vo , parName )
55+ if not res ["OK" ]:
56+ return res
57+ parameters = res ["Value" ]
58+ else : # a service is connecting, no proxy, e.g. StalledJobAgent
59+ q = f"SELECT JobID, VO FROM Jobs WHERE JobID IN ({ ',' .join ([str (jobID ) for jobID in jobIDs ])} )"
60+ res = jobDB ._query (q )
61+ if not res ["OK" ]:
62+ return res
63+ if not res ["Value" ]:
64+ return S_OK ({})
65+ # get the VO for each jobID
66+ voDict = {}
67+ for jobID , vo in res ["Value" ]:
68+ if vo not in voDict :
69+ voDict [vo ] = []
70+ voDict [vo ].append (jobID )
71+ # get the parameters for each VO
72+ parameters = {}
73+ for vo , jobIDs in voDict .items ():
74+ res = elasticJobParametersDB .getJobParameters (jobIDs , vo , parName )
75+ if not res ["OK" ]:
76+ return res
77+ parameters .update (res ["Value" ])
78+
79+ # Need anyway to get also from JobDB, for those jobs with parameters registered in MySQL or in both backends
80+ res = jobDB .getJobParameters (jobIDs , parName )
81+ if not res ["OK" ]:
82+ return res
83+ parametersM = res ["Value" ]
84+
85+ # and now combine
86+ final = dict (parametersM )
87+ # if job in JobDB, update with parameters from ES if any
88+ for jobID in final :
89+ final [jobID ].update (parameters .get (jobID , {}))
90+ # if job in ES and not in JobDB, take ES
91+ for jobID in parameters :
92+ if jobID not in final :
93+ final [jobID ] = parameters [jobID ]
94+ return S_OK (final )
0 commit comments