mirror of
https://github.com/zvx-echo6/central.git
synced 2026-05-22 10:34:43 +02:00
refactor: rename CloudEvents extension attributes hub* → central*
Rename extension attributes for consistency with project naming: - hubschemaversion → centralschemaversion - hubcategory → centralcategory - hubseverity → centralseverity Non-breaking change - no consumers depend on these names yet. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
31be17430d
commit
4a7f1a76c7
2 changed files with 33 additions and 33 deletions
|
|
@ -11,27 +11,27 @@ from central.models import Event
|
||||||
def wrap_event(event: Event, config: Config) -> tuple[dict[str, Any], str]:
|
def wrap_event(event: Event, config: Config) -> tuple[dict[str, Any], str]:
|
||||||
"""
|
"""
|
||||||
Wrap an Event into a CNCF CloudEvents v1.0 JSON envelope.
|
Wrap an Event into a CNCF CloudEvents v1.0 JSON envelope.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A tuple of (envelope_dict, msg_id) where msg_id is the
|
A tuple of (envelope_dict, msg_id) where msg_id is the
|
||||||
CloudEvent id for use as Nats-Msg-Id header.
|
CloudEvent id for use as Nats-Msg-Id header.
|
||||||
"""
|
"""
|
||||||
# Build CE type: {prefix}.{category}.v1
|
# Build CE type: {prefix}.{category}.v1
|
||||||
ce_type = f"{config.cloudevents.type_prefix}.{event.category}.v1"
|
ce_type = f"{config.cloudevents.type_prefix}.{event.category}.v1"
|
||||||
|
|
||||||
# Serialize event data
|
# Serialize event data
|
||||||
event_data = event.model_dump(mode="json")
|
event_data = event.model_dump(mode="json")
|
||||||
|
|
||||||
# Build extension attributes - lowercase, no underscores per CE spec
|
# Build extension attributes - lowercase, no underscores per CE spec
|
||||||
extensions: dict[str, Any] = {
|
extensions: dict[str, Any] = {
|
||||||
"hubschemaversion": config.cloudevents.schema_version,
|
"centralschemaversion": config.cloudevents.schema_version,
|
||||||
"hubcategory": event.category,
|
"centralcategory": event.category,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Only include hubseverity if severity is present
|
# Only include centralseverity if severity is present
|
||||||
if event.severity is not None:
|
if event.severity is not None:
|
||||||
extensions["hubseverity"] = event.severity
|
extensions["centralseverity"] = event.severity
|
||||||
|
|
||||||
# Create CloudEvent
|
# Create CloudEvent
|
||||||
ce = CloudEvent(
|
ce = CloudEvent(
|
||||||
attributes={
|
attributes={
|
||||||
|
|
@ -44,9 +44,9 @@ def wrap_event(event: Event, config: Config) -> tuple[dict[str, Any], str]:
|
||||||
},
|
},
|
||||||
data=event_data,
|
data=event_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Build envelope dict from CloudEvent
|
# Build envelope dict from CloudEvent
|
||||||
envelope: dict[str, Any] = dict(ce.get_attributes())
|
envelope: dict[str, Any] = dict(ce.get_attributes())
|
||||||
envelope["data"] = ce.data
|
envelope["data"] = ce.data
|
||||||
|
|
||||||
return envelope, event.id
|
return envelope, event.id
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,12 @@ def sample_config() -> Config:
|
||||||
|
|
||||||
class TestSubjectForEvent:
|
class TestSubjectForEvent:
|
||||||
"""Tests for subject_for_event helper."""
|
"""Tests for subject_for_event helper."""
|
||||||
|
|
||||||
def test_county_subject(self, sample_event: Event) -> None:
|
def test_county_subject(self, sample_event: Event) -> None:
|
||||||
"""County codes produce county subject."""
|
"""County codes produce county subject."""
|
||||||
subject = subject_for_event(sample_event)
|
subject = subject_for_event(sample_event)
|
||||||
assert subject == "central.wx.alert.us.id.county.ada"
|
assert subject == "central.wx.alert.us.id.county.ada"
|
||||||
|
|
||||||
def test_zone_subject(self, sample_geo: Geo) -> None:
|
def test_zone_subject(self, sample_geo: Geo) -> None:
|
||||||
"""Zone codes produce zone subject."""
|
"""Zone codes produce zone subject."""
|
||||||
geo = Geo(
|
geo = Geo(
|
||||||
|
|
@ -83,7 +83,7 @@ class TestSubjectForEvent:
|
||||||
)
|
)
|
||||||
subject = subject_for_event(event)
|
subject = subject_for_event(event)
|
||||||
assert subject == "central.wx.alert.us.id.zone.z033"
|
assert subject == "central.wx.alert.us.id.zone.z033"
|
||||||
|
|
||||||
def test_unknown_subject(self, sample_event: Event) -> None:
|
def test_unknown_subject(self, sample_event: Event) -> None:
|
||||||
"""Missing primary_region produces unknown subject."""
|
"""Missing primary_region produces unknown subject."""
|
||||||
geo = Geo(regions=[], primary_region=None)
|
geo = Geo(regions=[], primary_region=None)
|
||||||
|
|
@ -97,7 +97,7 @@ class TestSubjectForEvent:
|
||||||
)
|
)
|
||||||
subject = subject_for_event(event)
|
subject = subject_for_event(event)
|
||||||
assert subject == "central.wx.alert.us.unknown"
|
assert subject == "central.wx.alert.us.unknown"
|
||||||
|
|
||||||
def test_custom_prefix(self, sample_event: Event) -> None:
|
def test_custom_prefix(self, sample_event: Event) -> None:
|
||||||
"""Custom prefix is used in subject."""
|
"""Custom prefix is used in subject."""
|
||||||
subject = subject_for_event(sample_event, prefix="myapp.events")
|
subject = subject_for_event(sample_event, prefix="myapp.events")
|
||||||
|
|
@ -106,13 +106,13 @@ class TestSubjectForEvent:
|
||||||
|
|
||||||
class TestCloudEventsWire:
|
class TestCloudEventsWire:
|
||||||
"""Tests for CloudEvents wire format."""
|
"""Tests for CloudEvents wire format."""
|
||||||
|
|
||||||
def test_required_fields_present(
|
def test_required_fields_present(
|
||||||
self, sample_event: Event, sample_config: Config
|
self, sample_event: Event, sample_config: Config
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Required CloudEvents fields are present."""
|
"""Required CloudEvents fields are present."""
|
||||||
envelope, msg_id = wrap_event(sample_event, sample_config)
|
envelope, msg_id = wrap_event(sample_event, sample_config)
|
||||||
|
|
||||||
assert msg_id == sample_event.id
|
assert msg_id == sample_event.id
|
||||||
assert envelope["id"] == sample_event.id
|
assert envelope["id"] == sample_event.id
|
||||||
assert envelope["source"] == sample_config.cloudevents.source
|
assert envelope["source"] == sample_config.cloudevents.source
|
||||||
|
|
@ -121,27 +121,27 @@ class TestCloudEventsWire:
|
||||||
assert "time" in envelope
|
assert "time" in envelope
|
||||||
assert envelope["datacontenttype"] == "application/json"
|
assert envelope["datacontenttype"] == "application/json"
|
||||||
assert "data" in envelope
|
assert "data" in envelope
|
||||||
|
|
||||||
def test_extension_attributes_lowercase(
|
def test_extension_attributes_lowercase(
|
||||||
self, sample_event: Event, sample_config: Config
|
self, sample_event: Event, sample_config: Config
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Extension attributes are lowercase with no underscores."""
|
"""Extension attributes are lowercase with no underscores."""
|
||||||
envelope, _ = wrap_event(sample_event, sample_config)
|
envelope, _ = wrap_event(sample_event, sample_config)
|
||||||
|
|
||||||
# Check that extension attributes exist and are lowercase
|
# Check that extension attributes exist and are lowercase
|
||||||
assert envelope["hubschemaversion"] == "1.0"
|
assert envelope["centralschemaversion"] == "1.0"
|
||||||
assert envelope["hubcategory"] == "wx.alert.severe_thunderstorm_warning"
|
assert envelope["centralcategory"] == "wx.alert.severe_thunderstorm_warning"
|
||||||
assert envelope["hubseverity"] == 3
|
assert envelope["centralseverity"] == 3
|
||||||
|
|
||||||
# Verify no uppercase or underscores in extension names
|
# Verify no uppercase or underscores in extension names
|
||||||
for key in ["hubschemaversion", "hubcategory", "hubseverity"]:
|
for key in ["centralschemaversion", "centralcategory", "centralseverity"]:
|
||||||
assert key.islower()
|
assert key.islower()
|
||||||
assert "_" not in key
|
assert "_" not in key
|
||||||
|
|
||||||
def test_severity_none_omits_hubseverity(
|
def test_severity_none_omits_centralseverity(
|
||||||
self, sample_geo: Geo, sample_config: Config
|
self, sample_geo: Geo, sample_config: Config
|
||||||
) -> None:
|
) -> None:
|
||||||
"""When severity is None, hubseverity is omitted entirely."""
|
"""When severity is None, centralseverity is omitted entirely."""
|
||||||
event = Event(
|
event = Event(
|
||||||
id="test-no-severity",
|
id="test-no-severity",
|
||||||
source="test",
|
source="test",
|
||||||
|
|
@ -151,11 +151,11 @@ class TestCloudEventsWire:
|
||||||
geo=sample_geo,
|
geo=sample_geo,
|
||||||
data={},
|
data={},
|
||||||
)
|
)
|
||||||
|
|
||||||
envelope, _ = wrap_event(event, sample_config)
|
envelope, _ = wrap_event(event, sample_config)
|
||||||
|
|
||||||
# hubseverity should not be present at all
|
# centralseverity should not be present at all
|
||||||
assert "hubseverity" not in envelope
|
assert "centralseverity" not in envelope
|
||||||
# Other extensions should still be present
|
# Other extensions should still be present
|
||||||
assert "hubschemaversion" in envelope
|
assert "centralschemaversion" in envelope
|
||||||
assert "hubcategory" in envelope
|
assert "centralcategory" in envelope
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue