Skip to content

Commit 64d079d

Browse files
Merge pull request #97 from alanconway/invalid-query
fix(COO-544): Troubleshooting panel shows "invalid query".
2 parents 0d31d69 + 575d656 commit 64d079d

6 files changed

Lines changed: 65 additions & 81 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ install-frontend-ci-clean: install-frontend-ci
1919

2020
.PHONY: build-frontend
2121
build-frontend:
22-
cd web && npm run build
22+
cd web && npm run i18n && npm run build
2323

2424
.PHONY: start-frontend
2525
start-frontend:
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
{
2+
"Cannot display in console": "Cannot display in console",
23
"Correlation result was empty.": "Correlation result was empty.",
3-
"Error Loading Data": "Error Loading Data",
44
"Find related resources.": "Find related resources.",
55
"Focus": "Focus",
66
"Goal class: ": "Goal class: ",
77
"Hide Query": "Hide Query",
88
"Korrel8 query selecting the starting points for correlation.": "Korrel8 query selecting the starting points for correlation.",
99
"Korrel8r Error": "Korrel8r Error",
10-
"Logging Plugin Disabled": "Logging Plugin Disabled",
1110
"Neighbourhood depth: ": "Neighbourhood depth: ",
12-
"Netflow Plugin Disabled": "Netflow Plugin Disabled",
1311
"No Correlated Signals Found": "No Correlated Signals Found",
1412
"Open the Troubleshooting Panel": "Open the Troubleshooting Panel",
13+
"Plugin disabled: ": "Plugin disabled: ",
1514
"Query": "Query",
1615
"Re-calculate the correlation graph starting from resources on the current console page.": "Re-calculate the correlation graph starting from resources on the current console page.",
16+
"Request Failed": "Request Failed",
1717
"Show graph of connected classes up to the specified depth.": "Show graph of connected classes up to the specified depth.",
1818
"Show graph of paths to signals of the specified class.": "Show graph of paths to signals of the specified class.",
1919
"Show Query": "Show Query",
2020
"The current console page does not show resources that are supported for correlation.": "The current console page does not show resources that are supported for correlation.",
2121
"Troubleshooting": "Troubleshooting",
22-
"Troubleshooting Panel": "Troubleshooting Panel",
23-
"Unable to find Console Link": "Unable to find Console Link"
22+
"Troubleshooting Panel": "Troubleshooting Panel"
2423
}

web/src/components/Korrel8rPanel.tsx

Lines changed: 46 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import * as React from 'react';
2-
import { CancellableFetch } from '../cancellable-fetch';
31
import {
42
Button,
53
Divider,
@@ -16,25 +14,36 @@ import {
1614
Radio,
1715
TextArea,
1816
TextInput,
19-
Tooltip,
17+
Tooltip
2018
} from '@patternfly/react-core';
21-
import { Korrel8rTopology } from './topology/Korrel8rTopology';
22-
import './korrel8rpanel.css';
23-
import { getGoalsGraph, getNeighborsGraph } from '../korrel8r-client';
24-
import { Korrel8rGraphResponse } from '../korrel8r/query.types';
25-
import { LoadingTopology } from './topology/LoadingTopology';
26-
import { TFunction, useTranslation } from 'react-i18next';
2719
import { CubesIcon, ExclamationCircleIcon } from '@patternfly/react-icons';
28-
import { useURLState } from '../hooks/useURLState';
29-
import { usePluginAvailable } from '../hooks/usePluginAvailable';
20+
import * as React from 'react';
21+
import { TFunction, useTranslation } from 'react-i18next';
3022
import { useDispatch, useSelector } from 'react-redux';
31-
import { State } from '../redux-reducers';
23+
import { usePluginAvailable } from '../hooks/usePluginAvailable';
24+
import { useURLState } from '../hooks/useURLState';
25+
import { getGoalsGraph, getNeighborsGraph } from '../korrel8r-client';
26+
import { Korrel8rGraphResponse } from '../korrel8r/query.types';
3227
import { Query, QueryType, setPersistedQuery } from '../redux-actions';
28+
import { State } from '../redux-reducers';
29+
import './korrel8rpanel.css';
30+
import { Korrel8rTopology } from './topology/Korrel8rTopology';
31+
import { LoadingTopology } from './topology/LoadingTopology';
3332

3433
type Result = {
3534
graph?: Korrel8rGraphResponse;
3635
message?: string;
3736
title?: string;
37+
isError?: boolean;
38+
};
39+
40+
const focusQuery = (urlQuery: string): Query => {
41+
return {
42+
query: urlQuery,
43+
queryType: QueryType.Neighbour,
44+
depth: 3,
45+
goal: null,
46+
};
3847
};
3948

4049
export default function Korrel8rPanel() {
@@ -46,34 +55,28 @@ export default function Korrel8rPanel() {
4655

4756
// State
4857
const { korrel8rQueryFromURL } = useURLState();
49-
// Initial value from persisted query if available (when opened from anywhere but
50-
// the alerts page or if never opened before), otherwise URL
51-
const initialQuery = persistedQuery.query
52-
? persistedQuery
53-
: {
54-
query: korrel8rQueryFromURL,
55-
queryType: QueryType.Neighbour,
56-
depth: 3,
57-
goal: null,
58-
};
59-
const [query, setQuery] = React.useState<Query>(initialQuery);
58+
const [query, setQuery] = React.useState<Query>(
59+
persistedQuery.query ? persistedQuery : focusQuery(korrel8rQueryFromURL),
60+
);
6061
const [result, setResult] = React.useState<Result | null>(null);
6162
const [showQuery, setShowQuery] = React.useState(false);
6263

64+
const cannotFocus = t(
65+
'The current console page does not show resources that are supported for correlation.',
66+
);
67+
6368
React.useEffect(() => {
6469
// Set result = null to trigger a reload, don't run the query till then.
6570
if (result !== null) {
6671
return;
6772
}
68-
let fetch: CancellableFetch<Korrel8rGraphResponse>;
69-
if (query.queryType === QueryType.Neighbour) {
70-
fetch = getNeighborsGraph(query);
71-
} else if (query.queryType === QueryType.Goal) {
72-
fetch = getGoalsGraph(query);
73-
} else {
73+
if (!query?.query && !korrel8rQueryFromURL) {
74+
setResult({ message: cannotFocus });
7475
return;
7576
}
76-
const { request, abort } = fetch;
77+
// Make the query request
78+
const { request, abort } =
79+
query.queryType === QueryType.Goal ? getGoalsGraph(query) : getNeighborsGraph(query);
7780
request()
7881
.then((response: Korrel8rGraphResponse) => {
7982
setResult({ graph: { nodes: response.nodes, edges: response.edges } });
@@ -84,22 +87,23 @@ export default function Korrel8rPanel() {
8487
})
8588
.catch((e: Error) => {
8689
try {
87-
setResult({ message: JSON.parse(e.message).error, title: t('Korrel8r Error') });
90+
setResult({
91+
isError: true,
92+
message: JSON.parse(e.message).error,
93+
title: t('Korrel8r Error'),
94+
});
8895
} catch {
89-
setResult({ message: e.message, title: t('Error Loading Data') });
96+
setResult({ isError: true, message: e.message, title: t('Request Failed') });
9097
}
9198
});
9299
return abort;
93-
}, [result, t, dispatch, query]);
100+
}, [result, t, dispatch, query, cannotFocus, korrel8rQueryFromURL]);
94101

95102
const queryToggleID = 'query-toggle';
96103
const queryContentID = 'query-content';
97104
const queryInputID = 'query-input';
98105
const queryTypeOptions = 'query-type-options';
99106

100-
const cannotFocus = t(
101-
'The current console page does not show resources that are supported for correlation.',
102-
);
103107
const focusTip = korrel8rQueryFromURL
104108
? t('Re-calculate the correlation graph starting from resources on the current console page.')
105109
: cannotFocus;
@@ -110,7 +114,6 @@ export default function Korrel8rPanel() {
110114
(newQuery: Query) => {
111115
newQuery.depth = depthBounds(newQuery.depth);
112116
newQuery.queryType = !newQuery.goal ? QueryType.Neighbour : newQuery.queryType;
113-
114117
setQuery(newQuery);
115118
setResult(null);
116119
},
@@ -123,14 +126,7 @@ export default function Korrel8rPanel() {
123126
<Tooltip content={focusTip}>
124127
<Button
125128
isAriaDisabled={!korrel8rQueryFromURL}
126-
onClick={() => {
127-
runQuery({
128-
query: korrel8rQueryFromURL,
129-
queryType: QueryType.Neighbour,
130-
depth: 3,
131-
goal: null,
132-
});
133-
}}
129+
onClick={() => runQuery(focusQuery(korrel8rQueryFromURL))}
134130
>
135131
{t('Focus')}
136132
</Button>
@@ -244,7 +240,7 @@ export default function Korrel8rPanel() {
244240
</FlexItem>
245241
</Flex>
246242
</Flex>
247-
<Button isAriaDisabled={!query} onClick={() => runQuery(query)} variant="secondary">
243+
<Button isAriaDisabled={!query?.query} onClick={() => runQuery(query)} variant="secondary">
248244
{t('Query')}
249245
</Button>
250246
</ExpandableSection>
@@ -284,23 +280,12 @@ const Topology: React.FC<TopologyProps> = ({ result, t, setQuery }) => {
284280
);
285281
}
286282

287-
if (result.message) {
288-
// Error returned from korrel8r
289-
return (
290-
<TopologyInfoState
291-
titleText={result.title}
292-
// Only display fisrt 400 characters of error to prevent repeating errors
293-
text={result.message.slice(0, 400)}
294-
isError={true}
295-
/>
296-
);
297-
}
298-
299283
return (
300284
<TopologyInfoState
301-
titleText={t('No Correlated Signals Found')}
302-
text={t('Correlation result was empty.')}
303-
isError={false}
285+
titleText={result.title || t('No Correlated Signals Found')}
286+
// Only display fisrt 400 characters of error to prevent repeating errors
287+
text={result.message ? result.message.slice(0, 400) : t('Correlation result was empty.')}
288+
isError={result.isError}
304289
/>
305290
);
306291
};

web/src/components/topology/Korrel8rTopology.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as React from 'react';
1+
import { ClusterIcon } from '@patternfly/react-icons';
22
import {
33
action,
44
BreadthFirstLayout,
@@ -24,16 +24,16 @@ import {
2424
withPanZoom,
2525
withSelection,
2626
} from '@patternfly/react-topology';
27-
import { ClusterIcon } from '@patternfly/react-icons';
28-
import { QueryEdge, QueryNode } from '../../korrel8r/query.types';
29-
import { nodeToLabel } from '../../korrel8r-utils';
30-
import { Korrel8rNodeFactory } from '../../korrel8r/node-factory';
27+
import * as React from 'react';
28+
import { TFunction, useTranslation } from 'react-i18next';
3129
import { useHistory, useLocation } from 'react-router';
32-
import { Korrel8rNode } from '../../korrel8r/korrel8r.types';
30+
import { nodeToLabel } from '../../korrel8r-utils';
3331
import { InvalidNode } from '../../korrel8r/invalid';
34-
import { TFunction, useTranslation } from 'react-i18next';
35-
import './korrel8rtopology.css';
32+
import { Korrel8rNode } from '../../korrel8r/korrel8r.types';
33+
import { Korrel8rNodeFactory } from '../../korrel8r/node-factory';
34+
import { QueryEdge, QueryNode } from '../../korrel8r/query.types';
3635
import { Query, QueryType } from '../../redux-actions';
36+
import './korrel8rtopology.css';
3737

3838
interface Korrel8rTopologyNodeProps {
3939
element: Node;
@@ -284,7 +284,7 @@ export const Korrel8rTopology: React.FC<{
284284
setTimeout(() => {
285285
// Center the graph on the next render tick once the graph elements have been sized and placed
286286
controller.getGraph().fit(30);
287-
}, 1);
287+
}, 100); // FIXME this timeout is racy, need to reliably centre graph after layout is done.
288288
return controller;
289289
}, [controller, selectionAction]);
290290

web/src/korrel8r-utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { QueryNode } from './korrel8r/query.types';
21
import { Korrel8rDomain } from './korrel8r/korrel8r.types';
2+
import { QueryNode } from './korrel8r/query.types';
33

4-
const getDomain = (node: QueryNode) => node.class.split(':')[0] ?? '';
4+
export const getDomain = (classOrQuery: string) => classOrQuery.split(':')[0] ?? '';
55

66
export const nodeToLabel = (node: QueryNode): string => {
7-
const domain = getDomain(node);
7+
const domain = getDomain(node.class);
88
switch (domain) {
99
case Korrel8rDomain.Alert:
1010
return `Alert (${node.count})`;

web/src/korrel8r/invalid.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ export class InvalidNode extends Korrel8rNode {
1111
}
1212

1313
static fromURL(url: string): Korrel8rNode {
14-
return new InvalidNode(url, 'invalid');
14+
return new InvalidNode(url, '');
1515
}
1616

1717
static fromQuery(query: string): Korrel8rNode {
18-
return new InvalidNode('invalid', query);
18+
return new InvalidNode('', query);
1919
}
2020

2121
toURL(): string {

0 commit comments

Comments
 (0)