Skip to content

Commit

Permalink
[BUG] Finding's fly-out has no correlations if open from alerts (#558)
Browse files Browse the repository at this point in the history
* [BUG] Finding's fly-out has no correlations if open from alerts #557

Signed-off-by: Jovan Cvetkovic <[email protected]>

* code review from #558 (comment)

Signed-off-by: Jovan Cvetkovic <[email protected]>

* cypress tests wait interval updated to 400

Signed-off-by: Jovan Cvetkovic <[email protected]>

* cypress tests wait interval updated to 400

Signed-off-by: Jovan Cvetkovic <[email protected]>

---------

Signed-off-by: Jovan Cvetkovic <[email protected]>
(cherry picked from commit 28edd8e)
  • Loading branch information
jovancvetkovic3006 authored and github-actions[bot] committed May 5, 2023
1 parent f93dfe0 commit c1a5d7d
Show file tree
Hide file tree
Showing 13 changed files with 156 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cypress-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:

- name: Sleep until OSD server starts - non-windows
if: ${{ matrix.os != 'windows-latest' }}
run: sleep 300
run: sleep 400
shell: bash

- name: Install Cypress
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/1_detectors.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ const createDetector = (detectorName, dataSource, expectFailure) => {
}
}

// Confirm entries user has made
// Confirm entries user made
cy.contains('Detector details');
cy.contains(detectorName);
cy.contains('dns');
Expand Down
1 change: 1 addition & 0 deletions public/pages/Alerts/components/AlertFlyout/AlertFlyout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ export class AlertFlyout extends React.Component<AlertFlyoutProps, AlertFlyoutSt
return !!this.state.findingFlyoutData ? (
<FindingDetailsFlyout
{...this.props}
shouldLoadAllFindings={true}
finding={{
...(findingFlyoutData as Finding),
detector: { _id: detector.id as string, _index: '', _source: detector },
Expand Down
6 changes: 3 additions & 3 deletions public/pages/Correlations/containers/CorrelationRules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const CorrelationRules: React.FC<RouteComponentProps> = (props: RouteComp

const getCorrelationRules = useCallback(
async (ruleItem?) => {
const allCorrelationRules: CorrelationRuleHit[] = await DataStore.correlationsStore.getCorrelationRules();
const allCorrelationRules: CorrelationRuleHit[] = await DataStore.correlations.getCorrelationRules();
const allRuleItems: CorrelationRuleTableItem[] = allCorrelationRules.map(
(rule: CorrelationRuleHit) => ({
...rule,
Expand All @@ -58,7 +58,7 @@ export const CorrelationRules: React.FC<RouteComponentProps> = (props: RouteComp
setAllRules(allRuleItems);
setFilteredRules(allRuleItems);
},
[DataStore.correlationsStore.getCorrelationRules]
[DataStore.correlations.getCorrelationRules]
);

useEffect(() => {
Expand Down Expand Up @@ -113,7 +113,7 @@ export const CorrelationRules: React.FC<RouteComponentProps> = (props: RouteComp

const onDeleteRuleConfirmed = async (rule: any) => {
if (selectedRule) {
const response = await DataStore.correlationsStore.deleteCorrelationRule(selectedRule.id);
const response = await DataStore.correlations.deleteCorrelationRule(selectedRule.id);

if (response) {
closeDeleteModal();
Expand Down
11 changes: 4 additions & 7 deletions public/pages/Correlations/containers/CorrelationsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export class Correlations extends React.Component<CorrelationsProps, Correlation
const end = datemath.parse(this.endTime);
const startTime = start?.valueOf() || Date.now();
const endTime = end?.valueOf() || Date.now();
let allCorrelations = await DataStore.correlationsStore.getAllCorrelationsInWindow(
let allCorrelations = await DataStore.correlations.getAllCorrelationsInWindow(
startTime.toString(),
endTime.toString()
);
Expand Down Expand Up @@ -207,9 +207,9 @@ export class Correlations extends React.Component<CorrelationsProps, Correlation
return;
}

const allFindings = await DataStore.correlationsStore.fetchAllFindings();
const allFindings = await DataStore.correlations.fetchAllFindings();
const detectorType = allFindings[findingId].logType;
const correlations = await DataStore.correlationsStore.getCorrelatedFindings(
const correlations = await DataStore.correlations.getCorrelatedFindings(
findingId,
detectorType
);
Expand Down Expand Up @@ -321,10 +321,7 @@ export class Correlations extends React.Component<CorrelationsProps, Correlation

onFindingInspect = async (id: string, logType: string) => {
// get finding data and set the specificFindingInfo
const specificFindingInfo = await DataStore.correlationsStore.getCorrelatedFindings(
id,
logType
);
const specificFindingInfo = await DataStore.correlations.getCorrelatedFindings(id, logType);
this.setState({ specificFindingInfo });
this.updateGraphDataState(specificFindingInfo);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export interface CorrelationOptions {
export const CreateCorrelationRule: React.FC<CreateCorrelationRuleProps> = (
props: CreateCorrelationRuleProps
) => {
const correlationStore = DataStore.correlationsStore;
const correlationStore = DataStore.correlations;
const validateCorrelationRule = useCallback((rule: CorrelationRuleModel) => {
if (!rule.name) {
return 'Invalid rule name';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const DetectorBasicDetailsView: React.FC<DetectorBasicDetailsViewProps> =
content: (
<>
{inputs[0].detector_input.indices.map((ind: string) => (
<EuiText>{ind}</EuiText>
<EuiText key={ind}>{ind}</EuiText>
))}
</>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1854,7 +1854,9 @@ exports[`<DetectorDetails /> spec renders the component 1`] = `
onBlur={[Function]}
onFocus={[Function]}
>
<EuiText>
<EuiText
key=".windows"
>
<div
className="euiText euiText--medium"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,9 @@ exports[`<DetectorDetailsView /> spec renders the component 1`] = `
onBlur={[Function]}
onFocus={[Function]}
>
<EuiText>
<EuiText
key=".windows"
>
<div
className="euiText euiText--medium"
>
Expand Down
28 changes: 19 additions & 9 deletions public/pages/Findings/components/FindingDetailsFlyout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ interface FindingDetailsFlyoutProps extends RouteComponentProps {
indexPatternsService: IndexPatternsService;
correlationService: CorrelationService;
closeFlyout: () => void;
shouldLoadAllFindings: boolean;
}

interface FindingDetailsFlyoutState {
Expand All @@ -83,16 +84,15 @@ export default class FindingDetailsFlyout extends Component<
};
}

componentDidMount(): void {
this.getIndexPatternId().then((patternId) => {
if (patternId) {
this.setState({ indexPatternId: patternId });
}
});

getCorrelations = async () => {
const { id, detector } = this.props.finding;
const allFindings = this.props.findings;
DataStore.correlationsStore
let allFindings = this.props.findings;
if (this.props.shouldLoadAllFindings) {
// if findings come from the alerts fly-out, we need to get all the findings to match those with the correlations
allFindings = await DataStore.findings.getAllFindings();
}

DataStore.correlations
.getCorrelatedFindings(id, detector._source?.detector_type)
.then((findings) => {
if (findings?.correlatedFindings.length) {
Expand All @@ -107,6 +107,16 @@ export default class FindingDetailsFlyout extends Component<
this.setState({ correlatedFindings });
}
});
};

componentDidMount(): void {
this.getIndexPatternId().then((patternId) => {
if (patternId) {
this.setState({ indexPatternId: patternId });
}
});

this.getCorrelations();

this.setState({
selectedTab: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export default class FindingsTable extends Component<FindingsTableProps, Finding
flyout: (
<FindingDetailsFlyout
{...this.props}
shouldLoadAllFindings={false}
finding={finding}
findings={findingsFiltered ? filteredFindings : findings}
closeFlyout={this.closeFlyout}
Expand Down
12 changes: 10 additions & 2 deletions public/store/DataStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import { NotificationsStart } from 'opensearch-dashboards/public';
import { DetectorsStore } from './DetectorsStore';
import { ICorrelationsStore } from '../../types';
import { CorrelationsStore } from './CorrelationsStore';
import { FindingsStore, IFindingsStore } from './FindingsStore';

export class DataStore {
public static rules: RulesStore;
public static detectors: DetectorsStore;
public static correlationsStore: ICorrelationsStore;
public static correlations: ICorrelationsStore;
public static findings: IFindingsStore;

public static init = (services: BrowserServices, notifications: NotificationsStart) => {
const rulesStore = new RulesStore(services.ruleService, notifications);
Expand All @@ -25,7 +27,13 @@ export class DataStore {
services.savedObjectsService
);

DataStore.correlationsStore = new CorrelationsStore(
DataStore.findings = new FindingsStore(
services.findingsService,
services.detectorsService,
notifications
);

DataStore.correlations = new CorrelationsStore(
services.correlationsService,
services.detectorsService,
services.findingsService,
Expand Down
108 changes: 108 additions & 0 deletions public/store/FindingsStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { DetectorsService, FindingsService } from '../services';
import { NotificationsStart } from 'opensearch-dashboards/public';
import { RouteComponentProps } from 'react-router-dom';
import { errorNotificationToast } from '../utils/helpers';
import { FindingItemType } from '../pages/Findings/containers/Findings/Findings';

export interface IFindingsStore {
readonly service: FindingsService;

readonly detectorsService: DetectorsService;

readonly notifications: NotificationsStart;

getFindingsPerDetector: (detectorId: string) => Promise<FindingItemType[]>;

getAllFindings: () => Promise<FindingItemType[]>;
}

export interface IFindingsCache {}

/**
* Findings store
*
* @class FindingsStore
* @implements IDetectorsStore
* @param {BrowserServices} services Uses services to make API requests
*/
export class FindingsStore implements IFindingsStore {
/**
* Findings service instance
*
* @property {FindingsService} service
* @readonly
*/
readonly service: FindingsService;

/**
* Detectors service instance
*
* @property {DetectorsService} detectorsService
* @readonly
*/
readonly detectorsService: DetectorsService;

/**
* Notifications
* @property {NotificationsStart}
* @readonly
*/
readonly notifications: NotificationsStart;

/**
* Router history
* @property {RouteComponentProps['history']}
* @readonly
*/
history: RouteComponentProps['history'] | undefined = undefined;

constructor(
service: FindingsService,
detectorsService: DetectorsService,
notifications: NotificationsStart
) {
this.service = service;
this.detectorsService = detectorsService;
this.notifications = notifications;
}

public getFindingsPerDetector = async (detectorId: string): Promise<FindingItemType[]> => {
let allFindings: FindingItemType[] = [];
const findingRes = await this.service.getFindings({ detectorId });
if (findingRes.ok) {
allFindings = findingRes.response.findings as FindingItemType[];
} else {
errorNotificationToast(this.notifications, 'retrieve', 'findings', findingRes.error);
}

return allFindings;
};

public getAllFindings = async (): Promise<FindingItemType[]> => {
let allFindings: FindingItemType[] = [];
const detectorsRes = await this.detectorsService.getDetectors();
if (detectorsRes.ok) {
const detectors = detectorsRes.response.hits.hits;

for (let detector of detectors) {
const findings = await this.getFindingsPerDetector(detector._id);
const findingsPerDetector: FindingItemType[] = findings.map((finding) => {
return {
...finding,
detectorName: detector._source.name,
logType: detector._source.detector_type,
detector: detector,
};
});
allFindings = allFindings.concat(findingsPerDetector);
}
}

return allFindings;
};
}

0 comments on commit c1a5d7d

Please sign in to comment.