From 7e07d725a72b64c8f1491cdcc6874acf777991cf Mon Sep 17 00:00:00 2001 From: Daniel Fangl Date: Thu, 21 Nov 2024 11:05:32 +0100 Subject: [PATCH] Add restructurings to fix events persistence in v2 --- .../localstack/services/events/event_bus.py | 31 +++++++----- .../localstack/services/events/models.py | 2 +- .../localstack/services/events/provider.py | 8 +-- .../localstack/services/events/rule.py | 49 +++++++++++-------- 4 files changed, 51 insertions(+), 39 deletions(-) diff --git a/localstack-core/localstack/services/events/event_bus.py b/localstack-core/localstack/services/events/event_bus.py index 685f9cb56b7b9..aa2bda33685ce 100644 --- a/localstack-core/localstack/services/events/event_bus.py +++ b/localstack-core/localstack/services/events/event_bus.py @@ -1,6 +1,6 @@ import json from datetime import datetime, timezone -from typing import Optional +from typing import Optional, Self from localstack.aws.api.events import ( Action, @@ -23,11 +23,14 @@ class EventBusService: event_source_name: str | None tags: TagList | None policy: str | None - rules: RuleDict | None event_bus: EventBus - def __init__( - self, + def __init__(self, event_bus: EventBus): + self.event_bus = event_bus + + @classmethod + def create_event_bus_service( + cls, name: EventBusName, region: str, account_id: str, @@ -35,15 +38,17 @@ def __init__( tags: Optional[TagList] = None, policy: Optional[str] = None, rules: Optional[RuleDict] = None, - ): - self.event_bus = EventBus( - name, - region, - account_id, - event_source_name, - tags, - policy, - rules, + ) -> Self: + return cls( + EventBus( + name, + region, + account_id, + event_source_name, + tags, + policy, + rules, + ) ) @property diff --git a/localstack-core/localstack/services/events/models.py b/localstack-core/localstack/services/events/models.py index 61481854372ac..a014636fa2176 100644 --- a/localstack-core/localstack/services/events/models.py +++ b/localstack-core/localstack/services/events/models.py @@ -237,4 +237,4 @@ class EventsStore(BaseStore): TAGS: TaggingService = CrossRegionAttribute(default=TaggingService) -events_store = AccountRegionBundle("events", EventsStore) +events_stores = AccountRegionBundle("events", EventsStore) diff --git a/localstack-core/localstack/services/events/provider.py b/localstack-core/localstack/services/events/provider.py index 370effe47642e..72021987becfe 100644 --- a/localstack-core/localstack/services/events/provider.py +++ b/localstack-core/localstack/services/events/provider.py @@ -132,7 +132,7 @@ RuleDict, TargetDict, ValidationException, - events_store, + events_stores, ) from localstack.services.events.models import ( InvalidEventPatternException as InternalInvalidEventPatternException, @@ -1521,7 +1521,7 @@ def untag_resource( def get_store(self, region: str, account_id: str) -> EventsStore: """Returns the events store for the account and region. On first call, creates the default event bus for the account region.""" - store = events_store[account_id][region] + store = events_stores[account_id][region] # create default event bus for account region on first call default_event_bus_name = "default" if default_event_bus_name not in store.event_buses: @@ -1577,7 +1577,7 @@ def create_event_bus_service( event_source_name: Optional[EventSourceName], tags: Optional[TagList], ) -> EventBusService: - event_bus_service = EventBusService( + event_bus_service = EventBusService.create_event_bus_service( name, region, account_id, @@ -1601,7 +1601,7 @@ def create_rule_service( event_bus_name: Optional[EventBusName], targets: Optional[TargetDict], ) -> RuleService: - rule_service = RuleService( + rule_service = RuleService.create_rule_service( name, region, account_id, diff --git a/localstack-core/localstack/services/events/rule.py b/localstack-core/localstack/services/events/rule.py index be03442e06c9a..f8c540221a803 100644 --- a/localstack-core/localstack/services/events/rule.py +++ b/localstack-core/localstack/services/events/rule.py @@ -42,8 +42,16 @@ class RuleService: managed_by: ManagedBy rule: Rule - def __init__( - self, + def __init__(self, rule: Rule): + self.rule = rule + if rule.schedule_expression: + self.schedule_cron = self._get_schedule_cron(rule.schedule_expression) + else: + self.schedule_cron = None + + @classmethod + def create_rule_service( + cls, name: RuleName, region: Optional[str] = None, account_id: Optional[str] = None, @@ -57,25 +65,23 @@ def __init__( targets: Optional[TargetDict] = None, managed_by: Optional[ManagedBy] = None, ): - self._validate_input(event_pattern, schedule_expression, event_bus_name) - if schedule_expression: - self.schedule_cron = self._get_schedule_cron(schedule_expression) - else: - self.schedule_cron = None + cls._validate_input(event_pattern, schedule_expression, event_bus_name) # required to keep data and functionality separate for persistence - self.rule = Rule( - name, - region, - account_id, - schedule_expression, - event_pattern, - state, - description, - role_arn, - tags, - event_bus_name, - targets, - managed_by, + return cls( + Rule( + name, + region, + account_id, + schedule_expression, + event_pattern, + state, + description, + role_arn, + tags, + event_bus_name, + targets, + managed_by, + ) ) @property @@ -178,8 +184,9 @@ def validate_targets_input(self, targets: TargetList) -> PutTargetsResultEntryLi return validation_errors + @classmethod def _validate_input( - self, + cls, event_pattern: Optional[EventPattern], schedule_expression: Optional[ScheduleExpression], event_bus_name: Optional[EventBusName] = "default",