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/message.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");
@@ -16,11 +15,11 @@
16
15
  import json
17
16
  from typing import TYPE_CHECKING
18
17
 
19
- from sqlalchemy import or_, delete, update, insert
18
+ from sqlalchemy import delete, insert, or_, select, update
20
19
  from sqlalchemy.exc import IntegrityError
21
20
 
22
21
  from rucio.common.config import config_get_list
23
- from rucio.common.constants import HermesService, MAX_MESSAGE_LENGTH
22
+ from rucio.common.constants import MAX_MESSAGE_LENGTH, HermesService
24
23
  from rucio.common.exception import InvalidObject, RucioException
25
24
  from rucio.common.utils import APIEncoder, chunks
26
25
  from rucio.db.sqla import filter_thread_work
@@ -29,6 +28,7 @@ from rucio.db.sqla.session import transactional_session
29
28
 
30
29
  if TYPE_CHECKING:
31
30
  from typing import Any, Optional
31
+
32
32
  from sqlalchemy.orm import Session
33
33
 
34
34
  MessageType = dict[str, Any]
@@ -74,7 +74,10 @@ def add_messages(messages: "MessagesListType", *, session: "Session") -> None:
74
74
  except TypeError as err: # noqa: F841
75
75
  raise InvalidObject(f'Invalid JSON for payload: {err}')
76
76
  for messages_chunk in chunks(msgs, 1000):
77
- session.execute(insert(Message), messages_chunk)
77
+ stmt = insert(
78
+ Message
79
+ )
80
+ session.execute(stmt, messages_chunk)
78
81
 
79
82
 
80
83
  @transactional_session
@@ -114,45 +117,58 @@ def retrieve_messages(bulk: int = 1000,
114
117
  """
115
118
  messages = []
116
119
  try:
117
- subquery = session.query(Message.id)
118
- subquery = filter_thread_work(session=session, query=subquery, total_threads=total_threads, thread_id=thread)
120
+ stmt_subquery = select(
121
+ Message.id
122
+ ).order_by(
123
+ Message.created_at
124
+ )
125
+ stmt_subquery = filter_thread_work(session=session, query=stmt_subquery, total_threads=total_threads, thread_id=thread)
119
126
  if event_type:
120
- subquery = subquery.filter_by(event_type=event_type)
127
+ stmt_subquery = stmt_subquery.where(
128
+ Message.event_type == event_type
129
+ )
121
130
  elif old_mode:
122
- subquery = subquery.filter(Message.event_type != 'email')
131
+ stmt_subquery = stmt_subquery.where(
132
+ Message.event_type != 'email'
133
+ )
123
134
 
124
135
  # Step 1:
125
136
  # MySQL does not support limits in nested queries, limit on the outer query instead.
126
137
  # This is not as performant, but the best we can get from MySQL.
127
138
  # FIXME: SQLAlchemy generates wrong nowait MySQL8 statement for MySQL5
128
139
  # Remove once this is resolved in SQLAlchemy
140
+ stmt = select(
141
+ Message.id,
142
+ Message.created_at,
143
+ Message.event_type,
144
+ Message.payload,
145
+ Message.services
146
+ )
129
147
  if session.bind.dialect.name == 'mysql':
130
- subquery = subquery.order_by(Message.created_at)
131
- query = session.query(Message.id,
132
- Message.created_at,
133
- Message.event_type,
134
- Message.payload,
135
- Message.services)\
136
- .filter(Message.id.in_(subquery))
148
+ stmt = stmt.where(
149
+ Message.id.in_(stmt_subquery)
150
+ )
137
151
  else:
138
- subquery = subquery.order_by(Message.created_at).limit(bulk)
139
- query = session.query(Message.id,
140
- Message.created_at,
141
- Message.event_type,
142
- Message.payload,
143
- Message.services)\
144
- .filter(Message.id.in_(subquery))\
145
- .with_for_update(nowait=True)
152
+ stmt_subquery = stmt_subquery.limit(
153
+ bulk
154
+ )
155
+ stmt = stmt.where(
156
+ Message.id.in_(stmt_subquery)
157
+ ).with_for_update(
158
+ nowait=True
159
+ )
146
160
 
147
161
  # Step 2:
148
162
  # MySQL does not support limits in nested queries, limit on the outer query instead.
149
163
  # This is not as performant, but the best we can get from MySQL.
150
164
  if session.bind.dialect.name == 'mysql':
151
- query = query.limit(bulk)
165
+ stmt = stmt.limit(
166
+ bulk
167
+ )
152
168
 
153
169
  # Step 3:
154
170
  # Assemble message object
155
- for id_, created_at, event_type, payload, services in query:
171
+ for id_, created_at, event_type, payload, services in session.execute(stmt).all():
156
172
  message = {'id': id_,
157
173
  'created_at': created_at,
158
174
  'event_type': event_type,
@@ -160,8 +176,12 @@ def retrieve_messages(bulk: int = 1000,
160
176
 
161
177
  # Only switch SQL context when necessary
162
178
  if payload == 'nolimit':
163
- nolimit_query = session.query(Message.payload_nolimit).filter(Message.id == id_).one()[0]
164
- message['payload'] = json.loads(str(nolimit_query))
179
+ nolimit_stmt = select(
180
+ Message.payload_nolimit
181
+ ).where(
182
+ Message.id == id_
183
+ )
184
+ message['payload'] = json.loads(str(session.execute(nolimit_stmt).scalar_one()))
165
185
  else:
166
186
  message['payload'] = json.loads(str(payload))
167
187
 
@@ -188,13 +208,22 @@ def delete_messages(messages: "MessagesListType", *, session: "Session") -> None
188
208
 
189
209
  try:
190
210
  if message_condition:
191
- stmt = delete(Message).\
192
- prefix_with("/*+ index(messages MESSAGES_ID_PK) */", dialect='oracle').\
193
- where(or_(*message_condition)).\
194
- execution_options(synchronize_session=False)
211
+ stmt = delete(
212
+ Message
213
+ ).prefix_with(
214
+ '/*+ INDEX(messages MESSAGES_ID_PK) */',
215
+ dialect='oracle'
216
+ ).where(
217
+ or_(*message_condition)
218
+ ).execution_options(
219
+ synchronize_session=False
220
+ )
195
221
  session.execute(stmt)
196
222
 
197
- session.execute(insert(MessageHistory), messages)
223
+ stmt = insert(
224
+ MessageHistory
225
+ )
226
+ session.execute(stmt, messages)
198
227
  except IntegrityError as e:
199
228
  raise RucioException(e.args)
200
229
 
@@ -208,7 +237,12 @@ def truncate_messages(*, session: "Session") -> None:
208
237
  """
209
238
 
210
239
  try:
211
- session.query(Message).delete(synchronize_session=False)
240
+ stmt = delete(
241
+ Message
242
+ ).execution_options(
243
+ synchronize_session=False
244
+ )
245
+ session.execute(stmt)
212
246
  except IntegrityError as e:
213
247
  raise RucioException(e.args)
214
248
 
@@ -230,11 +264,18 @@ def update_messages_services(messages: "MessagesListType", services: str, *, ses
230
264
 
231
265
  try:
232
266
  if message_condition:
233
- stmt = update(Message).\
234
- prefix_with("/*+ index(messages MESSAGES_ID_PK) */", dialect='oracle').\
235
- where(or_(*message_condition)).\
236
- execution_options(synchronize_session=False).\
237
- values(services=services)
267
+ stmt = update(
268
+ Message
269
+ ).prefix_with(
270
+ '/*+ INDEX(messages MESSAGES_ID_PK) */',
271
+ dialect='oracle'
272
+ ).where(
273
+ or_(*message_condition)
274
+ ).execution_options(
275
+ synchronize_session=False
276
+ ).values({
277
+ Message.services: services
278
+ })
238
279
  session.execute(stmt)
239
280
 
240
281
  except IntegrityError as err:
@@ -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,15 +13,13 @@
14
13
  # limitations under the License.
15
14
 
16
15
  from re import match
17
- from typing import TYPE_CHECKING
16
+ from typing import TYPE_CHECKING, Optional, Union
18
17
 
19
- from sqlalchemy.exc import IntegrityError
20
- from sqlalchemy.orm.exc import NoResultFound
18
+ from sqlalchemy import and_, delete, select
19
+ from sqlalchemy.exc import IntegrityError, NoResultFound
21
20
 
22
21
  from rucio.common.constraints import AUTHORIZED_VALUE_TYPES
23
- from rucio.common.exception import (Duplicate, RucioException,
24
- KeyNotFound, InvalidValueForKey, UnsupportedValueType,
25
- InvalidObject, UnsupportedKeyType)
22
+ from rucio.common.exception import Duplicate, InvalidObject, InvalidValueForKey, KeyNotFound, RucioException, UnsupportedKeyType, UnsupportedValueType
26
23
  from rucio.db.sqla import models
27
24
  from rucio.db.sqla.constants import DIDType, KeyType
28
25
  from rucio.db.sqla.session import read_session, transactional_session
@@ -32,9 +29,9 @@ if TYPE_CHECKING:
32
29
 
33
30
 
34
31
  @transactional_session
35
- def add_key(key, key_type, value_type=None, value_regexp=None, *, session: "Session"):
32
+ def add_key(key: str, key_type: Union[KeyType, str], value_type: Optional[str] = None, value_regexp: Optional[str] = None, *, session: "Session") -> None:
36
33
  """
37
- Adds a new allowed key.
34
+ Add an allowed key for DID metadata (update the DID Metadata Conventions table with a new key).
38
35
 
39
36
  :param key: the name for the new key.
40
37
  :param key_type: the type of the key: all(container, dataset, file), collection(dataset or container), file, derived(compute from file for collection).
@@ -65,7 +62,7 @@ def add_key(key, key_type, value_type=None, value_regexp=None, *, session: "Sess
65
62
  except ValueError:
66
63
  raise UnsupportedKeyType('The type \'%s\' is not supported for keys!' % str(key_type))
67
64
 
68
- new_key = models.DIDKey(key=key, value_type=value_type and str(value_type), value_regexp=value_regexp, key_type=key_type)
65
+ new_key = models.DIDMetaConventionsKey(key=key, value_type=value_type and str(value_type), value_regexp=value_regexp, key_type=key_type)
69
66
  try:
70
67
  new_key.save(session=session)
71
68
  except IntegrityError as error:
@@ -77,46 +74,54 @@ def add_key(key, key_type, value_type=None, value_regexp=None, *, session: "Sess
77
74
  or match('.*UniqueViolation.*duplicate key value violates unique constraint.*', error.args[0]) \
78
75
  or match('.*IntegrityError.*columns? key.*not unique.*', error.args[0]):
79
76
  raise Duplicate(f"key '{key}' already exists!")
80
- raise
77
+ raise RucioException(error.args)
81
78
 
82
79
 
83
80
  @transactional_session
84
- def del_key(key, *, session: "Session"):
81
+ def del_key(key: str, *, session: "Session") -> None:
85
82
  """
86
- Deletes a key.
83
+ Delete a key in the DID Metadata Conventions table.
87
84
 
88
85
  :param key: the name for the key.
89
86
  :param session: The database session in use.
90
87
  """
91
- session.query(models.DIDKey).filter(key == key).delete()
88
+ stmt = delete(
89
+ models.DIDMetaConventionsKey
90
+ ).where(
91
+ models.DIDMetaConventionsKey.key == key
92
+ )
93
+ session.execute(stmt)
92
94
 
93
95
 
94
96
  @read_session
95
- def list_keys(*, session: "Session"):
97
+ def list_keys(*, session: "Session") -> list[str]:
96
98
  """
97
- Lists all keys.
99
+ Lists all keys for DID Metadata Conventions.
98
100
 
99
101
  :param session: The database session in use.
100
102
 
101
103
  :returns: A list containing all keys.
102
104
  """
103
- key_list = []
104
- query = session.query(models.DIDKey)
105
- for row in query:
106
- key_list.append(row.key)
107
- return key_list
105
+ stmt = select(
106
+ models.DIDMetaConventionsKey.key
107
+ )
108
+ return list(session.execute(stmt).scalars().all())
108
109
 
109
110
 
110
111
  @transactional_session
111
- def add_value(key, value, *, session: "Session"):
112
+ def add_value(key: str, value: str, *, session: "Session") -> None:
112
113
  """
113
- Adds a new value to a key.
114
+ Adds a new value for a key in DID Metadata Convention.
114
115
 
115
116
  :param key: the name for the key.
116
117
  :param value: the value.
117
118
  :param session: The database session in use.
119
+
120
+ :raises Duplicate: Key-Value pair exists
121
+ :raises KeyNotFound: Key not in metadata conventions table
122
+ :raises InvalidValueForKey: Value conflicts with rse expression for key values or does not have the correct type
118
123
  """
119
- new_value = models.DIDKeyValueAssociation(key=key, value=value)
124
+ new_value = models.DIDMetaConventionsConstraint(key=key, value=value)
120
125
  try:
121
126
  new_value.save(session=session)
122
127
  except IntegrityError as error:
@@ -137,37 +142,43 @@ def add_value(key, value, *, session: "Session"):
137
142
 
138
143
  raise RucioException(error.args)
139
144
 
140
- k = session.query(models.DIDKey).filter_by(key=key).one()
145
+ statement = select(
146
+ models.DIDMetaConventionsKey,
147
+ ).where(
148
+ models.DIDMetaConventionsKey.key == key
149
+ )
150
+ query = session.execute(statement).scalar_one()
141
151
 
142
152
  # Check value against regexp, if defined
143
- if k.value_regexp and not match(k.value_regexp, value):
144
- raise InvalidValueForKey("The value '%s' for the key '%s' does not match the regular expression '%s'" % (value, key, k.value_regexp))
153
+ if query.value_regexp and not match(query.value_regexp, value):
154
+ raise InvalidValueForKey(f"The value {value} for the key {key} does not match the regular expression {query.value_regexp}")
145
155
 
146
156
  # Check value type, if defined
147
157
  type_map = dict([(str(t), t) for t in AUTHORIZED_VALUE_TYPES])
148
- if k.value_type and not isinstance(value, type_map.get(k.value_type)):
149
- raise InvalidValueForKey("The value '%s' for the key '%s' does not match the required type '%s'" % (value, key, k.value_type))
158
+ if query.value_type and not isinstance(value, type_map.get(query.value_type)): # type: ignore ; Typing error caused by 'isinstaince' not thinking types count as classes
159
+ raise InvalidValueForKey(f"The value {value} for the key {key} does not match the required type {query.value_type}")
150
160
 
151
161
 
152
162
  @read_session
153
- def list_values(key, *, session: "Session"):
163
+ def list_values(key: str, *, session: "Session") -> list[str]:
154
164
  """
155
- Lists all values for a key.
165
+ Lists all allowed values for a DID key (all values for a key in DID Metadata Conventions).
156
166
 
157
167
  :param key: the name for the key.
158
168
  :param session: The database session in use.
159
169
 
160
170
  :returns: A list containing all values.
161
171
  """
162
- value_list = []
163
- query = session.query(models.DIDKeyValueAssociation).filter_by(key=key)
164
- for row in query:
165
- value_list.append(row.value)
166
- return value_list
172
+ statement = select(
173
+ models.DIDMetaConventionsConstraint.value
174
+ ).where(
175
+ models.DIDMetaConventionsConstraint.key == key
176
+ )
177
+ return list(session.execute(statement).scalars().all())
167
178
 
168
179
 
169
180
  @read_session
170
- def validate_meta(meta, did_type, *, session: "Session"):
181
+ def validate_meta(meta: dict, did_type: DIDType, *, session: "Session") -> None:
171
182
  """
172
183
  Validates metadata for a did.
173
184
 
@@ -175,16 +186,18 @@ def validate_meta(meta, did_type, *, session: "Session"):
175
186
  :param meta: the type of the did, e.g, DATASET, CONTAINER, FILE.
176
187
  :param session: The database session in use.
177
188
 
178
- :returns: True
189
+ :raises InvalidObject:
179
190
  """
180
191
  # For now only validate the datatype for datasets
181
192
  key = 'datatype'
182
193
  if did_type == DIDType.DATASET and key in meta:
183
194
  try:
184
- session.query(models.DIDKeyValueAssociation.value).\
185
- filter_by(key=key).\
186
- filter_by(value=meta[key]).\
187
- one()
195
+ statement = select(
196
+ models.DIDMetaConventionsConstraint.value
197
+ ).where(
198
+ and_(models.DIDMetaConventionsConstraint.value == meta[key],
199
+ models.DIDMetaConventionsConstraint.key == key)
200
+ )
201
+ session.execute(statement).one()
188
202
  except NoResultFound:
189
- print("The value '%s' for the key '%s' is not valid" % (meta[key], key))
190
- raise InvalidObject("The value '%s' for the key '%s' is not valid" % (meta[key], key))
203
+ raise InvalidObject(f"The value {meta[key]}' for the key {key} is not valid")
rucio/core/monitor.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");
@@ -17,7 +16,6 @@
17
16
  Graphite and prometheus metrics
18
17
  """
19
18
 
20
- import __main__ as main
21
19
  import atexit
22
20
  import logging
23
21
  import os
@@ -28,23 +26,26 @@ from datetime import datetime, timedelta
28
26
  from functools import wraps
29
27
  from pathlib import Path
30
28
  from threading import Lock
31
- from typing import Any, Optional, TypeVar, Union
29
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
32
30
 
33
- from prometheus_client import (Counter, Gauge, Histogram, REGISTRY, CollectorRegistry, generate_latest, multiprocess,
34
- push_to_gateway, start_http_server, values)
31
+ from prometheus_client import REGISTRY, CollectorRegistry, Counter, Gauge, Histogram, generate_latest, multiprocess, push_to_gateway, start_http_server, values
35
32
  from statsd import StatsClient
36
33
 
34
+ import __main__ as main
37
35
  from rucio.common.config import config_get, config_get_bool, config_get_int
38
36
  from rucio.common.stopwatch import Stopwatch
39
37
  from rucio.common.utils import retrying
40
38
 
39
+ if TYPE_CHECKING:
40
+ from rucio.common.types import LoggerFunction
41
+
41
42
  _T = TypeVar('_T')
42
43
  _M = TypeVar('_M', bound="_MultiMetric")
43
44
 
44
45
  PROMETHEUS_MULTIPROC_DIR = os.environ.get('PROMETHEUS_MULTIPROC_DIR', os.environ.get('prometheus_multiproc_dir', None))
45
46
 
46
47
 
47
- def cleanup_prometheus_files_at_exit():
48
+ def cleanup_prometheus_files_at_exit() -> None:
48
49
  if PROMETHEUS_MULTIPROC_DIR:
49
50
  multiprocess.mark_process_dead(os.getpid())
50
51
 
@@ -101,7 +102,12 @@ METRICS_LOCK = Lock()
101
102
  _HISTOGRAM_DEFAULT_BUCKETS = Histogram.DEFAULT_BUCKETS
102
103
 
103
104
 
104
- def _cleanup_old_prometheus_files(path, file_pattern, cleanup_delay, logger):
105
+ def _cleanup_old_prometheus_files(
106
+ path: str,
107
+ file_pattern: str,
108
+ cleanup_delay: float,
109
+ logger: "LoggerFunction"
110
+ ) -> None:
105
111
  """cleanup behind processes which didn't finish gracefully."""
106
112
 
107
113
  oldest_accepted_mtime = datetime.now() - timedelta(seconds=cleanup_delay)
@@ -120,7 +126,7 @@ def _cleanup_old_prometheus_files(path, file_pattern, cleanup_delay, logger):
120
126
  pass
121
127
 
122
128
 
123
- def cleanup_old_prometheus_files(logger=logging.log):
129
+ def cleanup_old_prometheus_files(logger: "LoggerFunction" = logging.log) -> None:
124
130
  path = PROMETHEUS_MULTIPROC_DIR
125
131
  if path:
126
132
  _cleanup_old_prometheus_files(path, file_pattern='gauge_live*.db', cleanup_delay=timedelta(hours=1).total_seconds(), logger=logger)
@@ -130,7 +136,7 @@ def cleanup_old_prometheus_files(logger=logging.log):
130
136
  @retrying(retry_on_exception=lambda _: True,
131
137
  wait_fixed=500,
132
138
  stop_max_attempt_number=2)
133
- def generate_prometheus_metrics():
139
+ def generate_prometheus_metrics() -> bytes:
134
140
  cleanup_old_prometheus_files()
135
141
 
136
142
  registry = CollectorRegistry()
@@ -209,7 +215,7 @@ class _MultiCounter(_MultiMetric):
209
215
  if STATSD_CLIENT:
210
216
  STATSD_CLIENT.incr(self._statsd, delta)
211
217
 
212
- def init_prometheus_metric(self, name: str, documentation: Optional[str], labelnames: Sequence[str] = ()):
218
+ def init_prometheus_metric(self, name: str, documentation: str, labelnames: Sequence[str] = ()) -> Counter:
213
219
  return Counter(name, documentation, labelnames=labelnames, registry=self._registry)
214
220
 
215
221
 
@@ -220,7 +226,7 @@ class _MultiGauge(_MultiMetric):
220
226
  if STATSD_CLIENT:
221
227
  STATSD_CLIENT.gauge(self._statsd, value)
222
228
 
223
- def init_prometheus_metric(self, name: str, documentation: Optional[str], labelnames: Sequence[str] = ()):
229
+ def init_prometheus_metric(self, name: str, documentation: str, labelnames: Sequence[str] = ()) -> Gauge:
224
230
  return Gauge(name, documentation, labelnames=labelnames, registry=self._registry)
225
231
 
226
232
 
@@ -244,7 +250,7 @@ class _MultiTiming(_MultiMetric):
244
250
  if STATSD_CLIENT:
245
251
  STATSD_CLIENT.timing(self._statsd, value * 1000)
246
252
 
247
- def init_prometheus_metric(self, name: str, documentation: Optional[str], labelnames: Sequence[str] = ()):
253
+ def init_prometheus_metric(self, name: str, documentation: str, labelnames: Sequence[str] = ()) -> Histogram:
248
254
  return Histogram(name, documentation, labelnames=labelnames, registry=self._registry, buckets=self._histogram_buckets)
249
255
 
250
256
  def __enter__(self):
@@ -336,7 +342,7 @@ class MetricManager:
336
342
  self.registry = registry or REGISTRY
337
343
  self.push_gateways = push_gateways or []
338
344
 
339
- def full_name(self, name: str):
345
+ def full_name(self, name: str) -> str:
340
346
  if self.prefix:
341
347
  return f'{self.prefix}.{name}'
342
348
  return name