rucio 32.8.6__py3-none-any.whl → 35.8.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 (502) hide show
  1. rucio/__init__.py +0 -1
  2. rucio/alembicrevision.py +1 -2
  3. rucio/client/__init__.py +0 -1
  4. rucio/client/accountclient.py +45 -25
  5. rucio/client/accountlimitclient.py +37 -9
  6. rucio/client/baseclient.py +199 -154
  7. rucio/client/client.py +2 -3
  8. rucio/client/configclient.py +19 -6
  9. rucio/client/credentialclient.py +9 -4
  10. rucio/client/didclient.py +238 -63
  11. rucio/client/diracclient.py +13 -5
  12. rucio/client/downloadclient.py +162 -51
  13. rucio/client/exportclient.py +4 -4
  14. rucio/client/fileclient.py +3 -4
  15. rucio/client/importclient.py +4 -4
  16. rucio/client/lifetimeclient.py +21 -5
  17. rucio/client/lockclient.py +18 -8
  18. rucio/client/{metaclient.py → metaconventionsclient.py} +18 -15
  19. rucio/client/pingclient.py +0 -1
  20. rucio/client/replicaclient.py +15 -5
  21. rucio/client/requestclient.py +35 -19
  22. rucio/client/rseclient.py +133 -51
  23. rucio/client/ruleclient.py +29 -22
  24. rucio/client/scopeclient.py +8 -6
  25. rucio/client/subscriptionclient.py +47 -35
  26. rucio/client/touchclient.py +8 -4
  27. rucio/client/uploadclient.py +166 -82
  28. rucio/common/__init__.py +0 -1
  29. rucio/common/cache.py +4 -4
  30. rucio/common/config.py +52 -47
  31. rucio/common/constants.py +69 -2
  32. rucio/common/constraints.py +0 -1
  33. rucio/common/didtype.py +24 -22
  34. rucio/common/dumper/__init__.py +70 -41
  35. rucio/common/dumper/consistency.py +26 -22
  36. rucio/common/dumper/data_models.py +16 -23
  37. rucio/common/dumper/path_parsing.py +0 -1
  38. rucio/common/exception.py +281 -222
  39. rucio/common/extra.py +0 -1
  40. rucio/common/logging.py +54 -38
  41. rucio/common/pcache.py +122 -101
  42. rucio/common/plugins.py +153 -0
  43. rucio/common/policy.py +4 -4
  44. rucio/common/schema/__init__.py +17 -10
  45. rucio/common/schema/atlas.py +7 -5
  46. rucio/common/schema/belleii.py +7 -5
  47. rucio/common/schema/domatpc.py +7 -5
  48. rucio/common/schema/escape.py +7 -5
  49. rucio/common/schema/generic.py +8 -6
  50. rucio/common/schema/generic_multi_vo.py +7 -5
  51. rucio/common/schema/icecube.py +7 -5
  52. rucio/common/stomp_utils.py +0 -1
  53. rucio/common/stopwatch.py +0 -1
  54. rucio/common/test_rucio_server.py +2 -2
  55. rucio/common/types.py +262 -17
  56. rucio/common/utils.py +743 -451
  57. rucio/core/__init__.py +0 -1
  58. rucio/core/account.py +99 -29
  59. rucio/core/account_counter.py +89 -24
  60. rucio/core/account_limit.py +90 -24
  61. rucio/core/authentication.py +86 -29
  62. rucio/core/config.py +108 -38
  63. rucio/core/credential.py +14 -7
  64. rucio/core/did.py +680 -782
  65. rucio/core/did_meta_plugins/__init__.py +8 -6
  66. rucio/core/did_meta_plugins/did_column_meta.py +17 -12
  67. rucio/core/did_meta_plugins/did_meta_plugin_interface.py +60 -11
  68. rucio/core/did_meta_plugins/filter_engine.py +90 -50
  69. rucio/core/did_meta_plugins/json_meta.py +41 -16
  70. rucio/core/did_meta_plugins/mongo_meta.py +25 -8
  71. rucio/core/did_meta_plugins/postgres_meta.py +3 -4
  72. rucio/core/dirac.py +46 -17
  73. rucio/core/distance.py +66 -43
  74. rucio/core/exporter.py +5 -5
  75. rucio/core/heartbeat.py +181 -81
  76. rucio/core/identity.py +22 -12
  77. rucio/core/importer.py +23 -12
  78. rucio/core/lifetime_exception.py +32 -32
  79. rucio/core/lock.py +244 -142
  80. rucio/core/message.py +79 -38
  81. rucio/core/{meta.py → meta_conventions.py} +57 -44
  82. rucio/core/monitor.py +19 -13
  83. rucio/core/naming_convention.py +68 -27
  84. rucio/core/nongrid_trace.py +17 -5
  85. rucio/core/oidc.py +151 -29
  86. rucio/core/permission/__init__.py +18 -6
  87. rucio/core/permission/atlas.py +50 -35
  88. rucio/core/permission/belleii.py +6 -5
  89. rucio/core/permission/escape.py +8 -6
  90. rucio/core/permission/generic.py +82 -80
  91. rucio/core/permission/generic_multi_vo.py +9 -7
  92. rucio/core/quarantined_replica.py +91 -58
  93. rucio/core/replica.py +1303 -772
  94. rucio/core/replica_sorter.py +10 -12
  95. rucio/core/request.py +1133 -285
  96. rucio/core/rse.py +142 -102
  97. rucio/core/rse_counter.py +49 -18
  98. rucio/core/rse_expression_parser.py +6 -7
  99. rucio/core/rse_selector.py +41 -16
  100. rucio/core/rule.py +1538 -474
  101. rucio/core/rule_grouping.py +213 -68
  102. rucio/core/scope.py +50 -22
  103. rucio/core/subscription.py +92 -44
  104. rucio/core/topology.py +66 -24
  105. rucio/core/trace.py +42 -28
  106. rucio/core/transfer.py +543 -259
  107. rucio/core/vo.py +36 -18
  108. rucio/core/volatile_replica.py +59 -32
  109. rucio/daemons/__init__.py +0 -1
  110. rucio/daemons/abacus/__init__.py +0 -1
  111. rucio/daemons/abacus/account.py +29 -19
  112. rucio/daemons/abacus/collection_replica.py +21 -10
  113. rucio/daemons/abacus/rse.py +22 -12
  114. rucio/daemons/atropos/__init__.py +0 -1
  115. rucio/daemons/atropos/atropos.py +1 -2
  116. rucio/daemons/auditor/__init__.py +56 -28
  117. rucio/daemons/auditor/hdfs.py +17 -6
  118. rucio/daemons/auditor/srmdumps.py +116 -45
  119. rucio/daemons/automatix/__init__.py +0 -1
  120. rucio/daemons/automatix/automatix.py +30 -18
  121. rucio/daemons/badreplicas/__init__.py +0 -1
  122. rucio/daemons/badreplicas/minos.py +29 -18
  123. rucio/daemons/badreplicas/minos_temporary_expiration.py +5 -7
  124. rucio/daemons/badreplicas/necromancer.py +9 -13
  125. rucio/daemons/bb8/__init__.py +0 -1
  126. rucio/daemons/bb8/bb8.py +10 -13
  127. rucio/daemons/bb8/common.py +151 -154
  128. rucio/daemons/bb8/nuclei_background_rebalance.py +15 -9
  129. rucio/daemons/bb8/t2_background_rebalance.py +15 -8
  130. rucio/daemons/c3po/__init__.py +0 -1
  131. rucio/daemons/c3po/algorithms/__init__.py +0 -1
  132. rucio/daemons/c3po/algorithms/simple.py +8 -5
  133. rucio/daemons/c3po/algorithms/t2_free_space.py +10 -7
  134. rucio/daemons/c3po/algorithms/t2_free_space_only_pop.py +10 -7
  135. rucio/daemons/c3po/algorithms/t2_free_space_only_pop_with_network.py +30 -15
  136. rucio/daemons/c3po/c3po.py +81 -52
  137. rucio/daemons/c3po/collectors/__init__.py +0 -1
  138. rucio/daemons/c3po/collectors/agis.py +17 -17
  139. rucio/daemons/c3po/collectors/free_space.py +32 -13
  140. rucio/daemons/c3po/collectors/jedi_did.py +14 -5
  141. rucio/daemons/c3po/collectors/mock_did.py +11 -6
  142. rucio/daemons/c3po/collectors/network_metrics.py +12 -4
  143. rucio/daemons/c3po/collectors/workload.py +21 -19
  144. rucio/daemons/c3po/utils/__init__.py +0 -1
  145. rucio/daemons/c3po/utils/dataset_cache.py +15 -5
  146. rucio/daemons/c3po/utils/expiring_dataset_cache.py +16 -5
  147. rucio/daemons/c3po/utils/expiring_list.py +6 -7
  148. rucio/daemons/c3po/utils/popularity.py +5 -2
  149. rucio/daemons/c3po/utils/timeseries.py +25 -12
  150. rucio/daemons/cache/__init__.py +0 -1
  151. rucio/daemons/cache/consumer.py +21 -15
  152. rucio/daemons/common.py +42 -18
  153. rucio/daemons/conveyor/__init__.py +0 -1
  154. rucio/daemons/conveyor/common.py +69 -37
  155. rucio/daemons/conveyor/finisher.py +83 -46
  156. rucio/daemons/conveyor/poller.py +101 -69
  157. rucio/daemons/conveyor/preparer.py +35 -28
  158. rucio/daemons/conveyor/receiver.py +64 -21
  159. rucio/daemons/conveyor/stager.py +33 -28
  160. rucio/daemons/conveyor/submitter.py +71 -47
  161. rucio/daemons/conveyor/throttler.py +99 -35
  162. rucio/daemons/follower/__init__.py +0 -1
  163. rucio/daemons/follower/follower.py +12 -8
  164. rucio/daemons/hermes/__init__.py +0 -1
  165. rucio/daemons/hermes/hermes.py +57 -21
  166. rucio/daemons/judge/__init__.py +0 -1
  167. rucio/daemons/judge/cleaner.py +27 -17
  168. rucio/daemons/judge/evaluator.py +31 -18
  169. rucio/daemons/judge/injector.py +31 -23
  170. rucio/daemons/judge/repairer.py +28 -18
  171. rucio/daemons/oauthmanager/__init__.py +0 -1
  172. rucio/daemons/oauthmanager/oauthmanager.py +7 -8
  173. rucio/daemons/reaper/__init__.py +0 -1
  174. rucio/daemons/reaper/dark_reaper.py +15 -9
  175. rucio/daemons/reaper/reaper.py +109 -67
  176. rucio/daemons/replicarecoverer/__init__.py +0 -1
  177. rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +255 -116
  178. rucio/{api → daemons/rsedecommissioner}/__init__.py +0 -1
  179. rucio/daemons/rsedecommissioner/config.py +81 -0
  180. rucio/daemons/rsedecommissioner/profiles/__init__.py +24 -0
  181. rucio/daemons/rsedecommissioner/profiles/atlas.py +60 -0
  182. rucio/daemons/rsedecommissioner/profiles/generic.py +451 -0
  183. rucio/daemons/rsedecommissioner/profiles/types.py +92 -0
  184. rucio/daemons/rsedecommissioner/rse_decommissioner.py +280 -0
  185. rucio/daemons/storage/__init__.py +0 -1
  186. rucio/daemons/storage/consistency/__init__.py +0 -1
  187. rucio/daemons/storage/consistency/actions.py +152 -59
  188. rucio/daemons/tracer/__init__.py +0 -1
  189. rucio/daemons/tracer/kronos.py +47 -24
  190. rucio/daemons/transmogrifier/__init__.py +0 -1
  191. rucio/daemons/transmogrifier/transmogrifier.py +35 -26
  192. rucio/daemons/undertaker/__init__.py +0 -1
  193. rucio/daemons/undertaker/undertaker.py +10 -10
  194. rucio/db/__init__.py +0 -1
  195. rucio/db/sqla/__init__.py +16 -2
  196. rucio/db/sqla/constants.py +10 -1
  197. rucio/db/sqla/migrate_repo/__init__.py +0 -1
  198. rucio/db/sqla/migrate_repo/env.py +0 -1
  199. rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +0 -1
  200. rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +0 -3
  201. rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +1 -3
  202. rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +0 -3
  203. rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +1 -3
  204. rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +1 -3
  205. rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +0 -3
  206. rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +1 -4
  207. rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +0 -1
  208. rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +0 -2
  209. rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +0 -1
  210. rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +0 -1
  211. rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +0 -2
  212. rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +0 -1
  213. rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +1 -3
  214. rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +0 -1
  215. rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +0 -3
  216. rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +0 -1
  217. rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +1 -2
  218. rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +0 -1
  219. rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +0 -3
  220. rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +1 -3
  221. rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +1 -4
  222. rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +0 -2
  223. rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +0 -3
  224. rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +0 -3
  225. rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +1 -2
  226. rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +0 -1
  227. rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +0 -1
  228. rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +0 -2
  229. rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +0 -3
  230. rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +1 -3
  231. rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +0 -2
  232. rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +1 -4
  233. rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +0 -3
  234. rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +1 -4
  235. rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +0 -1
  236. rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +1 -3
  237. rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +0 -2
  238. rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +1 -3
  239. rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +1 -3
  240. rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +1 -2
  241. rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +1 -3
  242. rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +1 -3
  243. rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +0 -2
  244. rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +1 -3
  245. rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +2 -3
  246. rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +0 -3
  247. rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +1 -4
  248. rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +0 -1
  249. rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +0 -1
  250. rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +0 -3
  251. rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +0 -1
  252. rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +0 -2
  253. rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +0 -3
  254. rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +0 -2
  255. rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +2 -4
  256. rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +0 -2
  257. rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +1 -3
  258. rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +1 -4
  259. rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +0 -3
  260. rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +0 -3
  261. rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +0 -2
  262. rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +1 -3
  263. rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +0 -3
  264. rucio/db/sqla/migrate_repo/versions/4df2c5ddabc0_remove_temporary_dids.py +55 -0
  265. rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +0 -2
  266. rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +0 -2
  267. rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +0 -3
  268. rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +0 -3
  269. rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +0 -3
  270. rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +1 -2
  271. rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +0 -3
  272. rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +1 -3
  273. rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +1 -3
  274. rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +1 -2
  275. rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +0 -3
  276. rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +0 -3
  277. rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +1 -2
  278. rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +2 -4
  279. rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +0 -1
  280. rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +1 -4
  281. rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +0 -2
  282. rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +0 -3
  283. rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +1 -2
  284. rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +0 -3
  285. rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +1 -3
  286. rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +0 -3
  287. rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +0 -1
  288. rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +1 -2
  289. rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +0 -2
  290. rucio/db/sqla/migrate_repo/versions/a08fa8de1545_transfer_stats_table.py +55 -0
  291. rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +1 -3
  292. rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +0 -2
  293. rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +1 -4
  294. rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +0 -1
  295. rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +0 -1
  296. rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +1 -3
  297. rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +1 -4
  298. rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +0 -1
  299. rucio/db/sqla/migrate_repo/versions/b0070f3695c8_add_deletedidmeta_table.py +57 -0
  300. rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +0 -3
  301. rucio/db/sqla/migrate_repo/versions/b5493606bbf5_fix_primary_key_for_subscription_history.py +41 -0
  302. rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +1 -2
  303. rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +1 -3
  304. rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +0 -3
  305. rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +1 -5
  306. rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +1 -3
  307. rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +0 -3
  308. rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +1 -3
  309. rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +1 -2
  310. rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +0 -3
  311. rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +1 -4
  312. rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +1 -2
  313. rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +1 -4
  314. rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +1 -3
  315. rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +1 -4
  316. rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +0 -2
  317. rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +1 -3
  318. rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +0 -3
  319. rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +1 -3
  320. rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +0 -1
  321. rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +1 -2
  322. rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +1 -3
  323. rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +0 -2
  324. rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +0 -1
  325. rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +1 -2
  326. rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +0 -3
  327. rucio/db/sqla/models.py +122 -216
  328. rucio/db/sqla/sautils.py +12 -5
  329. rucio/db/sqla/session.py +71 -43
  330. rucio/db/sqla/types.py +3 -4
  331. rucio/db/sqla/util.py +91 -69
  332. rucio/gateway/__init__.py +13 -0
  333. rucio/{api → gateway}/account.py +119 -46
  334. rucio/{api → gateway}/account_limit.py +12 -13
  335. rucio/{api → gateway}/authentication.py +106 -33
  336. rucio/{api → gateway}/config.py +12 -13
  337. rucio/{api → gateway}/credential.py +15 -4
  338. rucio/{api → gateway}/did.py +384 -140
  339. rucio/{api → gateway}/dirac.py +16 -6
  340. rucio/{api → gateway}/exporter.py +3 -4
  341. rucio/{api → gateway}/heartbeat.py +17 -5
  342. rucio/{api → gateway}/identity.py +63 -19
  343. rucio/{api → gateway}/importer.py +3 -4
  344. rucio/{api → gateway}/lifetime_exception.py +35 -10
  345. rucio/{api → gateway}/lock.py +34 -12
  346. rucio/{api/meta.py → gateway/meta_conventions.py} +18 -16
  347. rucio/{api → gateway}/permission.py +4 -5
  348. rucio/{api → gateway}/quarantined_replica.py +13 -4
  349. rucio/{api → gateway}/replica.py +12 -11
  350. rucio/{api → gateway}/request.py +129 -28
  351. rucio/{api → gateway}/rse.py +11 -12
  352. rucio/{api → gateway}/rule.py +117 -35
  353. rucio/{api → gateway}/scope.py +24 -14
  354. rucio/{api → gateway}/subscription.py +65 -43
  355. rucio/{api → gateway}/vo.py +17 -7
  356. rucio/rse/__init__.py +3 -4
  357. rucio/rse/protocols/__init__.py +0 -1
  358. rucio/rse/protocols/bittorrent.py +184 -0
  359. rucio/rse/protocols/cache.py +1 -2
  360. rucio/rse/protocols/dummy.py +1 -2
  361. rucio/rse/protocols/gfal.py +12 -10
  362. rucio/rse/protocols/globus.py +7 -7
  363. rucio/rse/protocols/gsiftp.py +2 -3
  364. rucio/rse/protocols/http_cache.py +1 -2
  365. rucio/rse/protocols/mock.py +1 -2
  366. rucio/rse/protocols/ngarc.py +1 -2
  367. rucio/rse/protocols/posix.py +12 -13
  368. rucio/rse/protocols/protocol.py +116 -52
  369. rucio/rse/protocols/rclone.py +6 -7
  370. rucio/rse/protocols/rfio.py +4 -5
  371. rucio/rse/protocols/srm.py +9 -10
  372. rucio/rse/protocols/ssh.py +8 -9
  373. rucio/rse/protocols/storm.py +2 -3
  374. rucio/rse/protocols/webdav.py +17 -14
  375. rucio/rse/protocols/xrootd.py +23 -17
  376. rucio/rse/rsemanager.py +19 -7
  377. rucio/tests/__init__.py +0 -1
  378. rucio/tests/common.py +43 -17
  379. rucio/tests/common_server.py +3 -3
  380. rucio/transfertool/__init__.py +0 -1
  381. rucio/transfertool/bittorrent.py +199 -0
  382. rucio/transfertool/bittorrent_driver.py +52 -0
  383. rucio/transfertool/bittorrent_driver_qbittorrent.py +133 -0
  384. rucio/transfertool/fts3.py +250 -138
  385. rucio/transfertool/fts3_plugins.py +152 -0
  386. rucio/transfertool/globus.py +9 -8
  387. rucio/transfertool/globus_library.py +1 -2
  388. rucio/transfertool/mock.py +21 -12
  389. rucio/transfertool/transfertool.py +33 -24
  390. rucio/vcsversion.py +4 -4
  391. rucio/version.py +5 -13
  392. rucio/web/__init__.py +0 -1
  393. rucio/web/rest/__init__.py +0 -1
  394. rucio/web/rest/flaskapi/__init__.py +0 -1
  395. rucio/web/rest/flaskapi/authenticated_bp.py +0 -1
  396. rucio/web/rest/flaskapi/v1/__init__.py +0 -1
  397. rucio/web/rest/flaskapi/v1/accountlimits.py +15 -13
  398. rucio/web/rest/flaskapi/v1/accounts.py +49 -48
  399. rucio/web/rest/flaskapi/v1/archives.py +12 -10
  400. rucio/web/rest/flaskapi/v1/auth.py +146 -144
  401. rucio/web/rest/flaskapi/v1/common.py +82 -41
  402. rucio/web/rest/flaskapi/v1/config.py +5 -6
  403. rucio/web/rest/flaskapi/v1/credentials.py +7 -8
  404. rucio/web/rest/flaskapi/v1/dids.py +158 -28
  405. rucio/web/rest/flaskapi/v1/dirac.py +8 -8
  406. rucio/web/rest/flaskapi/v1/export.py +3 -5
  407. rucio/web/rest/flaskapi/v1/heartbeats.py +3 -5
  408. rucio/web/rest/flaskapi/v1/identities.py +3 -5
  409. rucio/web/rest/flaskapi/v1/import.py +3 -4
  410. rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +6 -9
  411. rucio/web/rest/flaskapi/v1/locks.py +2 -4
  412. rucio/web/rest/flaskapi/v1/main.py +10 -2
  413. rucio/web/rest/flaskapi/v1/{meta.py → meta_conventions.py} +26 -11
  414. rucio/web/rest/flaskapi/v1/metrics.py +1 -2
  415. rucio/web/rest/flaskapi/v1/nongrid_traces.py +4 -4
  416. rucio/web/rest/flaskapi/v1/ping.py +6 -7
  417. rucio/web/rest/flaskapi/v1/redirect.py +8 -9
  418. rucio/web/rest/flaskapi/v1/replicas.py +43 -19
  419. rucio/web/rest/flaskapi/v1/requests.py +178 -21
  420. rucio/web/rest/flaskapi/v1/rses.py +61 -26
  421. rucio/web/rest/flaskapi/v1/rules.py +48 -18
  422. rucio/web/rest/flaskapi/v1/scopes.py +3 -5
  423. rucio/web/rest/flaskapi/v1/subscriptions.py +22 -18
  424. rucio/web/rest/flaskapi/v1/traces.py +4 -4
  425. rucio/web/rest/flaskapi/v1/types.py +20 -0
  426. rucio/web/rest/flaskapi/v1/vos.py +3 -5
  427. rucio/web/rest/main.py +0 -1
  428. rucio/web/rest/metrics.py +0 -1
  429. rucio/web/rest/ping.py +27 -0
  430. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/ldap.cfg.template +1 -1
  431. rucio-35.8.0.data/data/rucio/requirements.server.txt +268 -0
  432. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/tools/bootstrap.py +3 -3
  433. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/tools/merge_rucio_configs.py +2 -5
  434. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/tools/reset_database.py +3 -3
  435. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio +87 -85
  436. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-abacus-account +0 -1
  437. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-abacus-collection-replica +0 -1
  438. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-abacus-rse +0 -1
  439. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-admin +45 -32
  440. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-atropos +0 -1
  441. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-auditor +13 -7
  442. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-automatix +1 -2
  443. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-bb8 +0 -1
  444. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-c3po +0 -1
  445. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-cache-client +2 -3
  446. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-cache-consumer +0 -1
  447. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-finisher +1 -2
  448. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-poller +0 -1
  449. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-preparer +0 -1
  450. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-receiver +0 -1
  451. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-stager +0 -1
  452. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-submitter +2 -3
  453. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-throttler +0 -1
  454. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-dark-reaper +0 -1
  455. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-dumper +11 -10
  456. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-follower +0 -1
  457. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-hermes +0 -1
  458. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-cleaner +0 -1
  459. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-evaluator +2 -3
  460. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-injector +0 -1
  461. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-repairer +0 -1
  462. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-kronos +1 -3
  463. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-minos +0 -1
  464. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-minos-temporary-expiration +0 -1
  465. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-necromancer +1 -2
  466. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-oauth-manager +2 -3
  467. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-reaper +0 -1
  468. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-replica-recoverer +6 -7
  469. rucio-35.8.0.data/scripts/rucio-rse-decommissioner +66 -0
  470. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-storage-consistency-actions +0 -1
  471. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-transmogrifier +0 -1
  472. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-undertaker +1 -2
  473. rucio-35.8.0.dist-info/METADATA +72 -0
  474. rucio-35.8.0.dist-info/RECORD +493 -0
  475. {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/WHEEL +1 -1
  476. {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/licenses/AUTHORS.rst +3 -0
  477. rucio/api/temporary_did.py +0 -49
  478. rucio/common/schema/cms.py +0 -478
  479. rucio/common/schema/lsst.py +0 -423
  480. rucio/core/permission/cms.py +0 -1166
  481. rucio/core/temporary_did.py +0 -188
  482. rucio/daemons/reaper/light_reaper.py +0 -255
  483. rucio/web/rest/flaskapi/v1/tmp_dids.py +0 -115
  484. rucio-32.8.6.data/data/rucio/requirements.txt +0 -55
  485. rucio-32.8.6.data/scripts/rucio-light-reaper +0 -53
  486. rucio-32.8.6.dist-info/METADATA +0 -83
  487. rucio-32.8.6.dist-info/RECORD +0 -481
  488. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/alembic.ini.template +0 -0
  489. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
  490. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
  491. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
  492. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
  493. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
  494. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
  495. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
  496. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
  497. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
  498. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
  499. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rucio.cfg.template +0 -0
  500. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -0
  501. {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/licenses/LICENSE +0 -0
  502. {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/top_level.txt +0 -0
rucio/core/rse.py CHANGED
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,28 +13,28 @@
14
13
  # limitations under the License.
15
14
 
16
15
  import json
17
- from collections.abc import Iterator, Iterable
16
+ from collections.abc import Iterable, Iterator
18
17
  from datetime import datetime
19
18
  from io import StringIO
20
19
  from re import match
21
- from typing import Any, Generic, Optional, TypeVar, Union, TYPE_CHECKING
20
+ from typing import TYPE_CHECKING, Any, Generic, Optional, TypeVar, Union
22
21
 
23
22
  import sqlalchemy
24
23
  from dogpile.cache.api import NO_VALUE
25
24
  from sqlalchemy.exc import DatabaseError, IntegrityError, OperationalError
26
25
  from sqlalchemy.orm import aliased
27
26
  from sqlalchemy.orm.exc import FlushError
28
- from sqlalchemy.sql.expression import or_, and_, desc, true, false, func, select, delete
27
+ from sqlalchemy.sql.expression import and_, delete, desc, false, func, or_, select, true
29
28
 
30
- from rucio.common import exception, utils
29
+ from rucio.common import exception, types, utils
31
30
  from rucio.common.cache import make_region_memcached
32
31
  from rucio.common.config import get_lfn2pfn_algorithm_default
33
- from rucio.common import types
32
+ from rucio.common.constants import RSE_SUPPORTED_PROTOCOL_OPERATIONS, RseAttr
34
33
  from rucio.common.utils import CHECKSUM_KEY, GLOBALLY_SUPPORTED_CHECKSUMS, Availability
35
34
  from rucio.core.rse_counter import add_counter, get_counter
36
35
  from rucio.db.sqla import models
37
- from rucio.db.sqla.constants import RSEType, ReplicaState
38
- from rucio.db.sqla.session import read_session, transactional_session, stream_session
36
+ from rucio.db.sqla.constants import ReplicaState, RSEType
37
+ from rucio.db.sqla.session import read_session, stream_session, transactional_session
39
38
  from rucio.db.sqla.util import temp_table_mngr
40
39
 
41
40
  if TYPE_CHECKING:
@@ -84,7 +83,7 @@ class RseData:
84
83
  return self._attributes
85
84
 
86
85
  @property
87
- def info(self) -> dict[str, Any]:
86
+ def info(self) -> types.RSESettingsDict:
88
87
  if self._info is None:
89
88
  raise ValueError(f'info not loaded for rse {self}')
90
89
  return self._info
@@ -121,12 +120,12 @@ class RseData:
121
120
  return self.id == other.id
122
121
 
123
122
  def is_tape(self):
124
- if self.info['rse_type'] == RSEType.TAPE or self.info['rse_type'] == 'TAPE':
123
+ if self.info['rse_type'] == RSEType.TAPE or self.info['rse_type'] == 'TAPE' or self.attributes.get(RseAttr.STAGING_REQUIRED, False):
125
124
  return True
126
125
  return False
127
126
 
128
127
  def is_tape_or_staging_required(self):
129
- if self.is_tape() or self.attributes.get('staging_required', False):
128
+ if self.is_tape() or self.attributes.get(RseAttr.STAGING_REQUIRED, False):
130
129
  return True
131
130
  return False
132
131
 
@@ -153,8 +152,18 @@ class RseData:
153
152
 
154
153
  @staticmethod
155
154
  @read_session
156
- def bulk_load(rse_id_to_data: "dict[str, RseData]", load_name=False, load_columns=False, load_attributes=False,
157
- load_info=False, load_usage=False, load_limits=False, *, session: "Session"):
155
+ def bulk_load(
156
+ rse_id_to_data: "dict[str, RseData]",
157
+ load_name: bool = False,
158
+ load_columns: bool = False,
159
+ load_attributes: bool = False,
160
+ load_info: bool = False,
161
+ load_usage: bool = False,
162
+ load_limits: bool = False,
163
+ include_deleted: bool = False,
164
+ *,
165
+ session: "Session"
166
+ ):
158
167
  """
159
168
  Given a dict of RseData objects indexed by rse_id, ensure that the desired fields are initialised
160
169
  in all objects from the input.
@@ -195,16 +204,18 @@ class RseData:
195
204
  # query, but this seems wasteful under normal operation: the caller of the current function probably
196
205
  # got the list of RSE IDs from list_rses (or another source which checks for deleted rses).
197
206
  #
198
- # Instead, directly fetch all RSEs, which allows to reduce the number (and complexity) of other queries bellow
207
+ # Instead, directly fetch all RSEs, which allows to reduce the number (and complexity) of other queries below
199
208
  stmt = select(
200
209
  models.RSE
201
210
  ).join_from(
202
211
  temp_table,
203
212
  models.RSE,
204
213
  models.RSE.id == temp_table.id
205
- ).where(
206
- models.RSE.deleted == false()
207
214
  )
215
+ if not include_deleted:
216
+ stmt = stmt.where(
217
+ models.RSE.deleted == false()
218
+ )
208
219
  db_rses_by_id = {str(db_rse.id): db_rse for db_rse in session.execute(stmt).scalars()}
209
220
 
210
221
  if len(db_rses_by_id) != len(rse_ids_to_load):
@@ -231,11 +242,11 @@ class RseData:
231
242
  if load_info:
232
243
  stmt = select(
233
244
  temp_table.id,
234
- models.RSEProtocols
245
+ models.RSEProtocol
235
246
  ).outerjoin_from(
236
247
  temp_table,
237
- models.RSEProtocols,
238
- models.RSEProtocols.rse_id == temp_table.id
248
+ models.RSEProtocol,
249
+ models.RSEProtocol.rse_id == temp_table.id
239
250
  ).order_by(
240
251
  temp_table.id,
241
252
  )
@@ -330,6 +341,7 @@ class RseCollection(Generic[T]):
330
341
  load_info: bool = False,
331
342
  load_usage: bool = False,
332
343
  load_limits: bool = False,
344
+ include_deleted: bool = False,
333
345
  *,
334
346
  session: "Session",
335
347
  ):
@@ -341,6 +353,7 @@ class RseCollection(Generic[T]):
341
353
  load_info=load_info,
342
354
  load_usage=load_usage,
343
355
  load_limits=load_limits,
356
+ include_deleted=include_deleted,
344
357
  session=session,
345
358
  )
346
359
 
@@ -446,10 +459,8 @@ def rse_exists(rse, vo='def', include_deleted=False, *, session: "Session"):
446
459
  stmt = select(
447
460
  models.RSE
448
461
  ).where(
449
- and_(
450
- models.RSE.rse == rse,
451
- models.RSE.vo == vo
452
- )
462
+ and_(models.RSE.rse == rse,
463
+ models.RSE.vo == vo)
453
464
  )
454
465
  if not include_deleted:
455
466
  stmt = stmt.where(models.RSE.deleted == false())
@@ -469,8 +480,8 @@ def del_rse(rse_id, *, session: "Session"):
469
480
  stmt = select(
470
481
  models.RSE
471
482
  ).where(
472
- models.RSE.id == rse_id,
473
- models.RSE.deleted == false()
483
+ and_(models.RSE.id == rse_id,
484
+ models.RSE.deleted == false())
474
485
  )
475
486
  db_rse = session.execute(stmt).scalar_one()
476
487
  rse_name = db_rse.rse
@@ -498,8 +509,8 @@ def restore_rse(rse_id, *, session: "Session"):
498
509
  stmt = select(
499
510
  models.RSE
500
511
  ).where(
501
- models.RSE.id == rse_id,
502
- models.RSE.deleted == true()
512
+ and_(models.RSE.id == rse_id,
513
+ models.RSE.deleted == true())
503
514
  )
504
515
  db_rse = session.execute(stmt).scalar_one()
505
516
  except sqlalchemy.orm.exc.NoResultFound:
@@ -565,13 +576,14 @@ def get_rse(rse_id, *, session: "Session"):
565
576
  :raises RSENotFound: If referred RSE was not found in the database.
566
577
  """
567
578
 
568
- false_value = False # To make pep8 checker happy ...
569
579
  try:
570
- tmp = session.query(models.RSE).\
571
- filter(sqlalchemy.and_(models.RSE.deleted == false_value,
572
- models.RSE.id == rse_id))\
573
- .one()
574
- return _format_get_rse(tmp, session=session)
580
+ stmt = select(
581
+ models.RSE
582
+ ).where(
583
+ and_(models.RSE.deleted == false(),
584
+ models.RSE.id == rse_id)
585
+ )
586
+ return _format_get_rse(session.execute(stmt).scalar_one(), session=session)
575
587
  except sqlalchemy.orm.exc.NoResultFound:
576
588
  raise exception.RSENotFound('RSE with id \'%s\' cannot be found' % rse_id)
577
589
 
@@ -603,8 +615,8 @@ def get_rse_id(rse, vo='def', include_deleted=True, *, session: "Session"):
603
615
  stmt = select(
604
616
  models.RSE.id
605
617
  ).where(
606
- models.RSE.rse == rse,
607
- models.RSE.vo == vo
618
+ and_(models.RSE.rse == rse,
619
+ models.RSE.vo == vo)
608
620
  )
609
621
  if not include_deleted:
610
622
  stmt = stmt.where(models.RSE.deleted == false())
@@ -687,7 +699,7 @@ def get_rse_vo(rse_id: str, include_deleted: bool = True, *, session: "Session")
687
699
 
688
700
 
689
701
  @read_session
690
- def list_rses(filters={}, *, session: "Session"):
702
+ def list_rses(filters: Optional[dict[str, Any]] = None, *, session: "Session") -> list[dict[str, Any]]:
691
703
  """
692
704
  Returns a list of all RSEs.
693
705
 
@@ -697,7 +709,7 @@ def list_rses(filters={}, *, session: "Session"):
697
709
  :returns: a list of dictionaries.
698
710
  """
699
711
 
700
- rse_list = []
712
+ filters = filters or {}
701
713
  filters = filters.copy() # Make a copy, so we can pop() without affecting the object `filters` outside this function
702
714
 
703
715
  stmt = select(
@@ -726,21 +738,15 @@ def list_rses(filters={}, *, session: "Session"):
726
738
  attr_assoc_alias = aliased(models.RSEAttrAssociation)
727
739
  stmt = stmt.join(
728
740
  attr_assoc_alias,
729
- and_(
730
- attr_assoc_alias.rse_id == models.RSE.id,
731
- attr_assoc_alias.key == k,
732
- attr_assoc_alias.value == v,
733
- )
741
+ and_(attr_assoc_alias.rse_id == models.RSE.id,
742
+ attr_assoc_alias.key == k,
743
+ attr_assoc_alias.value == v)
734
744
  )
735
- else:
736
- stmt = stmt.order_by(
737
- models.RSE.rse
738
- )
739
-
740
- for row in session.execute(stmt).scalars():
741
- rse_list.append(row.to_dict())
745
+ stmt = stmt.order_by(
746
+ models.RSE.rse
747
+ )
742
748
 
743
- return rse_list
749
+ return [row.to_dict() for row in session.execute(stmt).scalars()]
744
750
 
745
751
 
746
752
  @transactional_session
@@ -780,8 +786,8 @@ def del_rse_attribute(rse_id, key, *, session: "Session"):
780
786
  stmt = select(
781
787
  models.RSEAttrAssociation
782
788
  ).where(
783
- models.RSEAttrAssociation.rse_id == rse_id,
784
- models.RSEAttrAssociation.key == key
789
+ and_(models.RSEAttrAssociation.rse_id == rse_id,
790
+ models.RSEAttrAssociation.key == key)
785
791
  )
786
792
  rse_attr = session.execute(stmt).scalar_one()
787
793
  except sqlalchemy.orm.exc.NoResultFound:
@@ -870,8 +876,8 @@ def has_rse_attribute(rse_id, key, *, session: "Session"):
870
876
  stmt = select(
871
877
  models.RSEAttrAssociation.value
872
878
  ).where(
873
- models.RSEAttrAssociation.rse_id == rse_id,
874
- models.RSEAttrAssociation.key == key
879
+ and_(models.RSEAttrAssociation.rse_id == rse_id,
880
+ models.RSEAttrAssociation.key == key)
875
881
  )
876
882
  if session.execute(stmt).scalar():
877
883
  return True
@@ -896,10 +902,8 @@ def get_rses_with_attribute(key, *, session: "Session"):
896
902
  models.RSE.deleted == false()
897
903
  ).join(
898
904
  models.RSEAttrAssociation,
899
- and_(
900
- models.RSEAttrAssociation.rse_id == models.RSE.id,
901
- models.RSEAttrAssociation.key == key
902
- )
905
+ and_(models.RSEAttrAssociation.rse_id == models.RSE.id,
906
+ models.RSEAttrAssociation.key == key)
903
907
  )
904
908
 
905
909
  for db_rse in session.execute(stmt).scalars():
@@ -933,15 +937,13 @@ def get_rses_with_attribute_value(key, value, vo='def', *, session: "Session"):
933
937
  models.RSE.id,
934
938
  models.RSE.rse,
935
939
  ).where(
936
- models.RSE.deleted == false(),
937
- models.RSE.vo == vo
940
+ and_(models.RSE.deleted == false(),
941
+ models.RSE.vo == vo)
938
942
  ).join(
939
943
  models.RSEAttrAssociation,
940
- and_(
941
- models.RSEAttrAssociation.rse_id == models.RSE.id,
942
- models.RSEAttrAssociation.key == key,
943
- models.RSEAttrAssociation.value == value
944
- )
944
+ and_(models.RSEAttrAssociation.rse_id == models.RSE.id,
945
+ models.RSEAttrAssociation.key == key,
946
+ models.RSEAttrAssociation.value == value)
945
947
  )
946
948
 
947
949
  for row in session.execute(stmt):
@@ -979,8 +981,8 @@ def get_rse_attribute(rse_id: str, key: str, use_cache: bool = True, *, session:
979
981
  stmt = select(
980
982
  models.RSEAttrAssociation.value
981
983
  ).where(
982
- models.RSEAttrAssociation.rse_id == rse_id,
983
- models.RSEAttrAssociation.key == key
984
+ and_(models.RSEAttrAssociation.rse_id == rse_id,
985
+ models.RSEAttrAssociation.key == key)
984
986
  )
985
987
  value = session.execute(stmt).scalar_one_or_none()
986
988
 
@@ -1199,10 +1201,8 @@ def get_rse_transfer_limits(rse_id, activity=None, *, session: "Session"):
1199
1201
  )
1200
1202
  if activity:
1201
1203
  stmt = stmt.where(
1202
- or_(
1203
- models.TransferLimit.activity == activity,
1204
- models.TransferLimit.activity == 'all_activities',
1205
- )
1204
+ or_(models.TransferLimit.activity == activity,
1205
+ models.TransferLimit.activity == 'all_activities')
1206
1206
  )
1207
1207
 
1208
1208
  limits = {}
@@ -1255,7 +1255,7 @@ def add_protocol(
1255
1255
  parameter: dict[str, Any],
1256
1256
  *,
1257
1257
  session: "Session"
1258
- ) -> models.RSEProtocols:
1258
+ ) -> models.RSEProtocol:
1259
1259
  """
1260
1260
  Add a protocol to an existing RSE.
1261
1261
 
@@ -1289,7 +1289,7 @@ def add_protocol(
1289
1289
  if domain not in utils.rse_supported_protocol_domains():
1290
1290
  raise exception.RSEProtocolDomainNotSupported(f"The protocol domain '{domain}' is not defined in the schema.")
1291
1291
  for op in parameter['domains'][domain]:
1292
- if op not in utils.rse_supported_protocol_operations():
1292
+ if op not in RSE_SUPPORTED_PROTOCOL_OPERATIONS:
1293
1293
  raise exception.RSEOperationNotSupported(f"Operation '{op}' not defined in schema.")
1294
1294
  op_name = op if op.startswith('third_party_copy') else f'{op}_{domain}'.lower()
1295
1295
  priority = parameter['domains'][domain][op]
@@ -1309,7 +1309,7 @@ def add_protocol(
1309
1309
  raise exception.InvalidObject('Missing values! For SRM, extended_attributes and web_service_path must be specified')
1310
1310
 
1311
1311
  try:
1312
- new_protocol = models.RSEProtocols()
1312
+ new_protocol = models.RSEProtocol()
1313
1313
  new_protocol.update(parameter)
1314
1314
  new_protocol.save(session=session)
1315
1315
  except (IntegrityError, FlushError, OperationalError) as error:
@@ -1351,14 +1351,14 @@ def get_rse_protocols(rse_id, schemes=None, *, session: "Session") -> types.RSES
1351
1351
  if not _rse:
1352
1352
  raise exception.RSENotFound('RSE with id \'%s\' not found' % rse_id)
1353
1353
 
1354
- terms = [models.RSEProtocols.rse_id == rse_id]
1354
+ terms = [models.RSEProtocol.rse_id == rse_id]
1355
1355
  if schemes:
1356
1356
  if not type(schemes) is list:
1357
1357
  schemes = [schemes]
1358
- terms.extend([models.RSEProtocols.scheme.in_(schemes)])
1358
+ terms.extend([models.RSEProtocol.scheme.in_(schemes)])
1359
1359
 
1360
1360
  stmt = select(
1361
- models.RSEProtocols
1361
+ models.RSEProtocol
1362
1362
  ).where(
1363
1363
  *terms
1364
1364
  )
@@ -1369,16 +1369,16 @@ def get_rse_protocols(rse_id, schemes=None, *, session: "Session") -> types.RSES
1369
1369
 
1370
1370
  def _format_get_rse_protocols(
1371
1371
  rse: "models.RSE | dict[str, Any]",
1372
- db_protocols: Iterable[models.RSEProtocols],
1372
+ db_protocols: Iterable[models.RSEProtocol],
1373
1373
  rse_attributes: Optional[dict[str, Any]] = None,
1374
1374
  *,
1375
1375
  session: "Session"
1376
1376
  ) -> types.RSESettingsDict:
1377
1377
  _rse = rse
1378
1378
  if rse_attributes:
1379
- lfn2pfn_algorithm = rse_attributes.get('lfn2pfn_algorithm')
1379
+ lfn2pfn_algorithm = rse_attributes.get(RseAttr.LFN2PFN_ALGORITHM)
1380
1380
  else:
1381
- lfn2pfn_algorithm = get_rse_attribute(_rse['id'], 'lfn2pfn_algorithm', session=session)
1381
+ lfn2pfn_algorithm = get_rse_attribute(_rse['id'], RseAttr.LFN2PFN_ALGORITHM, session=session)
1382
1382
  # Resolve LFN2PFN default algorithm as soon as possible. This way, we can send back the actual
1383
1383
  # algorithm name in response to REST queries.
1384
1384
  if not lfn2pfn_algorithm:
@@ -1386,15 +1386,15 @@ def _format_get_rse_protocols(
1386
1386
 
1387
1387
  # Copy verify_checksum from the attributes, later: assume True if not specified
1388
1388
  if rse_attributes:
1389
- verify_checksum = rse_attributes.get('verify_checksum')
1389
+ verify_checksum = rse_attributes.get(RseAttr.VERIFY_CHECKSUM)
1390
1390
  else:
1391
- verify_checksum = get_rse_attribute(_rse['id'], 'verify_checksum', session=session)
1391
+ verify_checksum = get_rse_attribute(_rse['id'], RseAttr.VERIFY_CHECKSUM, session=session)
1392
1392
 
1393
1393
  # Copy sign_url from the attributes
1394
1394
  if rse_attributes:
1395
- sign_url = rse_attributes.get('sign_url')
1395
+ sign_url = rse_attributes.get(RseAttr.SIGN_URL)
1396
1396
  else:
1397
- sign_url = get_rse_attribute(_rse['id'], 'sign_url', session=session)
1397
+ sign_url = get_rse_attribute(_rse['id'], RseAttr.SIGN_URL, session=session)
1398
1398
 
1399
1399
  info = {'availability_delete': _rse['availability_delete'],
1400
1400
  'availability_read': _rse['availability_read'],
@@ -1413,7 +1413,7 @@ def _format_get_rse_protocols(
1413
1413
  'verify_checksum': verify_checksum if verify_checksum is not None else True,
1414
1414
  'volatile': _rse['volatile']}
1415
1415
 
1416
- for op in utils.rse_supported_protocol_operations():
1416
+ for op in RSE_SUPPORTED_PROTOCOL_OPERATIONS:
1417
1417
  info['%s_protocol' % op] = 1 # 1 indicates the default protocol
1418
1418
 
1419
1419
  for row in db_protocols:
@@ -1500,7 +1500,7 @@ def update_protocols(
1500
1500
  if domain not in utils.rse_supported_protocol_domains():
1501
1501
  raise exception.RSEProtocolDomainNotSupported(f"The protocol domain '{domain}' is not defined in the schema.")
1502
1502
  for op in data['domains'][domain]:
1503
- if op not in utils.rse_supported_protocol_operations():
1503
+ if op not in RSE_SUPPORTED_PROTOCOL_OPERATIONS:
1504
1504
  raise exception.RSEOperationNotSupported(f"Operation '{op}' not defined in schema.")
1505
1505
  op_name = op if op.startswith('third_party_copy') else f'{op}_{domain}'.lower()
1506
1506
  priority = data['domains'][domain][op]
@@ -1520,14 +1520,14 @@ def update_protocols(
1520
1520
  except exception.RSENotFound:
1521
1521
  raise exception.RSENotFound('RSE with id \'%s\' not found' % rse_id)
1522
1522
 
1523
- terms = [models.RSEProtocols.rse_id == rse_id,
1524
- models.RSEProtocols.scheme == scheme,
1525
- models.RSEProtocols.hostname == hostname,
1526
- models.RSEProtocols.port == port]
1523
+ terms = [models.RSEProtocol.rse_id == rse_id,
1524
+ models.RSEProtocol.scheme == scheme,
1525
+ models.RSEProtocol.hostname == hostname,
1526
+ models.RSEProtocol.port == port]
1527
1527
 
1528
1528
  try:
1529
1529
  stmt = select(
1530
- models.RSEProtocols
1530
+ models.RSEProtocol
1531
1531
  ).where(
1532
1532
  *terms
1533
1533
  )
@@ -1575,13 +1575,13 @@ def del_protocols(
1575
1575
  rse_name = get_rse_name(rse_id=rse_id, session=session, include_deleted=False)
1576
1576
  except exception.RSENotFound:
1577
1577
  raise exception.RSENotFound('RSE \'%s\' not found' % rse_id)
1578
- terms = [models.RSEProtocols.rse_id == rse_id, models.RSEProtocols.scheme == scheme]
1578
+ terms = [models.RSEProtocol.rse_id == rse_id, models.RSEProtocol.scheme == scheme]
1579
1579
  if hostname is not None:
1580
- terms.append(models.RSEProtocols.hostname == hostname)
1580
+ terms.append(models.RSEProtocol.hostname == hostname)
1581
1581
  if port is not None:
1582
- terms.append(models.RSEProtocols.port == port)
1582
+ terms.append(models.RSEProtocol.port == port)
1583
1583
  stmt = select(
1584
- models.RSEProtocols
1584
+ models.RSEProtocol
1585
1585
  ).where(
1586
1586
  *terms
1587
1587
  )
@@ -1771,8 +1771,8 @@ def delete_qos_policy(rse_id, qos_policy, *, session: "Session"):
1771
1771
  stmt = delete(
1772
1772
  models.RSEQoSAssociation
1773
1773
  ).where(
1774
- models.RSEQoSAssociation.rse_id == rse_id,
1775
- models.RSEQoSAssociation.qos_policy == qos_policy
1774
+ and_(models.RSEQoSAssociation.rse_id == rse_id,
1775
+ models.RSEQoSAssociation.qos_policy == qos_policy)
1776
1776
  )
1777
1777
  session.execute(stmt)
1778
1778
  except DatabaseError as error:
@@ -1820,12 +1820,14 @@ def fill_rse_expired(rse_id, *, session: "Session"):
1820
1820
  func.sum(models.RSEFileAssociation.bytes).label("bytes"),
1821
1821
  func.count().label("length")
1822
1822
  ).with_hint(
1823
- models.RSEFileAssociation, "INDEX(REPLICAS REPLICAS_RSE_ID_TOMBSTONE_IDX)", 'oracle'
1823
+ models.RSEFileAssociation,
1824
+ 'INDEX(REPLICAS REPLICAS_RSE_ID_TOMBSTONE_IDX)',
1825
+ 'oracle'
1824
1826
  ).where(
1825
- models.RSEFileAssociation.tombstone < datetime.utcnow(),
1826
- models.RSEFileAssociation.lock_cnt == 0,
1827
- models.RSEFileAssociation.rse_id == rse_id,
1828
- models.RSEFileAssociation.state.in_((ReplicaState.AVAILABLE, ReplicaState.UNAVAILABLE, ReplicaState.BAD))
1827
+ and_(models.RSEFileAssociation.tombstone < datetime.utcnow(),
1828
+ models.RSEFileAssociation.lock_cnt == 0,
1829
+ models.RSEFileAssociation.rse_id == rse_id,
1830
+ models.RSEFileAssociation.state.in_((ReplicaState.AVAILABLE, ReplicaState.UNAVAILABLE, ReplicaState.BAD)))
1829
1831
  )
1830
1832
 
1831
1833
  sum_bytes, sum_files = session.execute(stmt).one()
@@ -1833,3 +1835,41 @@ def fill_rse_expired(rse_id, *, session: "Session"):
1833
1835
  used=sum_bytes,
1834
1836
  files=sum_files,
1835
1837
  source='expired').save(session=session)
1838
+
1839
+
1840
+ def determine_audience_for_rse(rse_id: str) -> str:
1841
+ """Construct the Audience claim for an RSE."""
1842
+ rse_protocols = get_rse_protocols(rse_id)
1843
+ # FIXME: At the time of writing, there does not appear to be a common
1844
+ # agreement on how sites will configure their storages. Rucio had requested
1845
+ # that the protocol hostname be sufficient, but this may not come to pass.
1846
+ filtered_hostnames = {p['hostname']
1847
+ for p in rse_protocols['protocols']
1848
+ if p['scheme'] == 'davs'}
1849
+ return ' '.join(sorted(filtered_hostnames))
1850
+
1851
+
1852
+ def determine_scope_for_rse(
1853
+ rse_id: str,
1854
+ scopes: Iterable[str],
1855
+ extra_scopes: Optional[Iterable[str]] = None,
1856
+ ) -> str:
1857
+ """Construct the Scope claim for an RSE."""
1858
+ if extra_scopes is None:
1859
+ extra_scopes = []
1860
+ rse_protocols = get_rse_protocols(rse_id)
1861
+ filtered_prefixes = set()
1862
+ for protocol in rse_protocols['protocols']:
1863
+ # Token support is exclusive to WebDAV.
1864
+ if protocol['scheme'] != 'davs':
1865
+ continue
1866
+ # Remove base path from prefix. Storages typically map an issuer (i.e.
1867
+ # a VO) to a particular area. If so, then the path to that area acts as
1868
+ # a base which should be removed from the prefix (in order for '/' to
1869
+ # mean the entire resource associated with that issuer).
1870
+ prefix = protocol['prefix']
1871
+ if base_path := get_rse_attribute(rse_id, RseAttr.OIDC_BASE_PATH):
1872
+ prefix = prefix.removeprefix(base_path)
1873
+ filtered_prefixes.add(prefix)
1874
+ all_scopes = [f'{s}:{p}' for s in scopes for p in filtered_prefixes] + list(extra_scopes)
1875
+ return ' '.join(sorted(all_scopes))
rucio/core/rse_counter.py CHANGED
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,10 +13,11 @@
14
13
  # limitations under the License.
15
14
  from typing import TYPE_CHECKING
16
15
 
17
- from sqlalchemy.orm.exc import NoResultFound
16
+ from sqlalchemy import and_, delete, select
17
+ from sqlalchemy.exc import NoResultFound
18
18
 
19
19
  from rucio.common.exception import CounterNotFound
20
- from rucio.db.sqla import models, filter_thread_work
20
+ from rucio.db.sqla import filter_thread_work, models
21
21
  from rucio.db.sqla.session import read_session, transactional_session
22
22
 
23
23
  if TYPE_CHECKING:
@@ -72,8 +72,15 @@ def del_counter(rse_id, *, session: "Session"):
72
72
  :param session: The database session in use.
73
73
  """
74
74
 
75
- session.query(models.RSEUsage).filter_by(rse_id=rse_id, source='rucio').\
76
- delete(synchronize_session=False)
75
+ stmt = delete(
76
+ models.RSEUsage
77
+ ).where(
78
+ and_(models.RSEUsage.rse_id == rse_id,
79
+ models.RSEUsage.source == 'rucio')
80
+ ).execution_options(
81
+ synchronize_session=False
82
+ )
83
+ session.execute(stmt)
77
84
 
78
85
 
79
86
  @read_session
@@ -89,11 +96,20 @@ def get_counter(rse_id, *, session: "Session"):
89
96
  """
90
97
 
91
98
  try:
92
- counter = session.query(models.RSEUsage).\
93
- filter_by(rse_id=rse_id, source='rucio').one()
94
- return {'bytes': counter.used,
95
- 'files': counter.files,
96
- 'updated_at': counter.updated_at}
99
+ stmt = select(
100
+ models.RSEUsage.used,
101
+ models.RSEUsage.files,
102
+ models.RSEUsage.updated_at
103
+ ).where(
104
+ and_(models.RSEUsage.rse_id == rse_id,
105
+ models.RSEUsage.source == 'rucio')
106
+ )
107
+ usage_bytes, usage_files, usage_updated_at = session.execute(stmt).one()
108
+ return {
109
+ 'bytes': usage_bytes,
110
+ 'files': usage_files,
111
+ 'updated_at': usage_updated_at
112
+ }
97
113
  except NoResultFound:
98
114
  raise CounterNotFound()
99
115
 
@@ -108,12 +124,13 @@ def get_updated_rse_counters(total_workers, worker_number, *, session: "Session"
108
124
  :param session: Database session in use.
109
125
  :returns: List of rse_ids whose rse_counters need to be updated.
110
126
  """
111
- query = session.query(models.UpdatedRSECounter.rse_id).\
112
- distinct(models.UpdatedRSECounter.rse_id)
127
+ stmt = select(
128
+ models.UpdatedRSECounter.rse_id
129
+ ).distinct(
130
+ )
113
131
 
114
- query = filter_thread_work(session=session, query=query, total_threads=total_workers, thread_id=worker_number, hash_variable='rse_id')
115
- results = query.all()
116
- return [result.rse_id for result in results]
132
+ stmt = filter_thread_work(session=session, query=stmt, total_threads=total_workers, thread_id=worker_number, hash_variable='rse_id')
133
+ return session.execute(stmt).scalars().all()
117
134
 
118
135
 
119
136
  @transactional_session
@@ -125,12 +142,23 @@ def update_rse_counter(rse_id, *, session: "Session"):
125
142
  :param session: Database session in use.
126
143
  """
127
144
 
128
- updated_rse_counters = session.query(models.UpdatedRSECounter).filter_by(rse_id=rse_id).all()
145
+ stmt = select(
146
+ models.UpdatedRSECounter
147
+ ).where(
148
+ models.UpdatedRSECounter.rse_id == rse_id
149
+ )
150
+ updated_rse_counters = session.execute(stmt).scalars().all()
129
151
  sum_bytes = sum([updated_rse_counter.bytes for updated_rse_counter in updated_rse_counters])
130
152
  sum_files = sum([updated_rse_counter.files for updated_rse_counter in updated_rse_counters])
131
153
 
132
154
  try:
133
- rse_counter = session.query(models.RSEUsage).filter_by(rse_id=rse_id, source='rucio').one()
155
+ stmt = select(
156
+ models.RSEUsage
157
+ ).where(
158
+ and_(models.RSEUsage.rse_id == rse_id,
159
+ models.RSEUsage.source == 'rucio')
160
+ )
161
+ rse_counter = session.execute(stmt).scalar_one()
134
162
  rse_counter.used = (rse_counter.used or 0) + sum_bytes
135
163
  rse_counter.files = (rse_counter.files or 0) + sum_files
136
164
  except NoResultFound:
@@ -151,5 +179,8 @@ def fill_rse_counter_history_table(*, session: "Session"):
151
179
  :param session: Database session in use.
152
180
  """
153
181
  RSEUsageHistory = models.RSEUsageHistory
154
- for usage in session.query(models.RSEUsage).all():
182
+ stmt = select(
183
+ models.RSEUsage
184
+ )
185
+ for usage in session.execute(stmt).scalars().all():
155
186
  RSEUsageHistory(rse_id=usage['rse_id'], used=usage['used'], files=usage['files'], source=usage['source']).save(session=session)