omnibase_infra 0.2.1__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.
- omnibase_infra/__init__.py +101 -0
- omnibase_infra/cli/__init__.py +1 -0
- omnibase_infra/cli/commands.py +216 -0
- omnibase_infra/clients/__init__.py +0 -0
- omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +261 -0
- omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +138 -0
- omnibase_infra/decorators/__init__.py +29 -0
- omnibase_infra/decorators/allow_any.py +109 -0
- omnibase_infra/dlq/__init__.py +90 -0
- omnibase_infra/dlq/constants_dlq.py +57 -0
- omnibase_infra/dlq/models/__init__.py +26 -0
- omnibase_infra/dlq/models/enum_replay_status.py +37 -0
- omnibase_infra/dlq/models/model_dlq_replay_record.py +135 -0
- omnibase_infra/dlq/models/model_dlq_tracking_config.py +184 -0
- omnibase_infra/dlq/service_dlq_tracking.py +611 -0
- omnibase_infra/enums/__init__.py +123 -0
- omnibase_infra/enums/enum_any_type_violation.py +104 -0
- omnibase_infra/enums/enum_backend_type.py +27 -0
- omnibase_infra/enums/enum_capture_outcome.py +42 -0
- omnibase_infra/enums/enum_capture_state.py +88 -0
- omnibase_infra/enums/enum_chain_violation_type.py +119 -0
- omnibase_infra/enums/enum_circuit_state.py +51 -0
- omnibase_infra/enums/enum_confirmation_event_type.py +27 -0
- omnibase_infra/enums/enum_contract_type.py +84 -0
- omnibase_infra/enums/enum_dedupe_strategy.py +46 -0
- omnibase_infra/enums/enum_dispatch_status.py +191 -0
- omnibase_infra/enums/enum_environment.py +46 -0
- omnibase_infra/enums/enum_execution_shape_violation.py +103 -0
- omnibase_infra/enums/enum_handler_error_type.py +101 -0
- omnibase_infra/enums/enum_handler_loader_error.py +178 -0
- omnibase_infra/enums/enum_handler_source_type.py +87 -0
- omnibase_infra/enums/enum_handler_type.py +77 -0
- omnibase_infra/enums/enum_handler_type_category.py +61 -0
- omnibase_infra/enums/enum_infra_transport_type.py +73 -0
- omnibase_infra/enums/enum_introspection_reason.py +154 -0
- omnibase_infra/enums/enum_message_category.py +213 -0
- omnibase_infra/enums/enum_node_archetype.py +74 -0
- omnibase_infra/enums/enum_node_output_type.py +185 -0
- omnibase_infra/enums/enum_non_retryable_error_category.py +224 -0
- omnibase_infra/enums/enum_policy_type.py +32 -0
- omnibase_infra/enums/enum_registration_state.py +261 -0
- omnibase_infra/enums/enum_registration_status.py +33 -0
- omnibase_infra/enums/enum_registry_response_status.py +28 -0
- omnibase_infra/enums/enum_response_status.py +26 -0
- omnibase_infra/enums/enum_retry_error_category.py +98 -0
- omnibase_infra/enums/enum_security_rule_id.py +103 -0
- omnibase_infra/enums/enum_selection_strategy.py +91 -0
- omnibase_infra/enums/enum_topic_standard.py +42 -0
- omnibase_infra/enums/enum_validation_severity.py +78 -0
- omnibase_infra/errors/__init__.py +156 -0
- omnibase_infra/errors/error_architecture_violation.py +152 -0
- omnibase_infra/errors/error_chain_propagation.py +188 -0
- omnibase_infra/errors/error_compute_registry.py +92 -0
- omnibase_infra/errors/error_consul.py +132 -0
- omnibase_infra/errors/error_container_wiring.py +243 -0
- omnibase_infra/errors/error_event_bus_registry.py +102 -0
- omnibase_infra/errors/error_infra.py +608 -0
- omnibase_infra/errors/error_message_type_registry.py +101 -0
- omnibase_infra/errors/error_policy_registry.py +112 -0
- omnibase_infra/errors/error_vault.py +123 -0
- omnibase_infra/event_bus/__init__.py +72 -0
- omnibase_infra/event_bus/configs/kafka_event_bus_config.yaml +86 -0
- omnibase_infra/event_bus/event_bus_inmemory.py +743 -0
- omnibase_infra/event_bus/event_bus_kafka.py +1658 -0
- omnibase_infra/event_bus/mixin_kafka_broadcast.py +184 -0
- omnibase_infra/event_bus/mixin_kafka_dlq.py +765 -0
- omnibase_infra/event_bus/models/__init__.py +29 -0
- omnibase_infra/event_bus/models/config/__init__.py +20 -0
- omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +725 -0
- omnibase_infra/event_bus/models/model_dlq_event.py +206 -0
- omnibase_infra/event_bus/models/model_dlq_metrics.py +304 -0
- omnibase_infra/event_bus/models/model_event_headers.py +115 -0
- omnibase_infra/event_bus/models/model_event_message.py +60 -0
- omnibase_infra/event_bus/topic_constants.py +376 -0
- omnibase_infra/handlers/__init__.py +75 -0
- omnibase_infra/handlers/filesystem/__init__.py +48 -0
- omnibase_infra/handlers/filesystem/enum_file_system_operation.py +35 -0
- omnibase_infra/handlers/filesystem/model_file_system_request.py +298 -0
- omnibase_infra/handlers/filesystem/model_file_system_result.py +166 -0
- omnibase_infra/handlers/handler_consul.py +787 -0
- omnibase_infra/handlers/handler_db.py +1039 -0
- omnibase_infra/handlers/handler_filesystem.py +1478 -0
- omnibase_infra/handlers/handler_graph.py +1154 -0
- omnibase_infra/handlers/handler_http.py +920 -0
- omnibase_infra/handlers/handler_manifest_persistence.contract.yaml +184 -0
- omnibase_infra/handlers/handler_manifest_persistence.py +1539 -0
- omnibase_infra/handlers/handler_mcp.py +748 -0
- omnibase_infra/handlers/handler_qdrant.py +1076 -0
- omnibase_infra/handlers/handler_vault.py +422 -0
- omnibase_infra/handlers/mcp/__init__.py +19 -0
- omnibase_infra/handlers/mcp/adapter_onex_to_mcp.py +446 -0
- omnibase_infra/handlers/mcp/protocols.py +178 -0
- omnibase_infra/handlers/mcp/transport_streamable_http.py +352 -0
- omnibase_infra/handlers/mixins/__init__.py +42 -0
- omnibase_infra/handlers/mixins/mixin_consul_initialization.py +349 -0
- omnibase_infra/handlers/mixins/mixin_consul_kv.py +337 -0
- omnibase_infra/handlers/mixins/mixin_consul_service.py +277 -0
- omnibase_infra/handlers/mixins/mixin_vault_initialization.py +338 -0
- omnibase_infra/handlers/mixins/mixin_vault_retry.py +412 -0
- omnibase_infra/handlers/mixins/mixin_vault_secrets.py +450 -0
- omnibase_infra/handlers/mixins/mixin_vault_token.py +365 -0
- omnibase_infra/handlers/models/__init__.py +286 -0
- omnibase_infra/handlers/models/consul/__init__.py +81 -0
- omnibase_infra/handlers/models/consul/enum_consul_operation_type.py +57 -0
- omnibase_infra/handlers/models/consul/model_consul_deregister_payload.py +51 -0
- omnibase_infra/handlers/models/consul/model_consul_handler_config.py +153 -0
- omnibase_infra/handlers/models/consul/model_consul_handler_payload.py +89 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_found_payload.py +55 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_not_found_payload.py +49 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_recurse_payload.py +50 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_item.py +33 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_put_payload.py +41 -0
- omnibase_infra/handlers/models/consul/model_consul_register_payload.py +53 -0
- omnibase_infra/handlers/models/consul/model_consul_retry_config.py +66 -0
- omnibase_infra/handlers/models/consul/model_payload_consul.py +66 -0
- omnibase_infra/handlers/models/consul/registry_payload_consul.py +214 -0
- omnibase_infra/handlers/models/graph/__init__.py +35 -0
- omnibase_infra/handlers/models/graph/enum_graph_operation_type.py +20 -0
- omnibase_infra/handlers/models/graph/model_graph_execute_payload.py +38 -0
- omnibase_infra/handlers/models/graph/model_graph_handler_config.py +54 -0
- omnibase_infra/handlers/models/graph/model_graph_handler_payload.py +44 -0
- omnibase_infra/handlers/models/graph/model_graph_query_payload.py +40 -0
- omnibase_infra/handlers/models/graph/model_graph_record.py +22 -0
- omnibase_infra/handlers/models/http/__init__.py +50 -0
- omnibase_infra/handlers/models/http/enum_http_operation_type.py +29 -0
- omnibase_infra/handlers/models/http/model_http_body_content.py +45 -0
- omnibase_infra/handlers/models/http/model_http_get_payload.py +88 -0
- omnibase_infra/handlers/models/http/model_http_handler_payload.py +90 -0
- omnibase_infra/handlers/models/http/model_http_post_payload.py +88 -0
- omnibase_infra/handlers/models/http/model_payload_http.py +66 -0
- omnibase_infra/handlers/models/http/registry_payload_http.py +212 -0
- omnibase_infra/handlers/models/mcp/__init__.py +23 -0
- omnibase_infra/handlers/models/mcp/enum_mcp_operation_type.py +24 -0
- omnibase_infra/handlers/models/mcp/model_mcp_handler_config.py +40 -0
- omnibase_infra/handlers/models/mcp/model_mcp_tool_call.py +32 -0
- omnibase_infra/handlers/models/mcp/model_mcp_tool_result.py +45 -0
- omnibase_infra/handlers/models/model_consul_handler_response.py +96 -0
- omnibase_infra/handlers/models/model_db_describe_response.py +83 -0
- omnibase_infra/handlers/models/model_db_query_payload.py +95 -0
- omnibase_infra/handlers/models/model_db_query_response.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_config.py +98 -0
- omnibase_infra/handlers/models/model_filesystem_delete_payload.py +54 -0
- omnibase_infra/handlers/models/model_filesystem_delete_result.py +77 -0
- omnibase_infra/handlers/models/model_filesystem_directory_entry.py +75 -0
- omnibase_infra/handlers/models/model_filesystem_ensure_directory_payload.py +54 -0
- omnibase_infra/handlers/models/model_filesystem_ensure_directory_result.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_list_directory_payload.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_list_directory_result.py +68 -0
- omnibase_infra/handlers/models/model_filesystem_read_payload.py +62 -0
- omnibase_infra/handlers/models/model_filesystem_read_result.py +61 -0
- omnibase_infra/handlers/models/model_filesystem_write_payload.py +70 -0
- omnibase_infra/handlers/models/model_filesystem_write_result.py +55 -0
- omnibase_infra/handlers/models/model_graph_handler_response.py +98 -0
- omnibase_infra/handlers/models/model_handler_response.py +103 -0
- omnibase_infra/handlers/models/model_http_handler_response.py +101 -0
- omnibase_infra/handlers/models/model_manifest_metadata.py +75 -0
- omnibase_infra/handlers/models/model_manifest_persistence_config.py +62 -0
- omnibase_infra/handlers/models/model_manifest_query_payload.py +90 -0
- omnibase_infra/handlers/models/model_manifest_query_result.py +97 -0
- omnibase_infra/handlers/models/model_manifest_retrieve_payload.py +44 -0
- omnibase_infra/handlers/models/model_manifest_retrieve_result.py +98 -0
- omnibase_infra/handlers/models/model_manifest_store_payload.py +47 -0
- omnibase_infra/handlers/models/model_manifest_store_result.py +67 -0
- omnibase_infra/handlers/models/model_operation_context.py +187 -0
- omnibase_infra/handlers/models/model_qdrant_handler_response.py +98 -0
- omnibase_infra/handlers/models/model_retry_state.py +162 -0
- omnibase_infra/handlers/models/model_vault_handler_response.py +98 -0
- omnibase_infra/handlers/models/qdrant/__init__.py +44 -0
- omnibase_infra/handlers/models/qdrant/enum_qdrant_operation_type.py +26 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_collection_payload.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_delete_payload.py +36 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_handler_config.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_handler_payload.py +54 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_search_payload.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_search_result.py +30 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_upsert_payload.py +36 -0
- omnibase_infra/handlers/models/vault/__init__.py +69 -0
- omnibase_infra/handlers/models/vault/enum_vault_operation_type.py +35 -0
- omnibase_infra/handlers/models/vault/model_payload_vault.py +66 -0
- omnibase_infra/handlers/models/vault/model_vault_delete_payload.py +57 -0
- omnibase_infra/handlers/models/vault/model_vault_handler_config.py +148 -0
- omnibase_infra/handlers/models/vault/model_vault_handler_payload.py +101 -0
- omnibase_infra/handlers/models/vault/model_vault_list_payload.py +58 -0
- omnibase_infra/handlers/models/vault/model_vault_renew_token_payload.py +67 -0
- omnibase_infra/handlers/models/vault/model_vault_retry_config.py +66 -0
- omnibase_infra/handlers/models/vault/model_vault_secret_payload.py +106 -0
- omnibase_infra/handlers/models/vault/model_vault_write_payload.py +66 -0
- omnibase_infra/handlers/models/vault/registry_payload_vault.py +213 -0
- omnibase_infra/handlers/registration_storage/__init__.py +43 -0
- omnibase_infra/handlers/registration_storage/handler_registration_storage_mock.py +392 -0
- omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +915 -0
- omnibase_infra/handlers/registration_storage/models/__init__.py +23 -0
- omnibase_infra/handlers/registration_storage/models/model_delete_registration_request.py +58 -0
- omnibase_infra/handlers/registration_storage/models/model_update_registration_request.py +73 -0
- omnibase_infra/handlers/registration_storage/protocol_registration_persistence.py +191 -0
- omnibase_infra/handlers/service_discovery/__init__.py +43 -0
- omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +747 -0
- omnibase_infra/handlers/service_discovery/handler_service_discovery_mock.py +258 -0
- omnibase_infra/handlers/service_discovery/models/__init__.py +22 -0
- omnibase_infra/handlers/service_discovery/models/model_discovery_result.py +64 -0
- omnibase_infra/handlers/service_discovery/models/model_registration_result.py +138 -0
- omnibase_infra/handlers/service_discovery/models/model_service_info.py +99 -0
- omnibase_infra/handlers/service_discovery/protocol_discovery_operations.py +170 -0
- omnibase_infra/idempotency/__init__.py +94 -0
- omnibase_infra/idempotency/models/__init__.py +43 -0
- omnibase_infra/idempotency/models/model_idempotency_check_result.py +85 -0
- omnibase_infra/idempotency/models/model_idempotency_guard_config.py +130 -0
- omnibase_infra/idempotency/models/model_idempotency_record.py +86 -0
- omnibase_infra/idempotency/models/model_idempotency_store_health_check_result.py +81 -0
- omnibase_infra/idempotency/models/model_idempotency_store_metrics.py +140 -0
- omnibase_infra/idempotency/models/model_postgres_idempotency_store_config.py +299 -0
- omnibase_infra/idempotency/protocol_idempotency_store.py +184 -0
- omnibase_infra/idempotency/store_inmemory.py +265 -0
- omnibase_infra/idempotency/store_postgres.py +923 -0
- omnibase_infra/infrastructure/__init__.py +0 -0
- omnibase_infra/mixins/__init__.py +71 -0
- omnibase_infra/mixins/mixin_async_circuit_breaker.py +655 -0
- omnibase_infra/mixins/mixin_dict_like_accessors.py +146 -0
- omnibase_infra/mixins/mixin_envelope_extraction.py +119 -0
- omnibase_infra/mixins/mixin_node_introspection.py +2465 -0
- omnibase_infra/mixins/mixin_retry_execution.py +386 -0
- omnibase_infra/mixins/protocol_circuit_breaker_aware.py +133 -0
- omnibase_infra/models/__init__.py +136 -0
- omnibase_infra/models/corpus/__init__.py +17 -0
- omnibase_infra/models/corpus/model_capture_config.py +133 -0
- omnibase_infra/models/corpus/model_capture_result.py +86 -0
- omnibase_infra/models/discovery/__init__.py +42 -0
- omnibase_infra/models/discovery/model_dependency_spec.py +319 -0
- omnibase_infra/models/discovery/model_discovered_capabilities.py +50 -0
- omnibase_infra/models/discovery/model_introspection_config.py +311 -0
- omnibase_infra/models/discovery/model_introspection_performance_metrics.py +169 -0
- omnibase_infra/models/discovery/model_introspection_task_config.py +116 -0
- omnibase_infra/models/dispatch/__init__.py +147 -0
- omnibase_infra/models/dispatch/model_dispatch_context.py +439 -0
- omnibase_infra/models/dispatch/model_dispatch_error.py +336 -0
- omnibase_infra/models/dispatch/model_dispatch_log_context.py +400 -0
- omnibase_infra/models/dispatch/model_dispatch_metadata.py +228 -0
- omnibase_infra/models/dispatch/model_dispatch_metrics.py +496 -0
- omnibase_infra/models/dispatch/model_dispatch_outcome.py +317 -0
- omnibase_infra/models/dispatch/model_dispatch_outputs.py +231 -0
- omnibase_infra/models/dispatch/model_dispatch_result.py +436 -0
- omnibase_infra/models/dispatch/model_dispatch_route.py +279 -0
- omnibase_infra/models/dispatch/model_dispatcher_metrics.py +275 -0
- omnibase_infra/models/dispatch/model_dispatcher_registration.py +352 -0
- omnibase_infra/models/dispatch/model_parsed_topic.py +135 -0
- omnibase_infra/models/dispatch/model_topic_parser.py +725 -0
- omnibase_infra/models/dispatch/model_tracing_context.py +285 -0
- omnibase_infra/models/errors/__init__.py +45 -0
- omnibase_infra/models/errors/model_handler_validation_error.py +594 -0
- omnibase_infra/models/errors/model_infra_error_context.py +99 -0
- omnibase_infra/models/errors/model_message_type_registry_error_context.py +71 -0
- omnibase_infra/models/errors/model_timeout_error_context.py +110 -0
- omnibase_infra/models/handlers/__init__.py +37 -0
- omnibase_infra/models/handlers/model_contract_discovery_result.py +80 -0
- omnibase_infra/models/handlers/model_handler_descriptor.py +185 -0
- omnibase_infra/models/handlers/model_handler_identifier.py +215 -0
- omnibase_infra/models/health/__init__.py +9 -0
- omnibase_infra/models/health/model_health_check_result.py +40 -0
- omnibase_infra/models/lifecycle/__init__.py +39 -0
- omnibase_infra/models/logging/__init__.py +51 -0
- omnibase_infra/models/logging/model_log_context.py +756 -0
- omnibase_infra/models/model_retry_error_classification.py +78 -0
- omnibase_infra/models/projection/__init__.py +43 -0
- omnibase_infra/models/projection/model_capability_fields.py +112 -0
- omnibase_infra/models/projection/model_registration_projection.py +434 -0
- omnibase_infra/models/projection/model_registration_snapshot.py +322 -0
- omnibase_infra/models/projection/model_sequence_info.py +182 -0
- omnibase_infra/models/projection/model_snapshot_topic_config.py +590 -0
- omnibase_infra/models/projectors/__init__.py +41 -0
- omnibase_infra/models/projectors/model_projector_column.py +289 -0
- omnibase_infra/models/projectors/model_projector_discovery_result.py +65 -0
- omnibase_infra/models/projectors/model_projector_index.py +270 -0
- omnibase_infra/models/projectors/model_projector_schema.py +415 -0
- omnibase_infra/models/projectors/model_projector_validation_error.py +63 -0
- omnibase_infra/models/projectors/util_sql_identifiers.py +115 -0
- omnibase_infra/models/registration/__init__.py +59 -0
- omnibase_infra/models/registration/commands/__init__.py +15 -0
- omnibase_infra/models/registration/commands/model_node_registration_acked.py +108 -0
- omnibase_infra/models/registration/events/__init__.py +56 -0
- omnibase_infra/models/registration/events/model_node_became_active.py +103 -0
- omnibase_infra/models/registration/events/model_node_liveness_expired.py +103 -0
- omnibase_infra/models/registration/events/model_node_registration_accepted.py +98 -0
- omnibase_infra/models/registration/events/model_node_registration_ack_received.py +98 -0
- omnibase_infra/models/registration/events/model_node_registration_ack_timed_out.py +112 -0
- omnibase_infra/models/registration/events/model_node_registration_initiated.py +107 -0
- omnibase_infra/models/registration/events/model_node_registration_rejected.py +104 -0
- omnibase_infra/models/registration/model_introspection_metrics.py +253 -0
- omnibase_infra/models/registration/model_node_capabilities.py +179 -0
- omnibase_infra/models/registration/model_node_heartbeat_event.py +126 -0
- omnibase_infra/models/registration/model_node_introspection_event.py +175 -0
- omnibase_infra/models/registration/model_node_metadata.py +79 -0
- omnibase_infra/models/registration/model_node_registration.py +162 -0
- omnibase_infra/models/registration/model_node_registration_record.py +162 -0
- omnibase_infra/models/registry/__init__.py +29 -0
- omnibase_infra/models/registry/model_domain_constraint.py +202 -0
- omnibase_infra/models/registry/model_message_type_entry.py +271 -0
- omnibase_infra/models/resilience/__init__.py +9 -0
- omnibase_infra/models/resilience/model_circuit_breaker_config.py +227 -0
- omnibase_infra/models/routing/__init__.py +25 -0
- omnibase_infra/models/routing/model_routing_entry.py +52 -0
- omnibase_infra/models/routing/model_routing_subcontract.py +70 -0
- omnibase_infra/models/runtime/__init__.py +40 -0
- omnibase_infra/models/runtime/model_contract_security_config.py +41 -0
- omnibase_infra/models/runtime/model_discovery_error.py +81 -0
- omnibase_infra/models/runtime/model_discovery_result.py +162 -0
- omnibase_infra/models/runtime/model_discovery_warning.py +74 -0
- omnibase_infra/models/runtime/model_failed_plugin_load.py +63 -0
- omnibase_infra/models/runtime/model_handler_contract.py +280 -0
- omnibase_infra/models/runtime/model_loaded_handler.py +120 -0
- omnibase_infra/models/runtime/model_plugin_load_context.py +93 -0
- omnibase_infra/models/runtime/model_plugin_load_summary.py +124 -0
- omnibase_infra/models/security/__init__.py +50 -0
- omnibase_infra/models/security/classification_levels.py +99 -0
- omnibase_infra/models/security/model_environment_policy.py +145 -0
- omnibase_infra/models/security/model_handler_security_policy.py +107 -0
- omnibase_infra/models/security/model_security_error.py +81 -0
- omnibase_infra/models/security/model_security_validation_result.py +328 -0
- omnibase_infra/models/security/model_security_warning.py +67 -0
- omnibase_infra/models/snapshot/__init__.py +27 -0
- omnibase_infra/models/snapshot/model_field_change.py +65 -0
- omnibase_infra/models/snapshot/model_snapshot.py +270 -0
- omnibase_infra/models/snapshot/model_snapshot_diff.py +203 -0
- omnibase_infra/models/snapshot/model_subject_ref.py +81 -0
- omnibase_infra/models/types/__init__.py +71 -0
- omnibase_infra/models/validation/__init__.py +89 -0
- omnibase_infra/models/validation/model_any_type_validation_result.py +118 -0
- omnibase_infra/models/validation/model_any_type_violation.py +141 -0
- omnibase_infra/models/validation/model_category_match_result.py +345 -0
- omnibase_infra/models/validation/model_chain_violation.py +166 -0
- omnibase_infra/models/validation/model_coverage_metrics.py +316 -0
- omnibase_infra/models/validation/model_execution_shape_rule.py +159 -0
- omnibase_infra/models/validation/model_execution_shape_validation.py +208 -0
- omnibase_infra/models/validation/model_execution_shape_validation_result.py +294 -0
- omnibase_infra/models/validation/model_execution_shape_violation.py +122 -0
- omnibase_infra/models/validation/model_localhandler_validation_result.py +139 -0
- omnibase_infra/models/validation/model_localhandler_violation.py +100 -0
- omnibase_infra/models/validation/model_output_validation_params.py +74 -0
- omnibase_infra/models/validation/model_validate_and_raise_params.py +84 -0
- omnibase_infra/models/validation/model_validation_error_params.py +84 -0
- omnibase_infra/models/validation/model_validation_outcome.py +287 -0
- omnibase_infra/nodes/__init__.py +48 -0
- omnibase_infra/nodes/architecture_validator/__init__.py +79 -0
- omnibase_infra/nodes/architecture_validator/contract.yaml +252 -0
- omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +208 -0
- omnibase_infra/nodes/architecture_validator/mixins/__init__.py +16 -0
- omnibase_infra/nodes/architecture_validator/mixins/mixin_file_path_rule.py +92 -0
- omnibase_infra/nodes/architecture_validator/models/__init__.py +36 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_request.py +56 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_result.py +311 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_violation.py +163 -0
- omnibase_infra/nodes/architecture_validator/models/model_rule_check_result.py +265 -0
- omnibase_infra/nodes/architecture_validator/models/model_validation_request.py +105 -0
- omnibase_infra/nodes/architecture_validator/models/model_validation_result.py +314 -0
- omnibase_infra/nodes/architecture_validator/node.py +262 -0
- omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +383 -0
- omnibase_infra/nodes/architecture_validator/protocols/__init__.py +9 -0
- omnibase_infra/nodes/architecture_validator/protocols/protocol_architecture_rule.py +225 -0
- omnibase_infra/nodes/architecture_validator/registry/__init__.py +28 -0
- omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +99 -0
- omnibase_infra/nodes/architecture_validator/validators/__init__.py +104 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_direct_dispatch.py +422 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_handler_publishing.py +481 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_orchestrator_fsm.py +491 -0
- omnibase_infra/nodes/effects/README.md +358 -0
- omnibase_infra/nodes/effects/__init__.py +26 -0
- omnibase_infra/nodes/effects/contract.yaml +172 -0
- omnibase_infra/nodes/effects/models/__init__.py +32 -0
- omnibase_infra/nodes/effects/models/model_backend_result.py +190 -0
- omnibase_infra/nodes/effects/models/model_effect_idempotency_config.py +92 -0
- omnibase_infra/nodes/effects/models/model_registry_request.py +132 -0
- omnibase_infra/nodes/effects/models/model_registry_response.py +263 -0
- omnibase_infra/nodes/effects/protocol_consul_client.py +89 -0
- omnibase_infra/nodes/effects/protocol_effect_idempotency_store.py +143 -0
- omnibase_infra/nodes/effects/protocol_postgres_adapter.py +96 -0
- omnibase_infra/nodes/effects/registry_effect.py +525 -0
- omnibase_infra/nodes/effects/store_effect_idempotency_inmemory.py +425 -0
- omnibase_infra/nodes/node_registration_orchestrator/README.md +542 -0
- omnibase_infra/nodes/node_registration_orchestrator/__init__.py +120 -0
- omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +475 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/__init__.py +53 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_introspected.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_registration_acked.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_runtime_tick.py +373 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/__init__.py +62 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_heartbeat.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +609 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_registration_acked.py +458 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_runtime_tick.py +364 -0
- omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +544 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/__init__.py +75 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_intent_payload.py +194 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_registration_intent.py +67 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_intent_execution_result.py +50 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_node_liveness_expired.py +107 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_config.py +67 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_input.py +41 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_output.py +166 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_intent_payload.py +235 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_upsert_intent.py +68 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_execution_result.py +384 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_state.py +60 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_registration_intent.py +177 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_registry_intent.py +247 -0
- omnibase_infra/nodes/node_registration_orchestrator/node.py +195 -0
- omnibase_infra/nodes/node_registration_orchestrator/plugin.py +909 -0
- omnibase_infra/nodes/node_registration_orchestrator/protocols.py +439 -0
- omnibase_infra/nodes/node_registration_orchestrator/registry/__init__.py +41 -0
- omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +525 -0
- omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +392 -0
- omnibase_infra/nodes/node_registration_orchestrator/wiring.py +742 -0
- omnibase_infra/nodes/node_registration_reducer/__init__.py +15 -0
- omnibase_infra/nodes/node_registration_reducer/contract.yaml +301 -0
- omnibase_infra/nodes/node_registration_reducer/models/__init__.py +38 -0
- omnibase_infra/nodes/node_registration_reducer/models/model_validation_result.py +113 -0
- omnibase_infra/nodes/node_registration_reducer/node.py +139 -0
- omnibase_infra/nodes/node_registration_reducer/registry/__init__.py +9 -0
- omnibase_infra/nodes/node_registration_reducer/registry/registry_infra_node_registration_reducer.py +79 -0
- omnibase_infra/nodes/node_registration_storage_effect/__init__.py +41 -0
- omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +225 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/__init__.py +44 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_delete_result.py +132 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_record.py +199 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_update.py +155 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_details.py +123 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_result.py +117 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_query.py +100 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_result.py +136 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_upsert_result.py +127 -0
- omnibase_infra/nodes/node_registration_storage_effect/node.py +109 -0
- omnibase_infra/nodes/node_registration_storage_effect/protocols/__init__.py +22 -0
- omnibase_infra/nodes/node_registration_storage_effect/protocols/protocol_registration_persistence.py +333 -0
- omnibase_infra/nodes/node_registration_storage_effect/registry/__init__.py +23 -0
- omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +194 -0
- omnibase_infra/nodes/node_registry_effect/__init__.py +85 -0
- omnibase_infra/nodes/node_registry_effect/contract.yaml +682 -0
- omnibase_infra/nodes/node_registry_effect/handlers/__init__.py +70 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_deregister.py +211 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_register.py +212 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +416 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_deactivate.py +215 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_upsert.py +208 -0
- omnibase_infra/nodes/node_registry_effect/models/__init__.py +43 -0
- omnibase_infra/nodes/node_registry_effect/models/model_partial_retry_request.py +92 -0
- omnibase_infra/nodes/node_registry_effect/node.py +165 -0
- omnibase_infra/nodes/node_registry_effect/registry/__init__.py +27 -0
- omnibase_infra/nodes/node_registry_effect/registry/registry_infra_registry_effect.py +196 -0
- omnibase_infra/nodes/node_service_discovery_effect/__init__.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/contract.yaml +246 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/__init__.py +67 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/enum_health_status.py +72 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/enum_service_discovery_operation.py +58 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_query.py +99 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_result.py +98 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_health_check_config.py +121 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_query_metadata.py +63 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_registration_result.py +130 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_details.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_result.py +119 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_info.py +106 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_registration.py +121 -0
- omnibase_infra/nodes/node_service_discovery_effect/node.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/protocols/__init__.py +14 -0
- omnibase_infra/nodes/node_service_discovery_effect/protocols/protocol_discovery_operations.py +279 -0
- omnibase_infra/nodes/node_service_discovery_effect/registry/__init__.py +13 -0
- omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +214 -0
- omnibase_infra/nodes/reducers/__init__.py +30 -0
- omnibase_infra/nodes/reducers/models/__init__.py +32 -0
- omnibase_infra/nodes/reducers/models/model_payload_consul_register.py +76 -0
- omnibase_infra/nodes/reducers/models/model_payload_postgres_upsert_registration.py +60 -0
- omnibase_infra/nodes/reducers/models/model_registration_confirmation.py +166 -0
- omnibase_infra/nodes/reducers/models/model_registration_state.py +433 -0
- omnibase_infra/nodes/reducers/registration_reducer.py +1137 -0
- omnibase_infra/observability/__init__.py +143 -0
- omnibase_infra/observability/constants_metrics.py +91 -0
- omnibase_infra/observability/factory_observability_sink.py +525 -0
- omnibase_infra/observability/handlers/__init__.py +118 -0
- omnibase_infra/observability/handlers/handler_logging_structured.py +967 -0
- omnibase_infra/observability/handlers/handler_metrics_prometheus.py +1120 -0
- omnibase_infra/observability/handlers/model_logging_handler_config.py +71 -0
- omnibase_infra/observability/handlers/model_logging_handler_response.py +77 -0
- omnibase_infra/observability/handlers/model_metrics_handler_config.py +172 -0
- omnibase_infra/observability/handlers/model_metrics_handler_payload.py +135 -0
- omnibase_infra/observability/handlers/model_metrics_handler_response.py +101 -0
- omnibase_infra/observability/hooks/__init__.py +74 -0
- omnibase_infra/observability/hooks/hook_observability.py +1223 -0
- omnibase_infra/observability/models/__init__.py +30 -0
- omnibase_infra/observability/models/enum_required_log_context_key.py +77 -0
- omnibase_infra/observability/models/model_buffered_log_entry.py +117 -0
- omnibase_infra/observability/models/model_logging_sink_config.py +73 -0
- omnibase_infra/observability/models/model_metrics_sink_config.py +156 -0
- omnibase_infra/observability/sinks/__init__.py +69 -0
- omnibase_infra/observability/sinks/sink_logging_structured.py +809 -0
- omnibase_infra/observability/sinks/sink_metrics_prometheus.py +710 -0
- omnibase_infra/plugins/__init__.py +27 -0
- omnibase_infra/plugins/examples/__init__.py +28 -0
- omnibase_infra/plugins/examples/plugin_json_normalizer.py +271 -0
- omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +210 -0
- omnibase_infra/plugins/models/__init__.py +21 -0
- omnibase_infra/plugins/models/model_plugin_context.py +76 -0
- omnibase_infra/plugins/models/model_plugin_input_data.py +58 -0
- omnibase_infra/plugins/models/model_plugin_output_data.py +62 -0
- omnibase_infra/plugins/plugin_compute_base.py +435 -0
- omnibase_infra/projectors/__init__.py +30 -0
- omnibase_infra/projectors/contracts/__init__.py +63 -0
- omnibase_infra/projectors/contracts/registration_projector.yaml +370 -0
- omnibase_infra/projectors/projection_reader_registration.py +1559 -0
- omnibase_infra/projectors/snapshot_publisher_registration.py +1329 -0
- omnibase_infra/protocols/__init__.py +99 -0
- omnibase_infra/protocols/protocol_capability_projection.py +253 -0
- omnibase_infra/protocols/protocol_capability_query.py +251 -0
- omnibase_infra/protocols/protocol_event_bus_like.py +127 -0
- omnibase_infra/protocols/protocol_event_projector.py +96 -0
- omnibase_infra/protocols/protocol_idempotency_store.py +142 -0
- omnibase_infra/protocols/protocol_message_dispatcher.py +247 -0
- omnibase_infra/protocols/protocol_message_type_registry.py +306 -0
- omnibase_infra/protocols/protocol_plugin_compute.py +368 -0
- omnibase_infra/protocols/protocol_projector_schema_validator.py +82 -0
- omnibase_infra/protocols/protocol_registry_metrics.py +215 -0
- omnibase_infra/protocols/protocol_snapshot_publisher.py +396 -0
- omnibase_infra/protocols/protocol_snapshot_store.py +567 -0
- omnibase_infra/runtime/__init__.py +296 -0
- omnibase_infra/runtime/binding_config_resolver.py +2706 -0
- omnibase_infra/runtime/chain_aware_dispatch.py +467 -0
- omnibase_infra/runtime/contract_handler_discovery.py +582 -0
- omnibase_infra/runtime/contract_loaders/__init__.py +42 -0
- omnibase_infra/runtime/contract_loaders/handler_routing_loader.py +464 -0
- omnibase_infra/runtime/dispatch_context_enforcer.py +427 -0
- omnibase_infra/runtime/enums/__init__.py +18 -0
- omnibase_infra/runtime/enums/enum_config_ref_scheme.py +33 -0
- omnibase_infra/runtime/enums/enum_scheduler_status.py +170 -0
- omnibase_infra/runtime/envelope_validator.py +179 -0
- omnibase_infra/runtime/handler_contract_source.py +669 -0
- omnibase_infra/runtime/handler_plugin_loader.py +2029 -0
- omnibase_infra/runtime/handler_registry.py +321 -0
- omnibase_infra/runtime/invocation_security_enforcer.py +427 -0
- omnibase_infra/runtime/kernel.py +40 -0
- omnibase_infra/runtime/mixin_policy_validation.py +522 -0
- omnibase_infra/runtime/mixin_semver_cache.py +378 -0
- omnibase_infra/runtime/mixins/__init__.py +17 -0
- omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +757 -0
- omnibase_infra/runtime/models/__init__.py +192 -0
- omnibase_infra/runtime/models/model_batch_lifecycle_result.py +217 -0
- omnibase_infra/runtime/models/model_binding_config.py +168 -0
- omnibase_infra/runtime/models/model_binding_config_cache_stats.py +135 -0
- omnibase_infra/runtime/models/model_binding_config_resolver_config.py +329 -0
- omnibase_infra/runtime/models/model_cached_secret.py +138 -0
- omnibase_infra/runtime/models/model_compute_key.py +138 -0
- omnibase_infra/runtime/models/model_compute_registration.py +97 -0
- omnibase_infra/runtime/models/model_config_cache_entry.py +61 -0
- omnibase_infra/runtime/models/model_config_ref.py +331 -0
- omnibase_infra/runtime/models/model_config_ref_parse_result.py +125 -0
- omnibase_infra/runtime/models/model_domain_plugin_config.py +92 -0
- omnibase_infra/runtime/models/model_domain_plugin_result.py +270 -0
- omnibase_infra/runtime/models/model_duplicate_response.py +54 -0
- omnibase_infra/runtime/models/model_enabled_protocols_config.py +61 -0
- omnibase_infra/runtime/models/model_event_bus_config.py +54 -0
- omnibase_infra/runtime/models/model_failed_component.py +55 -0
- omnibase_infra/runtime/models/model_health_check_response.py +168 -0
- omnibase_infra/runtime/models/model_health_check_result.py +228 -0
- omnibase_infra/runtime/models/model_lifecycle_result.py +245 -0
- omnibase_infra/runtime/models/model_logging_config.py +42 -0
- omnibase_infra/runtime/models/model_optional_correlation_id.py +167 -0
- omnibase_infra/runtime/models/model_optional_string.py +94 -0
- omnibase_infra/runtime/models/model_optional_uuid.py +110 -0
- omnibase_infra/runtime/models/model_policy_context.py +100 -0
- omnibase_infra/runtime/models/model_policy_key.py +138 -0
- omnibase_infra/runtime/models/model_policy_registration.py +139 -0
- omnibase_infra/runtime/models/model_policy_result.py +103 -0
- omnibase_infra/runtime/models/model_policy_type_filter.py +157 -0
- omnibase_infra/runtime/models/model_projector_plugin_loader_config.py +47 -0
- omnibase_infra/runtime/models/model_protocol_registration_config.py +65 -0
- omnibase_infra/runtime/models/model_retry_policy.py +105 -0
- omnibase_infra/runtime/models/model_runtime_config.py +150 -0
- omnibase_infra/runtime/models/model_runtime_scheduler_config.py +624 -0
- omnibase_infra/runtime/models/model_runtime_scheduler_metrics.py +233 -0
- omnibase_infra/runtime/models/model_runtime_tick.py +193 -0
- omnibase_infra/runtime/models/model_secret_cache_stats.py +82 -0
- omnibase_infra/runtime/models/model_secret_mapping.py +63 -0
- omnibase_infra/runtime/models/model_secret_resolver_config.py +107 -0
- omnibase_infra/runtime/models/model_secret_resolver_metrics.py +111 -0
- omnibase_infra/runtime/models/model_secret_source_info.py +72 -0
- omnibase_infra/runtime/models/model_secret_source_spec.py +66 -0
- omnibase_infra/runtime/models/model_shutdown_batch_result.py +75 -0
- omnibase_infra/runtime/models/model_shutdown_config.py +94 -0
- omnibase_infra/runtime/projector_plugin_loader.py +1462 -0
- omnibase_infra/runtime/projector_schema_manager.py +565 -0
- omnibase_infra/runtime/projector_shell.py +1102 -0
- omnibase_infra/runtime/protocol_contract_descriptor.py +92 -0
- omnibase_infra/runtime/protocol_contract_source.py +92 -0
- omnibase_infra/runtime/protocol_domain_plugin.py +474 -0
- omnibase_infra/runtime/protocol_handler_discovery.py +221 -0
- omnibase_infra/runtime/protocol_handler_plugin_loader.py +327 -0
- omnibase_infra/runtime/protocol_lifecycle_executor.py +435 -0
- omnibase_infra/runtime/protocol_policy.py +366 -0
- omnibase_infra/runtime/protocols/__init__.py +27 -0
- omnibase_infra/runtime/protocols/protocol_runtime_scheduler.py +468 -0
- omnibase_infra/runtime/registry/__init__.py +93 -0
- omnibase_infra/runtime/registry/mixin_message_type_query.py +326 -0
- omnibase_infra/runtime/registry/mixin_message_type_registration.py +354 -0
- omnibase_infra/runtime/registry/registry_event_bus_binding.py +268 -0
- omnibase_infra/runtime/registry/registry_message_type.py +542 -0
- omnibase_infra/runtime/registry/registry_protocol_binding.py +444 -0
- omnibase_infra/runtime/registry_compute.py +1143 -0
- omnibase_infra/runtime/registry_dispatcher.py +678 -0
- omnibase_infra/runtime/registry_policy.py +1502 -0
- omnibase_infra/runtime/runtime_scheduler.py +1070 -0
- omnibase_infra/runtime/secret_resolver.py +2110 -0
- omnibase_infra/runtime/security_metadata_validator.py +776 -0
- omnibase_infra/runtime/service_kernel.py +1573 -0
- omnibase_infra/runtime/service_message_dispatch_engine.py +1805 -0
- omnibase_infra/runtime/service_runtime_host_process.py +2260 -0
- omnibase_infra/runtime/util_container_wiring.py +1123 -0
- omnibase_infra/runtime/util_validation.py +314 -0
- omnibase_infra/runtime/util_version.py +98 -0
- omnibase_infra/runtime/util_wiring.py +566 -0
- omnibase_infra/schemas/schema_registration_projection.sql +320 -0
- omnibase_infra/services/__init__.py +68 -0
- omnibase_infra/services/corpus_capture.py +678 -0
- omnibase_infra/services/service_capability_query.py +945 -0
- omnibase_infra/services/service_health.py +897 -0
- omnibase_infra/services/service_node_selector.py +530 -0
- omnibase_infra/services/service_timeout_emitter.py +682 -0
- omnibase_infra/services/service_timeout_scanner.py +390 -0
- omnibase_infra/services/snapshot/__init__.py +31 -0
- omnibase_infra/services/snapshot/service_snapshot.py +647 -0
- omnibase_infra/services/snapshot/store_inmemory.py +637 -0
- omnibase_infra/services/snapshot/store_postgres.py +1279 -0
- omnibase_infra/shared/__init__.py +8 -0
- omnibase_infra/testing/__init__.py +10 -0
- omnibase_infra/testing/utils.py +23 -0
- omnibase_infra/types/__init__.py +48 -0
- omnibase_infra/types/type_cache_info.py +49 -0
- omnibase_infra/types/type_dsn.py +173 -0
- omnibase_infra/types/type_infra_aliases.py +60 -0
- omnibase_infra/types/typed_dict/__init__.py +21 -0
- omnibase_infra/types/typed_dict/typed_dict_introspection_cache.py +128 -0
- omnibase_infra/types/typed_dict/typed_dict_performance_metrics_cache.py +140 -0
- omnibase_infra/types/typed_dict_capabilities.py +64 -0
- omnibase_infra/utils/__init__.py +89 -0
- omnibase_infra/utils/correlation.py +208 -0
- omnibase_infra/utils/util_datetime.py +372 -0
- omnibase_infra/utils/util_dsn_validation.py +333 -0
- omnibase_infra/utils/util_env_parsing.py +264 -0
- omnibase_infra/utils/util_error_sanitization.py +457 -0
- omnibase_infra/utils/util_pydantic_validators.py +477 -0
- omnibase_infra/utils/util_semver.py +233 -0
- omnibase_infra/validation/__init__.py +307 -0
- omnibase_infra/validation/enums/__init__.py +11 -0
- omnibase_infra/validation/enums/enum_contract_violation_severity.py +13 -0
- omnibase_infra/validation/infra_validators.py +1486 -0
- omnibase_infra/validation/linter_contract.py +907 -0
- omnibase_infra/validation/mixin_any_type_classification.py +120 -0
- omnibase_infra/validation/mixin_any_type_exemption.py +580 -0
- omnibase_infra/validation/mixin_any_type_reporting.py +106 -0
- omnibase_infra/validation/mixin_execution_shape_violation_checks.py +596 -0
- omnibase_infra/validation/mixin_node_archetype_detection.py +254 -0
- omnibase_infra/validation/models/__init__.py +15 -0
- omnibase_infra/validation/models/model_contract_lint_result.py +101 -0
- omnibase_infra/validation/models/model_contract_violation.py +41 -0
- omnibase_infra/validation/service_validation_aggregator.py +395 -0
- omnibase_infra/validation/validation_exemptions.yaml +1710 -0
- omnibase_infra/validation/validator_any_type.py +715 -0
- omnibase_infra/validation/validator_chain_propagation.py +839 -0
- omnibase_infra/validation/validator_execution_shape.py +465 -0
- omnibase_infra/validation/validator_localhandler.py +261 -0
- omnibase_infra/validation/validator_registration_security.py +410 -0
- omnibase_infra/validation/validator_routing_coverage.py +1020 -0
- omnibase_infra/validation/validator_runtime_shape.py +915 -0
- omnibase_infra/validation/validator_security.py +410 -0
- omnibase_infra/validation/validator_topic_category.py +1152 -0
- omnibase_infra-0.2.1.dist-info/METADATA +197 -0
- omnibase_infra-0.2.1.dist-info/RECORD +675 -0
- omnibase_infra-0.2.1.dist-info/WHEEL +4 -0
- omnibase_infra-0.2.1.dist-info/entry_points.txt +4 -0
- omnibase_infra-0.2.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,897 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
# ruff: noqa: S104
|
|
4
|
+
# S104 disabled: Binding to 0.0.0.0 is intentional for Docker/K8s health checks
|
|
5
|
+
"""HTTP Health Service for ONEX Runtime.
|
|
6
|
+
|
|
7
|
+
This module provides a minimal HTTP service for exposing health check endpoints.
|
|
8
|
+
It is designed to run alongside the ONEX runtime kernel to satisfy Docker/K8s
|
|
9
|
+
health check requirements.
|
|
10
|
+
|
|
11
|
+
The service exposes:
|
|
12
|
+
- GET /health: Returns runtime health status as JSON
|
|
13
|
+
- GET /ready: Returns readiness status as JSON (alias for /health)
|
|
14
|
+
|
|
15
|
+
Configuration:
|
|
16
|
+
ONEX_HTTP_PORT: Port to listen on (default: 8085)
|
|
17
|
+
|
|
18
|
+
Exports:
|
|
19
|
+
ServiceHealth: HTTP health check service class
|
|
20
|
+
DEFAULT_HTTP_HOST: Default bind address ("0.0.0.0")
|
|
21
|
+
DEFAULT_HTTP_PORT: Default HTTP port (8085)
|
|
22
|
+
|
|
23
|
+
Example (Direct Runtime Injection):
|
|
24
|
+
>>> from omnibase_infra.services.service_health import ServiceHealth
|
|
25
|
+
>>> from omnibase_infra.runtime import RuntimeHostProcess
|
|
26
|
+
>>>
|
|
27
|
+
>>> async def main():
|
|
28
|
+
... runtime = RuntimeHostProcess()
|
|
29
|
+
... server = ServiceHealth(runtime=runtime, port=8085)
|
|
30
|
+
... await server.start()
|
|
31
|
+
... # Server is now running
|
|
32
|
+
... await server.stop()
|
|
33
|
+
|
|
34
|
+
Example (Container-Based Injection - ONEX-Compliant):
|
|
35
|
+
>>> from omnibase_infra.services.service_health import ServiceHealth
|
|
36
|
+
>>> from omnibase_core.container import ModelONEXContainer
|
|
37
|
+
>>>
|
|
38
|
+
>>> async def main():
|
|
39
|
+
... container = ModelONEXContainer()
|
|
40
|
+
... # Wire infrastructure services to register RuntimeHostProcess
|
|
41
|
+
... await wire_infrastructure_services(container)
|
|
42
|
+
... # Create ServiceHealth using async factory method
|
|
43
|
+
... server = await ServiceHealth.create_from_container(container)
|
|
44
|
+
... await server.start()
|
|
45
|
+
... # Server is now running with container-resolved runtime
|
|
46
|
+
... await server.stop()
|
|
47
|
+
|
|
48
|
+
Note:
|
|
49
|
+
This service uses aiohttp for async HTTP handling, which is already a
|
|
50
|
+
dependency of omnibase_infra for other infrastructure operations.
|
|
51
|
+
|
|
52
|
+
See Also:
|
|
53
|
+
- :class:`ServiceHealth` for initialization modes and container integration
|
|
54
|
+
- :meth:`ServiceHealth.create_from_container` for ONEX-compliant factory method
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
from __future__ import annotations
|
|
58
|
+
|
|
59
|
+
import logging
|
|
60
|
+
from typing import TYPE_CHECKING, Literal
|
|
61
|
+
|
|
62
|
+
from aiohttp import web
|
|
63
|
+
|
|
64
|
+
from omnibase_infra.enums import EnumInfraTransportType
|
|
65
|
+
from omnibase_infra.errors import (
|
|
66
|
+
ModelInfraErrorContext,
|
|
67
|
+
ProtocolConfigurationError,
|
|
68
|
+
RuntimeHostError,
|
|
69
|
+
)
|
|
70
|
+
from omnibase_infra.runtime.models.model_health_check_response import (
|
|
71
|
+
ModelHealthCheckResponse,
|
|
72
|
+
)
|
|
73
|
+
from omnibase_infra.utils.correlation import generate_correlation_id
|
|
74
|
+
|
|
75
|
+
if TYPE_CHECKING:
|
|
76
|
+
from omnibase_core.container import ModelONEXContainer
|
|
77
|
+
from omnibase_infra.runtime.service_runtime_host_process import RuntimeHostProcess
|
|
78
|
+
|
|
79
|
+
logger = logging.getLogger(__name__)
|
|
80
|
+
|
|
81
|
+
# Default configuration - hardcoded to avoid import-time crashes from invalid env vars
|
|
82
|
+
# Environment variable override is handled safely in ServiceHealth.__init__
|
|
83
|
+
DEFAULT_HTTP_PORT: int = 8085
|
|
84
|
+
DEFAULT_HTTP_HOST = "0.0.0.0"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _get_port_from_env(default: int) -> int:
|
|
88
|
+
"""Safely parse ONEX_HTTP_PORT from environment with fallback to default.
|
|
89
|
+
|
|
90
|
+
This function handles invalid environment variable values gracefully by
|
|
91
|
+
logging a warning and returning the default value, rather than raising
|
|
92
|
+
an exception. This prevents import-time crashes and allows the application
|
|
93
|
+
to start even with misconfigured environment variables.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
default: The fallback port value if env var is unset or invalid.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Parsed port value if valid and within range (1-65535), otherwise default.
|
|
100
|
+
"""
|
|
101
|
+
from omnibase_infra.errors import ProtocolConfigurationError
|
|
102
|
+
from omnibase_infra.utils.util_env_parsing import parse_env_int
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
return parse_env_int(
|
|
106
|
+
"ONEX_HTTP_PORT",
|
|
107
|
+
default,
|
|
108
|
+
min_value=1,
|
|
109
|
+
max_value=65535,
|
|
110
|
+
transport_type=EnumInfraTransportType.HTTP,
|
|
111
|
+
service_name="health_server",
|
|
112
|
+
)
|
|
113
|
+
except ProtocolConfigurationError as e:
|
|
114
|
+
logger.warning(
|
|
115
|
+
"Invalid ONEX_HTTP_PORT environment variable, using default %d: %s",
|
|
116
|
+
default,
|
|
117
|
+
e,
|
|
118
|
+
)
|
|
119
|
+
return default
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class ServiceHealth:
|
|
123
|
+
"""Minimal HTTP server for health check endpoints.
|
|
124
|
+
|
|
125
|
+
This server provides health check endpoints for Docker and Kubernetes
|
|
126
|
+
liveness/readiness probes. It delegates health status to the RuntimeHostProcess.
|
|
127
|
+
|
|
128
|
+
Attributes:
|
|
129
|
+
runtime: The RuntimeHostProcess instance to query for health status.
|
|
130
|
+
Accessed via the :attr:`runtime` property, which raises
|
|
131
|
+
:exc:`ProtocolConfigurationError` if not available.
|
|
132
|
+
port: Port to listen on (default: 8085 or ONEX_HTTP_PORT env var).
|
|
133
|
+
host: Host to bind to (default: 0.0.0.0 for container networking).
|
|
134
|
+
version: Runtime version string to include in health response.
|
|
135
|
+
container: Optional ONEX dependency injection container for ONEX compliance.
|
|
136
|
+
|
|
137
|
+
Container Integration (OMN-529):
|
|
138
|
+
ServiceHealth supports two initialization modes to accommodate both
|
|
139
|
+
legacy code and ONEX-compliant container-based dependency injection:
|
|
140
|
+
|
|
141
|
+
**Mode 1: Direct Runtime Injection (Legacy/Simple)**
|
|
142
|
+
|
|
143
|
+
For simple use cases or legacy code, provide the runtime directly::
|
|
144
|
+
|
|
145
|
+
runtime = RuntimeHostProcess()
|
|
146
|
+
server = ServiceHealth(runtime=runtime, port=8085)
|
|
147
|
+
await server.start()
|
|
148
|
+
|
|
149
|
+
**Mode 2: Container-Based Injection (ONEX-Compliant)**
|
|
150
|
+
|
|
151
|
+
For ONEX-compliant applications using dependency injection, use the
|
|
152
|
+
async factory method which resolves RuntimeHostProcess from the container::
|
|
153
|
+
|
|
154
|
+
container = ModelONEXContainer()
|
|
155
|
+
await wire_infrastructure_services(container)
|
|
156
|
+
server = await ServiceHealth.create_from_container(container)
|
|
157
|
+
await server.start()
|
|
158
|
+
|
|
159
|
+
**Mode 3: Hybrid (Container + Explicit Runtime)**
|
|
160
|
+
|
|
161
|
+
When you have a container but want to provide a specific runtime instance::
|
|
162
|
+
|
|
163
|
+
server = ServiceHealth(container=container, runtime=my_runtime)
|
|
164
|
+
|
|
165
|
+
This is useful for testing or when the container's registered runtime
|
|
166
|
+
differs from the one you want to use for health checks.
|
|
167
|
+
|
|
168
|
+
Validation:
|
|
169
|
+
The constructor requires at least one of ``container`` or ``runtime`` to be
|
|
170
|
+
provided. If neither is provided, a :exc:`ProtocolConfigurationError` is raised.
|
|
171
|
+
When only ``container`` is provided, use :meth:`create_from_container` to
|
|
172
|
+
resolve the runtime, or access the :attr:`runtime` property will raise.
|
|
173
|
+
|
|
174
|
+
Example:
|
|
175
|
+
>>> server = ServiceHealth(runtime=runtime, port=8085)
|
|
176
|
+
>>> await server.start()
|
|
177
|
+
>>> # curl http://localhost:8085/health
|
|
178
|
+
>>> await server.stop()
|
|
179
|
+
|
|
180
|
+
See Also:
|
|
181
|
+
- :meth:`create_from_container`: Async factory for container-based initialization
|
|
182
|
+
- :attr:`runtime`: Property that returns RuntimeHostProcess or raises if unavailable
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
def __init__(
|
|
186
|
+
self,
|
|
187
|
+
container: ModelONEXContainer | None = None,
|
|
188
|
+
runtime: RuntimeHostProcess | None = None,
|
|
189
|
+
port: int | None = None,
|
|
190
|
+
host: str = DEFAULT_HTTP_HOST,
|
|
191
|
+
version: str = "unknown",
|
|
192
|
+
) -> None:
|
|
193
|
+
"""Initialize the health server.
|
|
194
|
+
|
|
195
|
+
This constructor validates that at least one dependency source is provided,
|
|
196
|
+
but it does NOT resolve the runtime from the container. For container-based
|
|
197
|
+
initialization with automatic runtime resolution, use the async factory
|
|
198
|
+
method :meth:`create_from_container` instead.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
container: Optional ONEX dependency injection container. When provided
|
|
202
|
+
alone (without runtime), the :attr:`runtime` property will raise
|
|
203
|
+
:exc:`ProtocolConfigurationError` until runtime is resolved via
|
|
204
|
+
:meth:`create_from_container` or set explicitly.
|
|
205
|
+
runtime: RuntimeHostProcess instance to delegate health checks to.
|
|
206
|
+
When provided, this instance is used directly for health checks.
|
|
207
|
+
port: Port to listen on. If None, uses ONEX_HTTP_PORT env var or 8085.
|
|
208
|
+
host: Host to bind to (default: 0.0.0.0 for container networking).
|
|
209
|
+
version: Runtime version string for health response.
|
|
210
|
+
|
|
211
|
+
Raises:
|
|
212
|
+
ProtocolConfigurationError: If neither ``container`` nor ``runtime``
|
|
213
|
+
is provided. At least one must be specified. The error includes
|
|
214
|
+
:class:`ModelInfraErrorContext` with transport type and operation.
|
|
215
|
+
|
|
216
|
+
Note:
|
|
217
|
+
**Why both container and runtime can be provided:**
|
|
218
|
+
|
|
219
|
+
The constructor accepts both parameters to support multiple use cases:
|
|
220
|
+
|
|
221
|
+
1. **Runtime-only** (``runtime=runtime``): Legacy/simple initialization.
|
|
222
|
+
The runtime is used directly without container involvement.
|
|
223
|
+
|
|
224
|
+
2. **Container-only** (``container=container``): ONEX-compliant pattern.
|
|
225
|
+
Use :meth:`create_from_container` to resolve runtime from container.
|
|
226
|
+
Direct ``__init__`` with container-only stores the container but
|
|
227
|
+
leaves runtime unresolved (accessing :attr:`runtime` will raise).
|
|
228
|
+
|
|
229
|
+
3. **Both provided** (``container=container, runtime=runtime``): Hybrid
|
|
230
|
+
pattern for testing or custom runtime selection. The container is
|
|
231
|
+
stored for ONEX compliance, but the explicit runtime is used.
|
|
232
|
+
|
|
233
|
+
**Container-only initialization pattern:**
|
|
234
|
+
|
|
235
|
+
If you only have a container, use the async factory method::
|
|
236
|
+
|
|
237
|
+
# Correct: Use factory method to resolve runtime
|
|
238
|
+
server = await ServiceHealth.create_from_container(container)
|
|
239
|
+
|
|
240
|
+
# Incorrect: Runtime will be None, accessing it will raise
|
|
241
|
+
server = ServiceHealth(container=container) # Works, but...
|
|
242
|
+
server.runtime # Raises ProtocolConfigurationError!
|
|
243
|
+
|
|
244
|
+
Warning:
|
|
245
|
+
When initializing with ``container`` only (no ``runtime``), the
|
|
246
|
+
:attr:`runtime` property will raise :exc:`ProtocolConfigurationError`
|
|
247
|
+
when accessed. This is by design - synchronous ``__init__`` cannot
|
|
248
|
+
perform async service resolution. Use :meth:`create_from_container`
|
|
249
|
+
for automatic runtime resolution from the container's service registry.
|
|
250
|
+
"""
|
|
251
|
+
# Store container for ONEX compliance (OMN-529)
|
|
252
|
+
self._container: ModelONEXContainer | None = container
|
|
253
|
+
|
|
254
|
+
# Validate that at least one dependency source is provided
|
|
255
|
+
if container is None and runtime is None:
|
|
256
|
+
context = ModelInfraErrorContext.with_correlation(
|
|
257
|
+
transport_type=EnumInfraTransportType.HTTP,
|
|
258
|
+
operation="initialize_health_server",
|
|
259
|
+
target_name="ServiceHealth",
|
|
260
|
+
)
|
|
261
|
+
raise ProtocolConfigurationError(
|
|
262
|
+
"ServiceHealth requires either 'container' or 'runtime' to be provided. "
|
|
263
|
+
"Use ServiceHealth(runtime=runtime) or ServiceHealth(container=container).",
|
|
264
|
+
context=context,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
self._runtime: RuntimeHostProcess | None = runtime
|
|
268
|
+
# If port is explicitly provided, use it; otherwise parse from env var safely
|
|
269
|
+
self._port: int = (
|
|
270
|
+
port if port is not None else _get_port_from_env(DEFAULT_HTTP_PORT)
|
|
271
|
+
)
|
|
272
|
+
self._host: str = host
|
|
273
|
+
self._version: str = version
|
|
274
|
+
|
|
275
|
+
# Server state
|
|
276
|
+
self._app: web.Application | None = None
|
|
277
|
+
self._runner: web.AppRunner | None = None
|
|
278
|
+
self._site: web.TCPSite | None = None
|
|
279
|
+
self._is_running: bool = False
|
|
280
|
+
|
|
281
|
+
logger.debug(
|
|
282
|
+
"ServiceHealth initialized",
|
|
283
|
+
extra={
|
|
284
|
+
"port": self._port,
|
|
285
|
+
"host": self._host,
|
|
286
|
+
"version": self._version,
|
|
287
|
+
},
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def is_running(self) -> bool:
|
|
292
|
+
"""Return True if the health server is running.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
Boolean indicating whether the server is running.
|
|
296
|
+
"""
|
|
297
|
+
return self._is_running
|
|
298
|
+
|
|
299
|
+
@property
|
|
300
|
+
def port(self) -> int:
|
|
301
|
+
"""Return the configured port.
|
|
302
|
+
|
|
303
|
+
Returns:
|
|
304
|
+
The port number the server listens on.
|
|
305
|
+
"""
|
|
306
|
+
return self._port
|
|
307
|
+
|
|
308
|
+
@property
|
|
309
|
+
def container(self) -> ModelONEXContainer | None:
|
|
310
|
+
"""Return the optional ONEX dependency injection container.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
The stored ModelONEXContainer instance, or None if not provided.
|
|
314
|
+
"""
|
|
315
|
+
return self._container
|
|
316
|
+
|
|
317
|
+
@property
|
|
318
|
+
def runtime(self) -> RuntimeHostProcess:
|
|
319
|
+
"""Return the RuntimeHostProcess instance, or raise if not available.
|
|
320
|
+
|
|
321
|
+
This property provides access to the RuntimeHostProcess that handles
|
|
322
|
+
the actual health status determination. The runtime must be provided
|
|
323
|
+
either directly via ``__init__`` or resolved from a container via
|
|
324
|
+
:meth:`create_from_container`.
|
|
325
|
+
|
|
326
|
+
Behavior:
|
|
327
|
+
- **When runtime is set**: Returns the RuntimeHostProcess instance.
|
|
328
|
+
- **When runtime is None**: Raises :exc:`ProtocolConfigurationError`
|
|
329
|
+
immediately. This happens when ``ServiceHealth(container=container)``
|
|
330
|
+
was called without using :meth:`create_from_container` to resolve
|
|
331
|
+
the runtime from the container's service registry.
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
The RuntimeHostProcess instance used to determine health status.
|
|
335
|
+
|
|
336
|
+
Raises:
|
|
337
|
+
ProtocolConfigurationError: If runtime is not available. This occurs when:
|
|
338
|
+
|
|
339
|
+
1. ``ServiceHealth(container=container)`` was called without runtime
|
|
340
|
+
and :meth:`create_from_container` was not used.
|
|
341
|
+
|
|
342
|
+
2. The runtime was never provided or resolved.
|
|
343
|
+
|
|
344
|
+
The error includes :class:`ModelInfraErrorContext` with transport
|
|
345
|
+
type (HTTP), operation name, and target for debugging.
|
|
346
|
+
|
|
347
|
+
Example:
|
|
348
|
+
>>> # Runtime provided directly - property works
|
|
349
|
+
>>> server = ServiceHealth(runtime=runtime)
|
|
350
|
+
>>> server.runtime # Returns RuntimeHostProcess
|
|
351
|
+
|
|
352
|
+
>>> # Container-only without factory - property raises
|
|
353
|
+
>>> server = ServiceHealth(container=container)
|
|
354
|
+
>>> server.runtime # Raises ProtocolConfigurationError!
|
|
355
|
+
|
|
356
|
+
>>> # Container with factory - property works
|
|
357
|
+
>>> server = await ServiceHealth.create_from_container(container)
|
|
358
|
+
>>> server.runtime # Returns RuntimeHostProcess
|
|
359
|
+
|
|
360
|
+
See Also:
|
|
361
|
+
:meth:`create_from_container`: Factory method that resolves runtime
|
|
362
|
+
"""
|
|
363
|
+
if self._runtime is None:
|
|
364
|
+
context = ModelInfraErrorContext.with_correlation(
|
|
365
|
+
transport_type=EnumInfraTransportType.HTTP,
|
|
366
|
+
operation="get_runtime",
|
|
367
|
+
target_name="ServiceHealth.runtime",
|
|
368
|
+
)
|
|
369
|
+
raise ProtocolConfigurationError(
|
|
370
|
+
"RuntimeHostProcess not available. "
|
|
371
|
+
"Either provide runtime during __init__ or use create_from_container().",
|
|
372
|
+
context=context,
|
|
373
|
+
)
|
|
374
|
+
return self._runtime
|
|
375
|
+
|
|
376
|
+
@classmethod
|
|
377
|
+
async def create_from_container(
|
|
378
|
+
cls,
|
|
379
|
+
container: ModelONEXContainer,
|
|
380
|
+
port: int | None = None,
|
|
381
|
+
host: str = DEFAULT_HTTP_HOST,
|
|
382
|
+
version: str = "unknown",
|
|
383
|
+
) -> ServiceHealth:
|
|
384
|
+
"""Create a ServiceHealth by resolving RuntimeHostProcess from container.
|
|
385
|
+
|
|
386
|
+
This is the preferred ONEX-compliant way to create a ServiceHealth when
|
|
387
|
+
using container-based dependency injection. It performs async service
|
|
388
|
+
resolution that cannot be done in the synchronous ``__init__`` method.
|
|
389
|
+
|
|
390
|
+
Parameters:
|
|
391
|
+
This factory method accepts 4 parameters (1 required, 3 optional):
|
|
392
|
+
|
|
393
|
+
- ``container`` (required): The ONEX container with registered services
|
|
394
|
+
- ``port`` (optional): Override for HTTP port
|
|
395
|
+
- ``host`` (optional): Override for bind address
|
|
396
|
+
- ``version`` (optional): Version string for health response
|
|
397
|
+
|
|
398
|
+
Args:
|
|
399
|
+
container: ONEX dependency injection container. Must have
|
|
400
|
+
RuntimeHostProcess registered in its service registry via
|
|
401
|
+
``wire_infrastructure_services(container)`` or equivalent.
|
|
402
|
+
port: Port to listen on. If None, uses ONEX_HTTP_PORT env var or 8085.
|
|
403
|
+
host: Host to bind to (default: 0.0.0.0 for container networking).
|
|
404
|
+
version: Runtime version string for health response.
|
|
405
|
+
|
|
406
|
+
Returns:
|
|
407
|
+
Initialized ServiceHealth with runtime resolved from container.
|
|
408
|
+
|
|
409
|
+
Raises:
|
|
410
|
+
ProtocolConfigurationError: If RuntimeHostProcess cannot be resolved
|
|
411
|
+
from the container's service registry. This typically occurs when:
|
|
412
|
+
|
|
413
|
+
1. ``wire_infrastructure_services()`` was not called before this method.
|
|
414
|
+
2. The container's service registry does not have RuntimeHostProcess
|
|
415
|
+
registered.
|
|
416
|
+
3. The service registry's ``resolve_service()`` method failed
|
|
417
|
+
for an infrastructure-related reason.
|
|
418
|
+
|
|
419
|
+
The error includes :class:`ModelInfraErrorContext` with correlation_id
|
|
420
|
+
for distributed tracing.
|
|
421
|
+
|
|
422
|
+
Example:
|
|
423
|
+
>>> container = ModelONEXContainer()
|
|
424
|
+
>>> await wire_infrastructure_services(container)
|
|
425
|
+
>>> server = await ServiceHealth.create_from_container(container)
|
|
426
|
+
>>> await server.start()
|
|
427
|
+
|
|
428
|
+
Example Error:
|
|
429
|
+
>>> container = ModelONEXContainer() # No wiring!
|
|
430
|
+
>>> server = await ServiceHealth.create_from_container(container)
|
|
431
|
+
ProtocolConfigurationError: Failed to resolve RuntimeHostProcess from container: ...
|
|
432
|
+
(correlation_id: 123e4567-e89b-12d3-a456-426614174000)
|
|
433
|
+
"""
|
|
434
|
+
from omnibase_infra.runtime.service_runtime_host_process import (
|
|
435
|
+
RuntimeHostProcess,
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
correlation_id = generate_correlation_id()
|
|
439
|
+
try:
|
|
440
|
+
runtime = await container.service_registry.resolve_service(
|
|
441
|
+
RuntimeHostProcess
|
|
442
|
+
)
|
|
443
|
+
except Exception as e:
|
|
444
|
+
context = ModelInfraErrorContext(
|
|
445
|
+
transport_type=EnumInfraTransportType.HTTP,
|
|
446
|
+
operation="resolve_runtime_from_container",
|
|
447
|
+
target_name="ServiceHealth.create_from_container",
|
|
448
|
+
correlation_id=correlation_id,
|
|
449
|
+
)
|
|
450
|
+
logger.exception(
|
|
451
|
+
"Failed to resolve RuntimeHostProcess from container (correlation_id=%s)",
|
|
452
|
+
correlation_id,
|
|
453
|
+
extra={
|
|
454
|
+
"error_type": type(e).__name__,
|
|
455
|
+
},
|
|
456
|
+
)
|
|
457
|
+
raise ProtocolConfigurationError(
|
|
458
|
+
f"Failed to resolve RuntimeHostProcess from container: {e}",
|
|
459
|
+
context=context,
|
|
460
|
+
) from e
|
|
461
|
+
|
|
462
|
+
return cls(
|
|
463
|
+
container=container,
|
|
464
|
+
runtime=runtime,
|
|
465
|
+
port=port,
|
|
466
|
+
host=host,
|
|
467
|
+
version=version,
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
async def start(self) -> None:
|
|
471
|
+
"""Start the HTTP health server for Docker/Kubernetes probes.
|
|
472
|
+
|
|
473
|
+
Creates an aiohttp web application with health check endpoints and starts
|
|
474
|
+
listening on the configured host and port. The server exposes standardized
|
|
475
|
+
health check endpoints that integrate with container orchestration platforms.
|
|
476
|
+
|
|
477
|
+
Startup Process:
|
|
478
|
+
1. Check if server is already running (idempotent safety check)
|
|
479
|
+
2. Create aiohttp Application instance
|
|
480
|
+
3. Register health check routes (/health, /ready)
|
|
481
|
+
4. Initialize AppRunner and perform async setup
|
|
482
|
+
5. Create TCPSite bound to configured host and port
|
|
483
|
+
6. Start listening for incoming health check requests
|
|
484
|
+
7. Mark server as running and log startup with correlation tracking
|
|
485
|
+
|
|
486
|
+
Health Endpoints:
|
|
487
|
+
- GET /health: Primary health check endpoint
|
|
488
|
+
- GET /ready: Readiness probe (alias for /health)
|
|
489
|
+
|
|
490
|
+
Both endpoints return JSON with:
|
|
491
|
+
- status: "healthy" | "degraded" | "unhealthy"
|
|
492
|
+
- version: Runtime kernel version
|
|
493
|
+
- details: Full health check details from RuntimeHostProcess
|
|
494
|
+
|
|
495
|
+
HTTP Status Codes:
|
|
496
|
+
- 200: Healthy or degraded (container operational)
|
|
497
|
+
- 503: Unhealthy (container should be restarted)
|
|
498
|
+
|
|
499
|
+
This method is idempotent - calling start() on an already running
|
|
500
|
+
server is safe and has no effect. This prevents double-start errors
|
|
501
|
+
during rapid restart scenarios.
|
|
502
|
+
|
|
503
|
+
Raises:
|
|
504
|
+
RuntimeHostError: If server fails to start. Common causes include:
|
|
505
|
+
- Port already in use (OSError with EADDRINUSE)
|
|
506
|
+
- Permission denied on privileged port (OSError with EACCES)
|
|
507
|
+
- Network interface unavailable
|
|
508
|
+
- Unexpected aiohttp initialization errors
|
|
509
|
+
|
|
510
|
+
All errors include:
|
|
511
|
+
- correlation_id: UUID for distributed tracing
|
|
512
|
+
- context: ModelInfraErrorContext with transport type, operation
|
|
513
|
+
- Original exception chaining: via "from e" for root cause analysis
|
|
514
|
+
|
|
515
|
+
Example:
|
|
516
|
+
>>> server = ServiceHealth(runtime=runtime, port=8085)
|
|
517
|
+
>>> await server.start()
|
|
518
|
+
>>> # Server now listening at http://0.0.0.0:8085/health
|
|
519
|
+
>>> # Docker can probe: curl http://localhost:8085/health
|
|
520
|
+
|
|
521
|
+
Example Error (Port In Use):
|
|
522
|
+
RuntimeHostError: Failed to start health server on 0.0.0.0:8085: [Errno 48] Address already in use
|
|
523
|
+
(correlation_id: 123e4567-e89b-12d3-a456-426614174000)
|
|
524
|
+
|
|
525
|
+
Docker Integration:
|
|
526
|
+
HEALTHCHECK --interval=30s --timeout=3s \\
|
|
527
|
+
CMD curl -f http://localhost:8085/health || exit 1
|
|
528
|
+
"""
|
|
529
|
+
if self._is_running:
|
|
530
|
+
logger.debug("ServiceHealth already started, skipping")
|
|
531
|
+
return
|
|
532
|
+
|
|
533
|
+
correlation_id = generate_correlation_id()
|
|
534
|
+
context = ModelInfraErrorContext(
|
|
535
|
+
transport_type=EnumInfraTransportType.HTTP,
|
|
536
|
+
operation="start_health_server",
|
|
537
|
+
target_name=f"{self._host}:{self._port}",
|
|
538
|
+
correlation_id=correlation_id,
|
|
539
|
+
)
|
|
540
|
+
|
|
541
|
+
try:
|
|
542
|
+
# Create aiohttp application
|
|
543
|
+
self._app = web.Application()
|
|
544
|
+
|
|
545
|
+
# Register routes
|
|
546
|
+
self._app.router.add_get("/health", self._handle_health)
|
|
547
|
+
self._app.router.add_get("/ready", self._handle_health) # Alias
|
|
548
|
+
|
|
549
|
+
# Create and start runner
|
|
550
|
+
self._runner = web.AppRunner(self._app)
|
|
551
|
+
await self._runner.setup()
|
|
552
|
+
|
|
553
|
+
# Create site and start listening
|
|
554
|
+
self._site = web.TCPSite(
|
|
555
|
+
self._runner,
|
|
556
|
+
self._host,
|
|
557
|
+
self._port,
|
|
558
|
+
)
|
|
559
|
+
await self._site.start()
|
|
560
|
+
|
|
561
|
+
self._is_running = True
|
|
562
|
+
|
|
563
|
+
logger.info(
|
|
564
|
+
"ServiceHealth started (correlation_id=%s)",
|
|
565
|
+
correlation_id,
|
|
566
|
+
extra={
|
|
567
|
+
"host": self._host,
|
|
568
|
+
"port": self._port,
|
|
569
|
+
"endpoints": ["/health", "/ready"],
|
|
570
|
+
"version": self._version,
|
|
571
|
+
},
|
|
572
|
+
)
|
|
573
|
+
|
|
574
|
+
except OSError as e:
|
|
575
|
+
# Port binding failure (e.g., address already in use, permission denied)
|
|
576
|
+
error_msg = (
|
|
577
|
+
f"Failed to start health server on {self._host}:{self._port}: {e}"
|
|
578
|
+
)
|
|
579
|
+
logger.exception(
|
|
580
|
+
"%s (correlation_id=%s)",
|
|
581
|
+
error_msg,
|
|
582
|
+
correlation_id,
|
|
583
|
+
extra={
|
|
584
|
+
"error_type": type(e).__name__,
|
|
585
|
+
"errno": e.errno if hasattr(e, "errno") else None,
|
|
586
|
+
},
|
|
587
|
+
)
|
|
588
|
+
raise RuntimeHostError(
|
|
589
|
+
error_msg,
|
|
590
|
+
context=context,
|
|
591
|
+
) from e
|
|
592
|
+
|
|
593
|
+
except Exception as e:
|
|
594
|
+
# Unexpected error during server startup
|
|
595
|
+
error_msg = f"Unexpected error starting health server: {e}"
|
|
596
|
+
logger.exception(
|
|
597
|
+
"%s (correlation_id=%s)",
|
|
598
|
+
error_msg,
|
|
599
|
+
correlation_id,
|
|
600
|
+
extra={
|
|
601
|
+
"error_type": type(e).__name__,
|
|
602
|
+
},
|
|
603
|
+
)
|
|
604
|
+
raise RuntimeHostError(
|
|
605
|
+
error_msg,
|
|
606
|
+
context=context,
|
|
607
|
+
) from e
|
|
608
|
+
|
|
609
|
+
async def stop(self) -> None:
|
|
610
|
+
"""Stop the HTTP health server gracefully.
|
|
611
|
+
|
|
612
|
+
Gracefully shuts down the aiohttp web server and releases all resources.
|
|
613
|
+
The shutdown process ensures proper cleanup of network resources, active
|
|
614
|
+
connections, and internal state.
|
|
615
|
+
|
|
616
|
+
Shutdown Process:
|
|
617
|
+
1. Check if server is already stopped (idempotent safety check)
|
|
618
|
+
2. Stop TCPSite to reject new connections
|
|
619
|
+
3. Clean up AppRunner to release resources
|
|
620
|
+
4. Clear Application reference
|
|
621
|
+
5. Mark server as not running
|
|
622
|
+
6. Log successful shutdown with correlation tracking
|
|
623
|
+
|
|
624
|
+
Resource Cleanup Order:
|
|
625
|
+
The cleanup follows reverse initialization order to ensure proper
|
|
626
|
+
resource release and prevent resource leaks:
|
|
627
|
+
- TCPSite (network binding)
|
|
628
|
+
- AppRunner (request handlers)
|
|
629
|
+
- Application (route definitions)
|
|
630
|
+
|
|
631
|
+
This method is idempotent - calling stop() on an already stopped
|
|
632
|
+
server is safe and has no effect. This prevents double-stop errors
|
|
633
|
+
during graceful shutdown scenarios.
|
|
634
|
+
|
|
635
|
+
Cleanup Guarantees:
|
|
636
|
+
- All network sockets are closed
|
|
637
|
+
- Active HTTP connections are terminated gracefully
|
|
638
|
+
- Event loop resources are released
|
|
639
|
+
- Server state is reset for potential restart
|
|
640
|
+
|
|
641
|
+
Example:
|
|
642
|
+
>>> server = ServiceHealth(runtime=runtime, port=8085)
|
|
643
|
+
>>> await server.start()
|
|
644
|
+
>>> # ... runtime operation ...
|
|
645
|
+
>>> await server.stop()
|
|
646
|
+
>>> # Server no longer listening, resources released
|
|
647
|
+
|
|
648
|
+
Exception Handling:
|
|
649
|
+
This method does not raise exceptions. Any errors during cleanup
|
|
650
|
+
are logged but do not prevent the shutdown sequence from completing.
|
|
651
|
+
This ensures that stop() always succeeds and the server state is
|
|
652
|
+
consistently marked as stopped.
|
|
653
|
+
"""
|
|
654
|
+
if not self._is_running:
|
|
655
|
+
logger.debug("ServiceHealth already stopped, skipping")
|
|
656
|
+
return
|
|
657
|
+
|
|
658
|
+
correlation_id = generate_correlation_id()
|
|
659
|
+
logger.info(
|
|
660
|
+
"Stopping ServiceHealth (correlation_id=%s)",
|
|
661
|
+
correlation_id,
|
|
662
|
+
)
|
|
663
|
+
|
|
664
|
+
# Cleanup in reverse order of creation
|
|
665
|
+
# Stop TCPSite first to reject new connections
|
|
666
|
+
if self._site is not None:
|
|
667
|
+
try:
|
|
668
|
+
await self._site.stop()
|
|
669
|
+
except Exception as e:
|
|
670
|
+
logger.warning(
|
|
671
|
+
"Error stopping TCPSite during shutdown (correlation_id=%s)",
|
|
672
|
+
correlation_id,
|
|
673
|
+
extra={
|
|
674
|
+
"error_type": type(e).__name__,
|
|
675
|
+
"error": str(e),
|
|
676
|
+
},
|
|
677
|
+
)
|
|
678
|
+
self._site = None
|
|
679
|
+
|
|
680
|
+
# Clean up AppRunner to release resources
|
|
681
|
+
if self._runner is not None:
|
|
682
|
+
try:
|
|
683
|
+
await self._runner.cleanup()
|
|
684
|
+
except Exception as e:
|
|
685
|
+
logger.warning(
|
|
686
|
+
"Error cleaning up AppRunner during shutdown (correlation_id=%s)",
|
|
687
|
+
correlation_id,
|
|
688
|
+
extra={
|
|
689
|
+
"error_type": type(e).__name__,
|
|
690
|
+
"error": str(e),
|
|
691
|
+
},
|
|
692
|
+
)
|
|
693
|
+
self._runner = None
|
|
694
|
+
|
|
695
|
+
# Clear application reference
|
|
696
|
+
self._app = None
|
|
697
|
+
self._is_running = False
|
|
698
|
+
|
|
699
|
+
logger.info(
|
|
700
|
+
"ServiceHealth stopped successfully (correlation_id=%s)",
|
|
701
|
+
correlation_id,
|
|
702
|
+
)
|
|
703
|
+
|
|
704
|
+
async def _handle_health(self, request: web.Request) -> web.Response:
|
|
705
|
+
"""Handle GET /health and GET /ready requests.
|
|
706
|
+
|
|
707
|
+
This is the main health check endpoint handler for Docker/Kubernetes
|
|
708
|
+
health probes. It delegates to RuntimeHostProcess.health_check() for
|
|
709
|
+
actual health status determination and returns a standardized JSON
|
|
710
|
+
response with status information and diagnostics.
|
|
711
|
+
|
|
712
|
+
Health Status Logic:
|
|
713
|
+
1. Query RuntimeHostProcess for current health state
|
|
714
|
+
2. Analyze health details to determine overall status
|
|
715
|
+
3. Map status to appropriate HTTP status code
|
|
716
|
+
4. Construct JSON response with version and diagnostics
|
|
717
|
+
5. Return response to health probe client
|
|
718
|
+
|
|
719
|
+
Status Determination:
|
|
720
|
+
- healthy: All components operational, return HTTP 200
|
|
721
|
+
- degraded: Core running but some handlers failed, return HTTP 200
|
|
722
|
+
- unhealthy: Critical failure, return HTTP 503
|
|
723
|
+
|
|
724
|
+
Degraded State HTTP 200 Design Decision:
|
|
725
|
+
Degraded containers intentionally return HTTP 200 to keep them in service
|
|
726
|
+
rotation. This is a deliberate design choice that prioritizes investigation
|
|
727
|
+
over automatic restarts.
|
|
728
|
+
|
|
729
|
+
Rationale:
|
|
730
|
+
1. Automatic restarts may mask recurring issues that need investigation
|
|
731
|
+
2. Reduced functionality is often preferable to no functionality
|
|
732
|
+
3. Cascading failures can occur if multiple containers restart simultaneously
|
|
733
|
+
4. Operators can monitor degraded status via metrics/alerts and investigate
|
|
734
|
+
|
|
735
|
+
Alternative Considered:
|
|
736
|
+
Returning HTTP 503 would remove degraded containers from load balancer
|
|
737
|
+
rotation while keeping liveness probes passing. This was rejected because
|
|
738
|
+
it reduces capacity during partial outages when some functionality may
|
|
739
|
+
still be valuable to users.
|
|
740
|
+
|
|
741
|
+
Customization:
|
|
742
|
+
If your deployment requires removing degraded containers from rotation,
|
|
743
|
+
you can override this behavior by subclassing ServiceHealth and modifying
|
|
744
|
+
the _handle_health method, or configure your load balancer to inspect
|
|
745
|
+
the response body "status" field instead of relying solely on HTTP codes.
|
|
746
|
+
|
|
747
|
+
Args:
|
|
748
|
+
request: The incoming aiohttp HTTP request. This parameter is required
|
|
749
|
+
by the aiohttp handler signature but is intentionally unused in this
|
|
750
|
+
implementation as health checks do not require request data.
|
|
751
|
+
|
|
752
|
+
Returns:
|
|
753
|
+
JSON response with health status information. The HTTP status code
|
|
754
|
+
indicates container health to orchestration platforms:
|
|
755
|
+
- HTTP 200: Container is healthy or degraded (operational)
|
|
756
|
+
- HTTP 503: Container is unhealthy (restart recommended)
|
|
757
|
+
|
|
758
|
+
Response Format (Success):
|
|
759
|
+
{
|
|
760
|
+
"status": "healthy" | "degraded" | "unhealthy",
|
|
761
|
+
"version": "x.y.z",
|
|
762
|
+
"details": {
|
|
763
|
+
"healthy": bool,
|
|
764
|
+
"degraded": bool,
|
|
765
|
+
"is_running": bool,
|
|
766
|
+
"is_draining": bool, // True during graceful shutdown drain
|
|
767
|
+
"pending_message_count": int, // In-flight messages
|
|
768
|
+
"handlers": {...},
|
|
769
|
+
// Additional health check details
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
Response Format (Error):
|
|
774
|
+
{
|
|
775
|
+
"status": "unhealthy",
|
|
776
|
+
"version": "x.y.z",
|
|
777
|
+
"error": "Exception message",
|
|
778
|
+
"correlation_id": "uuid-for-tracing"
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
Docker Integration Example:
|
|
782
|
+
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \\
|
|
783
|
+
CMD curl -f http://localhost:8085/health || exit 1
|
|
784
|
+
|
|
785
|
+
Kubernetes Integration Example:
|
|
786
|
+
livenessProbe:
|
|
787
|
+
httpGet:
|
|
788
|
+
path: /health
|
|
789
|
+
port: 8085
|
|
790
|
+
initialDelaySeconds: 30
|
|
791
|
+
periodSeconds: 10
|
|
792
|
+
|
|
793
|
+
Exception Handling:
|
|
794
|
+
If health_check() raises an exception, the handler:
|
|
795
|
+
1. Logs the full exception with correlation_id for tracing
|
|
796
|
+
2. Returns HTTP 503 with error details
|
|
797
|
+
3. Includes correlation_id in response for debugging
|
|
798
|
+
This ensures health probes always receive a response even during
|
|
799
|
+
runtime failures, preventing indefinite probe hangs.
|
|
800
|
+
"""
|
|
801
|
+
# Suppress unused argument warning - aiohttp handler signature requires request
|
|
802
|
+
_ = request
|
|
803
|
+
|
|
804
|
+
try:
|
|
805
|
+
# Get health status from runtime
|
|
806
|
+
health_details = await self.runtime.health_check()
|
|
807
|
+
|
|
808
|
+
# Runtime type validation: health_check() returns dict per contract
|
|
809
|
+
# This helps static analysis and provides runtime validation
|
|
810
|
+
# NOTE: Use explicit if/raise instead of assert - assertions can be
|
|
811
|
+
# disabled with Python's -O flag, which would skip this safety check
|
|
812
|
+
if not isinstance(health_details, dict):
|
|
813
|
+
context = ModelInfraErrorContext.with_correlation(
|
|
814
|
+
transport_type=EnumInfraTransportType.HTTP,
|
|
815
|
+
operation="validate_health_check_response",
|
|
816
|
+
target_name="RuntimeHostProcess.health_check",
|
|
817
|
+
)
|
|
818
|
+
raise ProtocolConfigurationError(
|
|
819
|
+
f"health_check() must return dict, got {type(health_details).__name__}",
|
|
820
|
+
context=context,
|
|
821
|
+
)
|
|
822
|
+
|
|
823
|
+
# Determine overall status based on health check results
|
|
824
|
+
is_healthy = bool(health_details.get("healthy", False))
|
|
825
|
+
is_degraded = bool(health_details.get("degraded", False))
|
|
826
|
+
|
|
827
|
+
if is_healthy:
|
|
828
|
+
status: Literal["healthy", "degraded", "unhealthy"] = "healthy"
|
|
829
|
+
http_status = 200
|
|
830
|
+
elif is_degraded:
|
|
831
|
+
# DESIGN DECISION: Degraded status returns HTTP 200 (not 503)
|
|
832
|
+
#
|
|
833
|
+
# Rationale: Degraded containers remain in service rotation to allow
|
|
834
|
+
# operators to investigate issues without triggering automatic restarts.
|
|
835
|
+
# The "degraded" status in the response body indicates reduced functionality
|
|
836
|
+
# while keeping the container operational for Docker/Kubernetes probes.
|
|
837
|
+
#
|
|
838
|
+
# Why HTTP 200 instead of 503:
|
|
839
|
+
# 1. Prevents cascading failures if multiple containers degrade together
|
|
840
|
+
# 2. Reduced functionality is often better than no functionality
|
|
841
|
+
# 3. Automatic restarts may mask recurring issues needing investigation
|
|
842
|
+
# 4. Operators can monitor "degraded" status via metrics/alerts
|
|
843
|
+
#
|
|
844
|
+
# Alternative considered: HTTP 503 would remove degraded containers from
|
|
845
|
+
# load balancer rotation while keeping liveness probes passing. Rejected
|
|
846
|
+
# because it reduces capacity during partial outages when degraded
|
|
847
|
+
# containers may still serve valuable traffic.
|
|
848
|
+
#
|
|
849
|
+
# Customization: To remove degraded containers from rotation, either:
|
|
850
|
+
# - Subclass ServiceHealth and override _handle_health()
|
|
851
|
+
# - Configure load balancer to inspect response body "status" field
|
|
852
|
+
# - Change http_status below to 503 if restart-on-degrade is preferred
|
|
853
|
+
status = "degraded"
|
|
854
|
+
http_status = 200
|
|
855
|
+
else:
|
|
856
|
+
status = "unhealthy"
|
|
857
|
+
http_status = 503
|
|
858
|
+
|
|
859
|
+
response = ModelHealthCheckResponse.success(
|
|
860
|
+
status=status,
|
|
861
|
+
version=self._version,
|
|
862
|
+
details=health_details,
|
|
863
|
+
)
|
|
864
|
+
|
|
865
|
+
return web.Response(
|
|
866
|
+
text=response.model_dump_json(exclude_none=True),
|
|
867
|
+
status=http_status,
|
|
868
|
+
content_type="application/json",
|
|
869
|
+
)
|
|
870
|
+
|
|
871
|
+
except Exception as e:
|
|
872
|
+
# Health check itself failed - generate correlation_id for tracing
|
|
873
|
+
correlation_id = generate_correlation_id()
|
|
874
|
+
logger.exception(
|
|
875
|
+
"Health check failed with exception (correlation_id=%s)",
|
|
876
|
+
correlation_id,
|
|
877
|
+
extra={
|
|
878
|
+
"error": str(e),
|
|
879
|
+
"error_type": type(e).__name__,
|
|
880
|
+
},
|
|
881
|
+
)
|
|
882
|
+
|
|
883
|
+
error_response = ModelHealthCheckResponse.failure(
|
|
884
|
+
version=self._version,
|
|
885
|
+
error=str(e),
|
|
886
|
+
error_type=type(e).__name__,
|
|
887
|
+
correlation_id=str(correlation_id),
|
|
888
|
+
)
|
|
889
|
+
|
|
890
|
+
return web.Response(
|
|
891
|
+
text=error_response.model_dump_json(exclude_none=True),
|
|
892
|
+
status=503,
|
|
893
|
+
content_type="application/json",
|
|
894
|
+
)
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
__all__: list[str] = ["DEFAULT_HTTP_HOST", "DEFAULT_HTTP_PORT", "ServiceHealth"]
|