Skip to content

[AAP-72873] fix: preserve event stream source swap after project sync#1540

Closed
B-Whitt wants to merge 1 commit into
ansible:mainfrom
B-Whitt:fix/preserve-event-stream-source-swap-AAP-72873
Closed

[AAP-72873] fix: preserve event stream source swap after project sync#1540
B-Whitt wants to merge 1 commit into
ansible:mainfrom
B-Whitt:fix/preserve-event-stream-source-swap-AAP-72873

Conversation

@B-Whitt
Copy link
Copy Markdown
Contributor

@B-Whitt B-Whitt commented Apr 30, 2026

What is being changed?

_update_activation_content() in src/aap_eda/tasks/project.py now skips the rulebook_rulesets overwrite for activations that have source_mappings. Previously it unconditionally overwrote the activation's cached rulesets with the raw rulebook from the DB, which does not have the event stream source swap applied.

Why is this change needed?

When a project sync completes for activations with update_revision_on_launch=True, _resume_waiting_activations() calls _update_activation_content() which overwrote rulebook_rulesets with the original (unswapped) rulebook from the DB. This lost the event stream source swap (webhook → pg_listener), causing ansible-rulebook to bind to the original webhook port. On podman this fails with "port already in use"; on K8s the activation runs but with the wrong source type.

Jira: https://redhat.atlassian.net/browse/AAP-72873

How does this change address the issue?

A single guard: if not activation.source_mappings: wraps the rulesets overwrite in _update_activation_content(). Activations with event stream source mappings keep their already-swapped rulesets intact. Only git_hash is updated unconditionally.

This is consistent with how _auto_restart_activations() already skips source-mapped activations when content changes (line 254).

Does this change introduce any new dependencies, blockers or breaking changes?

No new imports or dependencies. The change is a single guard condition.

How it can be tested?

Automated: 3 regression tests in tests/integration/tasks/test_projects.py:

  • test_update_activation_content_preserves_source_mapped_rulesets — verifies swapped rulesets are not overwritten
  • test_update_activation_content_updates_rulesets_without_source_mappings — verifies rulesets refresh still works for normal activations
  • test_resume_waiting_preserves_event_stream_swap — end-to-end test of the sync→resume path

All 68 tests in test_projects.py pass locally (0 failures).

Manual reproduction (from Jira):

  1. Sync a project with a rulebook that uses ansible.eda.webhook with a port configured
  2. Create a Token Event Stream Credential and Event Stream
  3. Create a Rulebook Activation with the project/rulebook and Event Stream
  4. Set update_revision_on_launch=True on the project
  5. Enable the Rulebook Activation
  6. Verify activation status transitions: "Waiting for project sync" → "starting" → "running" (no port binding error)

Tested on AAP 2.7 (aap-dev) — activation runs successfully through the sync→resume path with the swapped rulesets preserved.

Assisted by: Claude Opus

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of activation configuration to preserve cached settings when appropriate, while properly updating related metadata.
  • Tests

    • Added integration tests to verify activation configuration behavior.

@B-Whitt B-Whitt requested a review from a team as a code owner April 30, 2026 21:14
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

Warning

Rate limit exceeded

@B-Whitt has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 1 second before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: db2a496c-c04f-4e15-a2eb-b8b1c5d5f58c

📥 Commits

Reviewing files that changed from the base of the PR and between c2b7881 and 0222777.

📒 Files selected for processing (4)
  • src/aap_eda/services/project/imports.py
  • src/aap_eda/tasks/project.py
  • tests/integration/services/test_project_import.py
  • tests/integration/tasks/test_projects.py
📝 Walkthrough

Walkthrough

The changes modify _update_activation_content to conditionally skip updating cached rulebook rulesets when an activation has source_mappings, while preserving the git_hash update for all activations. Three integration tests validate this behavior and related activation resumption logic.

Changes

Cohort / File(s) Summary
Core Function Logic
src/aap_eda/tasks/project.py
Added conditional branch to skip fetching/updating rulebook_rulesets and rulebook_rulesets_sha256 when activation.source_mappings is present; git_hash remains updated for all activations. ObjectDoesNotExist handling moved to non-source_mappings branch. Docstring updated to document this behavior.
Integration Tests
tests/integration/tasks/test_projects.py
Three new tests validating: (1) rulebook_rulesets preservation when source_mappings exists while updating SHA256 and git_hash, (2) rulebook_rulesets overwrite when source_mappings absent, and (3) swapped rulebook_rulesets preservation across sync→resume cycle with activation enablement and rulebook process start.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: preserving event stream source swap after project sync, with reference to the specific Jira issue (AAP-72873).
Description check ✅ Passed The description comprehensively covers all required sections: what is changed, why it's needed, how it addresses the issue, dependencies/blockers, and testing approach with specific test cases and manual reproduction steps.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 16 minutes and 1 second.

Comment @coderabbitai help to get the list of available commands and usage tips.

@B-Whitt
Copy link
Copy Markdown
Contributor Author

B-Whitt commented Apr 30, 2026

/run-e2e

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/aap_eda/tasks/project.py`:
- Line 368: activation.source_mappings is being checked by raw string truthiness
which misdetects values like "[]" or whitespace as present; instead, parse or
normalize the YAML string and check for an actual empty mapping. Update the
logic around the activation.source_mappings check (the branch that currently
reads `if not activation.source_mappings`) to first normalize the string (e.g.,
strip() and compare against ""/"[]"/"{}") or better, safe_load the YAML and test
whether the resulting object is None/empty list/empty dict; treat those as empty
so the ruleset refresh path runs when mappings were cleared.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 8ad45c6c-e492-416f-8dfc-7796d4ad3f5d

📥 Commits

Reviewing files that changed from the base of the PR and between 3680b55 and c2b7881.

📒 Files selected for processing (2)
  • src/aap_eda/tasks/project.py
  • tests/integration/tasks/test_projects.py

Comment thread src/aap_eda/tasks/project.py Outdated
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 30, 2026

Codecov Report

❌ Patch coverage is 90.47619% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.97%. Comparing base (3680b55) to head (0222777).

Files with missing lines Patch % Lines
src/aap_eda/tasks/project.py 88.88% 2 Missing ⚠️
@@            Coverage Diff             @@
##             main    #1540      +/-   ##
==========================================
- Coverage   91.98%   91.97%   -0.01%     
==========================================
  Files         241      241              
  Lines       10955    10968      +13     
==========================================
+ Hits        10077    10088      +11     
- Misses        878      880       +2     
Flag Coverage Δ
unit-int-tests-3.11 91.97% <90.47%> (-0.01%) ⬇️
unit-int-tests-3.12 91.97% <90.47%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/aap_eda/services/project/imports.py 91.41% <100.00%> (+0.10%) ⬆️
src/aap_eda/tasks/project.py 98.28% <88.88%> (-0.65%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@hsong-rh
Copy link
Copy Markdown
Contributor

There's a second write site that also overwrites rulebook_rulesets with the raw (unswapped) content, and it's not covered by this PR.

In src/aap_eda/services/project/imports.py, the _sync_rulebook method does a bulk update:

models.Activation.objects.filter(
    rulebook=rulebook,
    restart_on_project_update=False,
).update(
    rulebook_rulesets=rulebook.rulesets,
    rulebook_rulesets_sha256=new_sha256,
    git_hash=git_hash,
)

This runs for activations with restart_on_project_update=False and will overwrite swapped rulesets the same way. The fix would be to split the bulk update:

no_restart = models.Activation.objects.filter(
    rulebook=rulebook,
    restart_on_project_update=False,
)
no_restart.filter(source_mappings="").update(
    rulebook_rulesets=rulebook.rulesets,
    rulebook_rulesets_sha256=new_sha256,
    git_hash=git_hash,
)
no_restart.exclude(source_mappings="").update(
    git_hash=git_hash,
)

This should be folded into this PR, without it the bug can still reproduce via the _sync_rulebook path.

@B-Whitt B-Whitt force-pushed the fix/preserve-event-stream-source-swap-AAP-72873 branch from c2b7881 to 879b5d3 Compare April 30, 2026 21:46
…AP-72873)

_update_activation_content() unconditionally overwrote rulebook_rulesets
with the raw (unswapped) rulebook from the DB, losing the event stream
source swap (webhook → pg_listener) for activations with source_mappings.
This caused ansible-rulebook to bind to the original webhook port,
failing on podman and using the wrong source on K8s.

Guard the rulesets overwrite with a source_mappings check — activations
that have event stream mappings keep their swapped rulesets, consistent
with how _auto_restart_activations() already skips source-mapped
activations.

Assisted by: Claude Opus
@B-Whitt B-Whitt force-pushed the fix/preserve-event-stream-source-swap-AAP-72873 branch from 879b5d3 to 0222777 Compare April 30, 2026 21:58
@B-Whitt
Copy link
Copy Markdown
Contributor Author

B-Whitt commented Apr 30, 2026

/run-e2e

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@hsong-rh hsong-rh left a comment

Choose a reason for hiding this comment

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

Hold the fix, this behavior is by design. See details in https://issues.redhat.com/browse/AAP-65811

@hsong-rh
Copy link
Copy Markdown
Contributor

hsong-rh commented May 1, 2026

Related PR: #1543

@B-Whitt B-Whitt marked this pull request as draft May 4, 2026 13:38
@B-Whitt
Copy link
Copy Markdown
Contributor Author

B-Whitt commented May 5, 2026

closed in favor of #1547

@B-Whitt B-Whitt closed this May 5, 2026
@B-Whitt
Copy link
Copy Markdown
Contributor Author

B-Whitt commented May 5, 2026

closed in favor of #1547

@B-Whitt B-Whitt deleted the fix/preserve-event-stream-source-swap-AAP-72873 branch May 5, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants