2
2
3
3
import datetime
4
4
import errno
5
- from packaging .version import Version
6
5
6
+ import fts3 .rest .client .easy as fts3
7
+ import requests
8
+ from cachetools import TTLCache , cached
7
9
8
10
# Requires at least version 3.3.3
9
11
from fts3 import __version__ as fts3_version
10
- import fts3 .rest .client .easy as fts3
11
12
from fts3 .rest .client .exceptions import FTS3ClientException , NotFound
13
+ from packaging .version import Version
12
14
13
15
# There is a breaking change in the API in 3.13
14
16
# https://gitlab.cern.ch/fts/fts-rest-flask/-/commit/5faa283e0cd4b80a0139a547c4a6356522c8449d
22
24
# default pycurl. See https://its.cern.ch/jira/browse/FTS-261
23
25
from fts3 .rest .client .request import Request as ftsSSLRequest
24
26
25
- from DIRAC .Resources .Storage .StorageElement import StorageElement
26
-
27
- from DIRAC .FrameworkSystem .Client .Logger import gLogger
28
- from DIRAC .FrameworkSystem .Client .TokenManagerClient import gTokenManager
29
-
30
- from DIRAC .Core .Utilities .ReturnValues import S_OK , S_ERROR
31
27
from DIRAC .Core .Utilities .DErrno import cmpError
32
-
33
28
from DIRAC .Core .Utilities .JEncode import JSerializable
29
+ from DIRAC .Core .Utilities .ReturnValues import S_ERROR , S_OK
34
30
from DIRAC .DataManagementSystem .Client .FTS3File import FTS3File
31
+ from DIRAC .FrameworkSystem .Client .Logger import gLogger
32
+ from DIRAC .FrameworkSystem .Client .TokenManagerClient import gTokenManager
33
+ from DIRAC .Resources .Storage .StorageElement import StorageElement
35
34
36
35
# 3 days in seconds
37
36
BRING_ONLINE_TIMEOUT = 259200
38
37
39
38
39
+ def get_scitag (vo : str , activity : str = None ):
40
+ """
41
+ Get the scitag based on the VO and activity.
42
+ If the VO is not found in the scitag.json, it defaults to 1.
43
+ If no specific activity is provided, it defaults to the "default" activityName.
44
+
45
+ :param vo: The VO for which to get the scitag
46
+ :param activity: The activity for which to get the scitag
47
+ :return: The scitag value
48
+ """
49
+
50
+ # Create a TTL cache: max 1 item, expires after 84400 seconds (1 day)
51
+ json_cache = TTLCache (maxsize = 1 , ttl = 86400 )
52
+
53
+ @cached (json_cache )
54
+ def get_remote_json ():
55
+ gLogger .verbose ("Fetching https://scitags.org/api.json from the network" )
56
+ response = requests .get ("https://scitags.org/api.json" )
57
+ response .raise_for_status ()
58
+ return response .json ()
59
+
60
+ # Load the JSON data from the cache or network
61
+ sj = get_remote_json ()
62
+
63
+ vo_id = 1 # Default VO ID
64
+ activity_id = 1 # Default activity ID
65
+
66
+ for experiment in sj .get ("experiments" , []):
67
+ if experiment .get ("expName" ) == vo .lower ():
68
+ vo_id = experiment .get ("expId" )
69
+ for act in experiment .get ("activities" , []):
70
+ if act .get ("activityName" ) == activity :
71
+ activity_id = act .get ("activityId" )
72
+
73
+ # Logic to determine the scitag based on vo and activity (this is what FTS wants)
74
+ return vo_id << 6 | activity_id # Example logic, replace with actual implementation
75
+
76
+
40
77
class FTS3Job (JSerializable ):
41
78
"""Abstract class to represent a job to be executed by FTS. It belongs
42
79
to an FTS3Operation
@@ -467,6 +504,9 @@ def _constructTransferJob(self, pinTime, allLFNs, target_spacetoken, protocols=N
467
504
# * stageProto://myFile -> stageProto://myFile
468
505
# * srcProto://myFile -> destProto://myFile
469
506
507
+ # scitag 65 is 1 << 6 | 1 (default experiment, default activity)
508
+ scitag = get_scitag (vo = self .vo , activity = self .activity )
509
+
470
510
if stageURL :
471
511
# We do not set a fileID in the metadata
472
512
# such that we do not update the DB when monitoring
@@ -485,6 +525,7 @@ def _constructTransferJob(self, pinTime, allLFNs, target_spacetoken, protocols=N
485
525
filesize = ftsFile .size ,
486
526
metadata = stageTrans_metadata ,
487
527
activity = self .activity ,
528
+ scitag = scitag ,
488
529
)
489
530
transfers .append (stageTrans )
490
531
@@ -553,6 +594,7 @@ def _constructTransferJob(self, pinTime, allLFNs, target_spacetoken, protocols=N
553
594
activity = self .activity ,
554
595
source_token = srcToken ,
555
596
destination_token = dstToken ,
597
+ scitag = scitag ,
556
598
)
557
599
558
600
transfers .append (trans )
0 commit comments