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.
- holado/__init__.py +358 -0
- holado/common/__init__.py +25 -0
- holado/common/context/__init__.py +25 -0
- holado/common/context/context.py +248 -0
- holado/common/context/service_manager.py +262 -0
- holado/common/context/session_context.py +516 -0
- holado/common/handlers/__init__.py +19 -0
- holado/common/handlers/enums.py +41 -0
- holado/common/handlers/object.py +175 -0
- holado/common/handlers/undefined.py +55 -0
- holado/common/tools/__init__.py +19 -0
- holado/common/tools/gc_manager.py +155 -0
- holado/holado_config.py +45 -0
- holado-0.13.22.dist-info/METADATA +194 -0
- holado-0.13.22.dist-info/RECORD +698 -0
- holado-0.13.22.dist-info/WHEEL +4 -0
- holado-0.13.22.dist-info/licenses/LICENSE +21 -0
- holado_ais/__init__.py +33 -0
- holado_ais/ais/MaritimeIdentificationDigits.csv +295 -0
- holado_ais/ais/ais_manager.py +151 -0
- holado_ais/ais/ais_messages.py +356 -0
- holado_ais/ais/ais_payload.py +35 -0
- holado_ais/ais/enums.py +37 -0
- holado_ais/ais/patch_pyais.py +1174 -0
- holado_ais/tests/behave/steps/__init__.py +17 -0
- holado_ais/tests/behave/steps/ais/__init__.py +0 -0
- holado_ais/tests/behave/steps/ais/ais_manager_steps.py +50 -0
- holado_ais/tests/behave/steps/ais/ais_messages_steps.py +237 -0
- holado_binary/__init__.py +17 -0
- holado_binary/ipc/binary.py +125 -0
- holado_binary/ipc/bit_series.py +307 -0
- holado_binary/tests/behave/steps/__init__.py +17 -0
- holado_binary/tests/behave/steps/ipc/binary_steps.py +57 -0
- holado_binary/tests/behave/steps/ipc/bit_series_steps.py +132 -0
- holado_context/__init__.py +16 -0
- holado_context/tests/behave/steps/__init__.py +16 -0
- holado_context/tests/behave/steps/private/__init__.py +16 -0
- holado_context/tests/behave/steps/private/common/context_steps.py +68 -0
- holado_core/__init__.py +32 -0
- holado_core/common/__init__.py +0 -0
- holado_core/common/actors/actions.py +97 -0
- holado_core/common/actors/actor.py +226 -0
- holado_core/common/actors/element_actor.py +32 -0
- holado_core/common/actors/find_actor.py +106 -0
- holado_core/common/actors/tree_actor.py +32 -0
- holado_core/common/actors/verify_actions.py +69 -0
- holado_core/common/block/base.py +122 -0
- holado_core/common/block/block_manager.py +173 -0
- holado_core/common/block/block_method.py +46 -0
- holado_core/common/block/block_steps.py +37 -0
- holado_core/common/block/function.py +42 -0
- holado_core/common/block/scope_function.py +28 -0
- holado_core/common/block/scope_manager.py +238 -0
- holado_core/common/block/scope_steps.py +141 -0
- holado_core/common/criterias/and_criteria.py +61 -0
- holado_core/common/criterias/criteria.py +78 -0
- holado_core/common/criterias/or_criteria.py +64 -0
- holado_core/common/criterias/tools/criteria_context.py +20 -0
- holado_core/common/criterias/tools/criteria_parameters.py +18 -0
- holado_core/common/drivers/driver.py +153 -0
- holado_core/common/drivers/element_driver.py +30 -0
- holado_core/common/drivers/element_internal_api.py +239 -0
- holado_core/common/drivers/internal_api.py +40 -0
- holado_core/common/drivers/tree_driver.py +30 -0
- holado_core/common/drivers/tree_internal_api.py +176 -0
- holado_core/common/exceptions/__init__.py +0 -0
- holado_core/common/exceptions/element_exception.py +28 -0
- holado_core/common/exceptions/exceptions.py +24 -0
- holado_core/common/exceptions/functional_exception.py +21 -0
- holado_core/common/exceptions/holado_exception.py +25 -0
- holado_core/common/exceptions/technical_exception.py +27 -0
- holado_core/common/exceptions/timeout_exception.py +20 -0
- holado_core/common/exceptions/verify_exception.py +20 -0
- holado_core/common/finders/after_in_tree_finder.py +87 -0
- holado_core/common/finders/element_finder.py +60 -0
- holado_core/common/finders/else_finder.py +105 -0
- holado_core/common/finders/finder.py +478 -0
- holado_core/common/finders/or_finder.py +98 -0
- holado_core/common/finders/then_finder.py +157 -0
- holado_core/common/finders/tools/enums.py +30 -0
- holado_core/common/finders/tools/find_builder.py +118 -0
- holado_core/common/finders/tools/find_context.py +405 -0
- holado_core/common/finders/tools/find_info.py +27 -0
- holado_core/common/finders/tools/find_parameters.py +240 -0
- holado_core/common/finders/tools/find_updater.py +95 -0
- holado_core/common/finders/tools/finder_info.py +26 -0
- holado_core/common/finders/tree_finder.py +146 -0
- holado_core/common/handlers/__init__.py +0 -0
- holado_core/common/handlers/abstracts/base_redo.py +702 -0
- holado_core/common/handlers/abstracts/get_or_create.py +120 -0
- holado_core/common/handlers/element_holder.py +122 -0
- holado_core/common/handlers/enums.py +23 -0
- holado_core/common/handlers/exceptions/redo_exceptions.py +28 -0
- holado_core/common/handlers/features/resource_by_name.py +187 -0
- holado_core/common/handlers/features/resource_by_type.py +174 -0
- holado_core/common/handlers/redo.py +119 -0
- holado_core/common/handlers/wait.py +127 -0
- holado_core/common/inspectors/element_inspector.py +57 -0
- holado_core/common/inspectors/inspector.py +221 -0
- holado_core/common/inspectors/tools/inspect_builder.py +169 -0
- holado_core/common/inspectors/tools/inspect_context.py +69 -0
- holado_core/common/inspectors/tools/inspect_parameters.py +181 -0
- holado_core/common/inspectors/tree_inspector.py +73 -0
- holado_core/common/resource/persisted_data_manager.py +113 -0
- holado_core/common/resource/persisted_method_to_call_manager.py +263 -0
- holado_core/common/resource/resource_manager.py +126 -0
- holado_core/common/resource/table_data_manager.py +110 -0
- holado_core/common/tables/__init__.py +1 -0
- holado_core/common/tables/comparators/__init__.py +0 -0
- holado_core/common/tables/comparators/boolean_table_cell_comparator.py +25 -0
- holado_core/common/tables/comparators/bytes_table_cell_comparator.py +25 -0
- holado_core/common/tables/comparators/datetime_table_cell_comparator.py +24 -0
- holado_core/common/tables/comparators/float_table_cell_comparator.py +31 -0
- holado_core/common/tables/comparators/integer_table_cell_comparator.py +25 -0
- holado_core/common/tables/comparators/internal_table_cell_comparator.py +30 -0
- holado_core/common/tables/comparators/string_table_cell_comparator.py +24 -0
- holado_core/common/tables/comparators/string_table_comparator.py +29 -0
- holado_core/common/tables/comparators/string_table_row_comparator.py +29 -0
- holado_core/common/tables/comparators/table_cell_comparator.py +40 -0
- holado_core/common/tables/comparators/table_comparator.py +209 -0
- holado_core/common/tables/comparators/table_comparator_manager.py +60 -0
- holado_core/common/tables/comparators/table_row_comparator.py +116 -0
- holado_core/common/tables/comparators/table_with_header_comparator.py +68 -0
- holado_core/common/tables/converters/__init__.py +0 -0
- holado_core/common/tables/converters/table_converter.py +233 -0
- holado_core/common/tables/enums.py +23 -0
- holado_core/common/tables/table.py +261 -0
- holado_core/common/tables/table_cell.py +126 -0
- holado_core/common/tables/table_manager.py +365 -0
- holado_core/common/tables/table_row.py +169 -0
- holado_core/common/tables/table_with_header.py +242 -0
- holado_core/common/tools/__init__.py +0 -0
- holado_core/common/tools/comparators/comparator.py +151 -0
- holado_core/common/tools/comparators/object_comparator.py +21 -0
- holado_core/common/tools/converters/converter.py +118 -0
- holado_core/common/tools/path_manager.py +238 -0
- holado_core/common/tools/string_tools.py +144 -0
- holado_core/common/tools/tools.py +197 -0
- holado_core/tests/behave/steps/__init__.py +20 -0
- holado_core/tests/behave/steps/common/__init__.py +0 -0
- holado_core/tests/behave/steps/common/common_steps.py +137 -0
- holado_core/tests/behave/steps/common/config_steps.py +42 -0
- holado_core/tests/behave/steps/common/resource_steps.py +62 -0
- holado_core/tests/behave/steps/common/tables_steps.py +560 -0
- holado_core/tools/__init__.py +0 -0
- holado_core/tools/abstracts/__init__.py +0 -0
- holado_core/tools/abstracts/blocking_command_service.py +64 -0
- holado_core/tools/abstracts/service.py +48 -0
- holado_crypto/__init__.py +31 -0
- holado_crypto/crypto/crypto.py +108 -0
- holado_crypto/crypto/key.py +92 -0
- holado_crypto/crypto/tcpbin.py +105 -0
- holado_crypto/crypto/transport/__init__.py +0 -0
- holado_crypto/crypto/transport/crc.py +40 -0
- holado_crypto/tests/behave/steps/__init__.py +18 -0
- holado_crypto/tests/behave/steps/crypto_steps.py +112 -0
- holado_crypto/tests/behave/steps/key_steps.py +82 -0
- holado_crypto/tests/behave/steps/tcpbin_steps.py +79 -0
- holado_data/__init__.py +31 -0
- holado_data/data/generator/base.py +93 -0
- holado_data/data/generator/generator_manager.py +27 -0
- holado_data/data/generator/python_generator.py +30 -0
- holado_data/tests/behave/steps/__init__.py +17 -0
- holado_data/tests/behave/steps/data/generator_steps.py +91 -0
- holado_data/tests/behave/steps/tools/utils_steps.py +59 -0
- holado_db/__init__.py +32 -0
- holado_db/tests/behave/steps/__init__.py +18 -0
- holado_db/tests/behave/steps/tools/db/db_client_steps.py +134 -0
- holado_db/tests/behave/steps/tools/db/postgresql_client_steps.py +59 -0
- holado_db/tests/behave/steps/tools/db/sqlite_client_steps.py +57 -0
- holado_db/tools/db/clients/base/db_audit.py +94 -0
- holado_db/tools/db/clients/base/db_client.py +344 -0
- holado_db/tools/db/clients/postgresql/postgresql_audit.py +75 -0
- holado_db/tools/db/clients/postgresql/postgresql_client.py +84 -0
- holado_db/tools/db/clients/sqlite/sqlite_audit.py +70 -0
- holado_db/tools/db/clients/sqlite/sqlite_client.py +60 -0
- holado_db/tools/db/db_manager.py +109 -0
- holado_db/tools/db/query/base/query_builder.py +138 -0
- holado_db/tools/db/query/pypika/pypika_query_builder.py +244 -0
- holado_db/tools/db/query/query_manager.py +77 -0
- holado_django/__init__.py +31 -0
- holado_django/server/HOWTO.txt +27 -0
- holado_django/server/django_projects/rest_api/db.sqlite3 +0 -0
- holado_django/server/django_projects/rest_api/manage.py +22 -0
- holado_django/server/django_projects/rest_api/rest_api/__init__.py +0 -0
- holado_django/server/django_projects/rest_api/rest_api/application/__init__.py +0 -0
- holado_django/server/django_projects/rest_api/rest_api/application/admin.py +3 -0
- holado_django/server/django_projects/rest_api/rest_api/application/apps.py +9 -0
- holado_django/server/django_projects/rest_api/rest_api/application/migrations/__init__.py +0 -0
- holado_django/server/django_projects/rest_api/rest_api/application/models.py +3 -0
- holado_django/server/django_projects/rest_api/rest_api/application/tests.py +3 -0
- holado_django/server/django_projects/rest_api/rest_api/application/views.py +6 -0
- holado_django/server/django_projects/rest_api/rest_api/asgi.py +16 -0
- holado_django/server/django_projects/rest_api/rest_api/settings.py +130 -0
- holado_django/server/django_projects/rest_api/rest_api/urls.py +35 -0
- holado_django/server/django_projects/rest_api/rest_api/wsgi.py +16 -0
- holado_django/server/django_server.py +110 -0
- holado_django/server/grpc_django_server.py +57 -0
- holado_django/server/patch_djangogrpcframework.py +46 -0
- holado_django/tests/behave/steps/__init__.py +16 -0
- holado_django/tests/behave/steps/django_server_steps.py +83 -0
- holado_docker/__init__.py +25 -0
- holado_docker/sdk/docker/container_logs.py +447 -0
- holado_docker/sdk/docker/docker_client.py +537 -0
- holado_docker/sdk/docker/docker_service.py +71 -0
- holado_docker/tests/behave/steps/__init__.py +16 -0
- holado_docker/tests/behave/steps/sdk/docker/container_logs_steps.py +47 -0
- holado_examples/projects/server_rest/server_rest_example/initialize_holado.py +72 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/db.sqlite3 +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/manage.py +22 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/__init__.py +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/__init__.py +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/admin.py +3 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/apps.py +7 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/migrations/__init__.py +0 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/models.py +3 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/serializers.py +15 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/tests.py +3 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/application/views.py +24 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/asgi.py +16 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/settings.py +130 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/urls.py +31 -0
- holado_examples/projects/server_rest/server_rest_example/rest_api/rest_api/wsgi.py +16 -0
- holado_examples/projects/server_rest/server_rest_example/rest_server.py +37 -0
- holado_examples/scripts/script_custom_initialization.py +16 -0
- holado_examples/scripts/script_minimal_initialization.py +23 -0
- holado_examples/tests/behave/testing_solution/__main__.py +13 -0
- holado_examples/tests/behave/testing_solution/behave_environment.py +35 -0
- holado_examples/tests/behave/testing_solution/environment.py +36 -0
- holado_examples/tests/behave/testing_solution/features/Configuration/Actions/configure_system.feature +10 -0
- holado_examples/tests/behave/testing_solution/features/NonReg/example.feature +26 -0
- holado_examples/tests/behave/testing_solution/initialize_holado.py +62 -0
- holado_examples/tests/behave/testing_solution/logging.conf +102 -0
- holado_examples/tests/behave/testing_solution/requirements.txt +5 -0
- holado_examples/tests/behave/testing_solution/run_test.sh +7 -0
- holado_examples/tests/behave/testing_solution/run_test_nonreg.sh +6 -0
- holado_examples/tests/behave/testing_solution/src/common/tools/path_manager.py +40 -0
- holado_examples/tests/behave/testing_solution/src/config/config_manager.py +30 -0
- holado_examples/tests/behave/testing_solution/src/context/session_context.py +45 -0
- holado_examples/tests/behave/testing_solution/steps/config_steps.py +21 -0
- holado_examples/tests/behave/testing_solution/steps/public_steps.py +10 -0
- holado_grpc/TODO +8 -0
- holado_grpc/__init__.py +40 -0
- holado_grpc/api/rpc/TODO.txt +4 -0
- holado_grpc/api/rpc/grpc_client.py +210 -0
- holado_grpc/api/rpc/grpc_manager.py +81 -0
- holado_grpc/ipc/rpc/__init__.py +0 -0
- holado_grpc/ipc/rpc/grpc_compiler.py +45 -0
- holado_grpc/ipc/rpc/grpc_services.py +165 -0
- holado_grpc/tests/behave/steps/__init__.py +16 -0
- holado_grpc/tests/behave/steps/api/grpc_client_steps.py +173 -0
- holado_grpc/tests/behave/steps/private/__init__.py +16 -0
- holado_grpc/tests/behave/steps/private/api/grpc_steps.py +77 -0
- holado_helper/__init__.py +35 -0
- holado_helper/debug/README.txt +32 -0
- holado_helper/debug/memory/memory_profiler.py +106 -0
- holado_helper/docker/init_user.sh +24 -0
- holado_helper/docker/logging.conf +44 -0
- holado_helper/docker/run_holado_test_nonreg_in_docker.sh +120 -0
- holado_helper/docker/run_terminal_in_docker.sh +101 -0
- holado_helper/holado_module_template/__init__.py +38 -0
- holado_helper/holado_module_template/tests/behave/steps/__init__.py +16 -0
- holado_helper/holado_module_template/tests/behave/steps/private/__init__.py +16 -0
- holado_helper/initialize_holado.py +72 -0
- holado_helper/script/action.py +130 -0
- holado_helper/script/action_script.py +477 -0
- holado_helper/script/any_action_script.py +126 -0
- holado_helper/script/behave_action_script.py +99 -0
- holado_helper/script/csv_action_script.py +142 -0
- holado_helper/script/initialize_script.py +95 -0
- holado_helper/script/input_output_script.py +136 -0
- holado_helper/script/job.py +75 -0
- holado_helper/script/json_action_script.py +104 -0
- holado_helper/script/script.py +110 -0
- holado_json/__init__.py +16 -0
- holado_json/filesystem/json_file.py +94 -0
- holado_json/filesystem/stream_json_file.py +117 -0
- holado_json/ipc/json.py +146 -0
- holado_json/ipc/json_converter.py +69 -0
- holado_json/ipc/json_types.py +183 -0
- holado_json/tests/behave/steps/__init__.py +16 -0
- holado_json/tests/behave/steps/ipc/__init__.py +0 -0
- holado_json/tests/behave/steps/ipc/json_steps.py +131 -0
- holado_keycloak/__init__.py +16 -0
- holado_keycloak/tests/behave/steps/__init__.py +16 -0
- holado_keycloak/tests/behave/steps/tools/keycloak_client_steps.py +73 -0
- holado_keycloak/tools/keycloak/__init__.py +0 -0
- holado_keycloak/tools/keycloak/keycloak_client.py +90 -0
- holado_logging/__init__.py +38 -0
- holado_logging/common/logging/holado_logger.py +71 -0
- holado_logging/common/logging/log_config.py +163 -0
- holado_logging/common/logging/log_manager.py +335 -0
- holado_multitask/__init__.py +33 -0
- holado_multitask/multiprocessing/context/process_context.py +35 -0
- holado_multitask/multiprocessing/function_process.py +102 -0
- holado_multitask/multiprocessing/periodic_function_process.py +137 -0
- holado_multitask/multiprocessing/process.py +213 -0
- holado_multitask/multiprocessing/processesmanager.py +137 -0
- holado_multitask/multitasking/multitask_manager.py +464 -0
- holado_multitask/multithreading/__init__.py +0 -0
- holado_multitask/multithreading/context/thread_context.py +86 -0
- holado_multitask/multithreading/functionthreaded.py +129 -0
- holado_multitask/multithreading/loopfunctionthreaded.py +45 -0
- holado_multitask/multithreading/loopthread.py +110 -0
- holado_multitask/multithreading/periodicfunctionthreaded.py +135 -0
- holado_multitask/multithreading/reflection/inspect.py +47 -0
- holado_multitask/multithreading/reflection/sys.py +29 -0
- holado_multitask/multithreading/reflection/traceback.py +35 -0
- holado_multitask/multithreading/thread.py +203 -0
- holado_multitask/multithreading/threadsmanager.py +167 -0
- holado_multitask/multithreading/timer.py +51 -0
- holado_multitask/tests/behave/steps/__init__.py +17 -0
- holado_multitask/tests/behave/steps/multiprocessing_steps.py +138 -0
- holado_multitask/tests/behave/steps/multithreading_steps.py +129 -0
- holado_protobuf/__init__.py +61 -0
- holado_protobuf/ipc/protobuf/__init__.py +0 -0
- holado_protobuf/ipc/protobuf/abstracts/type.py +45 -0
- holado_protobuf/ipc/protobuf/protobuf_compiler.py +118 -0
- holado_protobuf/ipc/protobuf/protobuf_converter.py +153 -0
- holado_protobuf/ipc/protobuf/protobuf_messages.py +968 -0
- holado_protobuf/ipc/protobuf/protobuf_modifier.py +65 -0
- holado_protobuf/ipc/protobuf/types/__init__.py +0 -0
- holado_protobuf/ipc/protobuf/types/google/__init__.py +0 -0
- holado_protobuf/ipc/protobuf/types/google/protobuf.py +124 -0
- holado_protobuf/tests/behave/steps/__init__.py +16 -0
- holado_protobuf/tests/behave/steps/ipc/protobuf_steps.py +297 -0
- holado_python/__init__.py +36 -0
- holado_python/common/enums.py +34 -0
- holado_python/common/iterables.py +38 -0
- holado_python/common/tools/comparators/boolean_comparator.py +37 -0
- holado_python/common/tools/comparators/bytes_comparator.py +48 -0
- holado_python/common/tools/comparators/datetime_comparator.py +74 -0
- holado_python/common/tools/comparators/float_comparator.py +97 -0
- holado_python/common/tools/comparators/integer_comparator.py +37 -0
- holado_python/common/tools/comparators/string_comparator.py +99 -0
- holado_python/common/tools/comparators/type_comparator.py +31 -0
- holado_python/common/tools/datetime.py +341 -0
- holado_python/standard_library/csv.py +207 -0
- holado_python/standard_library/hashlib.py +110 -0
- holado_python/standard_library/multiprocessing.py +62 -0
- holado_python/standard_library/queue.py +79 -0
- holado_python/standard_library/socket/blocking_socket.py +219 -0
- holado_python/standard_library/socket/echo_server.py +29 -0
- holado_python/standard_library/socket/message_socket.py +152 -0
- holado_python/standard_library/socket/non_blocking_socket.py +172 -0
- holado_python/standard_library/socket/socket.py +411 -0
- holado_python/standard_library/ssl/resources/certificates/NOTES.txt +5 -0
- holado_python/standard_library/ssl/resources/certificates/localhost.crt +19 -0
- holado_python/standard_library/ssl/resources/certificates/localhost.key +28 -0
- holado_python/standard_library/ssl/ssl.py +131 -0
- holado_python/standard_library/typing.py +192 -0
- holado_python/tests/behave/steps/__init__.py +27 -0
- holado_python/tests/behave/steps/builtins/str_steps.py +45 -0
- holado_python/tests/behave/steps/convert_steps.py +59 -0
- holado_python/tests/behave/steps/iterable_steps.py +87 -0
- holado_python/tests/behave/steps/standard_library/csv_steps.py +134 -0
- holado_python/tests/behave/steps/standard_library/datetime_steps.py +163 -0
- holado_python/tests/behave/steps/standard_library/hashlib_steps.py +57 -0
- holado_python/tests/behave/steps/standard_library/multiprocessing_steps.py +56 -0
- holado_python/tests/behave/steps/standard_library/queue_steps.py +358 -0
- holado_python/tests/behave/steps/standard_library/socket_steps.py +384 -0
- holado_python/tests/behave/steps/standard_library/ssl_steps.py +71 -0
- holado_rabbitmq/__init__.py +28 -0
- holado_rabbitmq/tests/behave/steps/__init__.py +17 -0
- holado_rabbitmq/tests/behave/steps/tools/rabbitmq_client_steps.py +565 -0
- holado_rabbitmq/tests/behave/steps/tools/rabbitmq_server_steps.py +64 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_blocking_client.py +333 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_client.py +678 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_manager.py +146 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_select_client.py +428 -0
- holado_rabbitmq/tools/rabbitmq/rabbitmq_server.py +24 -0
- holado_redis/__init__.py +17 -0
- holado_redis/tests/behave/steps/__init__.py +16 -0
- holado_redis/tests/behave/steps/tools/redis_client_steps.py +101 -0
- holado_redis/tools/redis/TODO.txt +7 -0
- holado_redis/tools/redis/redis_client.py +190 -0
- holado_redis/tools/redis/redis_manager.py +38 -0
- holado_report/__init__.py +36 -0
- holado_report/campaign/campaign_manager.py +348 -0
- holado_report/report/analyze/execution_historic_manager.py +96 -0
- holado_report/report/analyze/scenario_duration_manager.py +245 -0
- holado_report/report/builders/detailed_scenario_report_builder.py +172 -0
- holado_report/report/builders/execution_historic_report_builder.py +132 -0
- holado_report/report/builders/failure_report_builder.py +150 -0
- holado_report/report/builders/report_builder.py +64 -0
- holado_report/report/builders/short_scenario_report_builder.py +94 -0
- holado_report/report/builders/summary_by_category_report_builder.py +103 -0
- holado_report/report/builders/summary_report_builder.py +110 -0
- holado_report/report/builders/summary_scenario_by_category_report_builder.py +109 -0
- holado_report/report/builders/summary_scenario_report_builder.py +81 -0
- holado_report/report/execution_historic.py +144 -0
- holado_report/report/report_manager.py +424 -0
- holado_report/report/reports/base_report.py +163 -0
- holado_report/report/reports/feature_report.py +106 -0
- holado_report/report/reports/scenario_report.py +64 -0
- holado_rest/__init__.py +32 -0
- holado_rest/api/rest/TODO.txt +2 -0
- holado_rest/api/rest/rest_client.py +200 -0
- holado_rest/api/rest/rest_manager.py +72 -0
- holado_rest/tests/behave/steps/__init__.py +16 -0
- holado_rest/tests/behave/steps/api/__init__.py +0 -0
- holado_rest/tests/behave/steps/api/rest_client_steps.py +181 -0
- holado_rest/tests/behave/steps/private/__init__.py +16 -0
- holado_rest/tests/behave/steps/private/api/__init__.py +0 -0
- holado_rest/tests/behave/steps/private/api/rest_steps.py +75 -0
- holado_s3/__init__.py +17 -0
- holado_s3/tests/behave/steps/__init__.py +17 -0
- holado_s3/tests/behave/steps/private/__init__.py +16 -0
- holado_s3/tests/behave/steps/private/tools/s3_steps.py +89 -0
- holado_s3/tests/behave/steps/tools/s3_client_steps.py +403 -0
- holado_s3/tests/behave/steps/tools/s3_server_steps.py +57 -0
- holado_s3/tools/s3/__init__.py +0 -0
- holado_s3/tools/s3/boto3_s3_client.py +59 -0
- holado_s3/tools/s3/minio_client.py +75 -0
- holado_s3/tools/s3/moto_server.py +52 -0
- holado_scripting/__init__.py +54 -0
- holado_scripting/common/tools/dynamic_text_manager.py +73 -0
- holado_scripting/common/tools/evaluate_parameters.py +228 -0
- holado_scripting/common/tools/expression_evaluator.py +389 -0
- holado_scripting/common/tools/variable_manager.py +354 -0
- holado_scripting/tests/behave/steps/__init__.py +22 -0
- holado_scripting/tests/behave/steps/common/tools/variable_convert_steps.py +159 -0
- holado_scripting/tests/behave/steps/common/tools/variable_new_steps.py +130 -0
- holado_scripting/tests/behave/steps/common/tools/variable_steps.py +108 -0
- holado_scripting/tests/behave/steps/common/tools/variable_verify_steps.py +160 -0
- holado_scripting/tests/behave/steps/scenario/function_steps.py +77 -0
- holado_scripting/tests/behave/steps/scenario/if_steps.py +87 -0
- holado_scripting/tests/behave/steps/scenario/loop_steps.py +119 -0
- holado_scripting/text/base/base_function.py +25 -0
- holado_scripting/text/base/base_verify_function.py +25 -0
- holado_scripting/text/base/text_inspecter.py +204 -0
- holado_scripting/text/interpreter/exceptions/interpreter_exception.py +25 -0
- holado_scripting/text/interpreter/functions/function_apply_function.py +60 -0
- holado_scripting/text/interpreter/functions/function_cast.py +60 -0
- holado_scripting/text/interpreter/functions/function_convert.py +57 -0
- holado_scripting/text/interpreter/functions/function_dynamic_value.py +40 -0
- holado_scripting/text/interpreter/functions/function_escape_all_bytes.py +35 -0
- holado_scripting/text/interpreter/functions/function_exists_variable.py +39 -0
- holado_scripting/text/interpreter/functions/function_hex_to_bytes.py +49 -0
- holado_scripting/text/interpreter/functions/function_hex_to_int.py +53 -0
- holado_scripting/text/interpreter/functions/function_to_base_64.py +41 -0
- holado_scripting/text/interpreter/functions/function_to_bytes.py +50 -0
- holado_scripting/text/interpreter/functions/function_to_hex.py +42 -0
- holado_scripting/text/interpreter/functions/function_to_string.py +50 -0
- holado_scripting/text/interpreter/text_interpreter.py +219 -0
- holado_scripting/text/verifier/exceptions/verifier_exception.py +21 -0
- holado_scripting/text/verifier/functions/verify_function_extract_in.py +35 -0
- holado_scripting/text/verifier/functions/verify_function_match_pattern.py +63 -0
- holado_scripting/text/verifier/text_verifier.py +103 -0
- holado_sftp/__init__.py +16 -0
- holado_sftp/tests/behave/steps/__init__.py +17 -0
- holado_sftp/tests/behave/steps/private/__init__.py +16 -0
- holado_sftp/tests/behave/steps/private/tools/sftp_steps.py +78 -0
- holado_sftp/tests/behave/steps/tools/sftp_client_steps.py +94 -0
- holado_sftp/tests/behave/steps/tools/sftp_server_steps.py +82 -0
- holado_sftp/tools/sftp/__init__.py +0 -0
- holado_sftp/tools/sftp/sftp_client.py +103 -0
- holado_sftp/tools/sftp/sftp_server.py +39 -0
- holado_swagger/__init__.py +31 -0
- holado_swagger/swagger_hub/mockserver/mockserver_client.py +82 -0
- holado_swagger/swagger_hub/mockserver/mockserver_manager.py +33 -0
- holado_swagger/tests/behave/steps/__init__.py +16 -0
- holado_swagger/tests/behave/steps/swagger_hub/mockserver_steps.py +74 -0
- holado_system/system/command/command.py +247 -0
- holado_system/system/command/command_result.py +128 -0
- holado_system/system/command/curl_command.py +101 -0
- holado_system/system/command/exceptions.py +59 -0
- holado_system/system/filesystem/file.py +150 -0
- holado_system/system/global_system.py +187 -0
- holado_system/tests/behave/steps/__init__.py +18 -0
- holado_system/tests/behave/steps/system/commands_steps.py +92 -0
- holado_system/tests/behave/steps/system/file_steps.py +231 -0
- holado_system/tests/behave/steps/system/system_steps.py +84 -0
- holado_test/__init__.py +30 -0
- holado_test/behave/__init__.py +0 -0
- holado_test/behave/behave.py +400 -0
- holado_test/behave/behave_environment.py +169 -0
- holado_test/behave/behave_function.py +33 -0
- holado_test/behave/behave_manager.py +558 -0
- holado_test/behave/independant_runner.py +66 -0
- holado_test/behave/scenario/__init__.py +0 -0
- holado_test/behave/scenario/behave_step_tools.py +157 -0
- holado_test/common/context/feature_context.py +81 -0
- holado_test/common/context/scenario_context.py +169 -0
- holado_test/common/context/step_context.py +66 -0
- holado_test/common/exceptions/undefined_step_exception.py +21 -0
- holado_test/scenario/step_tools.py +547 -0
- holado_test/scenario/tester_tools.py +57 -0
- holado_test/test_config.py +26 -0
- holado_test/tests/behave/steps/__init__.py +18 -0
- holado_test/tests/behave/steps/scenario/exception_steps.py +87 -0
- holado_test/tests/behave/steps/scenario/scenario_steps.py +100 -0
- holado_test/tests/behave/steps/scenario/tester_steps.py +65 -0
- holado_test/tools/test_server/client/rest/test_server_client.py +150 -0
- holado_test/tools/test_server/server/Dockerfile +60 -0
- holado_test/tools/test_server/server/core/server_context.py +42 -0
- holado_test/tools/test_server/server/core/server_manager.py +41 -0
- holado_test/tools/test_server/server/requirements.txt +2 -0
- holado_test/tools/test_server/server/rest/README +2 -0
- holado_test/tools/test_server/server/rest/api/__init__.py +24 -0
- holado_test/tools/test_server/server/rest/api/campaign/__init__.py +32 -0
- holado_test/tools/test_server/server/rest/api/campaign/scenario.py +40 -0
- holado_test/tools/test_server/server/rest/initialize_holado.py +72 -0
- holado_test/tools/test_server/server/rest/logging.conf +51 -0
- holado_test/tools/test_server/server/rest/openapi.yaml +57 -0
- holado_test/tools/test_server/server/rest/run.py +41 -0
- holado_test/tools/test_server/server/run.sh +6 -0
- holado_test/tools/test_server/server/run_test_server_in_docker.sh +104 -0
- holado_tools/__init__.py +38 -0
- holado_tools/scripts/execute_persisted_post_processes/execute_persisted_post_processes.py +36 -0
- holado_tools/scripts/execute_persisted_post_processes/execute_persisted_post_processes.sh +6 -0
- holado_tools/scripts/execute_persisted_post_processes/initialize_holado.py +62 -0
- holado_tools/tests/behave/steps/__init__.py +16 -0
- holado_tools/tests/behave/steps/tools/host_controller/client_steps.py +97 -0
- holado_tools/tools/host_controller/client/rest/host_controller_client.py +275 -0
- holado_tools/tools/host_controller/server/Dockerfile +60 -0
- holado_tools/tools/host_controller/server/requirements.txt +2 -0
- holado_tools/tools/host_controller/server/rest/README +2 -0
- holado_tools/tools/host_controller/server/rest/api/__init__.py +24 -0
- holado_tools/tools/host_controller/server/rest/api/config.py +88 -0
- holado_tools/tools/host_controller/server/rest/api/docker/__init__.py +66 -0
- holado_tools/tools/host_controller/server/rest/api/docker/container.py +144 -0
- holado_tools/tools/host_controller/server/rest/api/docker/logs.py +66 -0
- holado_tools/tools/host_controller/server/rest/api/os.py +58 -0
- holado_tools/tools/host_controller/server/rest/initialize_holado.py +72 -0
- holado_tools/tools/host_controller/server/rest/openapi.yaml +561 -0
- holado_tools/tools/host_controller/server/rest/run.py +31 -0
- holado_tools/tools/host_controller/server/run_host_controller_in_docker.sh +107 -0
- holado_tools/tools/host_viewer/client/rest/host_viewer_client.py +190 -0
- holado_tools/tools/host_viewer/server/Dockerfile +60 -0
- holado_tools/tools/host_viewer/server/requirements.txt +2 -0
- holado_tools/tools/host_viewer/server/rest/README +2 -0
- holado_tools/tools/host_viewer/server/rest/api/__init__.py +24 -0
- holado_tools/tools/host_viewer/server/rest/api/docker/__init__.py +65 -0
- holado_tools/tools/host_viewer/server/rest/api/docker/container.py +87 -0
- holado_tools/tools/host_viewer/server/rest/api/os.py +58 -0
- holado_tools/tools/host_viewer/server/rest/initialize_holado.py +72 -0
- holado_tools/tools/host_viewer/server/rest/openapi.yaml +301 -0
- holado_tools/tools/host_viewer/server/rest/run.py +31 -0
- holado_tools/tools/host_viewer/server/run_host_viewer_in_docker.sh +107 -0
- holado_value/__init__.py +24 -0
- holado_value/common/tables/comparators/table_2_value_table_cell_comparator.py +196 -0
- holado_value/common/tables/comparators/table_2_value_table_comparator.py +27 -0
- holado_value/common/tables/comparators/table_2_value_table_row_comparator.py +27 -0
- holado_value/common/tables/comparators/table_2_value_table_with_header_comparator.py +27 -0
- holado_value/common/tables/converters/value_table_converter.py +267 -0
- holado_value/common/tables/value_table.py +29 -0
- holado_value/common/tables/value_table_cell.py +76 -0
- holado_value/common/tables/value_table_manager.py +48 -0
- holado_value/common/tables/value_table_row.py +43 -0
- holado_value/common/tables/value_table_with_header.py +28 -0
- holado_value/common/tools/unique_value_manager.py +109 -0
- holado_value/common/tools/value.py +191 -0
- holado_value/common/tools/value_types.py +41 -0
- holado_value/tests/behave/steps/__init__.py +16 -0
- holado_value/tests/behave/steps/private/__init__.py +16 -0
- holado_ws/__init__.py +16 -0
- holado_ws/api/ws/TODO.txt +2 -0
- holado_ws/tests/behave/steps/__init__.py +16 -0
- holado_ws/tests/behave/steps/api/web_service_steps.py +189 -0
- holado_xml/__init__.py +38 -0
- holado_xml/tests/behave/steps/__init__.py +16 -0
- holado_xml/tests/behave/steps/private/__init__.py +16 -0
- holado_xml/xml/stream_xml_file.py +181 -0
- holado_xml/xml/xml_file.py +97 -0
- holado_xml/xml/xml_manager.py +35 -0
- holado_yaml/__init__.py +31 -0
- holado_yaml/tests/behave/steps/__init__.py +16 -0
- holado_yaml/tests/behave/steps/yaml_steps.py +161 -0
- holado_yaml/yaml/enums.py +28 -0
- holado_yaml/yaml/pyyaml/pyyaml_client.py +72 -0
- holado_yaml/yaml/ruamel/ruamel_yaml_client.py +80 -0
- holado_yaml/yaml/yaml_client.py +203 -0
- holado_yaml/yaml/yaml_manager.py +94 -0
- test_holado/Dockerfile_test_holado +82 -0
- test_holado/__init__.py +4 -0
- test_holado/__main__.py +25 -0
- test_holado/build_docker_image_to_test_holado_in_docker.sh +7 -0
- test_holado/environment.py +60 -0
- test_holado/features/Configuration/Actions/execute_persisted_post_processes.feature +13 -0
- test_holado/features/NonReg/api/REST.feature +26 -0
- test_holado/features/NonReg/api/gRPC.feature +116 -0
- test_holado/features/NonReg/common/multiprocessing/simple.feature +60 -0
- test_holado/features/NonReg/common/system/commands.feature +43 -0
- test_holado/features/NonReg/common/system/system.feature +20 -0
- test_holado/features/NonReg/common/tables/table.feature +245 -0
- test_holado/features/NonReg/common/tables/value_table_conversion.feature +29 -0
- test_holado/features/NonReg/common/tools/DateTime.feature +88 -0
- test_holado/features/NonReg/common/tools/UniqueValueManager.feature +43 -0
- test_holado/features/NonReg/holado_ais/ais_message-bitarray_to_nmea.feature +135 -0
- test_holado/features/NonReg/holado_ais/ais_message-nmea_raw_to_dict.feature +93 -0
- test_holado/features/NonReg/holado_ais/message_types/type-10.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-12.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-14.feature +36 -0
- test_holado/features/NonReg/holado_ais/message_types/type-15.feature +36 -0
- test_holado/features/NonReg/holado_ais/message_types/type-16.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-17.feature +46 -0
- test_holado/features/NonReg/holado_ais/message_types/type-18.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-19.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-1_2_3.feature +42 -0
- test_holado/features/NonReg/holado_ais/message_types/type-20.feature +38 -0
- test_holado/features/NonReg/holado_ais/message_types/type-21.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-22.feature +84 -0
- test_holado/features/NonReg/holado_ais/message_types/type-23.feature +49 -0
- test_holado/features/NonReg/holado_ais/message_types/type-24.feature +72 -0
- test_holado/features/NonReg/holado_ais/message_types/type-25.feature +143 -0
- test_holado/features/NonReg/holado_ais/message_types/type-26.feature +144 -0
- test_holado/features/NonReg/holado_ais/message_types/type-27.feature +36 -0
- test_holado/features/NonReg/holado_ais/message_types/type-4_11.feature +39 -0
- test_holado/features/NonReg/holado_ais/message_types/type-5.feature +33 -0
- test_holado/features/NonReg/holado_ais/message_types/type-6.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-7_13.feature +43 -0
- test_holado/features/NonReg/holado_ais/message_types/type-8.feature +37 -0
- test_holado/features/NonReg/holado_ais/message_types/type-9.feature +37 -0
- test_holado/features/NonReg/holado_binary/bit_series.error.feature +33 -0
- test_holado/features/NonReg/holado_binary/bit_series.feature +144 -0
- test_holado/features/NonReg/holado_protobuf/protobuf.feature +291 -0
- test_holado/features/NonReg/holado_python/convert.feature +20 -0
- test_holado/features/NonReg/holado_python/iterable.feature +61 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_reset.feature +191 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_with_tls_and_verify.feature +279 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_with_tls_without_verify.feature +299 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/local_echo_server/socket_without_tls.feature +163 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_with_mtls.feature +214 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_with_tls.feature +184 -0
- test_holado/features/NonReg/holado_python/standard_library/socket/tcpbin.com/socket_without_tls.feature +169 -0
- test_holado/features/NonReg/holado_scripting/common/tools/dynamic_text_manager.feature +18 -0
- test_holado/features/NonReg/holado_scripting/common/tools/expression_evaluator.feature +185 -0
- test_holado/features/NonReg/holado_scripting/common/tools/variable_manager.feature +71 -0
- test_holado/features/NonReg/holado_scripting/text/interpreter/interpreter.error.feature +21 -0
- test_holado/features/NonReg/holado_scripting/text/interpreter/interpreter.feature +120 -0
- test_holado/features/NonReg/holado_yaml/yaml.feature +514 -0
- test_holado/features/NonReg/ipc/json.feature +20 -0
- test_holado/features/NonReg/scenario/scenario.feature +183 -0
- test_holado/features/NonReg/test_steps/behave.feature +275 -0
- test_holado/features/NonReg/test_steps/common.feature +100 -0
- test_holado/features/NonReg/tools/RabbitMQ.feature +445 -0
- test_holado/features/NonReg/tools/RabbitMQ_steps.feature +276 -0
- test_holado/features/NonReg/tools/S3/boto3_client.feature +73 -0
- test_holado/features/NonReg/tools/S3/minio_client.feature +75 -0
- test_holado/features/NonReg/tools/db_sqlite3.feature +41 -0
- test_holado/features/NonReg/tools/sFTP.feature +25 -0
- test_holado/features/Test/logger.feature +28 -0
- test_holado/features/Test/test_host_controller.feature +13 -0
- test_holado/features/Test/test_parameter.feature +15 -0
- test_holado/features/__init__.py +0 -0
- test_holado/initialize_holado.py +62 -0
- test_holado/logging.conf +53 -0
- test_holado/resources/proto/definitions/protobuf/custom_types/field_types.proto +24 -0
- test_holado/resources/proto/definitions/protobuf/protobuf.dev/tutorial/addressbook.proto +56 -0
- test_holado/resources/proto/generated/protobuf/custom_types/field_types_pb2.py +34 -0
- test_holado/resources/proto/generated/protobuf/protobuf/dev/tutorial/addressbook_pb2.py +34 -0
- test_holado/resources/scripts/list_tags.sh +2 -0
- test_holado/resources/scripts/update_resources_proto_generated.py +70 -0
- test_holado/steps/__init__.py +0 -0
- test_holado/steps/private_steps.py +20 -0
- test_holado/steps/public_steps.py +23 -0
- test_holado/test_holado_session_context.py +43 -0
- test_holado/tools/connexion/api_rest/openapi.yaml +16 -0
- test_holado/tools/connexion/api_rest/run.py +19 -0
- test_holado/tools/django/README.txt +3 -0
- test_holado/tools/django/api_grpc/api_grpc/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/admin.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/apps.py +6 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/migrations/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/models.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/__init__.py +0 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/account.proto +27 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/account_pb2.py +33 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/proto/account_pb2_grpc.py +199 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/serializers.py +12 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/services.py +11 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/tests.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/api1/views.py +3 -0
- test_holado/tools/django/api_grpc/api_grpc/asgi.py +16 -0
- test_holado/tools/django/api_grpc/api_grpc/settings.py +126 -0
- test_holado/tools/django/api_grpc/api_grpc/urls.py +27 -0
- test_holado/tools/django/api_grpc/api_grpc/wsgi.py +16 -0
- test_holado/tools/django/api_grpc/db.sqlite3 +0 -0
- test_holado/tools/django/api_grpc/manage.py +29 -0
- test_holado/tools/django/api_grpc/manual_test_commands.txt +25 -0
- test_holado/tools/django/api_grpc/patch_djangogrpcframework.py +42 -0
- test_holado/tools/django/api_rest/api_rest/__init__.py +0 -0
- test_holado/tools/django/api_rest/api_rest/api1/__init__.py +0 -0
- test_holado/tools/django/api_rest/api_rest/api1/admin.py +3 -0
- test_holado/tools/django/api_rest/api_rest/api1/apps.py +6 -0
- test_holado/tools/django/api_rest/api_rest/api1/migrations/__init__.py +0 -0
- test_holado/tools/django/api_rest/api_rest/api1/models.py +3 -0
- test_holado/tools/django/api_rest/api_rest/api1/serializers.py +15 -0
- test_holado/tools/django/api_rest/api_rest/api1/tests.py +3 -0
- test_holado/tools/django/api_rest/api_rest/api1/views.py +24 -0
- test_holado/tools/django/api_rest/api_rest/asgi.py +16 -0
- test_holado/tools/django/api_rest/api_rest/settings.py +133 -0
- test_holado/tools/django/api_rest/api_rest/urls.py +32 -0
- test_holado/tools/django/api_rest/api_rest/wsgi.py +16 -0
- test_holado/tools/django/api_rest/db.sqlite3 +0 -0
- test_holado/tools/django/api_rest/manage.py +22 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from holado_core.common.tools.tools import Tools
|
|
5
|
+
from holado_rabbitmq.tools.rabbitmq.rabbitmq_client import RMQBufferConsumer
|
|
6
|
+
from holado_core.common.exceptions.technical_exception import TechnicalException
|
|
7
|
+
from holado_python.standard_library.typing import Typing
|
|
8
|
+
from holado_core.common.exceptions.functional_exception import FunctionalException
|
|
9
|
+
from holado_core.common.handlers.wait import WaitEndChange, WaitChange
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class RMQManager:
|
|
15
|
+
|
|
16
|
+
def __init__(self):
|
|
17
|
+
self.__protobuf_messages = None
|
|
18
|
+
|
|
19
|
+
def initialize(self, protobuf_messages):
|
|
20
|
+
self.__protobuf_messages = protobuf_messages
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def received_messages_as_protobuf_objects(self, consumer, message_type_fullname):
|
|
24
|
+
"""Unserialize messages received by a buffer consumer to given Protobuf message type"""
|
|
25
|
+
|
|
26
|
+
if not isinstance(consumer, RMQBufferConsumer):
|
|
27
|
+
raise TechnicalException(f"Consumer has to be a buffer consumer (obtained type: {Typing.get_object_class_fullname(consumer)})")
|
|
28
|
+
|
|
29
|
+
res = []
|
|
30
|
+
for ind, m in enumerate(consumer.messages):
|
|
31
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
32
|
+
logger.debug(f"Received message [{ind}]: {m[3]}")
|
|
33
|
+
msg = self.__protobuf_messages.new_message(message_type_fullname, serialized_string=m[3])
|
|
34
|
+
res.append(msg)
|
|
35
|
+
# logger.debug(f"+++++ New message: type={Typing.get_object_class_fullname(msg)} ; dir={dir(msg)}")
|
|
36
|
+
return res
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def await_message_reception(self, consumers, timeout_seconds=None, polling_seconds=None, raise_exception=True):
|
|
40
|
+
"""Wait until one of the buffer consumers has received a message.
|
|
41
|
+
@param consumers: list of buffer consumers
|
|
42
|
+
@param timeout_seconds: wait timeout
|
|
43
|
+
@param polling_seconds: time to wait between pollings of received messages of all consumers
|
|
44
|
+
"""
|
|
45
|
+
if raise_exception is None:
|
|
46
|
+
raise_exception = True
|
|
47
|
+
|
|
48
|
+
wait = WaitChange(f"Wait message reception by consumers",
|
|
49
|
+
lambda: sum([c.nb_messages for c in consumers if c.nb_messages > 0]),
|
|
50
|
+
do_process_in_thread = False,
|
|
51
|
+
result_reference = 0,
|
|
52
|
+
timeout_seconds=timeout_seconds, polling_seconds=polling_seconds)
|
|
53
|
+
# On timeout, we will have res==0 and raise is managed before return
|
|
54
|
+
wait.without_raise_on_timeout()
|
|
55
|
+
|
|
56
|
+
res = wait.execute()
|
|
57
|
+
|
|
58
|
+
if res == 0 and raise_exception:
|
|
59
|
+
names = ",".join([c.name for c in consumers])
|
|
60
|
+
raise FunctionalException(f"[{names}] No message was received (timeout: {timeout_seconds} seconds)")
|
|
61
|
+
return res
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
#TODO EKL: add a first_accepted_seconds and a accepted_window_seconds to be able to raise an exception that first or next message arrived but too late
|
|
65
|
+
#TODO EKL: change use of polling_seconds to something like a timer, rather than waiting polling_seconds
|
|
66
|
+
def await_messages_reception(self, consumers, first_timeout_seconds=None, window_seconds=None, polling_seconds=None, raise_exception=True):
|
|
67
|
+
"""Wait until buffer consumers stop to receive messages.
|
|
68
|
+
It begins by waiting a first message in any consumer, since their creation or last reset.
|
|
69
|
+
If no consumer receives a first message during first_timeout_seconds period, wait stops.
|
|
70
|
+
Then after each message received by any consumer, a window duration of window_seconds is waited for a new message.
|
|
71
|
+
When no new message is received by any consumer during the window period, wait stops.
|
|
72
|
+
@param consumers: list of buffer consumers
|
|
73
|
+
@param first_timeout_seconds: reception timeout of a first message
|
|
74
|
+
@param window_seconds: time window for wait of a new message since last received message
|
|
75
|
+
@param polling_seconds: time to wait between pollings of received messages of all consumers
|
|
76
|
+
"""
|
|
77
|
+
# res = 0
|
|
78
|
+
#
|
|
79
|
+
# if window_seconds is None:
|
|
80
|
+
# if first_timeout_seconds is not None and first_timeout_seconds > 0:
|
|
81
|
+
# window_seconds = first_timeout_seconds / 10
|
|
82
|
+
# else:
|
|
83
|
+
# window_seconds = 1
|
|
84
|
+
# if window_seconds < 0.01:
|
|
85
|
+
# window_seconds = 0.01 # a window period below 10 ms is usually not efficient in testing context
|
|
86
|
+
# if polling_seconds is None:
|
|
87
|
+
# min_window = min(first_timeout_seconds, window_seconds) if first_timeout_seconds is not None else window_seconds
|
|
88
|
+
# polling_seconds = min_window / 100 # 1% of error on window detection
|
|
89
|
+
# if polling_seconds > 0.1:
|
|
90
|
+
# polling_seconds = 0.1 # a polling period over 100 ms is usually not efficient in testing context
|
|
91
|
+
# elif polling_seconds < 0.001:
|
|
92
|
+
# polling_seconds = 0.001 # a polling period below 1 ms is usually not efficient in testing context
|
|
93
|
+
#
|
|
94
|
+
# # Wait first message is needed
|
|
95
|
+
# dt_begin = DateTime.now()
|
|
96
|
+
# dt_last_poll = dt_begin
|
|
97
|
+
# if first_timeout_seconds is not None:
|
|
98
|
+
# while (dt_last_poll - dt_begin).total_seconds() < first_timeout_seconds:
|
|
99
|
+
# nb_msg_by_consumer = {c.name: c.nb_messages for c in consumers if c.nb_messages > 0}
|
|
100
|
+
# dt_last_poll = DateTime.now()
|
|
101
|
+
# if len(nb_msg_by_consumer) > 0:
|
|
102
|
+
# res = sum(nb_msg_by_consumer.values())
|
|
103
|
+
# if Tools.do_log(logger, logging.DEBUG):
|
|
104
|
+
# logger.debug(f"Received first messages: total={res} ; " + " ; ".join(f"{k}:{v}" for k,v in nb_msg_by_consumer.items()))
|
|
105
|
+
# break
|
|
106
|
+
# time.sleep(polling_seconds)
|
|
107
|
+
# if res == 0:
|
|
108
|
+
# if raise_exception:
|
|
109
|
+
# names = ",".join([c.name for c in consumers])
|
|
110
|
+
# raise FunctionalException(f"[{names}] No message was received (timeout: {first_timeout_seconds} seconds)")
|
|
111
|
+
# return res
|
|
112
|
+
#
|
|
113
|
+
# # Wait end of reception
|
|
114
|
+
# dt_last_receive = dt_last_poll
|
|
115
|
+
# while (dt_last_poll - dt_last_receive).total_seconds() < window_seconds:
|
|
116
|
+
# nb_msg_by_consumer = {c.name: c.nb_messages for c in consumers if c.nb_messages > 0}
|
|
117
|
+
# nb = sum(nb_msg_by_consumer.values())
|
|
118
|
+
# dt_last_poll = DateTime.now()
|
|
119
|
+
# if nb > res:
|
|
120
|
+
# res = nb
|
|
121
|
+
# if Tools.do_log(logger, logging.DEBUG):
|
|
122
|
+
# logger.debug(f"Received messages: total={res} ; " + " ; ".join(f"{k}:{v}" for k,v in nb_msg_by_consumer.items()))
|
|
123
|
+
# dt_last_receive = dt_last_poll
|
|
124
|
+
# time.sleep(polling_seconds)
|
|
125
|
+
#
|
|
126
|
+
# return res
|
|
127
|
+
if raise_exception is None:
|
|
128
|
+
raise_exception = True
|
|
129
|
+
|
|
130
|
+
wait = WaitEndChange(f"Wait end of message reception by consumers",
|
|
131
|
+
lambda: sum([c.nb_messages for c in consumers if c.nb_messages > 0]),
|
|
132
|
+
do_process_in_thread = False,
|
|
133
|
+
result_reference = 0,
|
|
134
|
+
first_timeout_seconds=first_timeout_seconds, window_seconds=window_seconds, polling_seconds=polling_seconds)
|
|
135
|
+
# On timeout, we will have res==0 and raise is managed before return
|
|
136
|
+
wait.without_raise_on_timeout()
|
|
137
|
+
|
|
138
|
+
res = wait.execute()
|
|
139
|
+
|
|
140
|
+
if res == 0 and raise_exception:
|
|
141
|
+
names = ",".join([c.name for c in consumers])
|
|
142
|
+
raise FunctionalException(f"[{names}] No message was received (timeout: {first_timeout_seconds} seconds)")
|
|
143
|
+
return res
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
@@ -0,0 +1,428 @@
|
|
|
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.technical_exception import TechnicalException
|
|
16
|
+
from holado_multitask.multithreading.functionthreaded import FunctionThreaded
|
|
17
|
+
from holado_core.common.handlers.redo import Redo
|
|
18
|
+
from holado_core.common.exceptions.timeout_exception import TimeoutException
|
|
19
|
+
from holado_core.common.handlers.wait import WaitIsTrueOnEvent
|
|
20
|
+
from holado_rabbitmq.tools.rabbitmq.rabbitmq_client import RMQClient,\
|
|
21
|
+
RMQPublisher
|
|
22
|
+
import queue
|
|
23
|
+
import threading
|
|
24
|
+
from holado_core.common.tools.tools import Tools
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
if RMQClient.is_available():
|
|
31
|
+
import pika
|
|
32
|
+
from pika.exceptions import ConnectionClosedByClient
|
|
33
|
+
from pika.exchange_type import ExchangeType
|
|
34
|
+
|
|
35
|
+
class RMQChannel(pika.channel.Channel):
|
|
36
|
+
"""
|
|
37
|
+
Add features to pika.channel.Channel:
|
|
38
|
+
- Confirm delivery
|
|
39
|
+
- Automatically wait exchange, queue and bind are OK, like with a blocking connection
|
|
40
|
+
"""
|
|
41
|
+
def __init__(self, connection, channel_number, on_open_callback):
|
|
42
|
+
super().__init__(connection, channel_number, on_open_callback)
|
|
43
|
+
self.__confirm_delivery = False
|
|
44
|
+
self.__ack_nack_callback_func = None
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def has_confirm_delivery(self):
|
|
48
|
+
return self.__confirm_delivery
|
|
49
|
+
|
|
50
|
+
def set_confirm_delivery(self, wait_select_ok=True):
|
|
51
|
+
if wait_select_ok:
|
|
52
|
+
def callback_select_ok(method_frame):
|
|
53
|
+
if method_frame.method.NAME == 'Confirm.SelectOk':
|
|
54
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
55
|
+
logger.debug(f"[Channel {self.channel_number}] Confirm delivery mode is set")
|
|
56
|
+
return True
|
|
57
|
+
else:
|
|
58
|
+
raise TechnicalException(f"[Channel {self.channel_number}] Unexpected method frame {method_frame} (expected Confirm.SelectOk)")
|
|
59
|
+
wait_declare_ok = WaitIsTrueOnEvent(f"wait confirm select is OK", callback_select_ok)
|
|
60
|
+
|
|
61
|
+
self.confirm_delivery(self.__ack_nack_callback, wait_declare_ok.on_event)
|
|
62
|
+
|
|
63
|
+
wait_declare_ok.execute()
|
|
64
|
+
else:
|
|
65
|
+
self.confirm_delivery(self.__ack_nack_callback)
|
|
66
|
+
|
|
67
|
+
self.__confirm_delivery = True
|
|
68
|
+
|
|
69
|
+
def set_ack_nack_callback(self, func):
|
|
70
|
+
self.__ack_nack_callback_func = func
|
|
71
|
+
|
|
72
|
+
def __ack_nack_callback(self, method_frame:pika.frame.Method):
|
|
73
|
+
if self.__ack_nack_callback_func:
|
|
74
|
+
self.__ack_nack_callback_func(method_frame)
|
|
75
|
+
|
|
76
|
+
def exchange_declare(self, exchange, exchange_type=ExchangeType.direct, passive=False, durable=False, auto_delete=False, internal=False, arguments=None, wait_declare_ok=True):
|
|
77
|
+
if wait_declare_ok:
|
|
78
|
+
def callback_declare_ok(method_frame):
|
|
79
|
+
if method_frame.method.NAME == 'Exchange.DeclareOk':
|
|
80
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
81
|
+
logger.debug(f"[Channel {self.channel_number}] Exchange declare is OK")
|
|
82
|
+
return True
|
|
83
|
+
else:
|
|
84
|
+
raise TechnicalException(f"[Channel {self.channel_number}] Unexpected method frame {method_frame} (expected Exchange.DeclareOk)")
|
|
85
|
+
wait_declare_ok = WaitIsTrueOnEvent(f"wait exchange declare is OK", callback_declare_ok)
|
|
86
|
+
|
|
87
|
+
super().exchange_declare(exchange, exchange_type=exchange_type, passive=passive, durable=durable, auto_delete=auto_delete, internal=internal, arguments=arguments, callback=wait_declare_ok.on_event)
|
|
88
|
+
|
|
89
|
+
wait_declare_ok.execute()
|
|
90
|
+
else:
|
|
91
|
+
return super().exchange_declare(exchange, exchange_type=exchange_type, passive=passive, durable=durable, auto_delete=auto_delete, internal=internal, arguments=arguments, callback=None)
|
|
92
|
+
|
|
93
|
+
def queue_declare(self, queue, passive=False, durable=False, exclusive=False, auto_delete=False, arguments=None, wait_declare_ok=True):
|
|
94
|
+
if wait_declare_ok:
|
|
95
|
+
def callback_declare_ok(method_frame):
|
|
96
|
+
if method_frame.method.NAME == 'Queue.DeclareOk':
|
|
97
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
98
|
+
logger.debug(f"[Channel {self.channel_number}] Queue declare is OK")
|
|
99
|
+
return True
|
|
100
|
+
else:
|
|
101
|
+
raise TechnicalException(f"[Channel {self.channel_number}] Unexpected method frame {method_frame} (expected Queue.DeclareOk)")
|
|
102
|
+
wait_declare_ok = WaitIsTrueOnEvent(f"wait queue declare is OK", callback_declare_ok)
|
|
103
|
+
|
|
104
|
+
super().queue_declare(queue, passive=passive, durable=durable, exclusive=exclusive, auto_delete=auto_delete, arguments=arguments, callback=wait_declare_ok.on_event)
|
|
105
|
+
|
|
106
|
+
wait_declare_ok.execute()
|
|
107
|
+
else:
|
|
108
|
+
return super().queue_declare(queue, passive=passive, durable=durable, exclusive=exclusive, auto_delete=auto_delete, arguments=arguments, callback=None)
|
|
109
|
+
|
|
110
|
+
def queue_bind(self, queue, exchange, routing_key=None, arguments=None, wait_bind_ok=True):
|
|
111
|
+
if wait_bind_ok:
|
|
112
|
+
def callback_bind_ok(method_frame):
|
|
113
|
+
if method_frame.method.NAME == 'Queue.BindOk':
|
|
114
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
115
|
+
logger.debug(f"[Channel {self.channel_number}] Bind is OK")
|
|
116
|
+
return True
|
|
117
|
+
else:
|
|
118
|
+
raise TechnicalException(f"[Channel {self.channel_number}] Unexpected method frame {method_frame} (expected Queue.BindOk)")
|
|
119
|
+
wait_bind_ok = WaitIsTrueOnEvent(f"wait bind is OK", callback_bind_ok)
|
|
120
|
+
|
|
121
|
+
super().queue_bind(queue, exchange, routing_key=routing_key, arguments=arguments, callback=wait_bind_ok.on_event)
|
|
122
|
+
|
|
123
|
+
wait_bind_ok.execute()
|
|
124
|
+
else:
|
|
125
|
+
return super().queue_bind(queue, exchange, routing_key=routing_key, arguments=arguments)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class RMQSelectConnection(pika.adapters.select_connection.SelectConnection):
|
|
129
|
+
"""
|
|
130
|
+
Add features to pika.adapters.select_connection.SelectConnection:
|
|
131
|
+
- Be able to wait until connection is opened.
|
|
132
|
+
- Be able to wait until channel is opened.
|
|
133
|
+
- Use default on_xxx methods to raise on unexpected behaviour
|
|
134
|
+
Note: start_ioloop is automatically started if wait_is_opened is True
|
|
135
|
+
"""
|
|
136
|
+
def __init__(self, parameters=None,
|
|
137
|
+
on_open_callback=None,
|
|
138
|
+
on_open_error_callback=None,
|
|
139
|
+
on_close_callback=None,
|
|
140
|
+
custom_ioloop=None,
|
|
141
|
+
internal_connection_workflow=True,
|
|
142
|
+
wait_is_opened=True):
|
|
143
|
+
"""
|
|
144
|
+
Note: Parameters on_open_callback and on_open_error_callback are omitted if waiting until connection is opened.
|
|
145
|
+
"""
|
|
146
|
+
# Declare first private variables in case of open error while closing
|
|
147
|
+
self.__is_closing = False
|
|
148
|
+
self.__on_close_callback = on_close_callback
|
|
149
|
+
self.__ioloop_started = False
|
|
150
|
+
self.__func_ioloop_start = None
|
|
151
|
+
self.__channels = []
|
|
152
|
+
|
|
153
|
+
if wait_is_opened:
|
|
154
|
+
class WaitConnection(Redo):
|
|
155
|
+
def __init__(self):
|
|
156
|
+
super().__init__(f"redo connection is opened")
|
|
157
|
+
self.__connection = None
|
|
158
|
+
self.__exception = None
|
|
159
|
+
|
|
160
|
+
def _process(self):
|
|
161
|
+
return (self.__connection, self.__exception)
|
|
162
|
+
|
|
163
|
+
def on_open(self, connection):
|
|
164
|
+
self.__connection = connection
|
|
165
|
+
|
|
166
|
+
def on_open_error(self, connection, exception):
|
|
167
|
+
self.__connection = connection
|
|
168
|
+
self.__exception = exception
|
|
169
|
+
wait_connection = WaitConnection()
|
|
170
|
+
wait_connection.redo_while( (None,None) )
|
|
171
|
+
|
|
172
|
+
super().__init__(parameters=parameters,
|
|
173
|
+
on_open_callback=wait_connection.on_open,
|
|
174
|
+
on_open_error_callback=wait_connection.on_open_error,
|
|
175
|
+
on_close_callback=self.__on_close,
|
|
176
|
+
custom_ioloop=custom_ioloop,
|
|
177
|
+
internal_connection_workflow=internal_connection_workflow)
|
|
178
|
+
|
|
179
|
+
self.start_ioloop()
|
|
180
|
+
conn, exc = wait_connection.execute()
|
|
181
|
+
if exc is not None:
|
|
182
|
+
raise exc
|
|
183
|
+
if conn is not self:
|
|
184
|
+
raise TechnicalException(f"Unexpected connection object after waiting open (obtained: {id(conn)} ; expected: {id(self)})")
|
|
185
|
+
|
|
186
|
+
else:
|
|
187
|
+
super().__init__(parameters=parameters,
|
|
188
|
+
on_open_callback=on_open_callback,
|
|
189
|
+
on_open_error_callback=on_open_error_callback,
|
|
190
|
+
on_close_callback=self.__on_close,
|
|
191
|
+
custom_ioloop=custom_ioloop,
|
|
192
|
+
internal_connection_workflow=internal_connection_workflow)
|
|
193
|
+
|
|
194
|
+
def __on_close(self, connection, exception):
|
|
195
|
+
if not self.__is_closing and exception is not None:
|
|
196
|
+
if isinstance(exception, ConnectionClosedByClient) and exception.reply_code != 200:
|
|
197
|
+
raise exception
|
|
198
|
+
|
|
199
|
+
if self.__on_close_callback:
|
|
200
|
+
self.__on_close_callback(connection, exception)
|
|
201
|
+
|
|
202
|
+
def start_ioloop(self, in_thread=True, raise_if_already_started=True):
|
|
203
|
+
if self.__ioloop_started and raise_if_already_started:
|
|
204
|
+
raise TechnicalException(f"IO loop is already started")
|
|
205
|
+
|
|
206
|
+
if in_thread:
|
|
207
|
+
if self.__func_ioloop_start is not None and self.__func_ioloop_start.is_alive():
|
|
208
|
+
raise TechnicalException(f"IO loop is running in a thread")
|
|
209
|
+
|
|
210
|
+
if self.__func_ioloop_start is None:
|
|
211
|
+
name = f"[Connection {id(self)}] start ioloop"
|
|
212
|
+
self.__func_ioloop_start = FunctionThreaded(self.start_ioloop, kwargs={'in_thread':False}, name=name)
|
|
213
|
+
self.__func_ioloop_start.start()
|
|
214
|
+
else:
|
|
215
|
+
self.__ioloop_started = True
|
|
216
|
+
self.ioloop.start()
|
|
217
|
+
self.__ioloop_started = False
|
|
218
|
+
|
|
219
|
+
def stop_ioloop(self):
|
|
220
|
+
if self.__ioloop_started:
|
|
221
|
+
# self.ioloop.stop()
|
|
222
|
+
self.ioloop.add_callback_threadsafe(self.ioloop.stop)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def channel(self, channel_number=None, on_open_callback=None, wait_is_opened=True):
|
|
226
|
+
"""
|
|
227
|
+
Override channel method to enable waiting until channel is opened.
|
|
228
|
+
Note: Parameter on_open_callback is omitted if waiting until channel is opened.
|
|
229
|
+
"""
|
|
230
|
+
res = None
|
|
231
|
+
|
|
232
|
+
if wait_is_opened:
|
|
233
|
+
# Create wait redo
|
|
234
|
+
class WaitChannel(Redo):
|
|
235
|
+
def __init__(self):
|
|
236
|
+
super().__init__(f"redo channel is opened")
|
|
237
|
+
self.__channel = None
|
|
238
|
+
|
|
239
|
+
def _process(self):
|
|
240
|
+
return self.__channel
|
|
241
|
+
|
|
242
|
+
def set_channel(self, channel):
|
|
243
|
+
self.__channel = channel
|
|
244
|
+
|
|
245
|
+
wait_channel = WaitChannel()
|
|
246
|
+
wait_channel.with_timeout(3)
|
|
247
|
+
wait_channel.redo_while_none()
|
|
248
|
+
|
|
249
|
+
# Make maxium 3 retries
|
|
250
|
+
nb_retries = 3
|
|
251
|
+
for n in range(nb_retries):
|
|
252
|
+
# Call channel method
|
|
253
|
+
res = super().channel(channel_number=channel_number, on_open_callback=wait_channel.set_channel)
|
|
254
|
+
|
|
255
|
+
try:
|
|
256
|
+
res = wait_channel.execute()
|
|
257
|
+
except TimeoutException as exc:
|
|
258
|
+
if n + 1 == nb_retries:
|
|
259
|
+
raise exc
|
|
260
|
+
else:
|
|
261
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
262
|
+
logger.debug("Channel was not open in time, retry")
|
|
263
|
+
continue
|
|
264
|
+
else:
|
|
265
|
+
break
|
|
266
|
+
else:
|
|
267
|
+
res = super().channel(channel_number=channel_number, on_open_callback=on_open_callback)
|
|
268
|
+
|
|
269
|
+
if res is None:
|
|
270
|
+
raise TechnicalException(f"Failed to get channel")
|
|
271
|
+
self.__channels.append(res)
|
|
272
|
+
|
|
273
|
+
return res
|
|
274
|
+
|
|
275
|
+
def _create_channel(self, channel_number, on_open_callback):
|
|
276
|
+
"""Override _create_channel method to use RMQChannel instead of pika.channel.Channel"""
|
|
277
|
+
return RMQChannel(self, channel_number, on_open_callback)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class RMQSelectClient(RMQClient):
|
|
281
|
+
def __init__(self):
|
|
282
|
+
super().__init__('RMQSelectClient')
|
|
283
|
+
|
|
284
|
+
def _new_connection_parameters(self):
|
|
285
|
+
connection_kwargs = self._connection_kwargs
|
|
286
|
+
wait_connection = connection_kwargs.pop('wait_connection', True)
|
|
287
|
+
return pika.ConnectionParameters(**connection_kwargs), wait_connection
|
|
288
|
+
|
|
289
|
+
def _new_connection(self):
|
|
290
|
+
if self.rapid_close:
|
|
291
|
+
raise TechnicalException(f"Rapid close is not managed for select connection")
|
|
292
|
+
connection_parameters, wait_connection = self._new_connection_parameters()
|
|
293
|
+
return RMQSelectConnection(parameters=connection_parameters, wait_is_opened=wait_connection)
|
|
294
|
+
|
|
295
|
+
def _close_connection(self, connection=None):
|
|
296
|
+
if connection is None:
|
|
297
|
+
connection = self.connection
|
|
298
|
+
connection.stop_ioloop()
|
|
299
|
+
super().stop_consuming()
|
|
300
|
+
|
|
301
|
+
def _new_publisher(self, connection, channel, exchange, routing_key, nb_runners):
|
|
302
|
+
res = RMQSelectPublisher(self, connection, channel, exchange, routing_key, nb_runners)
|
|
303
|
+
return res
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
class RMQSelectPublisher(RMQPublisher):
|
|
307
|
+
"""
|
|
308
|
+
Implementation of a publisher for long and intensive publishes.
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
def __init__(self, client, connection, channel, exchange, routing_key, nb_runners=None):
|
|
312
|
+
super().__init__(client, connection, channel, exchange, routing_key)
|
|
313
|
+
|
|
314
|
+
# Manage message publish
|
|
315
|
+
self.__publish_lock = threading.Lock()
|
|
316
|
+
self.__publish_nb_runners = nb_runners if nb_runners is not None else 100
|
|
317
|
+
self.__publish_running_nb = 0
|
|
318
|
+
self.__publish_queue = queue.Queue(maxsize=self.__publish_nb_runners * 2)
|
|
319
|
+
self.__publish_counter = 0
|
|
320
|
+
self.__published_counter = 0
|
|
321
|
+
|
|
322
|
+
# Manage ack/nack
|
|
323
|
+
self.__ack_counter = 0
|
|
324
|
+
self.__nack_counter = 0
|
|
325
|
+
self.__delivery_tag_counter = 0
|
|
326
|
+
self.__ack_nack_lock = threading.Lock()
|
|
327
|
+
# self.__ack_nack_queue = queue.Queue(maxsize=self.__publish_nb_runners * 2)
|
|
328
|
+
self.__ack_nack_queue = queue.Queue()
|
|
329
|
+
self.__last_log_index = 0
|
|
330
|
+
|
|
331
|
+
# Set ack/nack callback
|
|
332
|
+
channel.set_ack_nack_callback(self.__ack_nack_callback)
|
|
333
|
+
|
|
334
|
+
def flush(self):
|
|
335
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
336
|
+
logger.debug(f"[{self.name}] flushing...")
|
|
337
|
+
self.__publish_queue.join()
|
|
338
|
+
self.__ack_nack_queue.join()
|
|
339
|
+
if Tools.do_log(logger, logging.DEBUG):
|
|
340
|
+
logger.debug(f"[{self.name}] flushed")
|
|
341
|
+
|
|
342
|
+
def __publish_start(self):
|
|
343
|
+
with self.__publish_lock:
|
|
344
|
+
if self.__publish_running_nb < self.__publish_nb_runners:
|
|
345
|
+
self.__publish_running_nb += 1
|
|
346
|
+
else:
|
|
347
|
+
return
|
|
348
|
+
|
|
349
|
+
self.__publish_next()
|
|
350
|
+
|
|
351
|
+
def __publish_next(self):
|
|
352
|
+
try:
|
|
353
|
+
msg_item = self.__publish_queue.get(block=False)
|
|
354
|
+
except queue.Empty:
|
|
355
|
+
with self.__publish_lock:
|
|
356
|
+
self.__publish_running_nb -= 1
|
|
357
|
+
return
|
|
358
|
+
|
|
359
|
+
self.client.connection.ioloop.add_callback_threadsafe(
|
|
360
|
+
lambda: self.__publish_message(msg_item[0], **msg_item[1]) )
|
|
361
|
+
|
|
362
|
+
self.__publish_queue.task_done()
|
|
363
|
+
|
|
364
|
+
def __publish_message(self, body, **kwargs):
|
|
365
|
+
# Add delivery tag in queue
|
|
366
|
+
with self.__ack_nack_lock:
|
|
367
|
+
self.__delivery_tag_counter += 1
|
|
368
|
+
del_tag = self.__delivery_tag_counter
|
|
369
|
+
self.__ack_nack_queue.put(del_tag)
|
|
370
|
+
|
|
371
|
+
# Publish message
|
|
372
|
+
# RMQPublisher.publish(self, body, **kwargs)
|
|
373
|
+
self.client.connection.ioloop.add_callback_threadsafe(
|
|
374
|
+
lambda: RMQPublisher.publish(self, body, **kwargs) )
|
|
375
|
+
self.__published_counter += 1
|
|
376
|
+
|
|
377
|
+
# Manage to publish next message
|
|
378
|
+
self.__publish_next()
|
|
379
|
+
|
|
380
|
+
def publish(self, body, **kwargs):
|
|
381
|
+
# Add message to publish in queue
|
|
382
|
+
self.__publish_queue.put((body, kwargs))
|
|
383
|
+
self.__publish_counter += 1
|
|
384
|
+
|
|
385
|
+
# Start publishing if it is not already running
|
|
386
|
+
self.__publish_start()
|
|
387
|
+
|
|
388
|
+
def __ack_nack_callback(self, method_frame:pika.frame.Method):
|
|
389
|
+
if method_frame.method.NAME == 'Basic.Ack':
|
|
390
|
+
self.__ack_counter += 1
|
|
391
|
+
del_tag_obtained = method_frame.method.delivery_tag
|
|
392
|
+
del_tag_expected = self.__get_next_delivery_tag_from_ack_nack_queue()
|
|
393
|
+
if method_frame.method.multiple:
|
|
394
|
+
while del_tag_expected < del_tag_obtained:
|
|
395
|
+
del_tag_expected = self.__get_next_delivery_tag_from_ack_nack_queue()
|
|
396
|
+
if del_tag_expected > del_tag_obtained:
|
|
397
|
+
raise TechnicalException(f"[{self.name}] Ack: inconsistent multiple delivery tags (obtained: {del_tag_obtained} ; expected: {del_tag_expected})")
|
|
398
|
+
else:
|
|
399
|
+
if del_tag_obtained != del_tag_expected:
|
|
400
|
+
raise TechnicalException(f"[{self.name}] Ack: inconsistent delivery tags (obtained: {del_tag_obtained} ; expected: {del_tag_expected})")
|
|
401
|
+
|
|
402
|
+
elif method_frame.method.NAME == 'Basic.Nack':
|
|
403
|
+
self.__nack_counter += 1
|
|
404
|
+
del_tag_obtained = method_frame.method.delivery_tag
|
|
405
|
+
del_tag_expected = self.__get_next_delivery_tag_from_ack_nack_queue()
|
|
406
|
+
if del_tag_obtained != del_tag_expected:
|
|
407
|
+
raise TechnicalException(f"[{self.name}] Nack: inconsistent delivery tags (obtained: {del_tag_obtained} ; expected: {del_tag_expected})")
|
|
408
|
+
|
|
409
|
+
else:
|
|
410
|
+
raise TechnicalException(f"Unexpected method frame {method_frame}")
|
|
411
|
+
# if self.__delivery_tag_counter // 1000 != self.__last_log_index:
|
|
412
|
+
# logger.warning(f"++++++++++++++++++++++++++++++++++++++++ __ack_nack_callback: publish queue size: {self.__publish_queue.qsize()} ; delivery tag counter: {self.__delivery_tag_counter} ; ack/nack queue size: {self.__ack_nack_queue.qsize()}")
|
|
413
|
+
# self.__last_log_index = self.__delivery_tag_counter // 1000
|
|
414
|
+
|
|
415
|
+
def __get_next_delivery_tag_from_ack_nack_queue(self):
|
|
416
|
+
res = self.__ack_nack_queue.get(block=False)
|
|
417
|
+
self.__ack_nack_queue.task_done()
|
|
418
|
+
return res
|
|
419
|
+
|
|
420
|
+
def _log_stats(self, level=logging.DEBUG):
|
|
421
|
+
if Tools.do_log(logger, level):
|
|
422
|
+
logger.log(level, f"[{self.name}] delivery tag: {self.__delivery_tag_counter} ; nack: {self.__nack_counter}")
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
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_docker.sdk.docker.docker_service import DockerService
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
class RMQServer(DockerService):
|
|
20
|
+
def __init__(self, name):
|
|
21
|
+
super().__init__(name)
|
|
22
|
+
|
|
23
|
+
def run_as_docker(self, image="rabbitmq:3-management", ports={'5672/tcp':5672, '15672/tcp':15672}, **kwargs):
|
|
24
|
+
super().run_as_docker(image, ports=ports, **kwargs)
|
holado_redis/__init__.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
#################################################
|
|
4
|
+
# HolAdo (Holistic Automation do)
|
|
5
|
+
#
|
|
6
|
+
# (C) Copyright 2021-2025 by Eric Klumpp
|
|
7
|
+
#
|
|
8
|
+
# 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:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
11
|
+
|
|
12
|
+
# 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.
|
|
13
|
+
#################################################
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
#################################################
|
|
4
|
+
# HolAdo (Holistic Automation do)
|
|
5
|
+
#
|
|
6
|
+
# (C) Copyright 2021-2025 by Eric Klumpp
|
|
7
|
+
#
|
|
8
|
+
# 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:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
11
|
+
|
|
12
|
+
# 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.
|
|
13
|
+
#################################################
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
from .tools.redis_client_steps import *
|