Add module event producer coverage
This commit is contained in:
@@ -6,6 +6,7 @@ from typing import Any, Iterable, Sequence
|
||||
from sqlalchemy import BigInteger, DateTime, Index, Integer, JSON, String, UniqueConstraint, func
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from govoplan_core.core.events import EventActorRef, EventObjectRef, EventTenantRef, PlatformEvent, publish_platform_event
|
||||
from govoplan_core.db.base import Base, utcnow
|
||||
|
||||
WATERMARK_PREFIX = "seq:"
|
||||
@@ -95,9 +96,42 @@ def record_change(
|
||||
payload=payload or {},
|
||||
)
|
||||
session.add(entry)
|
||||
_publish_change_event(entry)
|
||||
return entry
|
||||
|
||||
|
||||
def _publish_change_event(entry: ChangeSequenceEntry) -> None:
|
||||
event_type = _change_event_type(entry.module_id, entry.resource_type, entry.operation)
|
||||
publish_platform_event(
|
||||
PlatformEvent(
|
||||
type=event_type,
|
||||
module_id=entry.module_id,
|
||||
payload={
|
||||
"collection": entry.collection,
|
||||
"operation": entry.operation,
|
||||
"payload": dict(entry.payload or {}),
|
||||
},
|
||||
actor=EventActorRef(type=entry.actor_type, id=entry.actor_id) if entry.actor_type else None,
|
||||
tenant=EventTenantRef(id=entry.tenant_id) if entry.tenant_id else None,
|
||||
resource=EventObjectRef(type=entry.resource_type, id=entry.resource_id),
|
||||
classification="internal",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _change_event_type(module_id: str, resource_type: str, operation: str) -> str:
|
||||
resource = _event_segment(resource_type)
|
||||
module = _event_segment(module_id)
|
||||
if resource.startswith(f"{module}."):
|
||||
resource = resource[len(module) + 1:]
|
||||
return ".".join(item for item in (module, resource, _event_segment(operation)) if item)
|
||||
|
||||
|
||||
def _event_segment(value: str) -> str:
|
||||
compact = "".join(character if character.isalnum() else "." for character in value.casefold())
|
||||
return ".".join(part for part in compact.split(".") if part)
|
||||
|
||||
|
||||
def max_sequence_id(
|
||||
session: Session,
|
||||
*,
|
||||
|
||||
@@ -168,5 +168,26 @@ class EventBus:
|
||||
handler(traced)
|
||||
|
||||
|
||||
_default_event_bus = EventBus()
|
||||
_current_event_bus: ContextVar[EventBus | None] = ContextVar("govoplan_event_bus", default=None)
|
||||
|
||||
|
||||
def platform_event_bus() -> EventBus:
|
||||
return _current_event_bus.get() or _default_event_bus
|
||||
|
||||
|
||||
@contextmanager
|
||||
def event_bus_context(bus: EventBus):
|
||||
token = _current_event_bus.set(bus)
|
||||
try:
|
||||
yield bus
|
||||
finally:
|
||||
_current_event_bus.reset(token)
|
||||
|
||||
|
||||
def publish_platform_event(event: PlatformEvent) -> None:
|
||||
platform_event_bus().publish(event)
|
||||
|
||||
|
||||
def _compact_dict(value: Mapping[str, Any]) -> dict[str, Any]:
|
||||
return {key: item for key, item in value.items() if item is not None}
|
||||
|
||||
Reference in New Issue
Block a user