holado 0.13.22__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.
Files changed (698) hide show
  1. holado/__init__.py +358 -0
  2. holado/common/__init__.py +25 -0
  3. holado/common/context/__init__.py +25 -0
  4. holado/common/context/context.py +248 -0
  5. holado/common/context/service_manager.py +262 -0
  6. holado/common/context/session_context.py +516 -0
  7. holado/common/handlers/__init__.py +19 -0
  8. holado/common/handlers/enums.py +41 -0
  9. holado/common/handlers/object.py +175 -0
  10. holado/common/handlers/undefined.py +55 -0
  11. holado/common/tools/__init__.py +19 -0
  12. holado/common/tools/gc_manager.py +155 -0
  13. holado/holado_config.py +45 -0
  14. holado-0.13.22.dist-info/METADATA +194 -0
  15. holado-0.13.22.dist-info/RECORD +698 -0
  16. holado-0.13.22.dist-info/WHEEL +4 -0
  17. holado-0.13.22.dist-info/licenses/LICENSE +21 -0
  18. holado_ais/__init__.py +33 -0
  19. holado_ais/ais/MaritimeIdentificationDigits.csv +295 -0
  20. holado_ais/ais/ais_manager.py +151 -0
  21. holado_ais/ais/ais_messages.py +356 -0
  22. holado_ais/ais/ais_payload.py +35 -0
  23. holado_ais/ais/enums.py +37 -0
  24. holado_ais/ais/patch_pyais.py +1174 -0
  25. holado_ais/tests/behave/steps/__init__.py +17 -0
  26. holado_ais/tests/behave/steps/ais/__init__.py +0 -0
  27. holado_ais/tests/behave/steps/ais/ais_manager_steps.py +50 -0
  28. holado_ais/tests/behave/steps/ais/ais_messages_steps.py +237 -0
  29. holado_binary/__init__.py +17 -0
  30. holado_binary/ipc/binary.py +125 -0
  31. holado_binary/ipc/bit_series.py +307 -0
  32. holado_binary/tests/behave/steps/__init__.py +17 -0
  33. holado_binary/tests/behave/steps/ipc/binary_steps.py +57 -0
  34. holado_binary/tests/behave/steps/ipc/bit_series_steps.py +132 -0
  35. holado_context/__init__.py +16 -0
  36. holado_context/tests/behave/steps/__init__.py +16 -0
  37. holado_context/tests/behave/steps/private/__init__.py +16 -0
  38. holado_context/tests/behave/steps/private/common/context_steps.py +68 -0
  39. holado_core/__init__.py +32 -0
  40. holado_core/common/__init__.py +0 -0
  41. holado_core/common/actors/actions.py +97 -0
  42. holado_core/common/actors/actor.py +226 -0
  43. holado_core/common/actors/element_actor.py +32 -0
  44. holado_core/common/actors/find_actor.py +106 -0
  45. holado_core/common/actors/tree_actor.py +32 -0
  46. holado_core/common/actors/verify_actions.py +69 -0
  47. holado_core/common/block/base.py +122 -0
  48. holado_core/common/block/block_manager.py +173 -0
  49. holado_core/common/block/block_method.py +46 -0
  50. holado_core/common/block/block_steps.py +37 -0
  51. holado_core/common/block/function.py +42 -0
  52. holado_core/common/block/scope_function.py +28 -0
  53. holado_core/common/block/scope_manager.py +238 -0
  54. holado_core/common/block/scope_steps.py +141 -0
  55. holado_core/common/criterias/and_criteria.py +61 -0
  56. holado_core/common/criterias/criteria.py +78 -0
  57. holado_core/common/criterias/or_criteria.py +64 -0
  58. holado_core/common/criterias/tools/criteria_context.py +20 -0
  59. holado_core/common/criterias/tools/criteria_parameters.py +18 -0
  60. holado_core/common/drivers/driver.py +153 -0
  61. holado_core/common/drivers/element_driver.py +30 -0
  62. holado_core/common/drivers/element_internal_api.py +239 -0
  63. holado_core/common/drivers/internal_api.py +40 -0
  64. holado_core/common/drivers/tree_driver.py +30 -0
  65. holado_core/common/drivers/tree_internal_api.py +176 -0
  66. holado_core/common/exceptions/__init__.py +0 -0
  67. holado_core/common/exceptions/element_exception.py +28 -0
  68. holado_core/common/exceptions/exceptions.py +24 -0
  69. holado_core/common/exceptions/functional_exception.py +21 -0
  70. holado_core/common/exceptions/holado_exception.py +25 -0
  71. holado_core/common/exceptions/technical_exception.py +27 -0
  72. holado_core/common/exceptions/timeout_exception.py +20 -0
  73. holado_core/common/exceptions/verify_exception.py +20 -0
  74. holado_core/common/finders/after_in_tree_finder.py +87 -0
  75. holado_core/common/finders/element_finder.py +60 -0
  76. holado_core/common/finders/else_finder.py +105 -0
  77. holado_core/common/finders/finder.py +478 -0
  78. holado_core/common/finders/or_finder.py +98 -0
  79. holado_core/common/finders/then_finder.py +157 -0
  80. holado_core/common/finders/tools/enums.py +30 -0
  81. holado_core/common/finders/tools/find_builder.py +118 -0
  82. holado_core/common/finders/tools/find_context.py +405 -0
  83. holado_core/common/finders/tools/find_info.py +27 -0
  84. holado_core/common/finders/tools/find_parameters.py +240 -0
  85. holado_core/common/finders/tools/find_updater.py +95 -0
  86. holado_core/common/finders/tools/finder_info.py +26 -0
  87. holado_core/common/finders/tree_finder.py +146 -0
  88. holado_core/common/handlers/__init__.py +0 -0
  89. holado_core/common/handlers/abstracts/base_redo.py +702 -0
  90. holado_core/common/handlers/abstracts/get_or_create.py +120 -0
  91. holado_core/common/handlers/element_holder.py +122 -0
  92. holado_core/common/handlers/enums.py +23 -0
  93. holado_core/common/handlers/exceptions/redo_exceptions.py +28 -0
  94. holado_core/common/handlers/features/resource_by_name.py +187 -0
  95. holado_core/common/handlers/features/resource_by_type.py +174 -0
  96. holado_core/common/handlers/redo.py +119 -0
  97. holado_core/common/handlers/wait.py +127 -0
  98. holado_core/common/inspectors/element_inspector.py +57 -0
  99. holado_core/common/inspectors/inspector.py +221 -0
  100. holado_core/common/inspectors/tools/inspect_builder.py +169 -0
  101. holado_core/common/inspectors/tools/inspect_context.py +69 -0
  102. holado_core/common/inspectors/tools/inspect_parameters.py +181 -0
  103. holado_core/common/inspectors/tree_inspector.py +73 -0
  104. holado_core/common/resource/persisted_data_manager.py +113 -0
  105. holado_core/common/resource/persisted_method_to_call_manager.py +263 -0
  106. holado_core/common/resource/resource_manager.py +126 -0
  107. holado_core/common/resource/table_data_manager.py +110 -0
  108. holado_core/common/tables/__init__.py +1 -0
  109. holado_core/common/tables/comparators/__init__.py +0 -0
  110. holado_core/common/tables/comparators/boolean_table_cell_comparator.py +25 -0
  111. holado_core/common/tables/comparators/bytes_table_cell_comparator.py +25 -0
  112. holado_core/common/tables/comparators/datetime_table_cell_comparator.py +24 -0
  113. holado_core/common/tables/comparators/float_table_cell_comparator.py +31 -0
  114. holado_core/common/tables/comparators/integer_table_cell_comparator.py +25 -0
  115. holado_core/common/tables/comparators/internal_table_cell_comparator.py +30 -0
  116. holado_core/common/tables/comparators/string_table_cell_comparator.py +24 -0
  117. holado_core/common/tables/comparators/string_table_comparator.py +29 -0
  118. holado_core/common/tables/comparators/string_table_row_comparator.py +29 -0
  119. holado_core/common/tables/comparators/table_cell_comparator.py +40 -0
  120. holado_core/common/tables/comparators/table_comparator.py +209 -0
  121. holado_core/common/tables/comparators/table_comparator_manager.py +60 -0
  122. holado_core/common/tables/comparators/table_row_comparator.py +116 -0
  123. holado_core/common/tables/comparators/table_with_header_comparator.py +68 -0
  124. holado_core/common/tables/converters/__init__.py +0 -0
  125. holado_core/common/tables/converters/table_converter.py +233 -0
  126. holado_core/common/tables/enums.py +23 -0
  127. holado_core/common/tables/table.py +261 -0
  128. holado_core/common/tables/table_cell.py +126 -0
  129. holado_core/common/tables/table_manager.py +365 -0
  130. holado_core/common/tables/table_row.py +169 -0
  131. holado_core/common/tables/table_with_header.py +242 -0
  132. holado_core/common/tools/__init__.py +0 -0
  133. holado_core/common/tools/comparators/comparator.py +151 -0
  134. holado_core/common/tools/comparators/object_comparator.py +21 -0
  135. holado_core/common/tools/converters/converter.py +118 -0
  136. holado_core/common/tools/path_manager.py +238 -0
  137. holado_core/common/tools/string_tools.py +144 -0
  138. holado_core/common/tools/tools.py +197 -0
  139. holado_core/tests/behave/steps/__init__.py +20 -0
  140. holado_core/tests/behave/steps/common/__init__.py +0 -0
  141. holado_core/tests/behave/steps/common/common_steps.py +137 -0
  142. holado_core/tests/behave/steps/common/config_steps.py +42 -0
  143. holado_core/tests/behave/steps/common/resource_steps.py +62 -0
  144. holado_core/tests/behave/steps/common/tables_steps.py +560 -0
  145. holado_core/tools/__init__.py +0 -0
  146. holado_core/tools/abstracts/__init__.py +0 -0
  147. holado_core/tools/abstracts/blocking_command_service.py +64 -0
  148. holado_core/tools/abstracts/service.py +48 -0
  149. holado_crypto/__init__.py +31 -0
  150. holado_crypto/crypto/crypto.py +108 -0
  151. holado_crypto/crypto/key.py +92 -0
  152. holado_crypto/crypto/tcpbin.py +105 -0
  153. holado_crypto/crypto/transport/__init__.py +0 -0
  154. holado_crypto/crypto/transport/crc.py +40 -0
  155. holado_crypto/tests/behave/steps/__init__.py +18 -0
  156. holado_crypto/tests/behave/steps/crypto_steps.py +112 -0
  157. holado_crypto/tests/behave/steps/key_steps.py +82 -0
  158. holado_crypto/tests/behave/steps/tcpbin_steps.py +79 -0
  159. holado_data/__init__.py +31 -0
  160. holado_data/data/generator/base.py +93 -0
  161. holado_data/data/generator/generator_manager.py +27 -0
  162. holado_data/data/generator/python_generator.py +30 -0
  163. holado_data/tests/behave/steps/__init__.py +17 -0
  164. holado_data/tests/behave/steps/data/generator_steps.py +91 -0
  165. holado_data/tests/behave/steps/tools/utils_steps.py +59 -0
  166. holado_db/__init__.py +32 -0
  167. holado_db/tests/behave/steps/__init__.py +18 -0
  168. holado_db/tests/behave/steps/tools/db/db_client_steps.py +134 -0
  169. holado_db/tests/behave/steps/tools/db/postgresql_client_steps.py +59 -0
  170. holado_db/tests/behave/steps/tools/db/sqlite_client_steps.py +57 -0
  171. holado_db/tools/db/clients/base/db_audit.py +94 -0
  172. holado_db/tools/db/clients/base/db_client.py +344 -0
  173. holado_db/tools/db/clients/postgresql/postgresql_audit.py +75 -0
  174. holado_db/tools/db/clients/postgresql/postgresql_client.py +84 -0
  175. holado_db/tools/db/clients/sqlite/sqlite_audit.py +70 -0
  176. holado_db/tools/db/clients/sqlite/sqlite_client.py +60 -0
  177. holado_db/tools/db/db_manager.py +109 -0
  178. holado_db/tools/db/query/base/query_builder.py +138 -0
  179. holado_db/tools/db/query/pypika/pypika_query_builder.py +244 -0
  180. holado_db/tools/db/query/query_manager.py +77 -0
  181. holado_django/__init__.py +31 -0
  182. holado_django/server/HOWTO.txt +27 -0
  183. holado_django/server/django_projects/rest_api/db.sqlite3 +0 -0
  184. holado_django/server/django_projects/rest_api/manage.py +22 -0
  185. holado_django/server/django_projects/rest_api/rest_api/__init__.py +0 -0
  186. holado_django/server/django_projects/rest_api/rest_api/application/__init__.py +0 -0
  187. holado_django/server/django_projects/rest_api/rest_api/application/admin.py +3 -0
  188. holado_django/server/django_projects/rest_api/rest_api/application/apps.py +9 -0
  189. holado_django/server/django_projects/rest_api/rest_api/application/migrations/__init__.py +0 -0
  190. holado_django/server/django_projects/rest_api/rest_api/application/models.py +3 -0
  191. holado_django/server/django_projects/rest_api/rest_api/application/tests.py +3 -0
  192. holado_django/server/django_projects/rest_api/rest_api/application/views.py +6 -0
  193. holado_django/server/django_projects/rest_api/rest_api/asgi.py +16 -0
  194. holado_django/server/django_projects/rest_api/rest_api/settings.py +130 -0
  195. holado_django/server/django_projects/rest_api/rest_api/urls.py +35 -0
  196. holado_django/server/django_projects/rest_api/rest_api/wsgi.py +16 -0
  197. holado_django/server/django_server.py +110 -0
  198. holado_django/server/grpc_django_server.py +57 -0
  199. holado_django/server/patch_djangogrpcframework.py +46 -0
  200. holado_django/tests/behave/steps/__init__.py +16 -0
  201. holado_django/tests/behave/steps/django_server_steps.py +83 -0
  202. holado_docker/__init__.py +25 -0
  203. holado_docker/sdk/docker/container_logs.py +447 -0
  204. holado_docker/sdk/docker/docker_client.py +537 -0
  205. holado_docker/sdk/docker/docker_service.py +71 -0
  206. holado_docker/tests/behave/steps/__init__.py +16 -0
  207. holado_docker/tests/behave/steps/sdk/docker/container_logs_steps.py +47 -0
  208. holado_examples/projects/server_rest/server_rest_example/initialize_holado.py +72 -0
  209. holado_examples/projects/server_rest/server_rest_example/rest_api/db.sqlite3 +0 -0
  210. holado_examples/projects/server_rest/server_rest_example/rest_api/manage.py +22 -0
  211. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/__init__.py +0 -0
  212. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/__init__.py +0 -0
  213. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/admin.py +3 -0
  214. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/apps.py +7 -0
  215. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/migrations/__init__.py +0 -0
  216. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/models.py +3 -0
  217. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/serializers.py +15 -0
  218. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/tests.py +3 -0
  219. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/views.py +24 -0
  220. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/asgi.py +16 -0
  221. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/settings.py +130 -0
  222. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/urls.py +31 -0
  223. holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/wsgi.py +16 -0
  224. holado_examples/projects/server_rest/server_rest_example/rest_server.py +37 -0
  225. holado_examples/scripts/script_custom_initialization.py +16 -0
  226. holado_examples/scripts/script_minimal_initialization.py +23 -0
  227. holado_examples/tests/behave/testing_solution/__main__.py +13 -0
  228. holado_examples/tests/behave/testing_solution/behave_environment.py +35 -0
  229. holado_examples/tests/behave/testing_solution/environment.py +36 -0
  230. holado_examples/tests/behave/testing_solution/features/Configuration/Actions/configure_system.feature +10 -0
  231. holado_examples/tests/behave/testing_solution/features/NonReg/example.feature +26 -0
  232. holado_examples/tests/behave/testing_solution/initialize_holado.py +62 -0
  233. holado_examples/tests/behave/testing_solution/logging.conf +102 -0
  234. holado_examples/tests/behave/testing_solution/requirements.txt +5 -0
  235. holado_examples/tests/behave/testing_solution/run_test.sh +7 -0
  236. holado_examples/tests/behave/testing_solution/run_test_nonreg.sh +6 -0
  237. holado_examples/tests/behave/testing_solution/src/common/tools/path_manager.py +40 -0
  238. holado_examples/tests/behave/testing_solution/src/config/config_manager.py +30 -0
  239. holado_examples/tests/behave/testing_solution/src/context/session_context.py +45 -0
  240. holado_examples/tests/behave/testing_solution/steps/config_steps.py +21 -0
  241. holado_examples/tests/behave/testing_solution/steps/public_steps.py +10 -0
  242. holado_grpc/TODO +8 -0
  243. holado_grpc/__init__.py +40 -0
  244. holado_grpc/api/rpc/TODO.txt +4 -0
  245. holado_grpc/api/rpc/grpc_client.py +210 -0
  246. holado_grpc/api/rpc/grpc_manager.py +81 -0
  247. holado_grpc/ipc/rpc/__init__.py +0 -0
  248. holado_grpc/ipc/rpc/grpc_compiler.py +45 -0
  249. holado_grpc/ipc/rpc/grpc_services.py +165 -0
  250. holado_grpc/tests/behave/steps/__init__.py +16 -0
  251. holado_grpc/tests/behave/steps/api/grpc_client_steps.py +173 -0
  252. holado_grpc/tests/behave/steps/private/__init__.py +16 -0
  253. holado_grpc/tests/behave/steps/private/api/grpc_steps.py +77 -0
  254. holado_helper/__init__.py +35 -0
  255. holado_helper/debug/README.txt +32 -0
  256. holado_helper/debug/memory/memory_profiler.py +106 -0
  257. holado_helper/docker/init_user.sh +24 -0
  258. holado_helper/docker/logging.conf +44 -0
  259. holado_helper/docker/run_holado_test_nonreg_in_docker.sh +120 -0
  260. holado_helper/docker/run_terminal_in_docker.sh +101 -0
  261. holado_helper/holado_module_template/__init__.py +38 -0
  262. holado_helper/holado_module_template/tests/behave/steps/__init__.py +16 -0
  263. holado_helper/holado_module_template/tests/behave/steps/private/__init__.py +16 -0
  264. holado_helper/initialize_holado.py +72 -0
  265. holado_helper/script/action.py +130 -0
  266. holado_helper/script/action_script.py +477 -0
  267. holado_helper/script/any_action_script.py +126 -0
  268. holado_helper/script/behave_action_script.py +99 -0
  269. holado_helper/script/csv_action_script.py +142 -0
  270. holado_helper/script/initialize_script.py +95 -0
  271. holado_helper/script/input_output_script.py +136 -0
  272. holado_helper/script/job.py +75 -0
  273. holado_helper/script/json_action_script.py +104 -0
  274. holado_helper/script/script.py +110 -0
  275. holado_json/__init__.py +16 -0
  276. holado_json/filesystem/json_file.py +94 -0
  277. holado_json/filesystem/stream_json_file.py +117 -0
  278. holado_json/ipc/json.py +146 -0
  279. holado_json/ipc/json_converter.py +69 -0
  280. holado_json/ipc/json_types.py +183 -0
  281. holado_json/tests/behave/steps/__init__.py +16 -0
  282. holado_json/tests/behave/steps/ipc/__init__.py +0 -0
  283. holado_json/tests/behave/steps/ipc/json_steps.py +131 -0
  284. holado_keycloak/__init__.py +16 -0
  285. holado_keycloak/tests/behave/steps/__init__.py +16 -0
  286. holado_keycloak/tests/behave/steps/tools/keycloak_client_steps.py +73 -0
  287. holado_keycloak/tools/keycloak/__init__.py +0 -0
  288. holado_keycloak/tools/keycloak/keycloak_client.py +90 -0
  289. holado_logging/__init__.py +38 -0
  290. holado_logging/common/logging/holado_logger.py +71 -0
  291. holado_logging/common/logging/log_config.py +163 -0
  292. holado_logging/common/logging/log_manager.py +335 -0
  293. holado_multitask/__init__.py +33 -0
  294. holado_multitask/multiprocessing/context/process_context.py +35 -0
  295. holado_multitask/multiprocessing/function_process.py +102 -0
  296. holado_multitask/multiprocessing/periodic_function_process.py +137 -0
  297. holado_multitask/multiprocessing/process.py +213 -0
  298. holado_multitask/multiprocessing/processesmanager.py +137 -0
  299. holado_multitask/multitasking/multitask_manager.py +464 -0
  300. holado_multitask/multithreading/__init__.py +0 -0
  301. holado_multitask/multithreading/context/thread_context.py +86 -0
  302. holado_multitask/multithreading/functionthreaded.py +129 -0
  303. holado_multitask/multithreading/loopfunctionthreaded.py +45 -0
  304. holado_multitask/multithreading/loopthread.py +110 -0
  305. holado_multitask/multithreading/periodicfunctionthreaded.py +135 -0
  306. holado_multitask/multithreading/reflection/inspect.py +47 -0
  307. holado_multitask/multithreading/reflection/sys.py +29 -0
  308. holado_multitask/multithreading/reflection/traceback.py +35 -0
  309. holado_multitask/multithreading/thread.py +203 -0
  310. holado_multitask/multithreading/threadsmanager.py +167 -0
  311. holado_multitask/multithreading/timer.py +51 -0
  312. holado_multitask/tests/behave/steps/__init__.py +17 -0
  313. holado_multitask/tests/behave/steps/multiprocessing_steps.py +138 -0
  314. holado_multitask/tests/behave/steps/multithreading_steps.py +129 -0
  315. holado_protobuf/__init__.py +61 -0
  316. holado_protobuf/ipc/protobuf/__init__.py +0 -0
  317. holado_protobuf/ipc/protobuf/abstracts/type.py +45 -0
  318. holado_protobuf/ipc/protobuf/protobuf_compiler.py +118 -0
  319. holado_protobuf/ipc/protobuf/protobuf_converter.py +153 -0
  320. holado_protobuf/ipc/protobuf/protobuf_messages.py +968 -0
  321. holado_protobuf/ipc/protobuf/protobuf_modifier.py +65 -0
  322. holado_protobuf/ipc/protobuf/types/__init__.py +0 -0
  323. holado_protobuf/ipc/protobuf/types/google/__init__.py +0 -0
  324. holado_protobuf/ipc/protobuf/types/google/protobuf.py +124 -0
  325. holado_protobuf/tests/behave/steps/__init__.py +16 -0
  326. holado_protobuf/tests/behave/steps/ipc/protobuf_steps.py +297 -0
  327. holado_python/__init__.py +36 -0
  328. holado_python/common/enums.py +34 -0
  329. holado_python/common/iterables.py +38 -0
  330. holado_python/common/tools/comparators/boolean_comparator.py +37 -0
  331. holado_python/common/tools/comparators/bytes_comparator.py +48 -0
  332. holado_python/common/tools/comparators/datetime_comparator.py +74 -0
  333. holado_python/common/tools/comparators/float_comparator.py +97 -0
  334. holado_python/common/tools/comparators/integer_comparator.py +37 -0
  335. holado_python/common/tools/comparators/string_comparator.py +99 -0
  336. holado_python/common/tools/comparators/type_comparator.py +31 -0
  337. holado_python/common/tools/datetime.py +341 -0
  338. holado_python/standard_library/csv.py +207 -0
  339. holado_python/standard_library/hashlib.py +110 -0
  340. holado_python/standard_library/multiprocessing.py +62 -0
  341. holado_python/standard_library/queue.py +79 -0
  342. holado_python/standard_library/socket/blocking_socket.py +219 -0
  343. holado_python/standard_library/socket/echo_server.py +29 -0
  344. holado_python/standard_library/socket/message_socket.py +152 -0
  345. holado_python/standard_library/socket/non_blocking_socket.py +172 -0
  346. holado_python/standard_library/socket/socket.py +411 -0
  347. holado_python/standard_library/ssl/resources/certificates/NOTES.txt +5 -0
  348. holado_python/standard_library/ssl/resources/certificates/localhost.crt +19 -0
  349. holado_python/standard_library/ssl/resources/certificates/localhost.key +28 -0
  350. holado_python/standard_library/ssl/ssl.py +131 -0
  351. holado_python/standard_library/typing.py +192 -0
  352. holado_python/tests/behave/steps/__init__.py +27 -0
  353. holado_python/tests/behave/steps/builtins/str_steps.py +45 -0
  354. holado_python/tests/behave/steps/convert_steps.py +59 -0
  355. holado_python/tests/behave/steps/iterable_steps.py +87 -0
  356. holado_python/tests/behave/steps/standard_library/csv_steps.py +134 -0
  357. holado_python/tests/behave/steps/standard_library/datetime_steps.py +163 -0
  358. holado_python/tests/behave/steps/standard_library/hashlib_steps.py +57 -0
  359. holado_python/tests/behave/steps/standard_library/multiprocessing_steps.py +56 -0
  360. holado_python/tests/behave/steps/standard_library/queue_steps.py +358 -0
  361. holado_python/tests/behave/steps/standard_library/socket_steps.py +384 -0
  362. holado_python/tests/behave/steps/standard_library/ssl_steps.py +71 -0
  363. holado_rabbitmq/__init__.py +28 -0
  364. holado_rabbitmq/tests/behave/steps/__init__.py +17 -0
  365. holado_rabbitmq/tests/behave/steps/tools/rabbitmq_client_steps.py +565 -0
  366. holado_rabbitmq/tests/behave/steps/tools/rabbitmq_server_steps.py +64 -0
  367. holado_rabbitmq/tools/rabbitmq/rabbitmq_blocking_client.py +333 -0
  368. holado_rabbitmq/tools/rabbitmq/rabbitmq_client.py +678 -0
  369. holado_rabbitmq/tools/rabbitmq/rabbitmq_manager.py +146 -0
  370. holado_rabbitmq/tools/rabbitmq/rabbitmq_select_client.py +428 -0
  371. holado_rabbitmq/tools/rabbitmq/rabbitmq_server.py +24 -0
  372. holado_redis/__init__.py +17 -0
  373. holado_redis/tests/behave/steps/__init__.py +16 -0
  374. holado_redis/tests/behave/steps/tools/redis_client_steps.py +101 -0
  375. holado_redis/tools/redis/TODO.txt +7 -0
  376. holado_redis/tools/redis/redis_client.py +190 -0
  377. holado_redis/tools/redis/redis_manager.py +38 -0
  378. holado_report/__init__.py +36 -0
  379. holado_report/campaign/campaign_manager.py +348 -0
  380. holado_report/report/analyze/execution_historic_manager.py +96 -0
  381. holado_report/report/analyze/scenario_duration_manager.py +245 -0
  382. holado_report/report/builders/detailed_scenario_report_builder.py +172 -0
  383. holado_report/report/builders/execution_historic_report_builder.py +132 -0
  384. holado_report/report/builders/failure_report_builder.py +150 -0
  385. holado_report/report/builders/report_builder.py +64 -0
  386. holado_report/report/builders/short_scenario_report_builder.py +94 -0
  387. holado_report/report/builders/summary_by_category_report_builder.py +103 -0
  388. holado_report/report/builders/summary_report_builder.py +110 -0
  389. holado_report/report/builders/summary_scenario_by_category_report_builder.py +109 -0
  390. holado_report/report/builders/summary_scenario_report_builder.py +81 -0
  391. holado_report/report/execution_historic.py +144 -0
  392. holado_report/report/report_manager.py +424 -0
  393. holado_report/report/reports/base_report.py +163 -0
  394. holado_report/report/reports/feature_report.py +106 -0
  395. holado_report/report/reports/scenario_report.py +64 -0
  396. holado_rest/__init__.py +32 -0
  397. holado_rest/api/rest/TODO.txt +2 -0
  398. holado_rest/api/rest/rest_client.py +200 -0
  399. holado_rest/api/rest/rest_manager.py +72 -0
  400. holado_rest/tests/behave/steps/__init__.py +16 -0
  401. holado_rest/tests/behave/steps/api/__init__.py +0 -0
  402. holado_rest/tests/behave/steps/api/rest_client_steps.py +181 -0
  403. holado_rest/tests/behave/steps/private/__init__.py +16 -0
  404. holado_rest/tests/behave/steps/private/api/__init__.py +0 -0
  405. holado_rest/tests/behave/steps/private/api/rest_steps.py +75 -0
  406. holado_s3/__init__.py +17 -0
  407. holado_s3/tests/behave/steps/__init__.py +17 -0
  408. holado_s3/tests/behave/steps/private/__init__.py +16 -0
  409. holado_s3/tests/behave/steps/private/tools/s3_steps.py +89 -0
  410. holado_s3/tests/behave/steps/tools/s3_client_steps.py +403 -0
  411. holado_s3/tests/behave/steps/tools/s3_server_steps.py +57 -0
  412. holado_s3/tools/s3/__init__.py +0 -0
  413. holado_s3/tools/s3/boto3_s3_client.py +59 -0
  414. holado_s3/tools/s3/minio_client.py +75 -0
  415. holado_s3/tools/s3/moto_server.py +52 -0
  416. holado_scripting/__init__.py +54 -0
  417. holado_scripting/common/tools/dynamic_text_manager.py +73 -0
  418. holado_scripting/common/tools/evaluate_parameters.py +228 -0
  419. holado_scripting/common/tools/expression_evaluator.py +389 -0
  420. holado_scripting/common/tools/variable_manager.py +354 -0
  421. holado_scripting/tests/behave/steps/__init__.py +22 -0
  422. holado_scripting/tests/behave/steps/common/tools/variable_convert_steps.py +159 -0
  423. holado_scripting/tests/behave/steps/common/tools/variable_new_steps.py +130 -0
  424. holado_scripting/tests/behave/steps/common/tools/variable_steps.py +108 -0
  425. holado_scripting/tests/behave/steps/common/tools/variable_verify_steps.py +160 -0
  426. holado_scripting/tests/behave/steps/scenario/function_steps.py +77 -0
  427. holado_scripting/tests/behave/steps/scenario/if_steps.py +87 -0
  428. holado_scripting/tests/behave/steps/scenario/loop_steps.py +119 -0
  429. holado_scripting/text/base/base_function.py +25 -0
  430. holado_scripting/text/base/base_verify_function.py +25 -0
  431. holado_scripting/text/base/text_inspecter.py +204 -0
  432. holado_scripting/text/interpreter/exceptions/interpreter_exception.py +25 -0
  433. holado_scripting/text/interpreter/functions/function_apply_function.py +60 -0
  434. holado_scripting/text/interpreter/functions/function_cast.py +60 -0
  435. holado_scripting/text/interpreter/functions/function_convert.py +57 -0
  436. holado_scripting/text/interpreter/functions/function_dynamic_value.py +40 -0
  437. holado_scripting/text/interpreter/functions/function_escape_all_bytes.py +35 -0
  438. holado_scripting/text/interpreter/functions/function_exists_variable.py +39 -0
  439. holado_scripting/text/interpreter/functions/function_hex_to_bytes.py +49 -0
  440. holado_scripting/text/interpreter/functions/function_hex_to_int.py +53 -0
  441. holado_scripting/text/interpreter/functions/function_to_base_64.py +41 -0
  442. holado_scripting/text/interpreter/functions/function_to_bytes.py +50 -0
  443. holado_scripting/text/interpreter/functions/function_to_hex.py +42 -0
  444. holado_scripting/text/interpreter/functions/function_to_string.py +50 -0
  445. holado_scripting/text/interpreter/text_interpreter.py +219 -0
  446. holado_scripting/text/verifier/exceptions/verifier_exception.py +21 -0
  447. holado_scripting/text/verifier/functions/verify_function_extract_in.py +35 -0
  448. holado_scripting/text/verifier/functions/verify_function_match_pattern.py +63 -0
  449. holado_scripting/text/verifier/text_verifier.py +103 -0
  450. holado_sftp/__init__.py +16 -0
  451. holado_sftp/tests/behave/steps/__init__.py +17 -0
  452. holado_sftp/tests/behave/steps/private/__init__.py +16 -0
  453. holado_sftp/tests/behave/steps/private/tools/sftp_steps.py +78 -0
  454. holado_sftp/tests/behave/steps/tools/sftp_client_steps.py +94 -0
  455. holado_sftp/tests/behave/steps/tools/sftp_server_steps.py +82 -0
  456. holado_sftp/tools/sftp/__init__.py +0 -0
  457. holado_sftp/tools/sftp/sftp_client.py +103 -0
  458. holado_sftp/tools/sftp/sftp_server.py +39 -0
  459. holado_swagger/__init__.py +31 -0
  460. holado_swagger/swagger_hub/mockserver/mockserver_client.py +82 -0
  461. holado_swagger/swagger_hub/mockserver/mockserver_manager.py +33 -0
  462. holado_swagger/tests/behave/steps/__init__.py +16 -0
  463. holado_swagger/tests/behave/steps/swagger_hub/mockserver_steps.py +74 -0
  464. holado_system/system/command/command.py +247 -0
  465. holado_system/system/command/command_result.py +128 -0
  466. holado_system/system/command/curl_command.py +101 -0
  467. holado_system/system/command/exceptions.py +59 -0
  468. holado_system/system/filesystem/file.py +150 -0
  469. holado_system/system/global_system.py +187 -0
  470. holado_system/tests/behave/steps/__init__.py +18 -0
  471. holado_system/tests/behave/steps/system/commands_steps.py +92 -0
  472. holado_system/tests/behave/steps/system/file_steps.py +231 -0
  473. holado_system/tests/behave/steps/system/system_steps.py +84 -0
  474. holado_test/__init__.py +30 -0
  475. holado_test/behave/__init__.py +0 -0
  476. holado_test/behave/behave.py +400 -0
  477. holado_test/behave/behave_environment.py +169 -0
  478. holado_test/behave/behave_function.py +33 -0
  479. holado_test/behave/behave_manager.py +558 -0
  480. holado_test/behave/independant_runner.py +66 -0
  481. holado_test/behave/scenario/__init__.py +0 -0
  482. holado_test/behave/scenario/behave_step_tools.py +157 -0
  483. holado_test/common/context/feature_context.py +81 -0
  484. holado_test/common/context/scenario_context.py +169 -0
  485. holado_test/common/context/step_context.py +66 -0
  486. holado_test/common/exceptions/undefined_step_exception.py +21 -0
  487. holado_test/scenario/step_tools.py +547 -0
  488. holado_test/scenario/tester_tools.py +57 -0
  489. holado_test/test_config.py +26 -0
  490. holado_test/tests/behave/steps/__init__.py +18 -0
  491. holado_test/tests/behave/steps/scenario/exception_steps.py +87 -0
  492. holado_test/tests/behave/steps/scenario/scenario_steps.py +100 -0
  493. holado_test/tests/behave/steps/scenario/tester_steps.py +65 -0
  494. holado_test/tools/test_server/client/rest/test_server_client.py +150 -0
  495. holado_test/tools/test_server/server/Dockerfile +60 -0
  496. holado_test/tools/test_server/server/core/server_context.py +42 -0
  497. holado_test/tools/test_server/server/core/server_manager.py +41 -0
  498. holado_test/tools/test_server/server/requirements.txt +2 -0
  499. holado_test/tools/test_server/server/rest/README +2 -0
  500. holado_test/tools/test_server/server/rest/api/__init__.py +24 -0
  501. holado_test/tools/test_server/server/rest/api/campaign/__init__.py +32 -0
  502. holado_test/tools/test_server/server/rest/api/campaign/scenario.py +40 -0
  503. holado_test/tools/test_server/server/rest/initialize_holado.py +72 -0
  504. holado_test/tools/test_server/server/rest/logging.conf +51 -0
  505. holado_test/tools/test_server/server/rest/openapi.yaml +57 -0
  506. holado_test/tools/test_server/server/rest/run.py +41 -0
  507. holado_test/tools/test_server/server/run.sh +6 -0
  508. holado_test/tools/test_server/server/run_test_server_in_docker.sh +104 -0
  509. holado_tools/__init__.py +38 -0
  510. holado_tools/scripts/execute_persisted_post_processes/execute_persisted_post_processes.py +36 -0
  511. holado_tools/scripts/execute_persisted_post_processes/execute_persisted_post_processes.sh +6 -0
  512. holado_tools/scripts/execute_persisted_post_processes/initialize_holado.py +62 -0
  513. holado_tools/tests/behave/steps/__init__.py +16 -0
  514. holado_tools/tests/behave/steps/tools/host_controller/client_steps.py +97 -0
  515. holado_tools/tools/host_controller/client/rest/host_controller_client.py +275 -0
  516. holado_tools/tools/host_controller/server/Dockerfile +60 -0
  517. holado_tools/tools/host_controller/server/requirements.txt +2 -0
  518. holado_tools/tools/host_controller/server/rest/README +2 -0
  519. holado_tools/tools/host_controller/server/rest/api/__init__.py +24 -0
  520. holado_tools/tools/host_controller/server/rest/api/config.py +88 -0
  521. holado_tools/tools/host_controller/server/rest/api/docker/__init__.py +66 -0
  522. holado_tools/tools/host_controller/server/rest/api/docker/container.py +144 -0
  523. holado_tools/tools/host_controller/server/rest/api/docker/logs.py +66 -0
  524. holado_tools/tools/host_controller/server/rest/api/os.py +58 -0
  525. holado_tools/tools/host_controller/server/rest/initialize_holado.py +72 -0
  526. holado_tools/tools/host_controller/server/rest/openapi.yaml +561 -0
  527. holado_tools/tools/host_controller/server/rest/run.py +31 -0
  528. holado_tools/tools/host_controller/server/run_host_controller_in_docker.sh +107 -0
  529. holado_tools/tools/host_viewer/client/rest/host_viewer_client.py +190 -0
  530. holado_tools/tools/host_viewer/server/Dockerfile +60 -0
  531. holado_tools/tools/host_viewer/server/requirements.txt +2 -0
  532. holado_tools/tools/host_viewer/server/rest/README +2 -0
  533. holado_tools/tools/host_viewer/server/rest/api/__init__.py +24 -0
  534. holado_tools/tools/host_viewer/server/rest/api/docker/__init__.py +65 -0
  535. holado_tools/tools/host_viewer/server/rest/api/docker/container.py +87 -0
  536. holado_tools/tools/host_viewer/server/rest/api/os.py +58 -0
  537. holado_tools/tools/host_viewer/server/rest/initialize_holado.py +72 -0
  538. holado_tools/tools/host_viewer/server/rest/openapi.yaml +301 -0
  539. holado_tools/tools/host_viewer/server/rest/run.py +31 -0
  540. holado_tools/tools/host_viewer/server/run_host_viewer_in_docker.sh +107 -0
  541. holado_value/__init__.py +24 -0
  542. holado_value/common/tables/comparators/table_2_value_table_cell_comparator.py +196 -0
  543. holado_value/common/tables/comparators/table_2_value_table_comparator.py +27 -0
  544. holado_value/common/tables/comparators/table_2_value_table_row_comparator.py +27 -0
  545. holado_value/common/tables/comparators/table_2_value_table_with_header_comparator.py +27 -0
  546. holado_value/common/tables/converters/value_table_converter.py +267 -0
  547. holado_value/common/tables/value_table.py +29 -0
  548. holado_value/common/tables/value_table_cell.py +76 -0
  549. holado_value/common/tables/value_table_manager.py +48 -0
  550. holado_value/common/tables/value_table_row.py +43 -0
  551. holado_value/common/tables/value_table_with_header.py +28 -0
  552. holado_value/common/tools/unique_value_manager.py +109 -0
  553. holado_value/common/tools/value.py +191 -0
  554. holado_value/common/tools/value_types.py +41 -0
  555. holado_value/tests/behave/steps/__init__.py +16 -0
  556. holado_value/tests/behave/steps/private/__init__.py +16 -0
  557. holado_ws/__init__.py +16 -0
  558. holado_ws/api/ws/TODO.txt +2 -0
  559. holado_ws/tests/behave/steps/__init__.py +16 -0
  560. holado_ws/tests/behave/steps/api/web_service_steps.py +189 -0
  561. holado_xml/__init__.py +38 -0
  562. holado_xml/tests/behave/steps/__init__.py +16 -0
  563. holado_xml/tests/behave/steps/private/__init__.py +16 -0
  564. holado_xml/xml/stream_xml_file.py +181 -0
  565. holado_xml/xml/xml_file.py +97 -0
  566. holado_xml/xml/xml_manager.py +35 -0
  567. holado_yaml/__init__.py +31 -0
  568. holado_yaml/tests/behave/steps/__init__.py +16 -0
  569. holado_yaml/tests/behave/steps/yaml_steps.py +161 -0
  570. holado_yaml/yaml/enums.py +28 -0
  571. holado_yaml/yaml/pyyaml/pyyaml_client.py +72 -0
  572. holado_yaml/yaml/ruamel/ruamel_yaml_client.py +80 -0
  573. holado_yaml/yaml/yaml_client.py +203 -0
  574. holado_yaml/yaml/yaml_manager.py +94 -0
  575. test_holado/Dockerfile_test_holado +82 -0
  576. test_holado/__init__.py +4 -0
  577. test_holado/__main__.py +25 -0
  578. test_holado/build_docker_image_to_test_holado_in_docker.sh +7 -0
  579. test_holado/environment.py +60 -0
  580. test_holado/features/Configuration/Actions/execute_persisted_post_processes.feature +13 -0
  581. test_holado/features/NonReg/api/REST.feature +26 -0
  582. test_holado/features/NonReg/api/gRPC.feature +116 -0
  583. test_holado/features/NonReg/common/multiprocessing/simple.feature +60 -0
  584. test_holado/features/NonReg/common/system/commands.feature +43 -0
  585. test_holado/features/NonReg/common/system/system.feature +20 -0
  586. test_holado/features/NonReg/common/tables/table.feature +245 -0
  587. test_holado/features/NonReg/common/tables/value_table_conversion.feature +29 -0
  588. test_holado/features/NonReg/common/tools/DateTime.feature +88 -0
  589. test_holado/features/NonReg/common/tools/UniqueValueManager.feature +43 -0
  590. test_holado/features/NonReg/holado_ais/ais_message-bitarray_to_nmea.feature +135 -0
  591. test_holado/features/NonReg/holado_ais/ais_message-nmea_raw_to_dict.feature +93 -0
  592. test_holado/features/NonReg/holado_ais/message_types/type-10.feature +38 -0
  593. test_holado/features/NonReg/holado_ais/message_types/type-12.feature +37 -0
  594. test_holado/features/NonReg/holado_ais/message_types/type-14.feature +36 -0
  595. test_holado/features/NonReg/holado_ais/message_types/type-15.feature +36 -0
  596. test_holado/features/NonReg/holado_ais/message_types/type-16.feature +38 -0
  597. test_holado/features/NonReg/holado_ais/message_types/type-17.feature +46 -0
  598. test_holado/features/NonReg/holado_ais/message_types/type-18.feature +37 -0
  599. test_holado/features/NonReg/holado_ais/message_types/type-19.feature +38 -0
  600. test_holado/features/NonReg/holado_ais/message_types/type-1_2_3.feature +42 -0
  601. test_holado/features/NonReg/holado_ais/message_types/type-20.feature +38 -0
  602. test_holado/features/NonReg/holado_ais/message_types/type-21.feature +37 -0
  603. test_holado/features/NonReg/holado_ais/message_types/type-22.feature +84 -0
  604. test_holado/features/NonReg/holado_ais/message_types/type-23.feature +49 -0
  605. test_holado/features/NonReg/holado_ais/message_types/type-24.feature +72 -0
  606. test_holado/features/NonReg/holado_ais/message_types/type-25.feature +143 -0
  607. test_holado/features/NonReg/holado_ais/message_types/type-26.feature +144 -0
  608. test_holado/features/NonReg/holado_ais/message_types/type-27.feature +36 -0
  609. test_holado/features/NonReg/holado_ais/message_types/type-4_11.feature +39 -0
  610. test_holado/features/NonReg/holado_ais/message_types/type-5.feature +33 -0
  611. test_holado/features/NonReg/holado_ais/message_types/type-6.feature +37 -0
  612. test_holado/features/NonReg/holado_ais/message_types/type-7_13.feature +43 -0
  613. test_holado/features/NonReg/holado_ais/message_types/type-8.feature +37 -0
  614. test_holado/features/NonReg/holado_ais/message_types/type-9.feature +37 -0
  615. test_holado/features/NonReg/holado_binary/bit_series.error.feature +33 -0
  616. test_holado/features/NonReg/holado_binary/bit_series.feature +144 -0
  617. test_holado/features/NonReg/holado_protobuf/protobuf.feature +291 -0
  618. test_holado/features/NonReg/holado_python/convert.feature +20 -0
  619. test_holado/features/NonReg/holado_python/iterable.feature +61 -0
  620. test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_reset.feature +191 -0
  621. test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_with_tls_and_verify.feature +279 -0
  622. test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_with_tls_without_verify.feature +299 -0
  623. test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_without_tls.feature +163 -0
  624. test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_with_mtls.feature +214 -0
  625. test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_with_tls.feature +184 -0
  626. test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_without_tls.feature +169 -0
  627. test_holado/features/NonReg/holado_scripting/common/tools/dynamic_text_manager.feature +18 -0
  628. test_holado/features/NonReg/holado_scripting/common/tools/expression_evaluator.feature +185 -0
  629. test_holado/features/NonReg/holado_scripting/common/tools/variable_manager.feature +71 -0
  630. test_holado/features/NonReg/holado_scripting/text/interpreter/interpreter.error.feature +21 -0
  631. test_holado/features/NonReg/holado_scripting/text/interpreter/interpreter.feature +120 -0
  632. test_holado/features/NonReg/holado_yaml/yaml.feature +514 -0
  633. test_holado/features/NonReg/ipc/json.feature +20 -0
  634. test_holado/features/NonReg/scenario/scenario.feature +183 -0
  635. test_holado/features/NonReg/test_steps/behave.feature +275 -0
  636. test_holado/features/NonReg/test_steps/common.feature +100 -0
  637. test_holado/features/NonReg/tools/RabbitMQ.feature +445 -0
  638. test_holado/features/NonReg/tools/RabbitMQ_steps.feature +276 -0
  639. test_holado/features/NonReg/tools/S3/boto3_client.feature +73 -0
  640. test_holado/features/NonReg/tools/S3/minio_client.feature +75 -0
  641. test_holado/features/NonReg/tools/db_sqlite3.feature +41 -0
  642. test_holado/features/NonReg/tools/sFTP.feature +25 -0
  643. test_holado/features/Test/logger.feature +28 -0
  644. test_holado/features/Test/test_host_controller.feature +13 -0
  645. test_holado/features/Test/test_parameter.feature +15 -0
  646. test_holado/features/__init__.py +0 -0
  647. test_holado/initialize_holado.py +62 -0
  648. test_holado/logging.conf +53 -0
  649. test_holado/resources/proto/definitions/protobuf/custom_types/field_types.proto +24 -0
  650. test_holado/resources/proto/definitions/protobuf/protobuf.dev/tutorial/addressbook.proto +56 -0
  651. test_holado/resources/proto/generated/protobuf/custom_types/field_types_pb2.py +34 -0
  652. test_holado/resources/proto/generated/protobuf/protobuf/dev/tutorial/addressbook_pb2.py +34 -0
  653. test_holado/resources/scripts/list_tags.sh +2 -0
  654. test_holado/resources/scripts/update_resources_proto_generated.py +70 -0
  655. test_holado/steps/__init__.py +0 -0
  656. test_holado/steps/private_steps.py +20 -0
  657. test_holado/steps/public_steps.py +23 -0
  658. test_holado/test_holado_session_context.py +43 -0
  659. test_holado/tools/connexion/api_rest/openapi.yaml +16 -0
  660. test_holado/tools/connexion/api_rest/run.py +19 -0
  661. test_holado/tools/django/README.txt +3 -0
  662. test_holado/tools/django/api_grpc/api_grpc/__init__.py +0 -0
  663. test_holado/tools/django/api_grpc/api_grpc/api1/__init__.py +0 -0
  664. test_holado/tools/django/api_grpc/api_grpc/api1/admin.py +3 -0
  665. test_holado/tools/django/api_grpc/api_grpc/api1/apps.py +6 -0
  666. test_holado/tools/django/api_grpc/api_grpc/api1/migrations/__init__.py +0 -0
  667. test_holado/tools/django/api_grpc/api_grpc/api1/models.py +3 -0
  668. test_holado/tools/django/api_grpc/api_grpc/api1/proto/__init__.py +0 -0
  669. test_holado/tools/django/api_grpc/api_grpc/api1/proto/account.proto +27 -0
  670. test_holado/tools/django/api_grpc/api_grpc/api1/proto/account_pb2.py +33 -0
  671. test_holado/tools/django/api_grpc/api_grpc/api1/proto/account_pb2_grpc.py +199 -0
  672. test_holado/tools/django/api_grpc/api_grpc/api1/serializers.py +12 -0
  673. test_holado/tools/django/api_grpc/api_grpc/api1/services.py +11 -0
  674. test_holado/tools/django/api_grpc/api_grpc/api1/tests.py +3 -0
  675. test_holado/tools/django/api_grpc/api_grpc/api1/views.py +3 -0
  676. test_holado/tools/django/api_grpc/api_grpc/asgi.py +16 -0
  677. test_holado/tools/django/api_grpc/api_grpc/settings.py +126 -0
  678. test_holado/tools/django/api_grpc/api_grpc/urls.py +27 -0
  679. test_holado/tools/django/api_grpc/api_grpc/wsgi.py +16 -0
  680. test_holado/tools/django/api_grpc/db.sqlite3 +0 -0
  681. test_holado/tools/django/api_grpc/manage.py +29 -0
  682. test_holado/tools/django/api_grpc/manual_test_commands.txt +25 -0
  683. test_holado/tools/django/api_grpc/patch_djangogrpcframework.py +42 -0
  684. test_holado/tools/django/api_rest/api_rest/__init__.py +0 -0
  685. test_holado/tools/django/api_rest/api_rest/api1/__init__.py +0 -0
  686. test_holado/tools/django/api_rest/api_rest/api1/admin.py +3 -0
  687. test_holado/tools/django/api_rest/api_rest/api1/apps.py +6 -0
  688. test_holado/tools/django/api_rest/api_rest/api1/migrations/__init__.py +0 -0
  689. test_holado/tools/django/api_rest/api_rest/api1/models.py +3 -0
  690. test_holado/tools/django/api_rest/api_rest/api1/serializers.py +15 -0
  691. test_holado/tools/django/api_rest/api_rest/api1/tests.py +3 -0
  692. test_holado/tools/django/api_rest/api_rest/api1/views.py +24 -0
  693. test_holado/tools/django/api_rest/api_rest/asgi.py +16 -0
  694. test_holado/tools/django/api_rest/api_rest/settings.py +133 -0
  695. test_holado/tools/django/api_rest/api_rest/urls.py +32 -0
  696. test_holado/tools/django/api_rest/api_rest/wsgi.py +16 -0
  697. test_holado/tools/django/api_rest/db.sqlite3 +0 -0
  698. test_holado/tools/django/api_rest/manage.py +22 -0
@@ -0,0 +1,678 @@
1
+
2
+ #################################################
3
+ # HolAdo (Holistic Automation do)
4
+ #
5
+ # (C) Copyright 2021-2025 by Eric Klumpp
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
+ #
9
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+
11
+ # The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.
12
+ #################################################
13
+
14
+ import logging
15
+ from holado_core.common.exceptions.functional_exception import FunctionalException
16
+ from holado_core.common.exceptions.technical_exception import TechnicalException
17
+ from holado_core.common.tools.tools import Tools
18
+ from typing import NamedTuple
19
+ import threading
20
+ from holado.common.handlers.object import DeleteableObject, Object
21
+ from holado.common.handlers.enums import ObjectStates
22
+ from holado_multitask.multithreading.functionthreaded import FunctionThreaded
23
+ from holado_core.common.handlers.redo import Redo
24
+ from holado_system.system.filesystem.file import File
25
+ from holado_core.common.exceptions.verify_exception import VerifyException
26
+ import abc
27
+ from holado_multitask.multithreading.loopfunctionthreaded import LoopFunctionThreaded
28
+ from holado_multitask.multitasking.multitask_manager import MultitaskManager
29
+
30
+
31
+ logger = logging.getLogger(__name__)
32
+
33
+ try:
34
+ import pika # @UnresolvedImport @UnusedImport
35
+ from pika.exceptions import ConnectionWrongStateError, StreamLostError
36
+ with_pika = True
37
+ except Exception as exc:
38
+ if Tools.do_log(logger, logging.DEBUG):
39
+ logger.debug(f"RMQClient is not available. Initialization failed on error: {exc}")
40
+ with_pika = False
41
+
42
+
43
+
44
+ class RMQClient(DeleteableObject):
45
+ __metaclass__ = abc.ABCMeta
46
+
47
+ @classmethod
48
+ def is_available(cls):
49
+ return with_pika
50
+
51
+ def __init__(self, name):
52
+ super().__init__(name)
53
+
54
+ self.__connection_kwargs = None
55
+ self.__publisher_and_kwargs = []
56
+ self.__consumer_and_kwargs = []
57
+ self.__buffer_consumer_and_kwargs = []
58
+
59
+ self.__connection = None
60
+ self.__connection_thread_id = None
61
+
62
+ self.__is_consuming = False
63
+ self.__is_stopping_consuming = False
64
+ self.__rapid_close = False
65
+
66
+ self.__process_data_events_thread = None
67
+ self.__is_processing_data_events = False
68
+ self.__is_stopping_processing_data_events = False
69
+
70
+ def _delete_object(self):
71
+ try:
72
+ if Tools.do_log(logger, logging.DEBUG):
73
+ logger.debug(f"[{self.name}] Deleting RabbitMQ client...")
74
+ self.close()
75
+ if Tools.do_log(logger, logging.DEBUG):
76
+ logger.debug(f"[{self.name}] Finished to delete RabbitMQ client")
77
+ except StreamLostError as exc:
78
+ if self.object_state == ObjectStates.Deleting:
79
+ pass
80
+ else:
81
+ raise exc
82
+
83
+ @property
84
+ def connection(self):
85
+ return self.__connection
86
+
87
+ @property
88
+ def _connection_kwargs(self):
89
+ return self.__connection_kwargs
90
+
91
+ @property
92
+ def is_in_connection_thread(self):
93
+ return MultitaskManager.get_thread_id() == self.__connection_thread_id
94
+
95
+ @property
96
+ def is_consuming(self):
97
+ return self.__is_consuming
98
+
99
+ @property
100
+ def is_processing_data_events(self):
101
+ return self.__is_processing_data_events
102
+
103
+ @property
104
+ def rapid_close(self):
105
+ return self.__rapid_close
106
+
107
+ @rapid_close.setter
108
+ def rapid_close(self, rapid_close):
109
+ self.__rapid_close = rapid_close
110
+
111
+ @property
112
+ def has_consumer(self):
113
+ return len(self.__consumer_and_kwargs) > 0
114
+
115
+ @property
116
+ def _consumer_and_kwargs(self):
117
+ return self.__consumer_and_kwargs
118
+
119
+ @property
120
+ def has_buffer_consumer(self):
121
+ return len(self.__buffer_consumer_and_kwargs) > 0
122
+
123
+ @property
124
+ def _buffer_consumer_and_kwargs(self):
125
+ return self.__buffer_consumer_and_kwargs
126
+
127
+ @property
128
+ def has_publisher(self):
129
+ return len(self.__publisher_and_kwargs) > 0
130
+
131
+ @property
132
+ def _publisher_and_kwargs(self):
133
+ return self.__publisher_and_kwargs
134
+
135
+ def _set_connection(self, connection):
136
+ self.__connection = connection
137
+ self.__connection_thread_id = MultitaskManager.get_thread_id()
138
+
139
+ def _build_and_save_connection_parameters_kwargs(self, **connection_parameters_kwargs):
140
+ if Tools.has_sub_kwargs(connection_parameters_kwargs, "authentication."):
141
+ authentication = Tools.pop_sub_kwargs(connection_parameters_kwargs, "authentication.")
142
+ if 'user' in authentication:
143
+ if type(authentication['user']) is tuple:
144
+ connection_parameters_kwargs['credentials'] = pika.PlainCredentials(authentication['user'][0], authentication['user'][1])
145
+ else:
146
+ raise FunctionalException(f"[{self.name}]When authenticating by user, the value has to be in format: ('{{USER}}', '{{PASSWORD}}') (obtained: {authentication['user']})")
147
+ else:
148
+ raise TechnicalException(f"[{self.name}]Unmanaged authentication type '{authentication.keys()}' (possible authentication types: 'user'")
149
+
150
+ self.__connection_kwargs = connection_parameters_kwargs
151
+
152
+ def _new_connection_parameters(self):
153
+ return pika.ConnectionParameters(**self._connection_kwargs)
154
+
155
+ @abc.abstractmethod
156
+ def _new_connection(self):
157
+ raise NotImplementedError()
158
+
159
+ def connect(self, **connection_parameters_kwargs):
160
+ """Connect with client appropriate connection"""
161
+ self._build_and_save_connection_parameters_kwargs(**connection_parameters_kwargs)
162
+ connection = self._new_connection()
163
+ self._set_connection(connection)
164
+
165
+ def close(self):
166
+ # Stop consuming
167
+ if self.is_consuming:
168
+ self.stop_consuming()
169
+
170
+ # Stop processing data events
171
+ if self.is_processing_data_events:
172
+ self.stop_process_data_events()
173
+
174
+ # Close connection
175
+ if self.__connection and self.__connection.is_open:
176
+ self._close_connection()
177
+
178
+ def _close_connection(self, connection=None):
179
+ if connection is None:
180
+ connection = self.connection
181
+
182
+ if connection is None or not connection.is_open:
183
+ raise TechnicalException(f"[{self.name}] Connection is not opened")
184
+
185
+ if Tools.do_log(logger, logging.DEBUG):
186
+ logger.debug(f"[{self.name}] Closing connection ({id(connection)})...")
187
+
188
+ try:
189
+ self.__connection.close()
190
+ except (StreamLostError, ConnectionWrongStateError):
191
+ pass
192
+ except Exception as exc: # @UnusedVariable
193
+ #TODO: When this warning is logged during self.__del__, the log is cleared before, thus it is commented
194
+ # logger.warn(f"Error catched while closing RabbitMQ client connection:\n{Tools.represent_exception(exc)}")
195
+ # pass
196
+ raise exc
197
+
198
+ def __new_object_kwargs(self, obj, **kwargs):
199
+ res = NamedTuple('ObjectKwargs', object=object, kwargs=dict)
200
+ res.object = obj
201
+ res.kwargs = kwargs
202
+ return res
203
+
204
+ def new_publisher(self, queue, queue_args=None, exchange="", exchange_args=None, routing_key=None, nb_runners=None):
205
+ return self._new_publisher_with_connection(self.connection, queue, queue_args, exchange, exchange_args, routing_key, nb_runners)
206
+
207
+ def _new_publisher_with_connection(self, connection, queue, queue_args=None, exchange="", exchange_args=None, routing_key=None, nb_runners=None):
208
+ pub_channel = connection.channel()
209
+
210
+ queue_name = self._prepare_queue(pub_channel, queue, queue_args, exchange, exchange_args, bind_args=None)
211
+ if self.connection.publisher_confirms:
212
+ pub_channel.set_confirm_delivery()
213
+ else:
214
+ if Tools.do_log(logger, logging.DEBUG):
215
+ logger.debug(f"[{self.name}] Connection doesn't support publisher confirms")
216
+
217
+ if routing_key:
218
+ res = self._new_publisher(connection, pub_channel, exchange, routing_key, nb_runners)
219
+ else:
220
+ # TODO EKL: verify this case is functional
221
+ res = self._new_publisher(connection, pub_channel, exchange, queue_name, nb_runners)
222
+
223
+ self.__publisher_and_kwargs.append( self.__new_object_kwargs(res, queue=queue, queue_args=queue_args, exchange=exchange, exchange_args=exchange_args, routing_key=routing_key, nb_runners=nb_runners) )
224
+ return res
225
+
226
+ def _new_publisher(self, connection, channel, exchange, routing_key, nb_runners):
227
+ raise NotImplementedError
228
+
229
+ def new_consumer(self, queue, message_callback, queue_args=None, exchange="", exchange_args=None, bind_args=None):
230
+ return self._new_consumer_with_connection(self.connection, queue, message_callback, queue_args, exchange, exchange_args, bind_args)
231
+
232
+ def _new_consumer_with_connection(self, connection, queue, message_callback, queue_args=None, exchange="", exchange_args=None, bind_args=None):
233
+ con_channel = connection.channel()
234
+
235
+ if self.is_consuming:
236
+ raise FunctionalException(f"[{self.name}] Not allowed to create a new consumer while consuming is started")
237
+ queue_name = self._prepare_queue(con_channel, queue, queue_args, exchange, exchange_args, bind_args)
238
+ res = RMQConsumer(self, connection, con_channel, queue_name, message_callback)
239
+ self.__consumer_and_kwargs.append( self.__new_object_kwargs(res, queue=queue, message_callback=message_callback, queue_args=queue_args, exchange=exchange, exchange_args=exchange_args, bind_args=bind_args) )
240
+ return res
241
+
242
+ def new_buffer_consumer(self, queue, queue_args=None, exchange="", exchange_args=None, bind_args=None):
243
+ return self._new_buffer_consumer_with_connection(self.connection, queue, queue_args, exchange, exchange_args, bind_args)
244
+
245
+ def _new_buffer_consumer_with_connection(self, connection, queue, queue_args=None, exchange="", exchange_args=None, bind_args=None):
246
+ con_channel = connection.channel()
247
+
248
+ if self.is_consuming:
249
+ raise FunctionalException(f"[{self.name}] Not allowed to create a new consumer while consuming is started")
250
+ queue_name = self._prepare_queue(con_channel, queue, queue_args, exchange, exchange_args, bind_args)
251
+ res = RMQBufferConsumer(self, connection, con_channel, queue_name)
252
+ self.__buffer_consumer_and_kwargs.append( self.__new_object_kwargs(res, queue=queue, queue_args=queue_args, exchange=exchange, exchange_args=exchange_args, bind_args=bind_args) )
253
+ return res
254
+
255
+ def start_consuming(self):
256
+ if Tools.do_log(logger, logging.DEBUG):
257
+ logger.debug(f"[{self.name}] Start consuming...")
258
+ self.__is_consuming = True
259
+
260
+ for obj_kwargs in self.__consumer_and_kwargs:
261
+ obj_kwargs.object.start_consuming_in_thread()
262
+
263
+ for obj_kwargs in self.__buffer_consumer_and_kwargs:
264
+ obj_kwargs.object.start_consuming_in_thread()
265
+
266
+ def stop_consuming(self):
267
+ if Tools.do_log(logger, logging.DEBUG):
268
+ logger.debug(f"[{self.name}] Beginning stop consuming...")
269
+ self.__is_stopping_consuming = True
270
+ consumers_exceptions = []
271
+ try:
272
+ for obj_kwargs in self.__consumer_and_kwargs:
273
+ try:
274
+ obj_kwargs.object.stop_consuming()
275
+ except Exception as exc:
276
+ consumers_exceptions.append( (obj_kwargs.object, exc) )
277
+ for obj_kwargs in self.__buffer_consumer_and_kwargs:
278
+ try:
279
+ obj_kwargs.object.stop_consuming()
280
+ except Exception as exc:
281
+ consumers_exceptions.append( (obj_kwargs.object, exc) )
282
+ finally:
283
+ self.__is_stopping_consuming = False
284
+ self.__is_consuming = False
285
+
286
+ if consumers_exceptions:
287
+ logger.error(f"[{self.name}] Errors while stopping consuming on consumers: { {o.name:e for o,e in consumers_exceptions} }")
288
+ elif Tools.do_log(logger, logging.DEBUG):
289
+ logger.debug(f"[{self.name}] Finished stop consuming")
290
+
291
+ def start_process_data_events(self, raise_if_already_started=True):
292
+ if self.__process_data_events_thread is not None and self.__process_data_events_thread.is_alive():
293
+ if raise_if_already_started:
294
+ raise TechnicalException(f"[{self.name}] Thread processing data events is already running")
295
+ else:
296
+ return
297
+
298
+ if Tools.do_log(logger, logging.DEBUG):
299
+ logger.debug(f"[{self.name}] Start processing data events...")
300
+ self.__is_processing_data_events = True
301
+
302
+ self.__process_data_events_thread = LoopFunctionThreaded(self.connection.process_data_events, kwargs={'time_limit':1}, register_thread=True, delay_before_run_sec=None, delay_between_run_sec=0.01)
303
+ self.__process_data_events_thread.start()
304
+
305
+ def stop_process_data_events(self):
306
+ if not self.__is_processing_data_events:
307
+ if Tools.do_log(logger, logging.DEBUG):
308
+ logger.debug(f"[{self.name}] Client is not processing data events")
309
+ return
310
+ if self.__is_stopping_processing_data_events:
311
+ raise TechnicalException(f"[{self.name}] Data events processing is already under stop")
312
+
313
+ if Tools.do_log(logger, logging.DEBUG):
314
+ logger.debug(f"[{self.name}] Beginning stop data events processing...")
315
+ self.__is_stopping_processing_data_events = True
316
+ try:
317
+ self.__process_data_events_thread.interrupt()
318
+ self.__process_data_events_thread.join()
319
+ finally:
320
+ self.__is_stopping_processing_data_events = False
321
+ self.__is_processing_data_events = False
322
+ if Tools.do_log(logger, logging.DEBUG):
323
+ logger.debug(f"[{self.name}] Finished stop data events processing")
324
+
325
+ def _prepare_queue(self, channel, queue, queue_args=None, exchange="", exchange_args=None, bind_args=None):
326
+ if exchange is not None and exchange != "":
327
+ self._exchange_declare(channel, exchange, exchange_args)
328
+
329
+ if queue is not None and queue != "":
330
+ self._queue_declare(channel, queue, queue_args)
331
+ queue_name = queue
332
+ else:
333
+ q_args = dict(queue_args) if queue_args else {}
334
+ q_args['exclusive'] = True
335
+ result = self._queue_declare(channel, queue, q_args)
336
+ queue_name = result.method.queue
337
+
338
+ if exchange is not None and exchange != "":
339
+ self._queue_bind(channel, queue_name, exchange, bind_args)
340
+
341
+ return queue_name
342
+
343
+ def delete_queue(self, queue):
344
+ self.connection.channel().queue_delete(queue=queue)
345
+
346
+ def purge_queue(self, queue):
347
+ self.connection.channel().queue_purge(queue)
348
+
349
+ def _exchange_declare(self, channel, exchange, exchange_args=None):
350
+ kwargs = {}
351
+ arguments = None
352
+ if exchange_args:
353
+ arguments = dict(exchange_args)
354
+ for name in ['exchange_type', 'passive', 'durable', 'auto_delete', 'internal']:
355
+ if name in arguments:
356
+ kwargs[name] = arguments.pop(name)
357
+ return channel.exchange_declare(exchange, arguments=arguments, **kwargs)
358
+
359
+ def _queue_declare(self, channel, queue, queue_args=None):
360
+ kwargs = {}
361
+ arguments = None
362
+ if queue_args:
363
+ arguments = dict(queue_args)
364
+ for name in ['passive', 'durable', 'exclusive', 'auto_delete']:
365
+ if name in arguments:
366
+ kwargs[name] = arguments.pop(name)
367
+ return channel.queue_declare(queue, arguments=arguments, **kwargs)
368
+
369
+ def _queue_bind(self, channel, queue, exchange, bind_args=None):
370
+ kwargs = {}
371
+ arguments = None
372
+ if bind_args:
373
+ arguments = dict(bind_args)
374
+ for name in ['routing_key']:
375
+ if name in arguments:
376
+ kwargs[name] = arguments.pop(name)
377
+ return channel.queue_bind(queue, exchange, arguments=arguments, **kwargs)
378
+
379
+ def get_queue_message_count(self, queue):
380
+ channel = self.connection.channel()
381
+ status = self._queue_declare(channel, queue, {'passive':True})
382
+ return status.method.message_count
383
+
384
+ def is_queue_empty(self, queue, raise_exception=False):
385
+ nb = self.get_queue_message_count(queue)
386
+ res = (nb == 0)
387
+
388
+ if not res and raise_exception:
389
+ raise VerifyException(f"[{self.name}] Queue '{queue}' is not empty, it contains {nb} messages.")
390
+ return res
391
+
392
+ def flush(self):
393
+ if Tools.do_log(logger, logging.DEBUG):
394
+ logger.debug(f"[{self.name}] Flushing...")
395
+ for obj_kwargs in self._publisher_and_kwargs:
396
+ obj_kwargs.object.flush()
397
+ if Tools.do_log(logger, logging.DEBUG):
398
+ logger.debug(f"[{self.name}] Flushed")
399
+
400
+
401
+
402
+ class RMQPublisher(Object):
403
+ def __init__(self, client, connection, channel, exchange, routing_key):
404
+ super().__init__(f"RMQPublisher({routing_key})")
405
+ self.__client = client
406
+ self.__connection = connection
407
+ self.__channel = channel
408
+ self.__exchange = exchange
409
+ self.__routing_key = routing_key
410
+
411
+ @property
412
+ def client(self):
413
+ return self.__client
414
+
415
+ @property
416
+ def connection(self):
417
+ return self.__connection
418
+
419
+ @property
420
+ def channel(self):
421
+ return self.__channel
422
+
423
+ def publish(self, body, **kwargs):
424
+ kwargs['properties'] = pika.BasicProperties(delivery_mode=pika.DeliveryMode.Transient)
425
+ # kwargs['properties'] = pika.BasicProperties(delivery_mode=pika.DeliveryMode.Persistent)
426
+ # if self.__channel.has_confirm_delivery:
427
+ # kwargs['mandatory'] = True
428
+ self.__channel.basic_publish(exchange=self.__exchange, routing_key=self.__routing_key, body=body, **kwargs)
429
+
430
+
431
+ class RMQConsumer(DeleteableObject):
432
+ def __init__(self, client, connection, channel, queue, message_callback):
433
+ super().__init__(f"RMQConsumer({queue})")
434
+
435
+ self.__client = client
436
+ self.__connection = connection
437
+ self.__channel = channel
438
+ self.__queue = queue
439
+ self.__message_callback = message_callback
440
+
441
+ # self.__consuming_thread_id = None
442
+ self.__is_consuming = False
443
+ self.__is_stopping_consuming = False
444
+
445
+ self.__consumer_tag = self.__channel.basic_consume(queue=self.__queue, on_message_callback=self.__message_callback, auto_ack=True)
446
+
447
+ @property
448
+ def connection(self):
449
+ return self.__connection
450
+
451
+ @property
452
+ def channel(self):
453
+ return self.__channel
454
+
455
+ @property
456
+ def queue(self):
457
+ return self.__queue
458
+
459
+ @property
460
+ def consumer_tag(self):
461
+ return self.__consumer_tag
462
+
463
+ # @property
464
+ # def consuming_thread_id(self):
465
+ # return self.__consuming_thread_id
466
+ #
467
+ # @consuming_thread_id.setter
468
+ # def consuming_thread_id(self, thread_id):
469
+ # self.__consuming_thread_id = thread_id
470
+
471
+ @property
472
+ def is_consuming(self):
473
+ return self.__is_consuming
474
+
475
+ def _delete_object(self):
476
+ try:
477
+ # Cancel consumer
478
+ # self.__channel.basic_cancel(self.consumer_tag)
479
+
480
+ # Stop consuming
481
+ if self.is_consuming:
482
+ if Tools.do_log(logger, logging.DEBUG):
483
+ logger.debug(f"[{self.name}] Deleting RabbitMQClient: Stopping consuming...")
484
+ self.stop_consuming()
485
+
486
+ # Close channel
487
+ if self.__channel.is_open:
488
+ if Tools.do_log(logger, logging.DEBUG):
489
+ logger.debug(f"[{self.name}] Deleting RabbitMQClient: Closing channel...")
490
+ self.__channel.close()
491
+ except StreamLostError as exc:
492
+ if self.object_state == ObjectStates.Deleting:
493
+ pass
494
+ else:
495
+ raise exc
496
+
497
+ def start_consuming_in_thread(self):
498
+ func = FunctionThreaded(self.start_consuming, register_thread=True, delay_before_run_sec=None)
499
+ func.start()
500
+ # self.consuming_thread_id = MultitaskManager.get_thread_id(thread=func)
501
+
502
+ def start_consuming(self):
503
+ if Tools.do_log(logger, logging.DEBUG):
504
+ logger.debug(f"[{self.name}] Beginning start consuming...")
505
+
506
+ # Workaround:
507
+ # Sometimes "When start consuming" is called rather than "Then client is consuming"
508
+ # cf implementation of step @Given(r"start consuming in a thread \(RMQ client: (?P<var_client>\w+)\)")
509
+ # Workaround: register the thread_id allowed to start consuming.
510
+ # Note: A possible reason is that execute_steps is not thread safe. If it's true, the new implementation
511
+ # of the step with the wait of 0.01 seconds has resolved the problem, and thus this workaround is not needed anymore.
512
+ # if self.consuming_thread_id is not None:
513
+ # thread_id = MultitaskManager.get_thread_id()
514
+ # if thread_id != self.consuming_thread_id:
515
+ # logger.error(f"Only thread {self.consuming_thread_id} is allowed to start consuming. Tried to start consuming in thread {thread_id} with traceback:\n{traceback.represent_stack(indent=4)}")
516
+ # return
517
+
518
+ self.__is_consuming = True
519
+ try:
520
+ self.channel.start_consuming()
521
+ except Exception as exc:
522
+ if self.__is_stopping_consuming:
523
+ if isinstance(exc, pika.exceptions.StreamLostError) \
524
+ or isinstance(exc, AttributeError) and "NoneType' object has no attribute 'clear'" in str(exc) \
525
+ or isinstance(exc, AssertionError):
526
+ logger.info(f"[{self.name}] Caught exception in consuming thread while stopping consuming: {exc}")
527
+ else:
528
+ logger.warn(f"[{self.name}] Caught unexpected exception in consuming thread while stopping consuming: {Tools.represent_exception(exc)}")
529
+ else:
530
+ raise TechnicalException(f"[{self.name}] Failed to start consuming: {str(exc)}") from exc
531
+ finally:
532
+ # In all cases, self.__is_consuming must began False, otherwise stopping processing is broken in case of "raise exc"
533
+ self.__is_consuming = False
534
+ if Tools.do_log(logger, logging.DEBUG):
535
+ logger.debug(f"[{self.name}] Finished start consuming")
536
+
537
+ def stop_consuming(self):
538
+ if not self.__is_consuming:
539
+ if Tools.do_log(logger, logging.DEBUG):
540
+ logger.debug(f"[{self.name}] Consumer is not consuming")
541
+ return
542
+ if self.__is_stopping_consuming:
543
+ raise TechnicalException(f"[{self.name}] Consuming is already under stop")
544
+
545
+ if Tools.do_log(logger, logging.DEBUG):
546
+ logger.debug(f"[{self.name}] Beginning stop consuming...")
547
+ self.__is_stopping_consuming = True
548
+ try:
549
+ self.__stop_consuming_by_channel_stop_consuming()
550
+ # self.__stop_consuming_by_deleting_channel_consumer_infos()
551
+
552
+ # gc.collect()
553
+
554
+ # Wait end of consuming
555
+ if self.__is_consuming:
556
+ logger.info(f"[{self.name}] Waiting consuming thread is stopped...")
557
+
558
+ class StopRedo(Redo):
559
+ def __init__(self2): # @NoSelf
560
+ super().__init__(f"[{self.name}] Stop consuming on consumer {self.consumer_tag}")
561
+
562
+ def _process(self2): # @NoSelf
563
+ return self.is_consuming
564
+ redo = StopRedo()
565
+ redo.redo_while(True)
566
+ redo.with_timeout(30*60) # Timeout of 30 min
567
+ redo.polling_every(0.01) # Wait 0.1 s beetween each try
568
+ redo.with_process_in_thread(False) # Run process in thread is not needed
569
+ redo.execute()
570
+
571
+ if Tools.do_log(logger, logging.DEBUG):
572
+ logger.debug(f"[{self.name}] Finished waiting consuming thread is stopped")
573
+ finally:
574
+ self.__is_stopping_consuming = False
575
+ if Tools.do_log(logger, logging.DEBUG):
576
+ logger.debug(f"[{self.name}] Finished stop consuming")
577
+
578
+ def __stop_consuming_by_channel_stop_consuming(self):
579
+ try:
580
+ self.channel.stop_consuming()
581
+ except Exception as exc:
582
+ if isinstance(exc, pika.exceptions.StreamLostError) \
583
+ or isinstance(exc, AttributeError) and "NoneType' object has no attribute 'clear'" in str(exc) \
584
+ or isinstance(exc, AssertionError):
585
+ logger.info(f"[{self.name}] Caught exception while executing consuming stopping method: {exc}")
586
+ else:
587
+ logger.warn(f"[{self.name}] Caught exception while executing consuming stopping method: {Tools.represent_exception(exc)}")
588
+
589
+ def __stop_consuming_by_deleting_channel_consumer_infos(self):
590
+ del self.channel._consumer_infos[self.consumer_tag]
591
+ # Schedule termination of connection.process_data_events using a
592
+ # negative channel number
593
+ # self.connection._request_channel_dispatch(-self.channel.channel_number)
594
+ self.client.connection._request_channel_dispatch(-self.channel.channel_number)
595
+
596
+
597
+
598
+ class RMQBufferConsumer(Object):
599
+ def __init__(self, client, connection, channel, queue):
600
+ super().__init__(f"RMQBufferConsumer({queue})")
601
+ self.__consumer = RMQConsumer(client, connection, channel, queue, self.__message_callback)
602
+
603
+ self.__messages = []
604
+ self.__messages_lock = threading.Lock()
605
+
606
+ @property
607
+ def connection(self):
608
+ return self.__consumer.connection
609
+
610
+ @property
611
+ def nb_messages(self):
612
+ with self.__messages_lock:
613
+ return len(self.__messages)
614
+
615
+ @property
616
+ def messages(self):
617
+ with self.__messages_lock:
618
+ return list(self.__messages)
619
+
620
+ @property
621
+ def consumer_tag(self):
622
+ return self.__consumer.consumer_tag
623
+
624
+ # @property
625
+ # def consuming_thread_id(self):
626
+ # return self.__consumer.consuming_thread_id
627
+ #
628
+ # @consuming_thread_id.setter
629
+ # def consuming_thread_id(self, thread_id):
630
+ # self.__consumer.consuming_thread_id = thread_id
631
+
632
+ def start_consuming_in_thread(self):
633
+ self.__consumer.start_consuming_in_thread()
634
+
635
+ def start_consuming(self):
636
+ self.__consumer.start_consuming()
637
+
638
+ def stop_consuming(self):
639
+ self.__consumer.stop_consuming()
640
+
641
+ def __message_callback(self, channel, method, properties, body):
642
+ with self.__messages_lock:
643
+ self.__messages.append( (channel, method, properties, body) )
644
+ # logger.debug(f"[Consumer '{self.__consumer.queue}'] New message (total: {len(self.__messages)}): {channel=} ; {method=} ; {properties=} ; {body=}")
645
+ if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
646
+ logger.trace(f"[{self.name}] New message (total: {len(self.__messages)}): {body}")
647
+ elif Tools.do_log(logger, logging.DEBUG):
648
+ logger.debug(f"[{self.name}] New message (total: {len(self.__messages)})")
649
+
650
+ def reset_messages(self):
651
+ with self.__messages_lock:
652
+ if Tools.do_log(logger, logging.DEBUG):
653
+ logger.debug(f"[{self.name}] Reset messages (delete {len(self.__messages)} messages)")
654
+ self.__messages.clear()
655
+
656
+ def pop_first_message(self):
657
+ with self.__messages_lock:
658
+ res = self.__messages.pop(0)
659
+ if Tools.do_log(logger, logging.DEBUG):
660
+ logger.debug(f"[{self.name}] Pop first message (remaining: {len(self.__messages)}): {res}")
661
+ return res
662
+
663
+ def pop_and_save_messages(self, file:File, max_messages=None):
664
+ res = 0
665
+
666
+ nb_messages = self.nb_messages
667
+ while nb_messages > 0 and (max_messages is None or res < nb_messages):
668
+ msg = self.pop_first_message()
669
+ file.writelines([msg[3].hex()])
670
+ res += 1
671
+
672
+ nb_messages = self.nb_messages
673
+ if Tools.do_log(logger, logging.DEBUG):
674
+ logger.debug(f"[{self.name}] Saved a message (nb saved: {res} ; remaining: {nb_messages})")
675
+
676
+ return res
677
+
678
+