|
25 | 25 | import re
|
26 | 26 | from collections import defaultdict
|
27 | 27 |
|
| 28 | +import requests |
| 29 | +from cachetools import TTLCache, cached |
| 30 | + |
28 | 31 | # # from DIRAC
|
29 |
| -from DIRAC import S_OK, S_ERROR, gLogger |
30 |
| -from DIRAC.Core.Utilities.Adler import compareAdler, hexAdlerToInt, intAdlerToHex |
| 32 | +from DIRAC import S_ERROR, S_OK, gLogger |
31 | 33 | from DIRAC.Core.Security.ProxyInfo import getVOfromProxyGroup
|
32 |
| - |
33 |
| -from DIRAC.DataManagementSystem.Client.DataManager import DataManager |
| 34 | +from DIRAC.Core.Utilities.Adler import compareAdler, hexAdlerToInt, intAdlerToHex |
34 | 35 | from DIRAC.DataManagementSystem.Agent.RequestOperations.DMSRequestOperationsBase import DMSRequestOperationsBase
|
35 |
| - |
36 |
| -from DIRAC.Resources.Storage.StorageElement import StorageElement |
37 |
| -from DIRAC.Resources.Catalog.FileCatalog import FileCatalog |
38 |
| - |
39 |
| -from DIRAC.DataManagementSystem.Client.FTS3Operation import FTS3TransferOperation |
40 |
| -from DIRAC.DataManagementSystem.Client.FTS3File import FTS3File |
| 36 | +from DIRAC.DataManagementSystem.Client.DataManager import DataManager |
41 | 37 | from DIRAC.DataManagementSystem.Client.FTS3Client import FTS3Client
|
| 38 | +from DIRAC.DataManagementSystem.Client.FTS3File import FTS3File |
| 39 | +from DIRAC.DataManagementSystem.Client.FTS3Operation import FTS3TransferOperation |
42 | 40 | from DIRAC.DataManagementSystem.private.FTS3Utilities import getFTS3Plugin
|
43 |
| - |
44 |
| -from DIRAC.ConfigurationSystem.Client.Helpers import Registry |
45 |
| - |
46 | 41 | from DIRAC.MonitoringSystem.Client.MonitoringReporter import MonitoringReporter
|
| 42 | +from DIRAC.Resources.Catalog.FileCatalog import FileCatalog |
| 43 | +from DIRAC.Resources.Storage.StorageElement import StorageElement |
47 | 44 |
|
48 | 45 |
|
49 | 46 | def filterReplicas(opFile, logger=None, dataManager=None, opSources=None, activeReplicas=None):
|
@@ -154,6 +151,44 @@ def filterReplicas(opFile, logger=None, dataManager=None, opSources=None, active
|
154 | 151 | return S_OK(result)
|
155 | 152 |
|
156 | 153 |
|
| 154 | +def get_scitag(vo: str, activity: str = None): |
| 155 | + """ |
| 156 | + Get the scitag based on the VO and activity. |
| 157 | + If the VO is not found in the scitag.json, it defaults to 1. |
| 158 | + If no specific activity is provided, it defaults to the "default" activityName. |
| 159 | +
|
| 160 | + :param vo: The VO for which to get the scitag |
| 161 | + :param activity: The activity for which to get the scitag |
| 162 | + :return: The scitag value |
| 163 | + """ |
| 164 | + |
| 165 | + # Create a TTL cache: max 1 item, expires after 84400 seconds (1 day) |
| 166 | + json_cache = TTLCache(maxsize=1, ttl=86400) |
| 167 | + |
| 168 | + @cached(json_cache) |
| 169 | + def get_remote_json(): |
| 170 | + gLogger.verbose("Fetching https://scitags.org/api.json from the network") |
| 171 | + response = requests.get("https://scitags.org/api.json") |
| 172 | + response.raise_for_status() |
| 173 | + return response.json() |
| 174 | + |
| 175 | + # Load the JSON data from the cache or network |
| 176 | + sj = get_remote_json() |
| 177 | + |
| 178 | + vo_id = 1 # Default VO ID |
| 179 | + activity_id = 1 # Default activity ID |
| 180 | + |
| 181 | + for experiment in sj.get("experiments", []): |
| 182 | + if experiment.get("expName") == vo.lower(): |
| 183 | + vo_id = experiment.get("expId") |
| 184 | + for act in experiment.get("activities", []): |
| 185 | + if act.get("activityName") == activity: |
| 186 | + activity_id = act.get("activityId") |
| 187 | + |
| 188 | + # Logic to determine the scitag based on vo and activity (this is what FTS wants) |
| 189 | + return vo_id << 6 | activity_id # Example logic, replace with actual implementation |
| 190 | + |
| 191 | + |
157 | 192 | ########################################################################
|
158 | 193 | class ReplicateAndRegister(DMSRequestOperationsBase):
|
159 | 194 | """
|
@@ -472,14 +507,23 @@ def fts3Transfer(self):
|
472 | 507 | fts3Operation = FTS3TransferOperation.fromRMSObjects(self.request, self.operation)
|
473 | 508 | fts3Operation.ftsFiles = fts3Files
|
474 | 509 |
|
| 510 | + vo = getVOfromProxyGroup().get("Value") |
475 | 511 | try:
|
476 | 512 | if not fts3Operation.activity:
|
477 |
| - vo = getVOfromProxyGroup().get("Value") |
478 | 513 | fts3Plugin = getFTS3Plugin(vo=vo)
|
479 | 514 | fts3Operation.activity = fts3Plugin.inferFTSActivity(fts3Operation, self.request, self.operation)
|
480 | 515 | except Exception:
|
481 | 516 | pass
|
482 | 517 |
|
| 518 | + try: |
| 519 | + if not fts3Operation.scitag: |
| 520 | + fts3Operation.scitag = get_scitag( |
| 521 | + vo=vo, |
| 522 | + activity=fts3Operation.activity if fts3Operation.activity else None, |
| 523 | + ) |
| 524 | + except Exception: |
| 525 | + pass |
| 526 | + |
483 | 527 | ftsSchedule = FTS3Client().persistOperation(fts3Operation)
|
484 | 528 | if not ftsSchedule["OK"]:
|
485 | 529 | self.log.error("Completely failed to schedule to FTS3:", ftsSchedule["Message"])
|
|
0 commit comments