Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Eventbridge v2: Add input path #10733

Merged
merged 9 commits into from May 13, 2024

Conversation

maxhoheiser
Copy link
Member

@maxhoheiser maxhoheiser commented Apr 26, 2024

Motivation

Enable the input path (transformer) feature (https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_Target.html).
This allows to specify an input path for the target, the body of matching event is parsed based on the specified json path and only the filtered content is sent to the target.

Changes

Add input transformer functionality to rule class.
Add process_event method that transforms the event content with the input path transformer if an input path is specified in the target.
Change from send_event to process_event method invoced by the provider.

@maxhoheiser maxhoheiser added aws:events Amazon EventBridge semver: minor Non-breaking changes which can be included in minor releases, but not in patch releases labels Apr 26, 2024
@maxhoheiser maxhoheiser self-assigned this Apr 26, 2024
Copy link

github-actions bot commented Apr 26, 2024

LocalStack Community integration with Pro

    2 files  ±0      2 suites  ±0   1h 36m 42s ⏱️ +54s
2 935 tests +3  2 641 ✅ +3  294 💤 ±0  0 ❌ ±0 
2 937 runs  +3  2 641 ✅ +3  296 💤 ±0  0 ❌ ±0 

Results for commit b9d2dd3. ± Comparison against base commit cbec2f4.

This pull request removes 1 and adds 4 tests. Note that renamed tests count towards both.
tests.aws.services.events.test_events_inputs.TestEventsInputPath ‑ test_put_events_with_input_path_multiple
tests.aws.services.events.test_events_inputs.TestEventsInputPath ‑ test_put_events_with_input_path_max_level_depth
tests.aws.services.events.test_events_inputs.TestEventsInputPath ‑ test_put_events_with_input_path_multiple_targets
tests.aws.services.events.test_events_inputs.TestEventsInputPath ‑ test_put_events_with_input_path_nested[event_detail0]
tests.aws.services.events.test_events_inputs.TestEventsInputPath ‑ test_put_events_with_input_path_nested[event_detail1]

♻️ This comment has been updated with latest results.

@maxhoheiser maxhoheiser force-pushed the feature/eventbridge_v2-add-input-path branch 4 times, most recently from 03803b1 to 76e25d8 Compare May 8, 2024 06:55
@maxhoheiser maxhoheiser marked this pull request as ready for review May 8, 2024 06:55
@maxhoheiser maxhoheiser force-pushed the feature/eventbridge_v2-add-input-path branch 6 times, most recently from 968a98c to f05b155 Compare May 8, 2024 14:20

def _create_sqs_events_target(queue_name: str | None = None) -> tuple[str, str]:
if not queue_name:
queue_name = f"tests-queue-{short_uid()}"
sqs_client = aws_client.sqs
queue_url = sqs_client.create_queue(QueueName=queue_name)["QueueUrl"]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This on purpose does not use the sqs_create_queue fixture here, since it would need to be moved to helper functions because no cleanup and thus no factory would be required, which in turn would not valid this to be a fixture. This would in turn require passing in the aws_client as input.
I believe it is easier to read if the queue is created with the boot client here directly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, fair point 👍

Why is no cleanup required here? Wouldn't the factory remove the need for an explicit cleanup after the yield here? It might have to do with the proper cleanup order 🤔

Copy link
Member

@joe4dev joe4dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main concern is regarding the introduction of an implicit transitive dependency and I'm not quite sure about the typings 😕
Otherwise, it looks good now 👍

localstack/services/events/target.py Outdated Show resolved Hide resolved
localstack/services/events/target.py Outdated Show resolved Hide resolved
tests/aws/services/events/test_events_integrations.py Outdated Show resolved Hide resolved

def _create_sqs_events_target(queue_name: str | None = None) -> tuple[str, str]:
if not queue_name:
queue_name = f"tests-queue-{short_uid()}"
sqs_client = aws_client.sqs
queue_url = sqs_client.create_queue(QueueName=queue_name)["QueueUrl"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, fair point 👍

Why is no cleanup required here? Wouldn't the factory remove the need for an explicit cleanup after the yield here? It might have to do with the proper cleanup order 🤔

localstack/services/events/models.py Outdated Show resolved Hide resolved
@@ -102,3 +106,20 @@ class InvalidEventPatternException(Exception):
def __init__(self, reason=None, message=None) -> None:
self.reason = reason
self.message = message or f"Event pattern is not valid. Reason: {reason}"


class FormattedEvent(BaseModel):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how much we gain by defining non-trivial types at this stage. Are we really sure this typing is correct?
It looks quite different than the previous type PutEventsRequestEntry, so at least one of these was/is quite wrong 😕

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is quite different since the initial defined type was not accurate. We transform the incoming event (here: https://github.com/localstack/localstack/blob/feature/eventbridge_v2-add-input-path/localstack/services/events/provider.py#L129) and add new fields since they are expected by the client.

@maxhoheiser maxhoheiser force-pushed the feature/eventbridge_v2-add-input-path branch from f05b155 to 31269bf Compare May 13, 2024 08:08
@maxhoheiser maxhoheiser force-pushed the feature/eventbridge_v2-add-input-path branch from 31269bf to 876a1be Compare May 13, 2024 08:08
@maxhoheiser maxhoheiser force-pushed the feature/eventbridge_v2-add-input-path branch from 876a1be to d0131f3 Compare May 13, 2024 08:15
@maxhoheiser maxhoheiser requested a review from joe4dev May 13, 2024 08:17
@maxhoheiser maxhoheiser force-pushed the feature/eventbridge_v2-add-input-path branch from d0131f3 to b9d2dd3 Compare May 13, 2024 10:53
Copy link
Member

@joe4dev joe4dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Thanks for removing the implicit pydantic dependency.

@maxhoheiser maxhoheiser merged commit cdb940e into master May 13, 2024
14 checks passed
@maxhoheiser maxhoheiser deleted the feature/eventbridge_v2-add-input-path branch May 13, 2024 12:00
class FormattedEvent(TypedDict):
version: str
id: str
detail_type: Optional[str] # key "detail-type" is automatically interpreted as detail_type
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maxhoheiser This type definition allows both detail-type and detail_type, but we should restrict it to the hyphen-only variant.

Python supports an alternative syntax for defining TypedDicts, which is recommended in such cases:

The functional syntax should also be used when any of the keys are not valid identifiers, for example because they are keywords or contain hyphens.
https://docs.python.org/3/library/typing.html#typing.TypedDict

All credits go to @dfangl for this suggestion 💯

detail: dict[str, str | dict]


TransformedEvent: TypeAlias = FormattedEvent | dict | str
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can understand why we end up such a flexible type definition given the many possibilities using input templates. For readers, this type definition is quite confusing. Consider adding a comment for now.
Maybe, we find something clearer in the future to clarify the type after each step without too many XORs (especially in methods).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aws:events Amazon EventBridge semver: minor Non-breaking changes which can be included in minor releases, but not in patch releases
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants