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] Extract frontend rule management logic from React components #92169

Open
3 tasks
banderror opened this issue Feb 22, 2021 · 2 comments
Open
3 tasks
Labels
Feature:Rule Management Security Solution Detection Rule Management refactoring Team:Detection Rule Management Security Detection Rule Management Team Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. technical debt Improvement of the software architecture and operational architecture

Comments

@banderror
Copy link
Contributor

banderror commented Feb 22, 2021

Epic: https://github.com/elastic/security-team/issues/1972

Summary

TL;DR:

  • Keep frontend app logic outside of React components.
  • Keep it consolidated in React contexts with its own state and exposed high-level actions.
  • Use high-level mechanisms for building app logic (e.g. React Query, XState) instead of over-relying on low-level hooks (e.g. useState, useCallback, useEffect).
  • Build high-level abstractions clearly describing what the app can do and what it can't do (i.e. what components are not supposed to be doing).
  • Be able to test app logic without unit testing large components like tables and pages.
  • Be able to test app logic without writing an exhaustive suite of e2e Cypress tests.
  • Be able to cover app logic scenarios with unit tests.

Our implementation of the Rule Management and Monitoring tables, as well as whole Rule Management and Rule Details pages, is pretty hairy, with pieces of the application logic being scattered across components, over-reliance on primitive React hooks to manage state and logic (useState, useCallback, etc), not using context and/or store, lack of a single source of truth for state (could be a reducer or a similar thing), duplication of state in hooks and components, overuse of flags here and there and thus complex boolean checks like !initLoading && (loading || isLoadingRules || isLoadingAnActionOnRule) && !isRefreshing, underuse of clearly and explicitly defined states, components overloaded with dependencies and inline logic which leads to testing client-side app logic being very difficult and brittle, so we skip all kinds of lower-level testing and add only Cypress tests.

Recently, we have been switching to React Query to manage the Rules table's state and the cache of loaded rules and made great progress so far. However, there's still a lot to do before we can consider all the business logic of rule management extracted from React components, which should in turn give us the ability to cover it with unit tests.

To do

  • Extract rule management logic that doesn't depend on the page (Rule Management, Rule Details, Rule Editing, etc) to separate React contexts. Examples of such logic: enabling/disabling an individual rule, creating a rule, editing a rule, deleting a rule, etc
  • Move the whole Rules table logic to the existing RulesTableContext. Expose higher-level actions from RulesTableActions like deleteRule, deleteSelectedRules, enableRule, enableSelectedRules, etc, and hide lower-level actions like setLoadingRules. The logic should determine some of its internal states like loading indicators on its own, without delegating it to components.
  • Extract logic of loading rule details (for the Rule Details page) to its own React context.
@banderror banderror added refactoring Feature:Detection Rules Anything related to Security Solution's Detection Rules Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. labels Feb 22, 2021
@banderror banderror self-assigned this Feb 22, 2021
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-solution (Team: SecuritySolution)

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-detections-response (Team:Detections and Resp)

@spong spong added the Feature:Rule Management Security Solution Detection Rule Management label Feb 23, 2021
@peluja1012 peluja1012 added the Team:Detection Rule Management Security Detection Rule Management Team label Sep 14, 2021
@peluja1012 peluja1012 added the technical debt Improvement of the software architecture and operational architecture label Oct 26, 2021
@banderror banderror removed their assignment Nov 24, 2021
@banderror banderror changed the title [Security Solution][Detections] Refactor rules management table before adding new filters, sorting and searching capabilities [Security Solution][Detections] Extract frontend rule management logic from React components Feb 14, 2022
@banderror banderror added the 8.2 candidate considered, but not committed, for 8.2 release label Feb 14, 2022
@banderror banderror removed the 8.2 candidate considered, but not committed, for 8.2 release label Feb 28, 2022
banderror added a commit that referenced this issue Oct 21, 2022
…toring Rule Management (#142950)

**Partially addresses:** #138600, #92169, #138606
**Addresses:** #136957, #136962, #138614

## Summary

In this PR we are:

- Splitting the Detection Engine into subdomains ([ticket](#138600)). Every subdomain got its own folder under `detection_engine`, and we moved some (not all) code into them. More on that is below. New subdomains introduced:
  - `fleet_integrations`
  - `prebuilt_rules`
  - `rule_actions_legacy`
  - `rule_exceptions`
  - `rule_management`
  - `rule_preview`
  - `rule_schema`
  - `rule_creation_ui`
  - `rule_details_ui`
  - `rule_management_ui`
  - `rule_exceptions_ui`
- Updating the CODEOWNERS file accordingly.
- Refactoring the Rule Management page and the Rules table. Our main focus was on the way how we communicate with the API endpoints, how we cache and invalidate the fetched data, and how this code is organized in the codebase. More on that is below.
- Increasing the bundle size limit. This is going to be decreased back in a follow-up PR ([ticket](#143532))

## Restructuring folders into subdomains

For the background and problem statement, please refer to #138600

We were focusing on code that is closely related to the Rules area: either owned by us de facto (we work on it) or owned by us de jure (according to the CODEOWNERS file). Or goal was to explicitly extract code that we don't own de facto into separate subdomains, transfer ownership to other area teams, and reflect this in the CODEOWNERS file. On the other hand, we wanted the code that we own to also be organized in clear subdomains that we could easily own via CODEOWNERS. We didn't touch the code that is already explicitly owned by other area teams, e.g. `x-pack/plugins/security_solution/server/lib/detection_engine/rule_types`.

This is a draft "domain map" - an architectural diagram that shows how the Detection Engine _could_ be split into subdomains. It's more a TO-BE idea/aspiration rather than an AS-IS statement. Any feedback, critiques, and suggestions would be extremely appreciated!

<img width="2592" alt="Screenshot 2022-10-18 at 16 08 40" src="https://user-images.githubusercontent.com/7359339/196453965-b65f5b49-9a33-4d90-bb48-1347e9576223.png">

It shows the flow of dependencies between subdomains and proposes some rules:

- The whole graph of dependencies between all subdomains should be a DAG. There should not be bi-directional or circular dependencies between them.
- **Generic subdomains** represent some general knowledge that can be used/applied outside of the Detection Engine.
  - Can depend on some generic kbn packages, npm packages or utils.
  - Can't depend on any other Detection Engine subdomains.
- **Crosscutting subdomains** represent some code that can be common to / shared between many other subdomains. This could be some very common domain models and API schemas.
  - Can depend on generic subdomains.
  - Can depend on other crosscutting subdomains (dependencies between them must form a DAG).
  - Can't depend on core or UI subdomains.
- **Core subdomains** contain most of the "meat" of the Detection Engine: domain models, server-side and client-side business logic, server-side API endpoints, client-side UI (potentially shareable between several pages).
  - Can depend on crosscutting and generic subdomains.
  - Can depend on other core subdomains (dependencies between them must form a DAG).
  - Can't depend on UI subdomains.
- **UI subdomains** contain the implementation of pages related to the Detection Engine. Every page can easily depend on several core subdomains, so these subdomain are on top of everything.
  - Can depend on any other subdomains. Dependencies must form a DAG.

Dashed lines show some existing dependencies that we think should be eliminated.

Ownership TO-BE is color-coded. We updated the CODEOWNERS file according to the new folders.

The folder restructuring is not 100% finished but we did a big part of it. Most of the FE code continues to live in legacy folders, e.g. see `x-pack/plugins/security_solution/public/detections`. So this work is to be continued...

## Refactoring of Rule Management FE

- [x] #136957 For effective HTTP requests caching and deduplication, we've migrated all data fetching logic to `useQuery` and `useMutation` hooks from `react-query`. That allowed us to introduce the following improvements to our codebase:
  * All outgoing HTTP requests are now automatically deduplicated. That means that data fetching hooks like `useRule` could be used on any level in the component tree to access response data directly. So, no need to put the hook on the top level anymore and use prop-drilling to make the response data available to all children components that require it.
  * All HTTP responses are now cached with the default TTL of 5 minutes—no more redundant requests. With a hot cache, transitions to some pages now happen immediately. 
- [x] #136962 Data fetching hooks of the Rules Area are now organized in one place. `security_solution/public/detection_engine/rule_management/api/hooks` contains abstraction layer on top of the Kibana's HTTP client. All data fetching should happen exclusively through that layer to ensure that:
  * Mutation queries automatically invalidate associated cache entries.
  * Optimistic updates or updates from mutation responses could be implemented centrally where possible.
- [x] #92169 From some of the Rule Management components, logic was extracted to hooks located in `security_solution/public/detection_engine/rule_management/logic`. 

### Checklist

- [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
@banderror banderror changed the title [Security Solution][Detections] Extract frontend rule management logic from React components [Security Solution] Extract frontend rule management logic from React components Nov 24, 2022
@banderror banderror removed the Feature:Detection Rules Anything related to Security Solution's Detection Rules label Nov 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Rule Management Security Solution Detection Rule Management refactoring Team:Detection Rule Management Security Detection Rule Management Team Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. technical debt Improvement of the software architecture and operational architecture
Projects
None yet
Development

No branches or pull requests

4 participants