Loading src/open_exposure_gateway/core/config.py +21 −13 Original line number Diff line number Diff line from functools import lru_cache from uuid import UUID from uuid import UUID, uuid5 from pydantic import BaseModel, HttpUrl from pydantic_settings import BaseSettings, SettingsConfigDict # The platform seeds one QoD service specification at deployment (ADR-0035); every # activate carries its id. There is no CAMARA registration step to resolve it from, # so the id cannot be derived per request -- minting one would reference no catalog # row and SRM would answer failed_before_start. This is the well-known id used when # nobody sets one at deploy time; SRM's topology bootstrap must seed the same value. # QoD and Location Retrieval have no CAMARA registration step to resolve a # service_specification_id from, so each uses one platform-seeded specification at a # well-known id (ADR-0035). Both sides derive that id from the recipe in SRM Interface # Contract §E.2 rather than pasting a constant, so neither can go stale if the recipe # changes; SRM's bootstrap seeds the same value. DEFAULT_QOD_SERVICE_SPECIFICATION_ID = UUID("7608e902-b927-559f-b448-e7e9061dfa5c") _SPECIFICATION_VERSION = "1" _NAMESPACE_URL = UUID("6ba7b811-9dad-11d1-80b4-00c04fd430c8") # Location Retrieval has no registration step either, so it resolves its # service_specification_id the same way (ADR-0035's pattern applied to a second family). # It persists nothing -- a sync query writes no service_order or capability_instance -- # but the internal query body still requires the field, and SRM uses it to resolve the # control path for the location_context capability. DEFAULT_LOCATION_RETRIEVAL_SERVICE_SPECIFICATION_ID = UUID("0129e7ce-8e02-5dfd-bae1-0303bcc7676e") def well_known_service_specification_id(ref: str) -> UUID: return uuid5( _NAMESPACE_URL, f"https://etsi.org/sdg/oop/service-specification/{ref}/{_SPECIFICATION_VERSION}", ) DEFAULT_QOD_SERVICE_SPECIFICATION_ID = well_known_service_specification_id("qod-session") DEFAULT_LOCATION_RETRIEVAL_SERVICE_SPECIFICATION_ID = well_known_service_specification_id( "location-context" ) class SRMSettings(BaseModel): Loading tests/unit/test_config.py +13 −15 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ from open_exposure_gateway.core.config import ( DEFAULT_QOD_SERVICE_SPECIFICATION_ID, Settings, get_settings, well_known_service_specification_id, ) Loading Loading @@ -93,23 +94,20 @@ class TestDefaults: assert settings.location_retrieval_settings.uses_default_service_specification_id is True class TestWellKnownQodServiceSpecificationId: def test_constant_matches_its_documented_derivation(self) -> None: """The default is a cross-component contract: SRM's bootstrap must seed this exact id. Both sides derive it from the same URL rather than copying a literal, so this pins the recipe -- changing the constant without changing the URL (or the reverse) is a silent break that only shows up as failed_before_start.""" assert DEFAULT_QOD_SERVICE_SPECIFICATION_ID == uuid5( NAMESPACE_URL, "https://etsi.org/sdg/oop/service-specification/qod-session/1" ) class TestWellKnownServiceSpecificationIds: """The ids are derived, so the literals live here rather than in src""" def test_qod_matches_the_published_id(self) -> None: assert DEFAULT_QOD_SERVICE_SPECIFICATION_ID == UUID("7608e902-b927-559f-b448-e7e9061dfa5c") class TestWellKnownLocationRetrievalServiceSpecificationId: def test_constant_matches_its_documented_derivation(self) -> None: """Same cross-component contract as the QoD id, same recipe -- only the `ref` differs. Pinning it here is what stops the two sides drifting apart silently.""" assert DEFAULT_LOCATION_RETRIEVAL_SERVICE_SPECIFICATION_ID == uuid5( NAMESPACE_URL, "https://etsi.org/sdg/oop/service-specification/location-context/1" def test_location_retrieval_matches_the_published_id(self) -> None: assert DEFAULT_LOCATION_RETRIEVAL_SERVICE_SPECIFICATION_ID == UUID( "0129e7ce-8e02-5dfd-bae1-0303bcc7676e" ) def test_the_recipe_is_the_documented_url(self) -> None: assert well_known_service_specification_id("qod-session") == uuid5( NAMESPACE_URL, "https://etsi.org/sdg/oop/service-specification/qod-session/1" ) Loading Loading
src/open_exposure_gateway/core/config.py +21 −13 Original line number Diff line number Diff line from functools import lru_cache from uuid import UUID from uuid import UUID, uuid5 from pydantic import BaseModel, HttpUrl from pydantic_settings import BaseSettings, SettingsConfigDict # The platform seeds one QoD service specification at deployment (ADR-0035); every # activate carries its id. There is no CAMARA registration step to resolve it from, # so the id cannot be derived per request -- minting one would reference no catalog # row and SRM would answer failed_before_start. This is the well-known id used when # nobody sets one at deploy time; SRM's topology bootstrap must seed the same value. # QoD and Location Retrieval have no CAMARA registration step to resolve a # service_specification_id from, so each uses one platform-seeded specification at a # well-known id (ADR-0035). Both sides derive that id from the recipe in SRM Interface # Contract §E.2 rather than pasting a constant, so neither can go stale if the recipe # changes; SRM's bootstrap seeds the same value. DEFAULT_QOD_SERVICE_SPECIFICATION_ID = UUID("7608e902-b927-559f-b448-e7e9061dfa5c") _SPECIFICATION_VERSION = "1" _NAMESPACE_URL = UUID("6ba7b811-9dad-11d1-80b4-00c04fd430c8") # Location Retrieval has no registration step either, so it resolves its # service_specification_id the same way (ADR-0035's pattern applied to a second family). # It persists nothing -- a sync query writes no service_order or capability_instance -- # but the internal query body still requires the field, and SRM uses it to resolve the # control path for the location_context capability. DEFAULT_LOCATION_RETRIEVAL_SERVICE_SPECIFICATION_ID = UUID("0129e7ce-8e02-5dfd-bae1-0303bcc7676e") def well_known_service_specification_id(ref: str) -> UUID: return uuid5( _NAMESPACE_URL, f"https://etsi.org/sdg/oop/service-specification/{ref}/{_SPECIFICATION_VERSION}", ) DEFAULT_QOD_SERVICE_SPECIFICATION_ID = well_known_service_specification_id("qod-session") DEFAULT_LOCATION_RETRIEVAL_SERVICE_SPECIFICATION_ID = well_known_service_specification_id( "location-context" ) class SRMSettings(BaseModel): Loading
tests/unit/test_config.py +13 −15 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ from open_exposure_gateway.core.config import ( DEFAULT_QOD_SERVICE_SPECIFICATION_ID, Settings, get_settings, well_known_service_specification_id, ) Loading Loading @@ -93,23 +94,20 @@ class TestDefaults: assert settings.location_retrieval_settings.uses_default_service_specification_id is True class TestWellKnownQodServiceSpecificationId: def test_constant_matches_its_documented_derivation(self) -> None: """The default is a cross-component contract: SRM's bootstrap must seed this exact id. Both sides derive it from the same URL rather than copying a literal, so this pins the recipe -- changing the constant without changing the URL (or the reverse) is a silent break that only shows up as failed_before_start.""" assert DEFAULT_QOD_SERVICE_SPECIFICATION_ID == uuid5( NAMESPACE_URL, "https://etsi.org/sdg/oop/service-specification/qod-session/1" ) class TestWellKnownServiceSpecificationIds: """The ids are derived, so the literals live here rather than in src""" def test_qod_matches_the_published_id(self) -> None: assert DEFAULT_QOD_SERVICE_SPECIFICATION_ID == UUID("7608e902-b927-559f-b448-e7e9061dfa5c") class TestWellKnownLocationRetrievalServiceSpecificationId: def test_constant_matches_its_documented_derivation(self) -> None: """Same cross-component contract as the QoD id, same recipe -- only the `ref` differs. Pinning it here is what stops the two sides drifting apart silently.""" assert DEFAULT_LOCATION_RETRIEVAL_SERVICE_SPECIFICATION_ID == uuid5( NAMESPACE_URL, "https://etsi.org/sdg/oop/service-specification/location-context/1" def test_location_retrieval_matches_the_published_id(self) -> None: assert DEFAULT_LOCATION_RETRIEVAL_SERVICE_SPECIFICATION_ID == UUID( "0129e7ce-8e02-5dfd-bae1-0303bcc7676e" ) def test_the_recipe_is_the_documented_url(self) -> None: assert well_known_service_specification_id("qod-session") == uuid5( NAMESPACE_URL, "https://etsi.org/sdg/oop/service-specification/qod-session/1" ) Loading