omnibase_infra 0.2.6__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/adapters/adapter_onex_tool_execution.py +451 -0
- omnibase_infra/capabilities/__init__.py +15 -0
- omnibase_infra/capabilities/capability_inference_rules.py +211 -0
- omnibase_infra/capabilities/contract_capability_extractor.py +221 -0
- omnibase_infra/capabilities/intent_type_extractor.py +160 -0
- omnibase_infra/cli/__init__.py +1 -0
- omnibase_infra/cli/commands.py +216 -0
- omnibase_infra/clients/__init__.py +0 -0
- omnibase_infra/configs/widget_mapping.yaml +176 -0
- omnibase_infra/constants_topic_patterns.py +26 -0
- omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +264 -0
- omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +141 -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 +132 -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_consumer_group_purpose.py +92 -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 +111 -0
- omnibase_infra/enums/enum_handler_loader_error.py +178 -0
- omnibase_infra/enums/enum_handler_source_mode.py +86 -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_kafka_acks.py +99 -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 +160 -0
- omnibase_infra/errors/error_architecture_violation.py +152 -0
- omnibase_infra/errors/error_binding_resolution.py +128 -0
- omnibase_infra/errors/error_chain_propagation.py +188 -0
- omnibase_infra/errors/error_compute_registry.py +95 -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 +105 -0
- omnibase_infra/errors/error_infra.py +610 -0
- omnibase_infra/errors/error_message_type_registry.py +101 -0
- omnibase_infra/errors/error_policy_registry.py +115 -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 +84 -0
- omnibase_infra/event_bus/event_bus_inmemory.py +797 -0
- omnibase_infra/event_bus/event_bus_kafka.py +1716 -0
- omnibase_infra/event_bus/mixin_kafka_broadcast.py +180 -0
- omnibase_infra/event_bus/mixin_kafka_dlq.py +771 -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 +693 -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/testing/__init__.py +26 -0
- omnibase_infra/event_bus/testing/adapter_protocol_event_publisher_inmemory.py +418 -0
- omnibase_infra/event_bus/testing/model_publisher_metrics.py +64 -0
- omnibase_infra/event_bus/topic_constants.py +376 -0
- omnibase_infra/handlers/__init__.py +82 -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 +795 -0
- omnibase_infra/handlers/handler_db.py +1046 -0
- omnibase_infra/handlers/handler_filesystem.py +1478 -0
- omnibase_infra/handlers/handler_graph.py +2015 -0
- omnibase_infra/handlers/handler_http.py +926 -0
- omnibase_infra/handlers/handler_intent.py +387 -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 +1430 -0
- omnibase_infra/handlers/handler_qdrant.py +1076 -0
- omnibase_infra/handlers/handler_vault.py +428 -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 +47 -0
- omnibase_infra/handlers/mixins/mixin_consul_initialization.py +349 -0
- omnibase_infra/handlers/mixins/mixin_consul_kv.py +338 -0
- omnibase_infra/handlers/mixins/mixin_consul_service.py +542 -0
- omnibase_infra/handlers/mixins/mixin_consul_topic_index.py +585 -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 +922 -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 +1051 -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 +109 -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/migrations/001_create_event_ledger.sql +166 -0
- omnibase_infra/migrations/001_drop_event_ledger.sql +18 -0
- omnibase_infra/mixins/__init__.py +71 -0
- omnibase_infra/mixins/mixin_async_circuit_breaker.py +656 -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 +2670 -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 +144 -0
- omnibase_infra/models/bindings/__init__.py +59 -0
- omnibase_infra/models/bindings/constants.py +144 -0
- omnibase_infra/models/bindings/model_binding_resolution_result.py +103 -0
- omnibase_infra/models/bindings/model_operation_binding.py +44 -0
- omnibase_infra/models/bindings/model_operation_bindings_subcontract.py +152 -0
- omnibase_infra/models/bindings/model_parsed_binding.py +52 -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 +330 -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 +155 -0
- omnibase_infra/models/dispatch/model_debug_trace_snapshot.py +114 -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_materialized_dispatch.py +141 -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 +80 -0
- omnibase_infra/models/handlers/model_bootstrap_handler_descriptor.py +162 -0
- omnibase_infra/models/handlers/model_contract_discovery_result.py +82 -0
- omnibase_infra/models/handlers/model_handler_descriptor.py +200 -0
- omnibase_infra/models/handlers/model_handler_identifier.py +215 -0
- omnibase_infra/models/handlers/model_handler_source_config.py +220 -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/mcp/__init__.py +15 -0
- omnibase_infra/models/mcp/model_mcp_contract_config.py +80 -0
- omnibase_infra/models/mcp/model_mcp_server_config.py +67 -0
- omnibase_infra/models/mcp/model_mcp_tool_definition.py +73 -0
- omnibase_infra/models/mcp/model_mcp_tool_parameter.py +35 -0
- omnibase_infra/models/model_node_identity.py +126 -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 +591 -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 +68 -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_event_bus_topic_entry.py +59 -0
- omnibase_infra/models/registration/model_introspection_metrics.py +253 -0
- omnibase_infra/models/registration/model_node_capabilities.py +190 -0
- omnibase_infra/models/registration/model_node_event_bus_config.py +99 -0
- omnibase_infra/models/registration/model_node_heartbeat_event.py +126 -0
- omnibase_infra/models/registration/model_node_introspection_event.py +195 -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 +49 -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 +296 -0
- omnibase_infra/models/runtime/model_loaded_handler.py +129 -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 +57 -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 +203 -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 +106 -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/contract_registry_reducer/__init__.py +29 -0
- omnibase_infra/nodes/contract_registry_reducer/contract.yaml +255 -0
- omnibase_infra/nodes/contract_registry_reducer/models/__init__.py +38 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_contract_registry_state.py +266 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_cleanup_topic_references.py +55 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_deactivate_contract.py +58 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_mark_stale.py +49 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_heartbeat.py +71 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_topic.py +66 -0
- omnibase_infra/nodes/contract_registry_reducer/models/model_payload_upsert_contract.py +92 -0
- omnibase_infra/nodes/contract_registry_reducer/node.py +121 -0
- omnibase_infra/nodes/contract_registry_reducer/reducer.py +784 -0
- omnibase_infra/nodes/contract_registry_reducer/registry/__init__.py +9 -0
- omnibase_infra/nodes/contract_registry_reducer/registry/registry_infra_contract_registry_reducer.py +101 -0
- omnibase_infra/nodes/effects/README.md +358 -0
- omnibase_infra/nodes/effects/__init__.py +26 -0
- omnibase_infra/nodes/effects/contract.yaml +167 -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/handlers/consul/contract.yaml +85 -0
- omnibase_infra/nodes/handlers/db/contract.yaml +72 -0
- omnibase_infra/nodes/handlers/graph/contract.yaml +127 -0
- omnibase_infra/nodes/handlers/http/contract.yaml +74 -0
- omnibase_infra/nodes/handlers/intent/contract.yaml +66 -0
- omnibase_infra/nodes/handlers/mcp/contract.yaml +69 -0
- omnibase_infra/nodes/handlers/vault/contract.yaml +91 -0
- omnibase_infra/nodes/node_intent_storage_effect/__init__.py +50 -0
- omnibase_infra/nodes/node_intent_storage_effect/contract.yaml +194 -0
- omnibase_infra/nodes/node_intent_storage_effect/models/__init__.py +24 -0
- omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_input.py +141 -0
- omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_output.py +130 -0
- omnibase_infra/nodes/node_intent_storage_effect/node.py +94 -0
- omnibase_infra/nodes/node_intent_storage_effect/registry/__init__.py +35 -0
- omnibase_infra/nodes/node_intent_storage_effect/registry/registry_infra_intent_storage.py +294 -0
- omnibase_infra/nodes/node_ledger_projection_compute/__init__.py +50 -0
- omnibase_infra/nodes/node_ledger_projection_compute/contract.yaml +104 -0
- omnibase_infra/nodes/node_ledger_projection_compute/node.py +284 -0
- omnibase_infra/nodes/node_ledger_projection_compute/registry/__init__.py +29 -0
- omnibase_infra/nodes/node_ledger_projection_compute/registry/registry_infra_ledger_projection.py +118 -0
- omnibase_infra/nodes/node_ledger_write_effect/__init__.py +82 -0
- omnibase_infra/nodes/node_ledger_write_effect/contract.yaml +200 -0
- omnibase_infra/nodes/node_ledger_write_effect/handlers/__init__.py +22 -0
- omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_append.py +372 -0
- omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_query.py +597 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/__init__.py +31 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_append_result.py +54 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_entry.py +92 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query.py +53 -0
- omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query_result.py +41 -0
- omnibase_infra/nodes/node_ledger_write_effect/node.py +89 -0
- omnibase_infra/nodes/node_ledger_write_effect/protocols/__init__.py +13 -0
- omnibase_infra/nodes/node_ledger_write_effect/protocols/protocol_ledger_persistence.py +127 -0
- omnibase_infra/nodes/node_ledger_write_effect/registry/__init__.py +9 -0
- omnibase_infra/nodes/node_ledger_write_effect/registry/registry_infra_ledger_write.py +121 -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 +482 -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 +694 -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 +528 -0
- omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +393 -0
- omnibase_infra/nodes/node_registration_orchestrator/wiring.py +743 -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 +220 -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 +112 -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 +215 -0
- omnibase_infra/nodes/node_registry_effect/__init__.py +85 -0
- omnibase_infra/nodes/node_registry_effect/contract.yaml +677 -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 +417 -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 +222 -0
- omnibase_infra/nodes/reducers/__init__.py +30 -0
- omnibase_infra/nodes/reducers/models/__init__.py +37 -0
- omnibase_infra/nodes/reducers/models/model_payload_consul_register.py +87 -0
- omnibase_infra/nodes/reducers/models/model_payload_ledger_append.py +133 -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 +1138 -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 +449 -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 +104 -0
- omnibase_infra/protocols/protocol_capability_projection.py +253 -0
- omnibase_infra/protocols/protocol_capability_query.py +251 -0
- omnibase_infra/protocols/protocol_container_aware.py +200 -0
- omnibase_infra/protocols/protocol_dispatch_engine.py +152 -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 +445 -0
- omnibase_infra/runtime/binding_config_resolver.py +2771 -0
- omnibase_infra/runtime/binding_resolver.py +753 -0
- omnibase_infra/runtime/chain_aware_dispatch.py +467 -0
- omnibase_infra/runtime/constants_notification.py +75 -0
- omnibase_infra/runtime/constants_security.py +70 -0
- omnibase_infra/runtime/contract_handler_discovery.py +587 -0
- omnibase_infra/runtime/contract_loaders/__init__.py +51 -0
- omnibase_infra/runtime/contract_loaders/handler_routing_loader.py +464 -0
- omnibase_infra/runtime/contract_loaders/operation_bindings_loader.py +789 -0
- omnibase_infra/runtime/dispatch_context_enforcer.py +427 -0
- omnibase_infra/runtime/emit_daemon/__init__.py +97 -0
- omnibase_infra/runtime/emit_daemon/cli.py +844 -0
- omnibase_infra/runtime/emit_daemon/client.py +811 -0
- omnibase_infra/runtime/emit_daemon/config.py +535 -0
- omnibase_infra/runtime/emit_daemon/daemon.py +812 -0
- omnibase_infra/runtime/emit_daemon/event_registry.py +477 -0
- omnibase_infra/runtime/emit_daemon/model_daemon_request.py +139 -0
- omnibase_infra/runtime/emit_daemon/model_daemon_response.py +191 -0
- omnibase_infra/runtime/emit_daemon/queue.py +618 -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/event_bus_subcontract_wiring.py +466 -0
- omnibase_infra/runtime/handler_bootstrap_source.py +507 -0
- omnibase_infra/runtime/handler_contract_config_loader.py +603 -0
- omnibase_infra/runtime/handler_contract_source.py +750 -0
- omnibase_infra/runtime/handler_identity.py +81 -0
- omnibase_infra/runtime/handler_plugin_loader.py +2046 -0
- omnibase_infra/runtime/handler_registry.py +329 -0
- omnibase_infra/runtime/handler_source_resolver.py +367 -0
- omnibase_infra/runtime/invocation_security_enforcer.py +427 -0
- omnibase_infra/runtime/kafka_contract_source.py +984 -0
- omnibase_infra/runtime/kernel.py +40 -0
- omnibase_infra/runtime/mixin_policy_validation.py +522 -0
- omnibase_infra/runtime/mixin_semver_cache.py +402 -0
- omnibase_infra/runtime/mixins/__init__.py +24 -0
- omnibase_infra/runtime/mixins/mixin_projector_notification_publishing.py +566 -0
- omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +778 -0
- omnibase_infra/runtime/models/__init__.py +229 -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_contract_load_result.py +224 -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 +229 -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_notification_config.py +171 -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_contract_config.py +268 -0
- omnibase_infra/runtime/models/model_runtime_scheduler_config.py +625 -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_security_config.py +109 -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/models/model_transition_notification_outbox_config.py +112 -0
- omnibase_infra/runtime/models/model_transition_notification_outbox_metrics.py +140 -0
- omnibase_infra/runtime/models/model_transition_notification_publisher_metrics.py +357 -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 +1330 -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 +37 -0
- omnibase_infra/runtime/protocols/protocol_runtime_scheduler.py +468 -0
- omnibase_infra/runtime/publisher_topic_scoped.py +294 -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 +445 -0
- omnibase_infra/runtime/registry_compute.py +1143 -0
- omnibase_infra/runtime/registry_contract_source.py +693 -0
- omnibase_infra/runtime/registry_dispatcher.py +678 -0
- omnibase_infra/runtime/registry_policy.py +1185 -0
- omnibase_infra/runtime/runtime_contract_config_loader.py +406 -0
- omnibase_infra/runtime/runtime_scheduler.py +1070 -0
- omnibase_infra/runtime/secret_resolver.py +2112 -0
- omnibase_infra/runtime/security_metadata_validator.py +776 -0
- omnibase_infra/runtime/service_kernel.py +1651 -0
- omnibase_infra/runtime/service_message_dispatch_engine.py +2350 -0
- omnibase_infra/runtime/service_runtime_host_process.py +3493 -0
- omnibase_infra/runtime/transition_notification_outbox.py +1190 -0
- omnibase_infra/runtime/transition_notification_publisher.py +765 -0
- omnibase_infra/runtime/util_container_wiring.py +1124 -0
- omnibase_infra/runtime/util_validation.py +314 -0
- omnibase_infra/runtime/util_version.py +98 -0
- omnibase_infra/runtime/util_wiring.py +723 -0
- omnibase_infra/schemas/schema_registration_projection.sql +320 -0
- omnibase_infra/schemas/schema_transition_notification_outbox.sql +245 -0
- omnibase_infra/services/__init__.py +89 -0
- omnibase_infra/services/corpus_capture.py +684 -0
- omnibase_infra/services/mcp/__init__.py +31 -0
- omnibase_infra/services/mcp/mcp_server_lifecycle.py +449 -0
- omnibase_infra/services/mcp/service_mcp_tool_discovery.py +411 -0
- omnibase_infra/services/mcp/service_mcp_tool_registry.py +329 -0
- omnibase_infra/services/mcp/service_mcp_tool_sync.py +565 -0
- omnibase_infra/services/registry_api/__init__.py +40 -0
- omnibase_infra/services/registry_api/main.py +261 -0
- omnibase_infra/services/registry_api/models/__init__.py +66 -0
- omnibase_infra/services/registry_api/models/model_capability_widget_mapping.py +38 -0
- omnibase_infra/services/registry_api/models/model_pagination_info.py +48 -0
- omnibase_infra/services/registry_api/models/model_registry_discovery_response.py +73 -0
- omnibase_infra/services/registry_api/models/model_registry_health_response.py +49 -0
- omnibase_infra/services/registry_api/models/model_registry_instance_view.py +88 -0
- omnibase_infra/services/registry_api/models/model_registry_node_view.py +88 -0
- omnibase_infra/services/registry_api/models/model_registry_summary.py +60 -0
- omnibase_infra/services/registry_api/models/model_response_list_instances.py +43 -0
- omnibase_infra/services/registry_api/models/model_response_list_nodes.py +51 -0
- omnibase_infra/services/registry_api/models/model_warning.py +49 -0
- omnibase_infra/services/registry_api/models/model_widget_defaults.py +28 -0
- omnibase_infra/services/registry_api/models/model_widget_mapping.py +51 -0
- omnibase_infra/services/registry_api/routes.py +371 -0
- omnibase_infra/services/registry_api/service.py +837 -0
- omnibase_infra/services/service_capability_query.py +945 -0
- omnibase_infra/services/service_health.py +898 -0
- omnibase_infra/services/service_node_selector.py +530 -0
- omnibase_infra/services/service_timeout_emitter.py +699 -0
- omnibase_infra/services/service_timeout_scanner.py +394 -0
- omnibase_infra/services/session/__init__.py +56 -0
- omnibase_infra/services/session/config_consumer.py +137 -0
- omnibase_infra/services/session/config_store.py +139 -0
- omnibase_infra/services/session/consumer.py +1007 -0
- omnibase_infra/services/session/protocol_session_aggregator.py +117 -0
- omnibase_infra/services/session/store.py +997 -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/topics/__init__.py +45 -0
- omnibase_infra/topics/platform_topic_suffixes.py +140 -0
- omnibase_infra/topics/util_topic_composition.py +95 -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 +29 -0
- omnibase_infra/types/typed_dict/typed_dict_envelope_build_params.py +115 -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 +117 -0
- omnibase_infra/utils/correlation.py +208 -0
- omnibase_infra/utils/util_atomic_file.py +261 -0
- omnibase_infra/utils/util_consumer_group.py +232 -0
- omnibase_infra/utils/util_datetime.py +372 -0
- omnibase_infra/utils/util_db_transaction.py +239 -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_retry_optimistic.py +281 -0
- omnibase_infra/utils/util_semver.py +233 -0
- omnibase_infra/validation/__init__.py +307 -0
- omnibase_infra/validation/contracts/security.validation.yaml +114 -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 +1514 -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 +2033 -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 +513 -0
- omnibase_infra/validation/validator_topic_category.py +1152 -0
- omnibase_infra-0.2.6.dist-info/METADATA +197 -0
- omnibase_infra-0.2.6.dist-info/RECORD +833 -0
- omnibase_infra-0.2.6.dist-info/WHEEL +4 -0
- omnibase_infra-0.2.6.dist-info/entry_points.txt +5 -0
- omnibase_infra-0.2.6.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Correlation ID utilities for distributed tracing.
|
|
4
|
+
|
|
5
|
+
Provides utilities for generating and propagating correlation IDs
|
|
6
|
+
across infrastructure components for distributed tracing and debugging.
|
|
7
|
+
|
|
8
|
+
Correlation IDs are used to:
|
|
9
|
+
- Track requests across service boundaries
|
|
10
|
+
- Link related log entries for debugging
|
|
11
|
+
- Enable distributed tracing in containerized environments
|
|
12
|
+
- Provide unique identifiers for error context
|
|
13
|
+
|
|
14
|
+
Example:
|
|
15
|
+
>>> from omnibase_infra.utils.correlation import generate_correlation_id
|
|
16
|
+
>>> correlation_id = generate_correlation_id()
|
|
17
|
+
>>> logger.info("Processing request", extra={"correlation_id": correlation_id})
|
|
18
|
+
|
|
19
|
+
Context Manager Example:
|
|
20
|
+
>>> from omnibase_infra.utils.correlation import CorrelationContext
|
|
21
|
+
>>> with CorrelationContext() as correlation_id:
|
|
22
|
+
... logger.info("Operation started", extra={"correlation_id": correlation_id})
|
|
23
|
+
... # All operations within this context share the same correlation_id
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
from contextvars import ContextVar, Token
|
|
29
|
+
from typing import TYPE_CHECKING
|
|
30
|
+
from uuid import UUID, uuid4
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from types import TracebackType
|
|
34
|
+
|
|
35
|
+
# Context variable for correlation ID propagation across async boundaries
|
|
36
|
+
# This enables correlation ID to be implicitly passed through async call chains
|
|
37
|
+
_correlation_id: ContextVar[UUID | None] = ContextVar("correlation_id", default=None)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def generate_correlation_id() -> UUID:
|
|
41
|
+
"""Generate a new correlation ID using UUID4.
|
|
42
|
+
|
|
43
|
+
Creates a cryptographically random UUID suitable for distributed tracing.
|
|
44
|
+
UUID4 is used because it provides high uniqueness guarantees without
|
|
45
|
+
requiring coordination between nodes.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
UUID: A new randomly generated UUID4 correlation ID.
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
>>> correlation_id = generate_correlation_id()
|
|
52
|
+
>>> print(correlation_id)
|
|
53
|
+
123e4567-e89b-12d3-a456-426614174000
|
|
54
|
+
>>> isinstance(correlation_id, UUID)
|
|
55
|
+
True
|
|
56
|
+
"""
|
|
57
|
+
return uuid4()
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_correlation_id() -> UUID:
|
|
61
|
+
"""Get current correlation ID from context or generate new one.
|
|
62
|
+
|
|
63
|
+
Retrieves the correlation ID from the current async context. If no
|
|
64
|
+
correlation ID has been set in the current context, generates a new
|
|
65
|
+
one and sets it for future retrieval.
|
|
66
|
+
|
|
67
|
+
This function is useful when you need a correlation ID but don't know
|
|
68
|
+
if one has already been established in the current execution context.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
UUID: Current correlation ID from context, or a new one if not set.
|
|
72
|
+
|
|
73
|
+
Example:
|
|
74
|
+
>>> # First call generates and stores a new ID
|
|
75
|
+
>>> id1 = get_correlation_id()
|
|
76
|
+
>>> # Second call returns the same ID
|
|
77
|
+
>>> id2 = get_correlation_id()
|
|
78
|
+
>>> id1 == id2
|
|
79
|
+
True
|
|
80
|
+
"""
|
|
81
|
+
correlation_id = _correlation_id.get()
|
|
82
|
+
if correlation_id is None:
|
|
83
|
+
correlation_id = generate_correlation_id()
|
|
84
|
+
_correlation_id.set(correlation_id)
|
|
85
|
+
return correlation_id
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def set_correlation_id(correlation_id: UUID) -> None:
|
|
89
|
+
"""Set correlation ID in current context.
|
|
90
|
+
|
|
91
|
+
Explicitly sets a correlation ID in the current async context. This is
|
|
92
|
+
useful when you want to propagate an existing correlation ID (e.g., from
|
|
93
|
+
an incoming request header) into the current execution context.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
correlation_id: The correlation ID to set. Must be a UUID instance.
|
|
97
|
+
|
|
98
|
+
Example:
|
|
99
|
+
>>> incoming_id = UUID("123e4567-e89b-12d3-a456-426614174000")
|
|
100
|
+
>>> set_correlation_id(incoming_id)
|
|
101
|
+
>>> get_correlation_id() == incoming_id
|
|
102
|
+
True
|
|
103
|
+
"""
|
|
104
|
+
_correlation_id.set(correlation_id)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def clear_correlation_id() -> None:
|
|
108
|
+
"""Clear the correlation ID from the current context.
|
|
109
|
+
|
|
110
|
+
Resets the correlation ID context variable to None. This is useful
|
|
111
|
+
when starting a new logical operation that should not inherit the
|
|
112
|
+
correlation ID from a previous operation.
|
|
113
|
+
|
|
114
|
+
Example:
|
|
115
|
+
>>> set_correlation_id(generate_correlation_id())
|
|
116
|
+
>>> clear_correlation_id()
|
|
117
|
+
>>> _correlation_id.get() is None
|
|
118
|
+
True
|
|
119
|
+
"""
|
|
120
|
+
_correlation_id.set(None)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class CorrelationContext:
|
|
124
|
+
"""Context manager for correlation ID scoping.
|
|
125
|
+
|
|
126
|
+
Provides a context manager that automatically generates or uses a provided
|
|
127
|
+
correlation ID for the duration of the context. The previous correlation ID
|
|
128
|
+
is restored when exiting the context, enabling nested correlation scopes.
|
|
129
|
+
|
|
130
|
+
This is useful for:
|
|
131
|
+
- Scoping correlation IDs to specific operations
|
|
132
|
+
- Ensuring cleanup of correlation context
|
|
133
|
+
- Nested correlation contexts with proper restoration
|
|
134
|
+
|
|
135
|
+
Attributes:
|
|
136
|
+
correlation_id: The correlation ID used within this context.
|
|
137
|
+
|
|
138
|
+
Example:
|
|
139
|
+
>>> with CorrelationContext() as correlation_id:
|
|
140
|
+
... logger.info("Operation", extra={"correlation_id": correlation_id})
|
|
141
|
+
... # correlation_id is available and set in context
|
|
142
|
+
|
|
143
|
+
Example with provided ID:
|
|
144
|
+
>>> existing_id = UUID("123e4567-e89b-12d3-a456-426614174000")
|
|
145
|
+
>>> with CorrelationContext(correlation_id=existing_id) as cid:
|
|
146
|
+
... cid == existing_id
|
|
147
|
+
True
|
|
148
|
+
|
|
149
|
+
Example with nesting:
|
|
150
|
+
>>> with CorrelationContext() as outer_id:
|
|
151
|
+
... with CorrelationContext() as inner_id:
|
|
152
|
+
... # inner_id is different from outer_id
|
|
153
|
+
... pass
|
|
154
|
+
... # outer_id is restored after inner context exits
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
def __init__(self, correlation_id: UUID | None = None) -> None:
|
|
158
|
+
"""Initialize the correlation context.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
correlation_id: Optional correlation ID to use. If not provided,
|
|
162
|
+
a new UUID4 will be generated when entering the context.
|
|
163
|
+
"""
|
|
164
|
+
self._correlation_id = correlation_id or generate_correlation_id()
|
|
165
|
+
self._token: Token[UUID | None] | None = None
|
|
166
|
+
|
|
167
|
+
@property
|
|
168
|
+
def correlation_id(self) -> UUID:
|
|
169
|
+
"""Return the correlation ID for this context.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
UUID: The correlation ID associated with this context.
|
|
173
|
+
"""
|
|
174
|
+
return self._correlation_id
|
|
175
|
+
|
|
176
|
+
def __enter__(self) -> UUID:
|
|
177
|
+
"""Enter the correlation context and set the correlation ID.
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
UUID: The correlation ID for this context.
|
|
181
|
+
"""
|
|
182
|
+
self._token = _correlation_id.set(self._correlation_id)
|
|
183
|
+
return self._correlation_id
|
|
184
|
+
|
|
185
|
+
def __exit__(
|
|
186
|
+
self,
|
|
187
|
+
exc_type: type[BaseException] | None,
|
|
188
|
+
exc_val: BaseException | None,
|
|
189
|
+
exc_tb: TracebackType | None,
|
|
190
|
+
) -> None:
|
|
191
|
+
"""Exit the correlation context and restore the previous correlation ID.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
exc_type: Exception type if an exception was raised.
|
|
195
|
+
exc_val: Exception value if an exception was raised.
|
|
196
|
+
exc_tb: Traceback if an exception was raised.
|
|
197
|
+
"""
|
|
198
|
+
if self._token is not None:
|
|
199
|
+
_correlation_id.reset(self._token)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
__all__: list[str] = [
|
|
203
|
+
"CorrelationContext",
|
|
204
|
+
"clear_correlation_id",
|
|
205
|
+
"generate_correlation_id",
|
|
206
|
+
"get_correlation_id",
|
|
207
|
+
"set_correlation_id",
|
|
208
|
+
]
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Atomic file write utilities.
|
|
4
|
+
|
|
5
|
+
This module provides primitives for atomic file writes using the temp-file-rename
|
|
6
|
+
pattern. Atomic writes ensure that file contents are either completely written
|
|
7
|
+
or not written at all - there is no intermediate state where the file contains
|
|
8
|
+
partial data.
|
|
9
|
+
|
|
10
|
+
POSIX Atomicity Guarantees:
|
|
11
|
+
On POSIX systems, rename() is atomic within the same filesystem. This module
|
|
12
|
+
creates the temporary file in the same directory as the target file to ensure
|
|
13
|
+
the rename operation is atomic.
|
|
14
|
+
|
|
15
|
+
**IMPORTANT**: The temp file MUST be created in the same directory as the
|
|
16
|
+
target file (using `dir=path.parent`). If the temp file is on a different
|
|
17
|
+
filesystem, the rename becomes a copy-and-delete operation, losing atomicity.
|
|
18
|
+
|
|
19
|
+
NFS Caveat:
|
|
20
|
+
NFS provides weaker atomicity guarantees. While rename() is still atomic on
|
|
21
|
+
NFSv4+, there may be brief windows where both files are visible to other
|
|
22
|
+
clients. For applications requiring strict consistency on NFS, additional
|
|
23
|
+
locking mechanisms may be needed.
|
|
24
|
+
|
|
25
|
+
Windows Notes:
|
|
26
|
+
- os.replace() is atomic on Windows since Python 3.3
|
|
27
|
+
- Path.rename() on Windows will fail if the target exists; use os.replace()
|
|
28
|
+
- This module uses os.replace() for cross-platform atomic rename
|
|
29
|
+
|
|
30
|
+
Durability Note:
|
|
31
|
+
This module provides atomicity (all-or-nothing) but not durability guarantees.
|
|
32
|
+
For systems requiring crash-recovery durability, consider adding fsync() after
|
|
33
|
+
write and before rename. This comes at a performance cost.
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
>>> from pathlib import Path
|
|
37
|
+
>>> from omnibase_infra.utils import write_atomic_bytes
|
|
38
|
+
>>>
|
|
39
|
+
>>> # Write data atomically
|
|
40
|
+
>>> data = b"Hello, World!"
|
|
41
|
+
>>> bytes_written = write_atomic_bytes(Path("/tmp/myfile.txt"), data)
|
|
42
|
+
>>> bytes_written
|
|
43
|
+
13
|
|
44
|
+
>>>
|
|
45
|
+
>>> # Async version (uses asyncio.to_thread internally)
|
|
46
|
+
>>> import asyncio
|
|
47
|
+
>>> from omnibase_infra.utils import write_atomic_bytes_async
|
|
48
|
+
>>> bytes_written = asyncio.run(write_atomic_bytes_async(Path("/tmp/myfile.txt"), data))
|
|
49
|
+
>>> bytes_written
|
|
50
|
+
13
|
|
51
|
+
|
|
52
|
+
.. versionadded:: 0.10.0
|
|
53
|
+
Created as part of OMN-1524 atomic write utilities.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
from __future__ import annotations
|
|
57
|
+
|
|
58
|
+
import asyncio
|
|
59
|
+
import logging
|
|
60
|
+
import os
|
|
61
|
+
import tempfile
|
|
62
|
+
from pathlib import Path
|
|
63
|
+
from uuid import UUID
|
|
64
|
+
|
|
65
|
+
logger = logging.getLogger(__name__)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def write_atomic_bytes(
|
|
69
|
+
path: Path,
|
|
70
|
+
data: bytes,
|
|
71
|
+
*,
|
|
72
|
+
temp_prefix: str = "",
|
|
73
|
+
temp_suffix: str = ".tmp",
|
|
74
|
+
correlation_id: UUID | None = None,
|
|
75
|
+
) -> int:
|
|
76
|
+
"""Write bytes to a file atomically using temp-file-rename pattern.
|
|
77
|
+
|
|
78
|
+
This function provides atomic file writes by:
|
|
79
|
+
1. Creating a temporary file in the same directory as the target
|
|
80
|
+
2. Writing all data to the temporary file
|
|
81
|
+
3. Atomically renaming the temporary file to the target path
|
|
82
|
+
|
|
83
|
+
The rename operation is atomic on POSIX systems when both files are on the
|
|
84
|
+
same filesystem. On Windows, os.replace() provides atomic semantics since
|
|
85
|
+
Python 3.3.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
path: Target file path. Parent directory must exist.
|
|
89
|
+
data: Bytes to write to the file.
|
|
90
|
+
temp_prefix: Optional prefix for the temporary file name. Useful for
|
|
91
|
+
debugging to identify the source of temp files.
|
|
92
|
+
temp_suffix: Suffix for the temporary file name. Defaults to ".tmp".
|
|
93
|
+
correlation_id: Optional correlation ID for ONEX logging. When provided,
|
|
94
|
+
errors are logged with correlation context before being raised.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
Number of bytes written to the file.
|
|
98
|
+
|
|
99
|
+
Raises:
|
|
100
|
+
InfraConnectionError: If the file cannot be written (permissions, disk full,
|
|
101
|
+
etc.). The underlying OSError is chained via ``from e``. The temporary
|
|
102
|
+
file is cleaned up before raising.
|
|
103
|
+
|
|
104
|
+
Example:
|
|
105
|
+
>>> from pathlib import Path
|
|
106
|
+
>>> from omnibase_infra.utils.util_atomic_file import write_atomic_bytes
|
|
107
|
+
>>>
|
|
108
|
+
>>> # Basic atomic write
|
|
109
|
+
>>> path = Path("/tmp/test_atomic.txt")
|
|
110
|
+
>>> bytes_written = write_atomic_bytes(path, b"test data")
|
|
111
|
+
>>> bytes_written
|
|
112
|
+
9
|
|
113
|
+
>>>
|
|
114
|
+
>>> # With debugging prefix
|
|
115
|
+
>>> bytes_written = write_atomic_bytes(
|
|
116
|
+
... path,
|
|
117
|
+
... b"test data",
|
|
118
|
+
... temp_prefix="manifest_",
|
|
119
|
+
... correlation_id=UUID("12345678-1234-5678-1234-567812345678"),
|
|
120
|
+
... )
|
|
121
|
+
|
|
122
|
+
Warning:
|
|
123
|
+
The parent directory of ``path`` must exist. This function does not
|
|
124
|
+
create parent directories.
|
|
125
|
+
|
|
126
|
+
Warning:
|
|
127
|
+
On NFS, atomicity guarantees are weaker. See module docstring for details.
|
|
128
|
+
|
|
129
|
+
Related:
|
|
130
|
+
- handler_manifest_persistence.py: Original pattern implementation
|
|
131
|
+
"""
|
|
132
|
+
temp_fd: int | None = None
|
|
133
|
+
temp_path: str | None = None
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
# Create temp file in same directory for atomic rename guarantee
|
|
137
|
+
temp_fd, temp_path = tempfile.mkstemp(
|
|
138
|
+
suffix=temp_suffix,
|
|
139
|
+
prefix=temp_prefix,
|
|
140
|
+
dir=path.parent,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Write data to temp file
|
|
144
|
+
with os.fdopen(temp_fd, "wb") as f:
|
|
145
|
+
temp_fd = None # fdopen takes ownership of fd
|
|
146
|
+
bytes_written = f.write(data)
|
|
147
|
+
|
|
148
|
+
# Atomic rename (Path.replace is atomic on both POSIX and Windows 3.3+)
|
|
149
|
+
Path(temp_path).replace(path)
|
|
150
|
+
temp_path = None # Rename succeeded, no cleanup needed
|
|
151
|
+
|
|
152
|
+
return bytes_written
|
|
153
|
+
|
|
154
|
+
except OSError as e:
|
|
155
|
+
# Log with correlation context if provided
|
|
156
|
+
if correlation_id is not None:
|
|
157
|
+
logger.exception(
|
|
158
|
+
"Atomic write failed for '%s'",
|
|
159
|
+
path,
|
|
160
|
+
extra={
|
|
161
|
+
"correlation_id": str(correlation_id),
|
|
162
|
+
"target_path": str(path),
|
|
163
|
+
"temp_prefix": temp_prefix,
|
|
164
|
+
"temp_suffix": temp_suffix,
|
|
165
|
+
"error_type": type(e).__name__,
|
|
166
|
+
},
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# Cleanup: close fd if fdopen didn't take ownership
|
|
170
|
+
if temp_fd is not None:
|
|
171
|
+
try:
|
|
172
|
+
os.close(temp_fd)
|
|
173
|
+
except OSError:
|
|
174
|
+
pass # Best effort cleanup
|
|
175
|
+
|
|
176
|
+
# Cleanup: remove temp file if it exists
|
|
177
|
+
if temp_path is not None:
|
|
178
|
+
try:
|
|
179
|
+
Path(temp_path).unlink(missing_ok=True)
|
|
180
|
+
except OSError:
|
|
181
|
+
pass # Best effort cleanup
|
|
182
|
+
|
|
183
|
+
# Wrap OSError in InfraConnectionError per ONEX error handling guidelines
|
|
184
|
+
# Deferred import to avoid circular dependency (utils -> errors -> utils)
|
|
185
|
+
from omnibase_infra.enums import EnumInfraTransportType
|
|
186
|
+
from omnibase_infra.errors import InfraConnectionError, ModelInfraErrorContext
|
|
187
|
+
|
|
188
|
+
context = ModelInfraErrorContext.with_correlation(
|
|
189
|
+
correlation_id=correlation_id,
|
|
190
|
+
transport_type=EnumInfraTransportType.FILESYSTEM,
|
|
191
|
+
operation="write_atomic_bytes",
|
|
192
|
+
target_name=str(path),
|
|
193
|
+
)
|
|
194
|
+
raise InfraConnectionError(
|
|
195
|
+
f"Atomic write failed for '{path}'",
|
|
196
|
+
context=context,
|
|
197
|
+
error_type=type(e).__name__,
|
|
198
|
+
errno=getattr(e, "errno", None),
|
|
199
|
+
) from e
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
async def write_atomic_bytes_async(
|
|
203
|
+
path: Path,
|
|
204
|
+
data: bytes,
|
|
205
|
+
*,
|
|
206
|
+
temp_prefix: str = "",
|
|
207
|
+
temp_suffix: str = ".tmp",
|
|
208
|
+
correlation_id: UUID | None = None,
|
|
209
|
+
) -> int:
|
|
210
|
+
"""Write bytes to a file atomically (async version).
|
|
211
|
+
|
|
212
|
+
This is a thin async wrapper around :func:`write_atomic_bytes` that uses
|
|
213
|
+
``asyncio.to_thread()`` to run the synchronous implementation in a thread
|
|
214
|
+
pool. This prevents blocking the event loop during file I/O.
|
|
215
|
+
|
|
216
|
+
All logic is delegated to :func:`write_atomic_bytes` - this function exists
|
|
217
|
+
only to provide an async interface.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
path: Target file path. Parent directory must exist.
|
|
221
|
+
data: Bytes to write to the file.
|
|
222
|
+
temp_prefix: Optional prefix for the temporary file name.
|
|
223
|
+
temp_suffix: Suffix for the temporary file name. Defaults to ".tmp".
|
|
224
|
+
correlation_id: Optional correlation ID for ONEX logging.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
Number of bytes written to the file.
|
|
228
|
+
|
|
229
|
+
Raises:
|
|
230
|
+
InfraConnectionError: If the file cannot be written (permissions, disk full,
|
|
231
|
+
etc.). The underlying OSError is chained via ``from e``.
|
|
232
|
+
|
|
233
|
+
Example:
|
|
234
|
+
>>> import asyncio
|
|
235
|
+
>>> from pathlib import Path
|
|
236
|
+
>>> from omnibase_infra.utils.util_atomic_file import write_atomic_bytes_async
|
|
237
|
+
>>>
|
|
238
|
+
>>> async def example():
|
|
239
|
+
... path = Path("/tmp/test_async.txt")
|
|
240
|
+
... return await write_atomic_bytes_async(path, b"async data")
|
|
241
|
+
>>>
|
|
242
|
+
>>> asyncio.run(example())
|
|
243
|
+
10
|
|
244
|
+
|
|
245
|
+
See Also:
|
|
246
|
+
:func:`write_atomic_bytes`: The synchronous canonical implementation.
|
|
247
|
+
"""
|
|
248
|
+
return await asyncio.to_thread(
|
|
249
|
+
write_atomic_bytes,
|
|
250
|
+
path,
|
|
251
|
+
data,
|
|
252
|
+
temp_prefix=temp_prefix,
|
|
253
|
+
temp_suffix=temp_suffix,
|
|
254
|
+
correlation_id=correlation_id,
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
__all__: list[str] = [
|
|
259
|
+
"write_atomic_bytes",
|
|
260
|
+
"write_atomic_bytes_async",
|
|
261
|
+
]
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Kafka consumer group ID utilities.
|
|
4
|
+
|
|
5
|
+
Provides utilities for normalizing and validating Kafka consumer group identifiers.
|
|
6
|
+
Kafka consumer group IDs have specific character and length constraints that this
|
|
7
|
+
module helps enforce consistently across the codebase.
|
|
8
|
+
|
|
9
|
+
Kafka Consumer Group ID Constraints:
|
|
10
|
+
- Maximum length: 255 characters
|
|
11
|
+
- Valid characters: alphanumeric, period (.), underscore (_), hyphen (-)
|
|
12
|
+
- Cannot be empty
|
|
13
|
+
|
|
14
|
+
This module provides:
|
|
15
|
+
- normalize_kafka_identifier: Normalize strings for use as Kafka consumer group IDs
|
|
16
|
+
- compute_consumer_group_id: Compute canonical consumer group ID from node identity
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import hashlib
|
|
22
|
+
import re
|
|
23
|
+
from typing import TYPE_CHECKING
|
|
24
|
+
|
|
25
|
+
from omnibase_infra.enums import EnumConsumerGroupPurpose
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from omnibase_infra.models import ModelNodeIdentity
|
|
29
|
+
|
|
30
|
+
# Maximum length for Kafka consumer group IDs
|
|
31
|
+
KAFKA_CONSUMER_GROUP_MAX_LENGTH = 255
|
|
32
|
+
|
|
33
|
+
# Pattern for invalid characters (anything not alphanumeric, period, underscore, or hyphen)
|
|
34
|
+
_INVALID_CHAR_PATTERN = re.compile(r"[^a-z0-9._-]")
|
|
35
|
+
|
|
36
|
+
# Pattern for consecutive separators (period, underscore, or hyphen)
|
|
37
|
+
_CONSECUTIVE_SEPARATOR_PATTERN = re.compile(r"[._-]{2,}")
|
|
38
|
+
|
|
39
|
+
# Pattern for leading/trailing separators
|
|
40
|
+
_EDGE_SEPARATOR_PATTERN = re.compile(r"^[._-]+|[._-]+$")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def normalize_kafka_identifier(value: str) -> str:
|
|
44
|
+
"""Normalize a string for use as a Kafka consumer group ID.
|
|
45
|
+
|
|
46
|
+
Applies the following transformations in order:
|
|
47
|
+
1. Convert to lowercase
|
|
48
|
+
2. Replace invalid characters (non-alphanumeric, non-separator) with underscore
|
|
49
|
+
3. Collapse consecutive separators (., _, -) into a single separator
|
|
50
|
+
4. Strip leading and trailing separators
|
|
51
|
+
5. Truncate to max length (255) with hash suffix if necessary
|
|
52
|
+
|
|
53
|
+
The hash suffix ensures uniqueness when truncation is required. The suffix
|
|
54
|
+
format is `_<8-char-hash>` appended after truncating to fit within 255 chars.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
value: The input string to normalize.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
A normalized string safe for use as a Kafka consumer group ID.
|
|
61
|
+
|
|
62
|
+
Raises:
|
|
63
|
+
ValueError: If the input is empty or results in an empty string after
|
|
64
|
+
normalization.
|
|
65
|
+
|
|
66
|
+
Example:
|
|
67
|
+
>>> normalize_kafka_identifier("My Service!!")
|
|
68
|
+
'my_service'
|
|
69
|
+
>>> normalize_kafka_identifier("foo..bar__baz")
|
|
70
|
+
'foo.bar_baz'
|
|
71
|
+
>>> normalize_kafka_identifier(" UPPER_Case-Test ")
|
|
72
|
+
'upper_case-test'
|
|
73
|
+
>>> normalize_kafka_identifier("valid.consumer-group_id")
|
|
74
|
+
'valid.consumer-group_id'
|
|
75
|
+
>>> normalize_kafka_identifier("@#$%^&*()") # Raises ValueError
|
|
76
|
+
Traceback (most recent call last):
|
|
77
|
+
...
|
|
78
|
+
ValueError: Input '@#$%^&*()' results in empty string after normalization
|
|
79
|
+
"""
|
|
80
|
+
if not value:
|
|
81
|
+
raise ValueError("Kafka consumer group ID cannot be empty")
|
|
82
|
+
|
|
83
|
+
# Step 1: Lowercase
|
|
84
|
+
result = value.lower()
|
|
85
|
+
|
|
86
|
+
# Step 2: Replace invalid characters with underscore
|
|
87
|
+
result = _INVALID_CHAR_PATTERN.sub("_", result)
|
|
88
|
+
|
|
89
|
+
# Step 3: Collapse consecutive separators, preserving the first separator type
|
|
90
|
+
result = _CONSECUTIVE_SEPARATOR_PATTERN.sub(lambda m: m.group(0)[0], result)
|
|
91
|
+
|
|
92
|
+
# Step 4: Strip leading and trailing separators
|
|
93
|
+
result = _EDGE_SEPARATOR_PATTERN.sub("", result)
|
|
94
|
+
|
|
95
|
+
# Check for empty result after normalization
|
|
96
|
+
if not result:
|
|
97
|
+
raise ValueError(f"Input {value!r} results in empty string after normalization")
|
|
98
|
+
|
|
99
|
+
# Step 5: Truncate with hash suffix if exceeds max length
|
|
100
|
+
if len(result) > KAFKA_CONSUMER_GROUP_MAX_LENGTH:
|
|
101
|
+
# Generate 8-character hash suffix from original value for determinism
|
|
102
|
+
hash_suffix = hashlib.sha256(value.encode()).hexdigest()[:8]
|
|
103
|
+
# Reserve space for underscore + hash suffix (9 chars total)
|
|
104
|
+
max_prefix_length = KAFKA_CONSUMER_GROUP_MAX_LENGTH - 9
|
|
105
|
+
result = f"{result[:max_prefix_length]}_{hash_suffix}"
|
|
106
|
+
|
|
107
|
+
return result
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def compute_consumer_group_id(
|
|
111
|
+
identity: ModelNodeIdentity,
|
|
112
|
+
purpose: EnumConsumerGroupPurpose = EnumConsumerGroupPurpose.CONSUME,
|
|
113
|
+
) -> str:
|
|
114
|
+
"""Compute canonical Kafka consumer group ID from node identity.
|
|
115
|
+
|
|
116
|
+
Generates a deterministic, Kafka-compliant consumer group ID using the
|
|
117
|
+
canonical format: ``{env}.{service}.{node_name}.{purpose}.{version}``
|
|
118
|
+
|
|
119
|
+
Each component is normalized using ``normalize_kafka_identifier()`` to ensure
|
|
120
|
+
the result is safe for use as a Kafka consumer group ID. The final result
|
|
121
|
+
is validated against Kafka's 255 character limit.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
identity: Node identity containing env, service, node_name, and version.
|
|
125
|
+
purpose: Consumer group purpose classification. Defaults to CONSUME.
|
|
126
|
+
The purpose determines consumer behavior semantics (e.g., offset
|
|
127
|
+
reset policy) and is included in the group ID for disambiguation.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
A canonical consumer group ID in the format:
|
|
131
|
+
``{env}.{service}.{node_name}.{purpose}.{version}``
|
|
132
|
+
|
|
133
|
+
If the combined length exceeds Kafka's 255 character limit, the result
|
|
134
|
+
is truncated with an 8-character hash suffix to preserve uniqueness
|
|
135
|
+
while fitting within the constraint.
|
|
136
|
+
|
|
137
|
+
Example:
|
|
138
|
+
>>> from omnibase_infra.models import ModelNodeIdentity
|
|
139
|
+
>>> from omnibase_infra.enums import EnumConsumerGroupPurpose
|
|
140
|
+
>>> identity = ModelNodeIdentity(
|
|
141
|
+
... env="dev",
|
|
142
|
+
... service="omniintelligence",
|
|
143
|
+
... node_name="claude_hook_event_effect",
|
|
144
|
+
... version="v1",
|
|
145
|
+
... )
|
|
146
|
+
>>> compute_consumer_group_id(identity)
|
|
147
|
+
'dev.omniintelligence.claude_hook_event_effect.consume.v1'
|
|
148
|
+
|
|
149
|
+
With a different purpose:
|
|
150
|
+
|
|
151
|
+
>>> compute_consumer_group_id(identity, EnumConsumerGroupPurpose.INTROSPECTION)
|
|
152
|
+
'dev.omniintelligence.claude_hook_event_effect.introspection.v1'
|
|
153
|
+
|
|
154
|
+
Component normalization is applied automatically:
|
|
155
|
+
|
|
156
|
+
>>> identity_mixed = ModelNodeIdentity(
|
|
157
|
+
... env="DEV",
|
|
158
|
+
... service="Omni Intelligence",
|
|
159
|
+
... node_name="claude-hook-event-effect",
|
|
160
|
+
... version="V1.0.0",
|
|
161
|
+
... )
|
|
162
|
+
>>> compute_consumer_group_id(identity_mixed)
|
|
163
|
+
'dev.omni_intelligence.claude-hook-event-effect.consume.v1.0.0'
|
|
164
|
+
|
|
165
|
+
Long identities are automatically truncated with a hash suffix:
|
|
166
|
+
|
|
167
|
+
>>> long_identity = ModelNodeIdentity(
|
|
168
|
+
... env="development",
|
|
169
|
+
... service="a" * 100,
|
|
170
|
+
... node_name="b" * 100,
|
|
171
|
+
... version="v1",
|
|
172
|
+
... )
|
|
173
|
+
>>> result = compute_consumer_group_id(long_identity)
|
|
174
|
+
>>> len(result) <= 255
|
|
175
|
+
True
|
|
176
|
+
>>> result.endswith("_" + result[-8:]) # Has hash suffix
|
|
177
|
+
True
|
|
178
|
+
|
|
179
|
+
Note:
|
|
180
|
+
The canonical format uses period (.) as the separator between components.
|
|
181
|
+
This enables hierarchical grouping and filtering in Kafka tooling while
|
|
182
|
+
maintaining compatibility with Kafka's consumer group ID constraints.
|
|
183
|
+
|
|
184
|
+
See Also:
|
|
185
|
+
- :func:`normalize_kafka_identifier`: Component normalization rules
|
|
186
|
+
- :class:`~omnibase_infra.enums.EnumConsumerGroupPurpose`: Purpose values
|
|
187
|
+
- :class:`~omnibase_infra.models.ModelNodeIdentity`: Identity model
|
|
188
|
+
|
|
189
|
+
.. versionadded:: 0.2.6
|
|
190
|
+
Created as part of OMN-1602.
|
|
191
|
+
"""
|
|
192
|
+
# Normalize each component
|
|
193
|
+
normalized_env = normalize_kafka_identifier(identity.env)
|
|
194
|
+
normalized_service = normalize_kafka_identifier(identity.service)
|
|
195
|
+
normalized_node_name = normalize_kafka_identifier(identity.node_name)
|
|
196
|
+
normalized_purpose = normalize_kafka_identifier(purpose.value)
|
|
197
|
+
normalized_version = normalize_kafka_identifier(identity.version)
|
|
198
|
+
|
|
199
|
+
# Join with period separator
|
|
200
|
+
group_id = ".".join(
|
|
201
|
+
[
|
|
202
|
+
normalized_env,
|
|
203
|
+
normalized_service,
|
|
204
|
+
normalized_node_name,
|
|
205
|
+
normalized_purpose,
|
|
206
|
+
normalized_version,
|
|
207
|
+
]
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
# Handle length constraint with truncation + hash (same strategy as normalize_kafka_identifier)
|
|
211
|
+
# This can occur when multiple long components combine, even though each was individually
|
|
212
|
+
# truncated to 255 chars by normalize_kafka_identifier.
|
|
213
|
+
if len(group_id) > KAFKA_CONSUMER_GROUP_MAX_LENGTH:
|
|
214
|
+
# Generate deterministic hash from original (pre-normalized) identity components
|
|
215
|
+
# to ensure the same identity always produces the same truncated group ID
|
|
216
|
+
hash_input = (
|
|
217
|
+
f"{identity.env}|{identity.service}|{identity.node_name}|"
|
|
218
|
+
f"{purpose.value}|{identity.version}"
|
|
219
|
+
)
|
|
220
|
+
hash_suffix = hashlib.sha256(hash_input.encode()).hexdigest()[:8]
|
|
221
|
+
# Reserve space for underscore + hash suffix (9 chars total)
|
|
222
|
+
max_prefix_length = KAFKA_CONSUMER_GROUP_MAX_LENGTH - 9
|
|
223
|
+
group_id = f"{group_id[:max_prefix_length]}_{hash_suffix}"
|
|
224
|
+
|
|
225
|
+
return group_id
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
__all__: list[str] = [
|
|
229
|
+
"KAFKA_CONSUMER_GROUP_MAX_LENGTH",
|
|
230
|
+
"compute_consumer_group_id",
|
|
231
|
+
"normalize_kafka_identifier",
|
|
232
|
+
]
|