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