Skip to content

[ResponseOps][Cases] Populate total alerts and comments in the cases saved objects#223992

Merged
cnasikas merged 13 commits intoelastic:mainfrom
cnasikas:cases_total_alerts_comments
Jun 23, 2025
Merged

[ResponseOps][Cases] Populate total alerts and comments in the cases saved objects#223992
cnasikas merged 13 commits intoelastic:mainfrom
cnasikas:cases_total_alerts_comments

Conversation

@cnasikas
Copy link
Member

@cnasikas cnasikas commented Jun 14, 2025

Summary

This is a farewell PR to Cases. Probably my last PR to the cases codebase. It was quite a journey, and I learned a lot. I hope the best for the feature of Cases.

Decisions

Just before Cases was forbidden to do migrations, we did a last migration to all cases to persist total_alerts: -1 and total_comments: -1. We did that so that in the future, when we would want to populate the fields, we would know which cases have their fields populated and which do not. In this PR, due to time constraints and criticality of the feature, I took the following decisions:

  • Cases return from their APIs the total comments and alerts of each case. They do that by doing an aggregation, getting the counts, and merging them with the response. I did not change that behavior. In following PRs, it can be optimized and fetch the stats only for cases that do not yet have their stats populated (cases with -1 in the counts)
  • When a case is created, the counts are zero.
  • When a comment or alert is added, I do an aggregation to get the stats (total alerts and comments) of the current case, and then update the counters with the number of the newly created attachments. The case is updated without version checks. In race conditions, where an attachment is being added before updating the case, the numbers could be off. This is a deliberate choice. It can be fixed later with retries and version concurrency control.
  • The case service will continue to not return the total_alerts and total_comments.
  • The case service will accept the total_alerts and total_comments attributes to be able to set them.

Fixes: #217636

cc @michaelolo24

Checklist

Check the PR satisfies following conditions.

Reviewers should verify this PR satisfies this list as well.

@cnasikas cnasikas self-assigned this Jun 14, 2025
@cnasikas cnasikas added release_note:skip Skip the PR/issue when compiling release notes Team:ResponseOps Platform ResponseOps team (formerly the Cases and Alerting teams) t// Feature:Cases Cases feature backport:version Backport to applied version labels v9.1.0 v8.19.0 labels Jun 14, 2025
@cnasikas cnasikas marked this pull request as ready for review June 15, 2025 12:52
@cnasikas cnasikas requested a review from a team as a code owner June 15, 2025 12:52
@elasticmachine
Copy link
Contributor

Pinging @elastic/response-ops (Team:ResponseOps)

@elasticmachine
Copy link
Contributor

Pinging @elastic/response-ops-cases (Feature:Cases)

Comment on lines +99 to +100
| Partial<CaseTransformedAttributes>
| Partial<CaseTransformedAttributesWithAttachmentStats>
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Isn't this enough?

Suggested change
| Partial<CaseTransformedAttributes>
| Partial<CaseTransformedAttributesWithAttachmentStats>
| Partial<CaseTransformedAttributesWithAttachmentStats>

@cnasikas cnasikas requested a review from a team June 16, 2025 12:09
@cnasikas
Copy link
Member Author

cnasikas commented Jun 18, 2025

@adcoelho, I have addressed your feedback and added the functionality for deletion. I changed the logic slightly and no longer rely on counting the stats in memory. I rely only on what ES returns. I realized that it is not feasible to perform the counts correctly in memory on each Kibana node, and I preferred to retrieve the state from Elasticsearch (ES) consistently. This will not fix the issue I mentioned in the description, but it will make it more robust.

Comment on lines +211 to +212
updated_at: date,
updated_by: user,
Copy link
Contributor

Choose a reason for hiding this comment

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

I noticed we include these two updated_* here, and wanted to check if maybe we were doing that twice.

We create the user action, but never change the updated fields. Weren't we updating them when deleting attachments?

Copy link
Member Author

Choose a reason for hiding this comment

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

We do not update these fields when creating user actions. Not sure if we should or not. We wanted to avoid version conflicts that will be caused by updating the case SO as much as possible. But now, with the new functionality, it is inevitable. We need to update the stats. Thought, that makes me think, deleting or creating a comment, is it considered an update to the case? Alternatively, we could only update the stats, but not the updated_* fields, as updating them may lead to wrong assumptions about who updated the case last and when. Wdyt?

Copy link
Contributor

@adcoelho adcoelho left a comment

Choose a reason for hiding this comment

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

👍


const theCase = res.body.hits.hits[0]._source?.cases!;

// We added 3 attachments, 2 user and 1 alert and we deleted 1 of each
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Since we call bulkCreateAttachments, we could do some checks before deletion and make this clear in the code instead of in a comment.

        expect(theCase.total_alerts).to.eql(1);
        expect(theCase.total_comments).to.eql(2);

Copy link
Member Author

@cnasikas cnasikas Jun 21, 2025

Choose a reason for hiding this comment

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

This is tested in x-pack/test/cases_api_integration/security_and_spaces/tests/common/internal/bulk_create_attachments.ts. I thought it was better to focus only on the functionality we are interested in. Wdyt?

@cnasikas
Copy link
Member Author

@elasticmachine merge upstream

@elasticmachine
Copy link
Contributor

merge conflict between base and head

@elasticmachine
Copy link
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #46 / ESQL execution logic API @ess @serverless ES|QL rule type esql query specific syntax mv_expand command pagination should create alerts from expanded values
  • [job] [logs] FTR Configs #100 / ESQL execution logic API @ess @serverless ES|QL rule type shard failures should handle shard failures and include warning in logs for query that is not aggregating

Metrics [docs]

✅ unchanged

History

cc @cnasikas

}),
this.partialUpdateCaseUserAndDateSkipRefresh(new Date().toISOString()),
]);
refresh: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we apply refresh: true or refresh: wait_for here given #158134

Copy link
Contributor

@michaelolo24 michaelolo24 left a comment

Choose a reason for hiding this comment

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

Just added a single comment regarding the refresh setting, otherwise relying on @adcoelho as the primary reviewer here to not block this work

@cnasikas cnasikas merged commit f30335a into elastic:main Jun 23, 2025
11 checks passed
@cnasikas cnasikas deleted the cases_total_alerts_comments branch June 23, 2025 16:56
@kibanamachine
Copy link
Contributor

Starting backport for target branches: 8.19

https://github.com/elastic/kibana/actions/runs/15830335609

@kibanamachine
Copy link
Contributor

💔 All backports failed

Status Branch Result
8.19 Backport failed because of merge conflicts

Manual backport

To create the backport manually run:

node scripts/backport --pr 223992

Questions ?

Please refer to the Backport tool documentation

@cnasikas
Copy link
Member Author

💚 All backports created successfully

Status Branch Result
8.19

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

cnasikas added a commit that referenced this pull request Jun 23, 2025
… cases saved objects (#223992) (#224928)

# Backport

This will backport the following commits from `main` to `8.19`:
- [[ResponseOps][Cases] Populate total alerts and comments in the cases
saved objects (#223992)](#223992)

<!--- Backport version: 10.0.1 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Christos
Nasikas","email":"christos.nasikas@elastic.co"},"sourceCommit":{"committedDate":"2025-06-23T16:56:01Z","message":"[ResponseOps][Cases]
Populate total alerts and comments in the cases saved objects
(#223992)\n\n## Summary\n\nThis is a farewell PR to Cases. Probably my
last PR to the cases\ncodebase. It was quite a journey, and I learned a
lot. I hope the best\nfor the feature of Cases.\n\n## Decisions\n\nJust
before Cases was forbidden to do migrations, we did a last\nmigration to
all cases to persist `total_alerts: -1` and\n`total_comments: -1`. We
did that so that in the future, when we would\nwant to populate the
fields, we would know which cases have their fields\npopulated and which
do not. In this PR, due to time constraints and\ncriticality of the
feature, I took the following decisions:\n\n- Cases return from their
APIs the total comments and alerts of each\ncase. They do that by doing
an aggregation, getting the counts, and\nmerging them with the response.
I did not change that behavior. In\nfollowing PRs, it can be optimized
and fetch the stats only for cases\nthat do not yet have their stats
populated (cases with -1 in the counts)\n- When a case is created, the
counts are zero.\n- When a comment or alert is added, I do an
aggregation to get the stats\n(total alerts and comments) of the current
case, and then update the\ncounters with the number of the newly created
attachments. The case is\nupdated without version checks. In race
conditions, where an attachment\nis being added before updating the
case, the numbers could be off. This\nis a deliberate choice. It can be
fixed later with retries and version\nconcurrency control.\n- The case
service will continue to not return the `total_alerts`
and\n`total_comments`.\n- The case service will accept the
`total_alerts` and `total_comments`\nattributes to be able to set
them.\n\nFixes: https://github.com/elastic/kibana/issues/217636\n\ncc
@michaelolo24 \n\n### Checklist\n\nCheck the PR satisfies following
conditions. \n\nReviewers should verify this PR satisfies this list as
well.\n\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common
scenarios","sha":"f30335ac3d74bd3310167a27d035544c72068111","branchLabelMapping":{"^v9.1.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:ResponseOps","Feature:Cases","backport:version","v9.1.0","v8.19.0"],"title":"[ResponseOps][Cases]
Populate total alerts and comments in the cases saved
objects","number":223992,"url":"https://github.com/elastic/kibana/pull/223992","mergeCommit":{"message":"[ResponseOps][Cases]
Populate total alerts and comments in the cases saved objects
(#223992)\n\n## Summary\n\nThis is a farewell PR to Cases. Probably my
last PR to the cases\ncodebase. It was quite a journey, and I learned a
lot. I hope the best\nfor the feature of Cases.\n\n## Decisions\n\nJust
before Cases was forbidden to do migrations, we did a last\nmigration to
all cases to persist `total_alerts: -1` and\n`total_comments: -1`. We
did that so that in the future, when we would\nwant to populate the
fields, we would know which cases have their fields\npopulated and which
do not. In this PR, due to time constraints and\ncriticality of the
feature, I took the following decisions:\n\n- Cases return from their
APIs the total comments and alerts of each\ncase. They do that by doing
an aggregation, getting the counts, and\nmerging them with the response.
I did not change that behavior. In\nfollowing PRs, it can be optimized
and fetch the stats only for cases\nthat do not yet have their stats
populated (cases with -1 in the counts)\n- When a case is created, the
counts are zero.\n- When a comment or alert is added, I do an
aggregation to get the stats\n(total alerts and comments) of the current
case, and then update the\ncounters with the number of the newly created
attachments. The case is\nupdated without version checks. In race
conditions, where an attachment\nis being added before updating the
case, the numbers could be off. This\nis a deliberate choice. It can be
fixed later with retries and version\nconcurrency control.\n- The case
service will continue to not return the `total_alerts`
and\n`total_comments`.\n- The case service will accept the
`total_alerts` and `total_comments`\nattributes to be able to set
them.\n\nFixes: https://github.com/elastic/kibana/issues/217636\n\ncc
@michaelolo24 \n\n### Checklist\n\nCheck the PR satisfies following
conditions. \n\nReviewers should verify this PR satisfies this list as
well.\n\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common
scenarios","sha":"f30335ac3d74bd3310167a27d035544c72068111"}},"sourceBranch":"main","suggestedTargetBranches":["8.19"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/223992","number":223992,"mergeCommit":{"message":"[ResponseOps][Cases]
Populate total alerts and comments in the cases saved objects
(#223992)\n\n## Summary\n\nThis is a farewell PR to Cases. Probably my
last PR to the cases\ncodebase. It was quite a journey, and I learned a
lot. I hope the best\nfor the feature of Cases.\n\n## Decisions\n\nJust
before Cases was forbidden to do migrations, we did a last\nmigration to
all cases to persist `total_alerts: -1` and\n`total_comments: -1`. We
did that so that in the future, when we would\nwant to populate the
fields, we would know which cases have their fields\npopulated and which
do not. In this PR, due to time constraints and\ncriticality of the
feature, I took the following decisions:\n\n- Cases return from their
APIs the total comments and alerts of each\ncase. They do that by doing
an aggregation, getting the counts, and\nmerging them with the response.
I did not change that behavior. In\nfollowing PRs, it can be optimized
and fetch the stats only for cases\nthat do not yet have their stats
populated (cases with -1 in the counts)\n- When a case is created, the
counts are zero.\n- When a comment or alert is added, I do an
aggregation to get the stats\n(total alerts and comments) of the current
case, and then update the\ncounters with the number of the newly created
attachments. The case is\nupdated without version checks. In race
conditions, where an attachment\nis being added before updating the
case, the numbers could be off. This\nis a deliberate choice. It can be
fixed later with retries and version\nconcurrency control.\n- The case
service will continue to not return the `total_alerts`
and\n`total_comments`.\n- The case service will accept the
`total_alerts` and `total_comments`\nattributes to be able to set
them.\n\nFixes: https://github.com/elastic/kibana/issues/217636\n\ncc
@michaelolo24 \n\n### Checklist\n\nCheck the PR satisfies following
conditions. \n\nReviewers should verify this PR satisfies this list as
well.\n\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common
scenarios","sha":"f30335ac3d74bd3310167a27d035544c72068111"}},{"branch":"8.19","label":"v8.19.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
akowalska622 pushed a commit to akowalska622/kibana that referenced this pull request Jun 25, 2025
…saved objects (elastic#223992)

## Summary

This is a farewell PR to Cases. Probably my last PR to the cases
codebase. It was quite a journey, and I learned a lot. I hope the best
for the feature of Cases.

## Decisions

Just before Cases was forbidden to do migrations, we did a last
migration to all cases to persist `total_alerts: -1` and
`total_comments: -1`. We did that so that in the future, when we would
want to populate the fields, we would know which cases have their fields
populated and which do not. In this PR, due to time constraints and
criticality of the feature, I took the following decisions:

- Cases return from their APIs the total comments and alerts of each
case. They do that by doing an aggregation, getting the counts, and
merging them with the response. I did not change that behavior. In
following PRs, it can be optimized and fetch the stats only for cases
that do not yet have their stats populated (cases with -1 in the counts)
- When a case is created, the counts are zero.
- When a comment or alert is added, I do an aggregation to get the stats
(total alerts and comments) of the current case, and then update the
counters with the number of the newly created attachments. The case is
updated without version checks. In race conditions, where an attachment
is being added before updating the case, the numbers could be off. This
is a deliberate choice. It can be fixed later with retries and version
concurrency control.
- The case service will continue to not return the `total_alerts` and
`total_comments`.
- The case service will accept the `total_alerts` and `total_comments`
attributes to be able to set them.

Fixes: elastic#217636

cc @michaelolo24 

### Checklist

Check the PR satisfies following conditions. 

Reviewers should verify this PR satisfies this list as well.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:version Backport to applied version labels Feature:Cases Cases feature release_note:skip Skip the PR/issue when compiling release notes Team:ResponseOps Platform ResponseOps team (formerly the Cases and Alerting teams) t// v8.19.0 v9.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ResponseOps][Cases] Track total comments and alerts on the cases SO

5 participants