Skip to content

Commit f939ecf

Browse files
committed
Port graphql query for snapshot to hapijs
1 parent e93cfd4 commit f939ecf

9 files changed

Lines changed: 341 additions & 31 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import * as rt from 'io-ts';
8+
9+
export const SnapshotNodePath = rt.type({
10+
value: rt.string,
11+
label: rt.string,
12+
ip: rt.string,
13+
});
14+
15+
const SnapshotMetricType = rt.keyof({
16+
count: 'count',
17+
cpu: 'cpu',
18+
load: 'load',
19+
memory: 'memory',
20+
tx: 'tx',
21+
rx: 'rx',
22+
logRate: 'logRate',
23+
});
24+
25+
const SnapshotNodeMetricOptional = rt.partial({
26+
value: rt.number,
27+
average: rt.number,
28+
max: rt.number,
29+
});
30+
31+
const SnapshotNodeMetricRequired = rt.type({
32+
name: SnapshotMetricType,
33+
});
34+
35+
export const SnapshotNodeRT = rt.type({
36+
metric: rt.intersection([SnapshotNodeMetricRequired, SnapshotNodeMetricOptional]),
37+
path: rt.array(SnapshotNodePath),
38+
});
39+
40+
export const SnapshotNodeResponseRT = rt.type({
41+
nodes: rt.array(SnapshotNodeRT),
42+
});
43+
44+
export type SnapshotNode = rt.TypeOf<typeof SnapshotNodeRT>;
45+
46+
export type SnapshotNodeResponse = rt.TypeOf<typeof SnapshotNodeResponseRT>;

x-pack/legacy/plugins/infra/public/components/inventory/layout.tsx

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,63 @@
66

77
import React from 'react';
88
import { InfraWaffleMapOptions, InfraWaffleMapBounds } from '../../lib/lib';
9-
import { InfraNodeType, InfraSnapshotNode, InfraTimerangeInput } from '../../graphql/types';
9+
import {
10+
InfraNodeType,
11+
InfraSnapshotNode,
12+
InfraTimerangeInput,
13+
InfraSnapshotMetricInput,
14+
InfraSnapshotGroupbyInput,
15+
} from '../../graphql/types';
1016
import { KueryFilterQuery } from '../../store/local/waffle_filter';
1117

1218
import { NodesOverview } from '../nodes_overview';
1319
import { Toolbar } from './toolbars/toolbar';
1420
import { PageContent } from '../page';
21+
import { useSnapshot } from '../../containers/waffle/use_snaphot';
1522

1623
export interface LayoutProps {
1724
options: InfraWaffleMapOptions;
1825
nodeType: InfraNodeType;
19-
nodes: InfraSnapshotNode[];
20-
loading: boolean;
21-
reload: () => void;
2226
onDrilldown: (filter: KueryFilterQuery) => void;
2327
timeRange: InfraTimerangeInput;
2428
onViewChange: (view: string) => void;
2529
view: string;
2630
boundsOverride: InfraWaffleMapBounds;
2731
autoBounds: boolean;
32+
33+
filterQuery: string | null | undefined;
34+
metric: InfraSnapshotMetricInput;
35+
groupBy: InfraSnapshotGroupbyInput[];
36+
sourceId: string;
37+
timerange: InfraTimerangeInput;
2838
}
2939

3040
export const Layout = (props: LayoutProps) => {
41+
const { loading, nodes, reload } = useSnapshot(
42+
props.filterQuery,
43+
props.metric,
44+
props.groupBy,
45+
props.nodeType,
46+
props.sourceId,
47+
props.timerange
48+
);
3149
return (
3250
<>
3351
<Toolbar nodeType={props.nodeType} />
3452
<PageContent>
35-
<NodesOverview {...props} />
53+
<NodesOverview
54+
nodes={nodes}
55+
options={props.options}
56+
nodeType={props.nodeType}
57+
loading={loading}
58+
reload={reload}
59+
onDrilldown={props.onDrilldown}
60+
timeRange={props.timeRange}
61+
onViewChange={props.onViewChange}
62+
view={props.view}
63+
autoBounds={props.autoBounds}
64+
boundsOverride={props.boundsOverride}
65+
/>
3666
</PageContent>
3767
</>
3868
);

x-pack/legacy/plugins/infra/public/components/nodes_overview/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ import { InfraLoadingPanel } from '../loading';
2525
import { Map } from '../waffle/map';
2626
import { ViewSwitcher } from '../waffle/view_switcher';
2727
import { TableView } from './table';
28+
import { SnapshotNode } from '../../../common/http_api/snapshot_api';
2829

2930
interface Props {
3031
options: InfraWaffleMapOptions;
3132
nodeType: InfraNodeType;
32-
nodes: InfraSnapshotNode[];
33+
nodes: SnapshotNode[];
3334
loading: boolean;
3435
reload: () => void;
3536
onDrilldown: (filter: KueryFilterQuery) => void;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { useEffect } from 'react';
8+
import { fold } from 'fp-ts/lib/Either';
9+
import { identity } from 'fp-ts/lib/function';
10+
import { pipe } from 'fp-ts/lib/pipeable';
11+
import {
12+
InfraNodeType,
13+
InfraSnapshotMetricInput,
14+
InfraSnapshotGroupbyInput,
15+
InfraTimerangeInput,
16+
} from '../../graphql/types';
17+
import { throwErrors, createPlainError } from '../../../common/runtime_types';
18+
import { useHTTPRequest } from '../../hooks/use_http_request';
19+
import {
20+
SnapshotNodeResponseRT,
21+
SnapshotNodeResponse,
22+
} from '../../../common/http_api/snapshot_api';
23+
24+
export function useSnapshot(
25+
filterQuery: string | null | undefined,
26+
metric: InfraSnapshotMetricInput,
27+
groupBy: InfraSnapshotGroupbyInput[],
28+
nodeType: InfraNodeType,
29+
sourceId: string,
30+
timerange: InfraTimerangeInput
31+
) {
32+
const decodeResponse = (response: any) => {
33+
return pipe(
34+
SnapshotNodeResponseRT.decode(response),
35+
fold(throwErrors(createPlainError), identity)
36+
);
37+
};
38+
39+
const { error, loading, response, makeRequest } = useHTTPRequest<SnapshotNodeResponse>(
40+
'/api/metrics/snapshot',
41+
'POST',
42+
JSON.stringify({
43+
metric,
44+
groupBy,
45+
nodeType,
46+
timerange,
47+
filterQuery,
48+
sourceId,
49+
decodeResponse,
50+
})
51+
);
52+
53+
useEffect(() => {
54+
(async () => {
55+
await makeRequest();
56+
})();
57+
}, [makeRequest]);
58+
59+
return {
60+
error: (error && error.message) || null,
61+
loading,
62+
nodes: response ? response.nodes : [],
63+
reload: makeRequest,
64+
};
65+
}

x-pack/legacy/plugins/infra/public/graphql/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ export interface InfraSnapshotNodePath {
291291
}
292292

293293
export interface InfraSnapshotNodeMetric {
294-
name: InfraSnapshotMetricType;
294+
name: 'count' | 'cpu' | 'load' | 'memory' | 'tx' | 'rx' | 'logRate';
295295

296296
value?: number | null;
297297

x-pack/legacy/plugins/infra/public/pages/infrastructure/snapshot/page_content.tsx

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import React from 'react';
88

99
import { WithWaffleFilter } from '../../../containers/waffle/with_waffle_filters';
10-
import { WithWaffleNodes } from '../../../containers/waffle/with_waffle_nodes';
1110
import { WithWaffleOptions } from '../../../containers/waffle/with_waffle_options';
1211
import { WithWaffleTime } from '../../../containers/waffle/with_waffle_time';
1312
import { WithOptions } from '../../../containers/with_options';
@@ -33,35 +32,25 @@ export const SnapshotPageContent: React.SFC = () => (
3332
autoBounds,
3433
boundsOverride,
3534
}) => (
36-
<WithWaffleNodes
35+
<Layout
3736
filterQuery={filterQueryAsJson}
3837
metric={metric}
3938
groupBy={groupBy}
4039
nodeType={nodeType}
4140
sourceId={sourceId}
4241
timerange={currentTimeRange}
43-
>
44-
{({ nodes, loading, refetch }) => (
45-
<Layout
46-
nodes={nodes}
47-
loading={nodes.length > 0 && isAutoReloading ? false : loading}
48-
nodeType={nodeType}
49-
options={{
50-
...wafflemap,
51-
metric,
52-
fields: configuration && configuration.fields,
53-
groupBy,
54-
}}
55-
reload={refetch}
56-
onDrilldown={applyFilterQuery}
57-
timeRange={currentTimeRange}
58-
view={view}
59-
onViewChange={changeView}
60-
autoBounds={autoBounds}
61-
boundsOverride={boundsOverride}
62-
/>
63-
)}
64-
</WithWaffleNodes>
42+
options={{
43+
...wafflemap,
44+
metric,
45+
fields: configuration && configuration.fields,
46+
groupBy,
47+
}}
48+
onDrilldown={applyFilterQuery}
49+
view={view}
50+
onViewChange={changeView}
51+
autoBounds={autoBounds}
52+
boundsOverride={boundsOverride}
53+
/>
6554
)}
6655
</WithWaffleOptions>
6756
)}

x-pack/legacy/plugins/infra/server/infra_server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { InfraBackendLibs } from './lib/infra_types';
1616
import { initLogAnalysisGetLogEntryRateRoute } from './routes/log_analysis';
1717
import { initMetricExplorerRoute } from './routes/metrics_explorer';
1818
import { initMetadataRoute } from './routes/metadata';
19+
import { initSnapshotRoute } from './routes/snapshot';
1920

2021
export const initInfraServer = (libs: InfraBackendLibs) => {
2122
const schema = makeExecutableSchema({
@@ -33,6 +34,7 @@ export const initInfraServer = (libs: InfraBackendLibs) => {
3334

3435
initIpToHostName(libs);
3536
initLogAnalysisGetLogEntryRateRoute(libs);
37+
initSnapshotRoute(libs);
3638
initMetricExplorerRoute(libs);
3739
initMetadataRoute(libs);
3840
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
import { InfraBackendLibs } from '../../lib/infra_types';
7+
import { InfraSnapshotRequestOptions } from '../../lib/snapshot';
8+
import { UsageCollector } from '../../usage/usage_collector';
9+
import { parseFilterQuery } from '../../utils/serialized_query';
10+
import { InfraSnapshotNode, SnapshotRequest } from './types';
11+
12+
export const initSnapshotRoute = (libs: InfraBackendLibs) => {
13+
const { framework } = libs;
14+
15+
framework.registerRoute<SnapshotRequest, Promise<{ nodes: InfraSnapshotNode[] }>>({
16+
method: 'POST',
17+
path: '/api/metrics/snapshot',
18+
handler: async req => {
19+
const source = await libs.sources.getSourceConfiguration(req, req.payload.sourceId);
20+
UsageCollector.countNode(req.payload.nodeType);
21+
const options: InfraSnapshotRequestOptions = {
22+
filterQuery: parseFilterQuery(req.payload.filterQuery),
23+
nodeType: req.payload.nodeType,
24+
groupBy: req.payload.groupBy,
25+
sourceConfiguration: source.configuration,
26+
metric: req.payload.metric,
27+
timerange: req.payload.timerange,
28+
};
29+
return { nodes: await libs.snapshot.getNodes(req, options) };
30+
},
31+
});
32+
};

0 commit comments

Comments
 (0)