From 0a4374ef78f63ecb6d9da5b03e4c4c1952619de0 Mon Sep 17 00:00:00 2001 From: Maximilian Hoheiser Date: Fri, 26 Apr 2024 14:37:16 +0200 Subject: [PATCH] refactor: remove v2 suffix --- localstack/services/events/event_bus.py | 2 +- .../events/{models_v2.py => models.py} | 0 .../events/{provider_v2.py => provider.py} | 138 +++--------------- localstack/services/events/rule.py | 6 +- localstack/services/providers.py | 2 +- 5 files changed, 24 insertions(+), 124 deletions(-) rename localstack/services/events/{models_v2.py => models.py} (100%) rename localstack/services/events/{provider_v2.py => provider.py} (80%) diff --git a/localstack/services/events/event_bus.py b/localstack/services/events/event_bus.py index c014461be20c5..348246c616449 100644 --- a/localstack/services/events/event_bus.py +++ b/localstack/services/events/event_bus.py @@ -1,7 +1,7 @@ from typing import Optional from localstack.aws.api.events import Arn, EventBusName, TagList -from localstack.services.events.models_v2 import EventBus, RuleDict +from localstack.services.events.models import EventBus, RuleDict class EventBusService: diff --git a/localstack/services/events/models_v2.py b/localstack/services/events/models.py similarity index 100% rename from localstack/services/events/models_v2.py rename to localstack/services/events/models.py diff --git a/localstack/services/events/provider_v2.py b/localstack/services/events/provider.py similarity index 80% rename from localstack/services/events/provider_v2.py rename to localstack/services/events/provider.py index 2c8544b09ee0e..1cc33cc8ce5af 100644 --- a/localstack/services/events/provider_v2.py +++ b/localstack/services/events/provider.py @@ -1,7 +1,5 @@ import base64 -import json import logging -from datetime import datetime, timezone from typing import Optional from localstack.aws.api import RequestContext, handler @@ -18,18 +16,14 @@ EventPattern, EventsApi, EventSourceName, - InvalidEventPatternException, LimitMax100, ListEventBusesResponse, ListRuleNamesByTargetResponse, ListRulesResponse, ListTargetsByRuleResponse, NextToken, - PutEventsRequestEntry, PutEventsRequestEntryList, PutEventsResponse, - PutEventsResultEntry, - PutEventsResultEntryList, PutPartnerEventsRequestEntryList, PutPartnerEventsResponse, PutRuleResponse, @@ -49,13 +43,11 @@ TargetId, TargetIdList, TargetList, - TestEventPatternResponse, ) from localstack.aws.api.events import EventBus as ApiTypeEventBus from localstack.aws.api.events import Rule as ApiTypeRule from localstack.services.events.event_bus import EventBusService, EventBusServiceDict -from localstack.services.events.event_ruler import matches_rule -from localstack.services.events.models_v2 import ( +from localstack.services.events.models import ( EventBus, EventBusDict, EventsStore, @@ -67,11 +59,7 @@ ) from localstack.services.events.rule import RuleService, RuleServiceDict from localstack.services.events.target import TargetSender, TargetSenderDict, TargetSenderFactory -from localstack.services.events.utils import ( - InvalidEventPatternException as InternalInvalidEventPatternException, -) from localstack.services.plugins import ServiceLifecycleHook -from localstack.utils.strings import long_uid LOG = logging.getLogger(__name__) @@ -91,57 +79,6 @@ def get_filtered_dict(name_prefix: str, input_dict: dict) -> dict: return {name: value for name, value in input_dict.items() if name.startswith(name_prefix)} -def get_event_time(event: PutEventsRequestEntry) -> str: - event_time = datetime.now(timezone.utc) - if event_timestamp := event.get("Time"): - try: - # use time from event if provided - event_time = event_timestamp.replace(tzinfo=timezone.utc) - except ValueError: - # use current time if event time is invalid - LOG.debug( - "Could not parse the `Time` parameter, falling back to current time for the following Event: '%s'", - event, - ) - formatted_time_string = event_time.strftime("%Y-%m-%dT%H:%M:%SZ") - return formatted_time_string - - -def validate_event(event: PutEventsRequestEntry) -> None | PutEventsResultEntry: - if not event.get("Source"): - return { - "ErrorCode": "InvalidArgument", - "ErrorMessage": "Parameter Source is not valid. Reason: Source is a required argument.", - } - elif not event.get("DetailType"): - return { - "ErrorCode": "InvalidArgument", - "ErrorMessage": "Parameter DetailType is not valid. Reason: DetailType is a required argument.", - } - elif not event.get("Detail"): - return { - "ErrorCode": "InvalidArgument", - "ErrorMessage": "Parameter Detail is not valid. Reason: Detail is a required argument.", - } - - -def format_event(event: PutEventsRequestEntry, region: str, account_id: str) -> dict: - # See https://docs.aws.amazon.com/AmazonS3/latest/userguide/ev-events.html - formatted_event = { - "version": "0", - "id": str(long_uid()), - "detail-type": event.get("DetailType"), - "source": event.get("Source"), - "account": account_id, - "time": get_event_time(event), - "region": region, - "resources": event.get("Resources", []), - "detail": json.loads(event.get("Detail", "{}")), - } - - return formatted_event - - class EventsProvider(EventsApi, ServiceLifecycleHook): # api methods are grouped by resource type and sorted in hierarchical order # each group is sorted alphabetically @@ -366,20 +303,6 @@ def put_rule( response = PutRuleResponse(RuleArn=rule_service.arn) return response - @handler("TestEventPattern") - def test_event_pattern( - self, context: RequestContext, event_pattern: EventPattern, event: str, **kwargs - ) -> TestEventPatternResponse: - """Test event pattern uses EventBridge event pattern matching: - https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns.html - """ - try: - result = matches_rule(event, event_pattern) - except InternalInvalidEventPatternException as e: - raise InvalidEventPatternException(e.message) from e - - return TestEventPatternResponse(Result=result) - ######### # Targets ######### @@ -422,7 +345,7 @@ def put_targets( rule_service = self.get_rule_service(context, rule, event_bus_name) failed_entries = rule_service.add_targets(targets) rule_arn = rule_service.arn - for target in targets: # TODO only add successful targets + for target in targets: self.create_target_sender(target, region, account_id, rule_arn) response = PutTargetsResponse( @@ -461,12 +384,9 @@ def put_events( endpoint_id: EndpointId = None, **kwargs, ) -> PutEventsResponse: - entries, failed_entry_count = self._process_entries(context, entries) + failed_entries = self._put_entries(context, entries) - response = PutEventsResponse( - Entries=entries, - FailedEntryCount=failed_entry_count, - ) + response = PutEventsResponse(FailedEntryCount=len(failed_entries), Entries=failed_entries) return response @handler("PutPartnerEvents") @@ -658,41 +578,25 @@ def _delete_target_sender(self, ids: TargetIdList, rule) -> None: except KeyError: LOG.error(f"Error deleting target service {target_arn}.") - def _process_entries( - self, context: RequestContext, entries: PutEventsRequestEntryList - ) -> tuple[PutEventsResultEntryList, int]: - processed_entries = [] - failed_entry_count = 0 + def _put_entries(self, context: RequestContext, entries: PutEventsRequestEntryList) -> list: + failed_entries = [] for event in entries: event_bus_name = event.get("EventBusName", "default") - if event_failed_validation := validate_event(event): - processed_entries.append(event_failed_validation) - failed_entry_count += 1 - continue - event = format_event(event, context.region, context.account_id) store = self.get_store(context) - try: - event_bus = self.get_event_bus(event_bus_name, store) - except ResourceNotFoundException: - # ignore events for non-existing event buses but add processed event - processed_entries.append({"EventId": event["id"]}) - continue + event_bus = self.get_event_bus(event_bus_name, store) + # TODO add pattern matching matching_rules = [rule for rule in event_bus.rules.values()] for rule in matching_rules: - event_pattern = rule.event_pattern - event_str = json.dumps(event) - if matches_rule(event_str, event_pattern): - for target in rule.targets.values(): - target_sender = self._target_sender_store[target["Arn"]] - try: - target_sender.send_event(event) - processed_entries.append({"EventId": event["id"]}) - except Exception as error: - processed_entries.append( - { - "ErrorCode": "InternalException", - "ErrorMessage": str(error), - } - ) - failed_entry_count += 1 - return processed_entries, failed_entry_count + for target in rule.targets.values(): + target_sender = self._target_sender_store[target["Arn"]] + try: + target_sender.send_event(event) + except Exception as error: + failed_entries.append( + { + "Entry": event, + "ErrorCode": "InternalException", + "ErrorMessage": str(error), + } + ) + return failed_entries diff --git a/localstack/services/events/rule.py b/localstack/services/events/rule.py index 61011ccec6286..4298f9c4622e8 100644 --- a/localstack/services/events/rule.py +++ b/localstack/services/events/rule.py @@ -19,11 +19,7 @@ TargetIdList, TargetList, ) -from localstack.services.events.models_v2 import ( - Rule, - TargetDict, - ValidationException, -) +from localstack.services.events.models import Rule, TargetDict, ValidationException TARGET_ID_REGEX = re.compile(r"^[\.\-_A-Za-z0-9]+$") TARGET_ARN_REGEX = re.compile(r"arn:[\d\w:\-/]*") diff --git a/localstack/services/providers.py b/localstack/services/providers.py index 86095fcb0b095..2610420627822 100644 --- a/localstack/services/providers.py +++ b/localstack/services/providers.py @@ -356,7 +356,7 @@ def events_v1(): @aws_provider(api="events", name="v2") def events_v2(): - from localstack.services.events.provider_v2 import EventsProvider + from localstack.services.events.provider import EventsProvider provider = EventsProvider() return Service.for_provider(provider)