rucio 37.3.0__py3-none-any.whl → 37.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rucio might be problematic. Click here for more details.

Files changed (128) hide show
  1. rucio/cli/rule.py +1 -1
  2. rucio/client/accountclient.py +205 -60
  3. rucio/client/accountlimitclient.py +84 -25
  4. rucio/client/baseclient.py +85 -48
  5. rucio/client/client.py +49 -41
  6. rucio/client/configclient.py +36 -13
  7. rucio/client/credentialclient.py +16 -6
  8. rucio/client/didclient.py +321 -133
  9. rucio/client/diracclient.py +13 -6
  10. rucio/client/downloadclient.py +435 -165
  11. rucio/client/exportclient.py +8 -2
  12. rucio/client/fileclient.py +10 -3
  13. rucio/client/importclient.py +4 -1
  14. rucio/client/lifetimeclient.py +48 -31
  15. rucio/client/lockclient.py +22 -7
  16. rucio/client/metaconventionsclient.py +59 -21
  17. rucio/client/pingclient.py +3 -1
  18. rucio/client/replicaclient.py +213 -96
  19. rucio/client/requestclient.py +124 -16
  20. rucio/client/rseclient.py +385 -160
  21. rucio/client/ruleclient.py +147 -51
  22. rucio/client/scopeclient.py +35 -10
  23. rucio/client/subscriptionclient.py +60 -27
  24. rucio/client/touchclient.py +16 -7
  25. rucio/common/constants.py +14 -17
  26. rucio/common/utils.py +18 -2
  27. rucio/core/permission/generic.py +40 -1
  28. rucio/core/replica.py +6 -6
  29. rucio/core/request.py +2 -2
  30. rucio/core/rule.py +5 -3
  31. rucio/core/transfer.py +4 -5
  32. rucio/daemons/conveyor/throttler.py +2 -1
  33. rucio/daemons/judge/evaluator.py +1 -1
  34. rucio/db/sqla/constants.py +3 -3
  35. rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +1 -1
  36. rucio/db/sqla/models.py +1 -1
  37. rucio/gateway/replica.py +129 -41
  38. rucio/gateway/request.py +177 -103
  39. rucio/gateway/subscription.py +90 -108
  40. rucio/rse/rsemanager.py +2 -2
  41. rucio/vcsversion.py +3 -3
  42. rucio/web/rest/flaskapi/v1/accountlimits.py +22 -22
  43. rucio/web/rest/flaskapi/v1/accounts.py +157 -157
  44. rucio/web/rest/flaskapi/v1/archives.py +10 -10
  45. rucio/web/rest/flaskapi/v1/auth.py +106 -106
  46. rucio/web/rest/flaskapi/v1/config.py +37 -37
  47. rucio/web/rest/flaskapi/v1/credentials.py +25 -25
  48. rucio/web/rest/flaskapi/v1/dids.py +381 -381
  49. rucio/web/rest/flaskapi/v1/dirac.py +8 -8
  50. rucio/web/rest/flaskapi/v1/export.py +6 -6
  51. rucio/web/rest/flaskapi/v1/heartbeats.py +14 -14
  52. rucio/web/rest/flaskapi/v1/identities.py +25 -25
  53. rucio/web/rest/flaskapi/v1/import.py +19 -19
  54. rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +54 -54
  55. rucio/web/rest/flaskapi/v1/locks.py +60 -60
  56. rucio/web/rest/flaskapi/v1/meta_conventions.py +29 -29
  57. rucio/web/rest/flaskapi/v1/nongrid_traces.py +4 -4
  58. rucio/web/rest/flaskapi/v1/ping.py +4 -4
  59. rucio/web/rest/flaskapi/v1/redirect.py +17 -17
  60. rucio/web/rest/flaskapi/v1/replicas.py +282 -282
  61. rucio/web/rest/flaskapi/v1/requests.py +424 -229
  62. rucio/web/rest/flaskapi/v1/rses.py +427 -427
  63. rucio/web/rest/flaskapi/v1/rules.py +129 -129
  64. rucio/web/rest/flaskapi/v1/scopes.py +21 -21
  65. rucio/web/rest/flaskapi/v1/subscriptions.py +122 -122
  66. rucio/web/rest/flaskapi/v1/traces.py +18 -18
  67. rucio/web/rest/flaskapi/v1/vos.py +32 -32
  68. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/rucio.cfg.template +0 -1
  69. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -1
  70. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/requirements.server.txt +1 -1
  71. {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/METADATA +1 -1
  72. {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/RECORD +128 -128
  73. {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/WHEEL +1 -1
  74. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/alembic.ini.template +0 -0
  75. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
  76. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
  77. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
  78. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
  79. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
  80. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
  81. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
  82. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
  83. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
  84. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
  85. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
  86. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/tools/bootstrap.py +0 -0
  87. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
  88. {rucio-37.3.0.data → rucio-37.5.0.data}/data/rucio/tools/reset_database.py +0 -0
  89. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio +0 -0
  90. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-abacus-account +0 -0
  91. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-abacus-collection-replica +0 -0
  92. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-abacus-rse +0 -0
  93. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-admin +0 -0
  94. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-atropos +0 -0
  95. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-auditor +0 -0
  96. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-automatix +0 -0
  97. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-bb8 +0 -0
  98. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-cache-client +0 -0
  99. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-cache-consumer +0 -0
  100. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-finisher +0 -0
  101. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-poller +0 -0
  102. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-preparer +0 -0
  103. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-receiver +0 -0
  104. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-stager +0 -0
  105. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-submitter +0 -0
  106. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-throttler +0 -0
  107. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-dark-reaper +0 -0
  108. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-dumper +0 -0
  109. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-follower +0 -0
  110. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-hermes +0 -0
  111. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-judge-cleaner +0 -0
  112. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-judge-evaluator +0 -0
  113. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-judge-injector +0 -0
  114. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-judge-repairer +0 -0
  115. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-kronos +0 -0
  116. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-minos +0 -0
  117. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-minos-temporary-expiration +0 -0
  118. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-necromancer +0 -0
  119. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-oauth-manager +0 -0
  120. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-reaper +0 -0
  121. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-replica-recoverer +0 -0
  122. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-rse-decommissioner +0 -0
  123. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-storage-consistency-actions +0 -0
  124. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-transmogrifier +0 -0
  125. {rucio-37.3.0.data → rucio-37.5.0.data}/scripts/rucio-undertaker +0 -0
  126. {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/licenses/AUTHORS.rst +0 -0
  127. {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/licenses/LICENSE +0 -0
  128. {rucio-37.3.0.dist-info → rucio-37.5.0.dist-info}/top_level.txt +0 -0
rucio/gateway/request.py CHANGED
@@ -19,28 +19,25 @@ Interface for the requests abstraction layer
19
19
  from typing import TYPE_CHECKING, Any, Optional
20
20
 
21
21
  from rucio.common import exception
22
+ from rucio.common.constants import TransferLimitDirection
22
23
  from rucio.common.types import InternalAccount, InternalScope, RequestGatewayDict
23
24
  from rucio.common.utils import gateway_update_return_dict
24
25
  from rucio.core import request
25
26
  from rucio.core.rse import get_rse_id
26
- from rucio.db.sqla.session import read_session, stream_session, transactional_session
27
+ from rucio.db.sqla.constants import DatabaseOperationType
28
+ from rucio.db.sqla.session import db_session
27
29
  from rucio.gateway import permission
28
30
 
29
31
  if TYPE_CHECKING:
30
32
  from collections.abc import Iterable, Iterator, Sequence
31
33
 
32
- from sqlalchemy.orm import Session
33
-
34
34
  from rucio.db.sqla.constants import RequestState, RequestType
35
35
 
36
36
 
37
- @transactional_session
38
37
  def queue_requests(
39
38
  requests: "Iterable[RequestGatewayDict]",
40
39
  issuer: str,
41
40
  vo: str = 'def',
42
- *,
43
- session: "Session"
44
41
  ) -> list[dict[str, Any]]:
45
42
  """
46
43
  Submit transfer or deletion requests on destination RSEs for data identifiers.
@@ -48,32 +45,29 @@ def queue_requests(
48
45
  :param requests: List of dictionaries containing 'scope', 'name', 'dest_rse_id', 'request_type', 'attributes'
49
46
  :param issuer: Issuing account as a string.
50
47
  :param vo: The VO to act on.
51
- :param session: The database session in use.
52
48
  :returns: List of Request-IDs as 32 character hex strings
53
49
  """
54
50
 
55
51
  kwargs = {'requests': requests, 'issuer': issuer}
56
- auth_result = permission.has_permission(issuer=issuer, vo=vo, action='queue_requests', kwargs=kwargs, session=session)
57
- if not auth_result.allowed:
58
- raise exception.AccessDenied(f'{issuer} can not queue request. {auth_result.message}')
52
+ with db_session(DatabaseOperationType.WRITE) as session:
53
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='queue_requests', kwargs=kwargs, session=session)
54
+ if not auth_result.allowed:
55
+ raise exception.AccessDenied(f'{issuer} can not queue request. {auth_result.message}')
59
56
 
60
- for req in requests:
61
- req['scope'] = InternalScope(req['scope'], vo=vo) # type: ignore (type reassignment)
62
- if 'account' in req:
63
- req['account'] = InternalAccount(req['account'], vo=vo) # type: ignore (type reassignment)
57
+ for req in requests:
58
+ req['scope'] = InternalScope(req['scope'], vo=vo) # type: ignore (type reassignment)
59
+ if 'account' in req:
60
+ req['account'] = InternalAccount(req['account'], vo=vo) # type: ignore (type reassignment)
64
61
 
65
- new_requests = request.queue_requests(requests, session=session)
66
- return [gateway_update_return_dict(r, session=session) for r in new_requests]
62
+ new_requests = request.queue_requests(requests, session=session)
63
+ return [gateway_update_return_dict(r, session=session) for r in new_requests]
67
64
 
68
65
 
69
- @transactional_session
70
66
  def cancel_request(
71
67
  request_id: str,
72
68
  issuer: str,
73
69
  account: str,
74
70
  vo: str = 'def',
75
- *,
76
- session: "Session"
77
71
  ) -> None:
78
72
  """
79
73
  Cancel a request.
@@ -82,18 +76,17 @@ def cancel_request(
82
76
  :param issuer: Issuing account as a string.
83
77
  :param account: Account identifier as a string.
84
78
  :param vo: The VO to act on.
85
- :param session: The database session in use.
86
79
  """
87
80
 
88
81
  kwargs = {'account': account, 'issuer': issuer, 'request_id': request_id}
89
- auth_result = permission.has_permission(issuer=issuer, vo=vo, action='cancel_request_', kwargs=kwargs, session=session)
82
+ with db_session(DatabaseOperationType.WRITE) as session:
83
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='cancel_request_', kwargs=kwargs, session=session)
90
84
  if not auth_result.allowed:
91
85
  raise exception.AccessDenied('%s cannot cancel request %s. %s' % (account, request_id, auth_result.message))
92
86
 
93
87
  raise NotImplementedError
94
88
 
95
89
 
96
- @transactional_session
97
90
  def cancel_request_did(
98
91
  scope: str,
99
92
  name: str,
@@ -102,8 +95,6 @@ def cancel_request_did(
102
95
  issuer: str,
103
96
  account: str,
104
97
  vo: str = 'def',
105
- *,
106
- session: "Session"
107
98
  ) -> dict[str, Any]:
108
99
  """
109
100
  Cancel a request based on a DID and request type.
@@ -115,29 +106,26 @@ def cancel_request_did(
115
106
  :param issuer: Issuing account as a string.
116
107
  :param account: Account identifier as a string.
117
108
  :param vo: The VO to act on.
118
- :param session: The database session in use.
119
109
  """
120
110
 
121
- dest_rse_id = get_rse_id(rse=dest_rse, vo=vo, session=session)
111
+ with db_session(DatabaseOperationType.WRITE) as session:
112
+ dest_rse_id = get_rse_id(rse=dest_rse, vo=vo, session=session)
122
113
 
123
- kwargs = {'account': account, 'issuer': issuer}
124
- auth_result = permission.has_permission(issuer=issuer, vo=vo, action='cancel_request_did', kwargs=kwargs, session=session)
125
- if not auth_result.allowed:
126
- raise exception.AccessDenied(f'{account} cannot cancel {request_type} request for {scope}:{name}. {auth_result.message}')
114
+ kwargs = {'account': account, 'issuer': issuer}
115
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='cancel_request_did', kwargs=kwargs, session=session)
116
+ if not auth_result.allowed:
117
+ raise exception.AccessDenied(f'{account} cannot cancel {request_type} request for {scope}:{name}. {auth_result.message}')
127
118
 
128
- internal_scope = InternalScope(scope, vo=vo)
129
- return request.cancel_request_did(internal_scope, name, dest_rse_id, request_type, session=session)
119
+ internal_scope = InternalScope(scope, vo=vo)
120
+ return request.cancel_request_did(internal_scope, name, dest_rse_id, request_type, session=session)
130
121
 
131
122
 
132
- @transactional_session
133
123
  def get_next(
134
124
  request_type: "RequestType",
135
125
  state: "RequestState",
136
126
  issuer: str,
137
127
  account: str,
138
128
  vo: str = 'def',
139
- *,
140
- session: "Session"
141
129
  ) -> list[dict[str, Any]]:
142
130
  """
143
131
  Retrieve the next request matching the request type and state.
@@ -147,28 +135,26 @@ def get_next(
147
135
  :param issuer: Issuing account as a string.
148
136
  :param account: Account identifier as a string.
149
137
  :param vo: The VO to act on.
150
- :param session: The database session in use.
151
138
  :returns: Request as a dictionary.
152
139
  """
153
140
 
154
141
  kwargs = {'account': account, 'issuer': issuer, 'request_type': request_type, 'state': state}
155
- auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_next', kwargs=kwargs, session=session)
156
- if not auth_result.allowed:
157
- raise exception.AccessDenied(f'{account} cannot get the next request of type {request_type} in state {state}. {auth_result.message}')
158
142
 
159
- reqs = request.get_and_mark_next(request_type, state, session=session)
160
- return [gateway_update_return_dict(r, session=session) for r in reqs]
143
+ with db_session(DatabaseOperationType.WRITE) as session:
144
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_next', kwargs=kwargs, session=session)
145
+ if not auth_result.allowed:
146
+ raise exception.AccessDenied(f'{account} cannot get the next request of type {request_type} in state {state}. {auth_result.message}')
147
+
148
+ reqs = request.get_and_mark_next(request_type, state, session=session)
149
+ return [gateway_update_return_dict(r, session=session) for r in reqs]
161
150
 
162
151
 
163
- @read_session
164
152
  def get_request_by_did(
165
153
  scope: str,
166
154
  name: str,
167
155
  rse: str,
168
156
  issuer: str,
169
157
  vo: str = 'def',
170
- *,
171
- session: "Session"
172
158
  ) -> dict[str, Any]:
173
159
  """
174
160
  Retrieve a request by its DID for a destination RSE.
@@ -178,31 +164,28 @@ def get_request_by_did(
178
164
  :param rse: The destination RSE of the request as a string.
179
165
  :param issuer: Issuing account as a string.
180
166
  :param vo: The VO to act on.
181
- :param session: The database session in use.
182
167
  :returns: Request as a dictionary.
183
168
  """
184
- rse_id = get_rse_id(rse=rse, vo=vo, session=session)
169
+ with db_session(DatabaseOperationType.READ) as session:
170
+ rse_id = get_rse_id(rse=rse, vo=vo, session=session)
185
171
 
186
- kwargs = {'scope': scope, 'name': name, 'rse': rse, 'rse_id': rse_id, 'issuer': issuer}
187
- auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_request_by_did', kwargs=kwargs, session=session)
188
- if not auth_result.allowed:
189
- raise exception.AccessDenied(f'{issuer} cannot retrieve the request DID {scope}:{name} to RSE {rse}. {auth_result.message}')
172
+ kwargs = {'scope': scope, 'name': name, 'rse': rse, 'rse_id': rse_id, 'issuer': issuer}
173
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_request_by_did', kwargs=kwargs, session=session)
174
+ if not auth_result.allowed:
175
+ raise exception.AccessDenied(f'{issuer} cannot retrieve the request DID {scope}:{name} to RSE {rse}. {auth_result.message}')
190
176
 
191
- internal_scope = InternalScope(scope, vo=vo)
192
- req = request.get_request_by_did(internal_scope, name, rse_id, session=session)
177
+ internal_scope = InternalScope(scope, vo=vo)
178
+ req = request.get_request_by_did(internal_scope, name, rse_id, session=session)
193
179
 
194
- return gateway_update_return_dict(req, session=session)
180
+ return gateway_update_return_dict(req, session=session)
195
181
 
196
182
 
197
- @read_session
198
183
  def get_request_history_by_did(
199
184
  scope: str,
200
185
  name: str,
201
186
  rse: str,
202
187
  issuer: str,
203
188
  vo: str = 'def',
204
- *,
205
- session: "Session"
206
189
  ) -> dict[str, Any]:
207
190
  """
208
191
  Retrieve a historical request by its DID for a destination RSE.
@@ -212,31 +195,28 @@ def get_request_history_by_did(
212
195
  :param rse: The destination RSE of the request as a string.
213
196
  :param issuer: Issuing account as a string.
214
197
  :param vo: The VO to act on.
215
- :param session: The database session in use.
216
198
  :returns: Request as a dictionary.
217
199
  """
218
- rse_id = get_rse_id(rse=rse, vo=vo, session=session)
200
+ with db_session(DatabaseOperationType.READ) as session:
201
+ rse_id = get_rse_id(rse=rse, vo=vo, session=session)
219
202
 
220
- kwargs = {'scope': scope, 'name': name, 'rse': rse, 'rse_id': rse_id, 'issuer': issuer}
221
- auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_request_history_by_did', kwargs=kwargs, session=session)
222
- if not auth_result.allowed:
223
- raise exception.AccessDenied(f'{issuer} cannot retrieve the request DID {scope}:{name} to RSE {rse}. {auth_result.message}')
203
+ kwargs = {'scope': scope, 'name': name, 'rse': rse, 'rse_id': rse_id, 'issuer': issuer}
204
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_request_history_by_did', kwargs=kwargs, session=session)
205
+ if not auth_result.allowed:
206
+ raise exception.AccessDenied(f'{issuer} cannot retrieve the request DID {scope}:{name} to RSE {rse}. {auth_result.message}')
224
207
 
225
- internal_scope = InternalScope(scope, vo=vo)
226
- req = request.get_request_history_by_did(internal_scope, name, rse_id, session=session)
208
+ internal_scope = InternalScope(scope, vo=vo)
209
+ req = request.get_request_history_by_did(internal_scope, name, rse_id, session=session)
227
210
 
228
- return gateway_update_return_dict(req, session=session)
211
+ return gateway_update_return_dict(req, session=session)
229
212
 
230
213
 
231
- @stream_session
232
214
  def list_requests(
233
215
  src_rses: "Iterable[str]",
234
216
  dst_rses: "Iterable[str]",
235
217
  states: "Sequence[RequestState]",
236
218
  issuer: str,
237
219
  vo: str = 'def',
238
- *,
239
- session: "Session"
240
220
  ) -> "Iterator[dict[str, Any]]":
241
221
  """
242
222
  List all requests in a specific state from a source RSE to a destination RSE.
@@ -245,22 +225,21 @@ def list_requests(
245
225
  :param dst_rses: destination RSEs.
246
226
  :param states: list of request states.
247
227
  :param issuer: Issuing account as a string.
248
- :param session: The database session in use.
249
228
  """
250
- src_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in src_rses]
251
- dst_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in dst_rses]
229
+ with db_session(DatabaseOperationType.READ) as session:
230
+ src_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in src_rses]
231
+ dst_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in dst_rses]
252
232
 
253
- kwargs = {'src_rse_id': src_rse_ids, 'dst_rse_id': dst_rse_ids, 'issuer': issuer}
254
- auth_result = permission.has_permission(issuer=issuer, vo=vo, action='list_requests', kwargs=kwargs, session=session)
255
- if not auth_result.allowed:
256
- raise exception.AccessDenied(f'{issuer} cannot list requests from RSEs {src_rses} to RSEs {dst_rses}. {auth_result.message}')
233
+ kwargs = {'src_rse_id': src_rse_ids, 'dst_rse_id': dst_rse_ids, 'issuer': issuer}
234
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='list_requests', kwargs=kwargs, session=session)
235
+ if not auth_result.allowed:
236
+ raise exception.AccessDenied(f'{issuer} cannot list requests from RSEs {src_rses} to RSEs {dst_rses}. {auth_result.message}')
257
237
 
258
- for req in request.list_requests(src_rse_ids, dst_rse_ids, states, session=session):
259
- req = req.to_dict()
260
- yield gateway_update_return_dict(req, session=session)
238
+ for req in request.list_requests(src_rse_ids, dst_rse_ids, states, session=session):
239
+ req = req.to_dict()
240
+ yield gateway_update_return_dict(req, session=session)
261
241
 
262
242
 
263
- @stream_session
264
243
  def list_requests_history(
265
244
  src_rses: "Iterable[str]",
266
245
  dst_rses: "Iterable[str]",
@@ -269,8 +248,6 @@ def list_requests_history(
269
248
  vo: str = 'def',
270
249
  offset: Optional[int] = None,
271
250
  limit: Optional[int] = None,
272
- *,
273
- session: "Session"
274
251
  ) -> "Iterator[dict[str, Any]]":
275
252
  """
276
253
  List all historical requests in a specific state from a source RSE to a destination RSE.
@@ -280,22 +257,21 @@ def list_requests_history(
280
257
  :param issuer: Issuing account as a string.
281
258
  :param offset: offset (for paging).
282
259
  :param limit: limit number of results.
283
- :param session: The database session in use.
284
260
  """
285
- src_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in src_rses]
286
- dst_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in dst_rses]
261
+ with db_session(DatabaseOperationType.READ) as session:
262
+ src_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in src_rses]
263
+ dst_rse_ids = [get_rse_id(rse=rse, vo=vo, session=session) for rse in dst_rses]
287
264
 
288
- kwargs = {'src_rse_id': src_rse_ids, 'dst_rse_id': dst_rse_ids, 'issuer': issuer}
289
- auth_result = permission.has_permission(issuer=issuer, vo=vo, action='list_requests_history', kwargs=kwargs, session=session)
290
- if not auth_result.allowed:
291
- raise exception.AccessDenied(f'{issuer} cannot list requests from RSEs {src_rses} to RSEs {dst_rses}. {auth_result.message}')
265
+ kwargs = {'src_rse_id': src_rse_ids, 'dst_rse_id': dst_rse_ids, 'issuer': issuer}
266
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='list_requests_history', kwargs=kwargs, session=session)
267
+ if not auth_result.allowed:
268
+ raise exception.AccessDenied(f'{issuer} cannot list requests from RSEs {src_rses} to RSEs {dst_rses}. {auth_result.message}')
292
269
 
293
- for req in request.list_requests_history(src_rse_ids, dst_rse_ids, states, offset, limit, session=session):
294
- req = req.to_dict()
295
- yield gateway_update_return_dict(req, session=session)
270
+ for req in request.list_requests_history(src_rse_ids, dst_rse_ids, states, offset, limit, session=session):
271
+ req = req.to_dict()
272
+ yield gateway_update_return_dict(req, session=session)
296
273
 
297
274
 
298
- @read_session
299
275
  def get_request_metrics(
300
276
  src_rse: Optional[str],
301
277
  dst_rse: Optional[str],
@@ -303,8 +279,6 @@ def get_request_metrics(
303
279
  group_by_rse_attribute: Optional[str],
304
280
  issuer: str,
305
281
  vo: str = 'def',
306
- *,
307
- session: "Session"
308
282
  ) -> dict[str, Any]:
309
283
  """
310
284
  Get statistics of requests in a specific state grouped by source RSE, destination RSE, and activity.
@@ -314,17 +288,117 @@ def get_request_metrics(
314
288
  :param activity: activity
315
289
  :param group_by_rse_attribute: The parameter to group the RSEs by.
316
290
  :param issuer: Issuing account as a string.
317
- :param session: The database session in use.
318
291
  """
319
292
  src_rse_id = None
320
- if src_rse:
321
- src_rse_id = get_rse_id(rse=src_rse, vo=vo, session=session)
322
293
  dst_rse_id = None
323
- if dst_rse:
324
- dst_rse_id = get_rse_id(rse=dst_rse, vo=vo, session=session)
325
294
  kwargs = {'issuer': issuer}
326
- auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_request_metrics', kwargs=kwargs, session=session)
327
- if not auth_result.allowed:
328
- raise exception.AccessDenied(f'{issuer} cannot get request statistics. {auth_result.message}')
329
295
 
330
- return request.get_request_metrics(dest_rse_id=dst_rse_id, src_rse_id=src_rse_id, activity=activity, group_by_rse_attribute=group_by_rse_attribute, session=session)
296
+ with db_session(DatabaseOperationType.READ) as session:
297
+ if src_rse:
298
+ src_rse_id = get_rse_id(rse=src_rse, vo=vo, session=session)
299
+
300
+ if dst_rse:
301
+ dst_rse_id = get_rse_id(rse=dst_rse, vo=vo, session=session)
302
+
303
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='get_request_metrics', kwargs=kwargs, session=session)
304
+ if not auth_result.allowed:
305
+ raise exception.AccessDenied(f'{issuer} cannot get request statistics. {auth_result.message}')
306
+
307
+ return request.get_request_metrics(dest_rse_id=dst_rse_id, src_rse_id=src_rse_id, activity=activity, group_by_rse_attribute=group_by_rse_attribute, session=session)
308
+
309
+
310
+ def list_transfer_limits(
311
+ issuer: str,
312
+ vo: str = 'def'
313
+ ) -> "Iterator[dict[str, Any]]":
314
+ """
315
+ List all the transfer limits.
316
+
317
+ :param issuer: Issuing account as a string.
318
+ :param session: The database session in use.
319
+
320
+ :returns: The list of transfer limits
321
+ """
322
+ with db_session(DatabaseOperationType.READ) as session:
323
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='list_transfer_limits', kwargs={}, session=session)
324
+ if not auth_result.allowed:
325
+ raise exception.AccessDenied(f'{issuer} cannot list transfer limits. {auth_result.message}')
326
+
327
+ return request.list_transfer_limits(session=session)
328
+
329
+
330
+ def set_transfer_limit(
331
+ issuer: str,
332
+ rse_expression: str,
333
+ activity: Optional[str] = None,
334
+ direction: TransferLimitDirection = TransferLimitDirection.DESTINATION,
335
+ max_transfers: Optional[int] = None,
336
+ volume: Optional[int] = None,
337
+ deadline: Optional[int] = None,
338
+ strategy: Optional[str] = None,
339
+ transfers: Optional[int] = None,
340
+ waitings: Optional[int] = None,
341
+ vo: str = 'def'
342
+ ) -> None:
343
+ """
344
+ Create or update a transfer limit
345
+
346
+ :param issuer: Issuing account as a string.
347
+ :param vo: The VO to act on.
348
+ :param rse_expression: RSE expression for which the transfer limit applies.
349
+ :param activity: The activity for which the transfer limit applies.
350
+ :param direction: The direction in which this limit applies (source/destination)
351
+ :param max_transfers: Maximum transfers.
352
+ :param volume: Maximum transfer volume in bytes.
353
+ :param deadline: Maximum waiting time in hours until a datasets gets released.
354
+ :param strategy: defines how to handle datasets: `fifo` (each file released separately) or `grouped_fifo` (wait for the entire dataset to fit)
355
+ :param transfers: Current number of active transfers
356
+ :param waitings: Current number of waiting transfers
357
+ :param session: The database session in use.
358
+
359
+ :returns: None
360
+ """
361
+ with db_session(DatabaseOperationType.WRITE) as session:
362
+ kwargs = {'rse_expression': rse_expression, 'activity': activity, 'max_transfers': max_transfers}
363
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='set_transfer_limit', kwargs=kwargs, session=session)
364
+ if not auth_result.allowed:
365
+ raise exception.AccessDenied(f'{issuer} cannot set transfer limits. {auth_result.message}')
366
+
367
+ request.set_transfer_limit(rse_expression=rse_expression,
368
+ activity=activity,
369
+ direction=direction,
370
+ max_transfers=max_transfers,
371
+ volume=volume,
372
+ deadline=deadline,
373
+ strategy=strategy,
374
+ transfers=transfers,
375
+ waitings=waitings)
376
+
377
+
378
+ def delete_transfer_limit(
379
+ issuer: str,
380
+ rse_expression: str,
381
+ activity: Optional[str] = None,
382
+ direction: TransferLimitDirection = TransferLimitDirection.DESTINATION,
383
+ vo: str = 'def'
384
+ ) -> None:
385
+ """
386
+ Delete a transfer limit
387
+
388
+ :param issuer: Issuing account as a string.
389
+ :param vo: The VO to act on.
390
+ :param rse_expression: RSE expression for which the transfer limit applies.
391
+ :param activity: The activity for which the transfer limit applies.
392
+ :param direction: The direction in which this limit applies (source/destination)
393
+ :param session: The database session in use.
394
+ """
395
+ with db_session(DatabaseOperationType.WRITE) as session:
396
+ kwargs = {'rse_expression': rse_expression, 'activity': activity}
397
+ auth_result = permission.has_permission(issuer=issuer, vo=vo, action='delete_transfer_limit', kwargs=kwargs, session=session)
398
+ if not auth_result.allowed:
399
+ raise exception.AccessDenied(f'{issuer} cannot delete transfer limits. {auth_result.message}')
400
+
401
+ request.delete_transfer_limit(rse_expression=rse_expression,
402
+ activity=activity,
403
+ direction=direction,
404
+ session=session)