feat(odin): Register fetch logs action and validate input dates#541
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a built-in fetch_logs action to stream rotated log files to CDF Files, validating date ranges up to a maximum of 7 days. It also adds a structured ActionError exception class to report structured metadata on action failures, integrates this built-in action registration and error handling into the base extractor, and includes comprehensive tests. Feedback on the changes suggests catching both ValueError and TypeError in _parse_date to ensure robust input validation when non-string types are passed in the metadata.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #541 +/- ##
==========================================
+ Coverage 82.73% 82.86% +0.12%
==========================================
Files 44 45 +1
Lines 4430 4475 +45
==========================================
+ Hits 3665 3708 +43
- Misses 765 767 +2
🚀 New features to boost your workflow:
|
| def _register_builtin_actions(self) -> None: | ||
| """Register framework-level actions available on every extractor.""" | ||
| self.add_action( | ||
| CustomAction( | ||
| name="fetch_logs", | ||
| target=fetch_logs_action, | ||
| description=_FETCH_LOGS_DESCRIPTION, | ||
| ) | ||
| ) | ||
|
|
||
| def __init_actions__(self) -> None: |
There was a problem hiding this comment.
This is a bit conflicting, its a built-in action being regarded as a custom action, which is a bit weird
There was a problem hiding this comment.
Maybe we can also have CogniteActions?
There was a problem hiding this comment.
fetch_logs uses the identical dispatch mechanism as user-registered actions (callable + ActionContext). The only difference is registration time (automatic in init vs explicit in init_actions). Introducing a parallel type (CogniteActions) hierarchy for the same runtime behaviour adds complexity without changing anything observable.
| assert len(req.available_actions) == 3 | ||
| names = [a.name for a in req.available_actions] | ||
| assert names == ["Start sync", "Stop sync", "flush"] | ||
| # Built-in actions precede scheduled-task start/stop, which precede user custom actions |
There was a problem hiding this comment.
this doesn't validate the order of custom actions?
There was a problem hiding this comment.
The code puts scheduled task start/stop first, then _custom_actions in registration order (built-ins first, user actions after). But agree an assert can be added here. Added.
Summary
Implements the first step of the bulk log upload feature for Odin: registers a built-in fetch_logs action on every extractor instance and validates the incoming date-range parameters before any file I/O is attempted.
Type of change
What changed
ctx.call_metadata(ISO 8601, inclusive, max 7 days). Raises ActionError with error_type of missing_parameter, invalid_parameter, or invalid_date_range on any validation failure.Extractor._register_builtin_actions()(base.py): New private method called unconditionally in__init__(between__init_tasks__and__init_actions__). Registers fetch_logs on every extractor without requiring subclass opt-in. add_action now raises ValueError on duplicate name to prevent subclasses from shadowing built-ins.Why it changed
Operators need to trigger log retrieval from the Odin UI without any per-extractor code changes. Registering as a built-in ensures the action is available on all extractors uniformly.
Related docs / discussion:
Design Doc - Bulk Log Upload Action
What to focus on during review
__init__before__init_actions__. Confirm this ordering is safe for all existing extractor subclasses (subclasses that call add_action in__init_actions__will see fetch_logs already present).Test evidence
tests/test_unstable/test_log_upload_action.py(new, 11 test cases): registration, all missing-param combinations, invalid ISO formats, invalid date ranges, boundary at exactly 7 days, ActionError.details wiring.tests/test_unstable/test_action_dispatch.py: addedtest_action_error_sets_result_metadata_and_keeps_failed_statuscovering the except ActionError branch in dispatch.tests/test_unstable/test_action_registration.py: updated 6 existing tests to be semantic (name/type lookups) rather than count-based, since the built-in adds one action to every extractor.Risks and unknowns
Rollout and rollback
Checklist