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

[Security Solution] Update cache invalidation logic to handle error responses #146271

Merged
merged 1 commit into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,22 @@ export interface BulkActionAggregatedError {
rules: Array<{ id: string; name?: string }>;
}

export interface BulkActionAttributes {
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for adding these types and discriminating between successful and error responses 👍

Only thing: I also added these types for the bulk edit response while working on the skipped rules PR. Do you think it makes sense to move them to the /common folder and then import them to both server and public?

https://github.com/elastic/kibana/pull/144461/files#diff-0bddfc1ba78df99099e714716ea1bb5d969c5d6da65946d2f1cbb964382f2405R34

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jpdjere Yes, if the types are the same on the front end and server side, it makes sense to move them to the common folder. Ideally, we should put there a runtime io-ts schema, which could be used for response validation, and derive the type from it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Allright, if we get merged this before than my PR I can update it on my side and refactor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Allright, if we get merged this before than my PR I can update it on my side and refactor.

Yes, as this one targets 8.6, it would be safer to do refactoring in the main. Thank you, @jpdjere 👍

summary: BulkActionSummary;
results: BulkActionResult;
errors?: BulkActionAggregatedError[];
}

export interface BulkActionResponse {
success?: boolean;
rules_count?: number;
attributes: {
summary: BulkActionSummary;
results: BulkActionResult;
errors?: BulkActionAggregatedError[];
};
attributes: BulkActionAttributes;
}

export interface BulkActionErrorResponse {
message: string;
status_code: number;
attributes?: BulkActionAttributes;
}

export type QueryOrIds = { query: string; ids?: undefined } | { query?: undefined; ids: string[] };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
*/
import type { UseMutationOptions } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import type { IHttpFetchError } from '@kbn/core/public';
import { BulkActionType } from '../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema';
import type { BulkActionResponse, PerformBulkActionProps } from '../api';
import type { BulkActionErrorResponse, BulkActionResponse, PerformBulkActionProps } from '../api';
import { performBulkAction } from '../api';
import { useInvalidateFetchPrebuiltRulesStatusQuery } from './use_fetch_prebuilt_rules_status_query';
import { useInvalidateFindRulesQuery, useUpdateRulesCache } from './use_find_rules_query';
Expand All @@ -18,55 +19,76 @@ import { DETECTION_ENGINE_RULES_BULK_ACTION } from '../../../../../common/consta
export const BULK_ACTION_MUTATION_KEY = ['POST', DETECTION_ENGINE_RULES_BULK_ACTION];

export const useBulkActionMutation = (
options?: UseMutationOptions<BulkActionResponse, Error, PerformBulkActionProps>
options?: UseMutationOptions<
BulkActionResponse,
IHttpFetchError<BulkActionErrorResponse>,
PerformBulkActionProps
>
) => {
const invalidateFindRulesQuery = useInvalidateFindRulesQuery();
const invalidateFetchRuleByIdQuery = useInvalidateFetchRuleByIdQuery();
const invalidateFetchTagsQuery = useInvalidateFetchTagsQuery();
const invalidateFetchPrebuiltRulesStatusQuery = useInvalidateFetchPrebuiltRulesStatusQuery();
const updateRulesCache = useUpdateRulesCache();

return useMutation<BulkActionResponse, Error, PerformBulkActionProps>(
(bulkActionProps: PerformBulkActionProps) => performBulkAction(bulkActionProps),
{
...options,
mutationKey: BULK_ACTION_MUTATION_KEY,
onSuccess: (...args) => {
const [
res,
{
bulkAction: { type: actionType },
},
] = args;
switch (actionType) {
case BulkActionType.enable:
case BulkActionType.disable: {
invalidateFetchRuleByIdQuery();
// This action doesn't affect rule content, no need for invalidation
updateRulesCache(res?.attributes?.results?.updated ?? []);
break;
}
case BulkActionType.delete:
invalidateFindRulesQuery();
invalidateFetchRuleByIdQuery();
invalidateFetchTagsQuery();
invalidateFetchPrebuiltRulesStatusQuery();
break;
case BulkActionType.duplicate:
return useMutation<
BulkActionResponse,
IHttpFetchError<BulkActionErrorResponse>,
PerformBulkActionProps
>((bulkActionProps: PerformBulkActionProps) => performBulkAction(bulkActionProps), {
...options,
mutationKey: BULK_ACTION_MUTATION_KEY,
onSettled: (...args) => {
const [
response,
error,
{
bulkAction: { type: actionType },
},
] = args;

const updatedRules =
response?.attributes?.results?.updated ?? error?.body?.attributes?.results?.updated;

switch (actionType) {
case BulkActionType.enable:
case BulkActionType.disable: {
invalidateFetchRuleByIdQuery();
if (updatedRules) {
// We have a list of updated rules, no need to invalidate all
updateRulesCache(updatedRules);
} else {
// We failed to receive the list of update rules, invalidate all
invalidateFindRulesQuery();
invalidateFetchPrebuiltRulesStatusQuery();
break;
case BulkActionType.edit:
updateRulesCache(res?.attributes?.results?.updated ?? []);
invalidateFetchRuleByIdQuery();
invalidateFetchTagsQuery();
break;
}
break;
}
case BulkActionType.delete:
invalidateFindRulesQuery();
invalidateFetchRuleByIdQuery();
invalidateFetchTagsQuery();
invalidateFetchPrebuiltRulesStatusQuery();
break;
case BulkActionType.duplicate:
invalidateFindRulesQuery();
invalidateFetchPrebuiltRulesStatusQuery();
break;
case BulkActionType.edit:
if (updatedRules) {
// We have a list of updated rules, no need to invalidate all
updateRulesCache(updatedRules);
} else {
// We failed to receive the list of update rules, invalidate all
invalidateFindRulesQuery();
}
invalidateFetchRuleByIdQuery();
invalidateFetchTagsQuery();
break;
}

if (options?.onSuccess) {
options.onSuccess(...args);
}
},
}
);
if (options?.onSettled) {
options.onSettled(...args);
}
},
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ export const useCreatePrebuiltRulesMutation = (
return useMutation(() => createPrepackagedRules(), {
...options,
mutationKey: CREATE_PREBUILT_RULES_MUTATION_KEY,
onSuccess: (...args) => {
onSettled: (...args) => {
// Always invalidate all rules and the prepackaged rules status cache as
// the number of rules might change after the installation
invalidatePrePackagedRulesStatus();
invalidateFindRulesQuery();
invalidateFetchTagsQuery();

if (options?.onSuccess) {
options.onSuccess(...args);
if (options?.onSettled) {
options.onSettled(...args);
}
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ export const useCreateRuleMutation = (
{
...options,
mutationKey: CREATE_RULE_MUTATION_KEY,
onSuccess: (...args) => {
onSettled: (...args) => {
invalidateFetchPrePackagedRulesStatusQuery();
invalidateFindRulesQuery();
invalidateFetchTagsQuery();

if (options?.onSuccess) {
options.onSuccess(...args);
if (options?.onSettled) {
options.onSettled(...args);
}
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ export const useUpdateRuleMutation = (
{
...options,
mutationKey: UPDATE_RULE_MUTATION_KEY,
onSuccess: (...args) => {
onSettled: (...args) => {
invalidateFindRulesQuery();
invalidateFetchRuleByIdQuery();
invalidateFetchTagsQuery();

if (options?.onSuccess) {
options.onSuccess(...args);
if (options?.onSettled) {
options.onSettled(...args);
}
},
}
Expand Down