diff --git a/x-pack/plugins/infra/common/http_api/health_snapshot_api.ts b/x-pack/plugins/infra/common/http_api/health_snapshot_api.ts new file mode 100644 index 0000000000000..dfd8a09015ec7 --- /dev/null +++ b/x-pack/plugins/infra/common/http_api/health_snapshot_api.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as runtimeTypes from 'io-ts'; + +export const healthSnapshotApiPath = '/api/infra/health-snapshot'; + +export const healthSnapshotApiRequestPayloadType = runtimeTypes.type({ + sourceId: runtimeTypes.string, + time: runtimeTypes.number, +}); + +export const healthStatusType = runtimeTypes.keyof({ + healthy: null, + unhealthy: null, +}); + +export const healthCheckType = runtimeTypes.type({ + id: runtimeTypes.string, + health: healthStatusType, + time: runtimeTypes.number, +}); + +export type HealthCheck = runtimeTypes.TypeOf; + +// export interface HealthCheck { +// id: string; +// health: 'healthy' | 'unhealthy'; +// time: number; +// } + +export const healthSnapshotApiResponsePayloadType = runtimeTypes.type({ + params: healthSnapshotApiRequestPayloadType, + data: runtimeTypes.type({ + healthSnapshot: runtimeTypes.array(healthCheckType), + }), +}); diff --git a/x-pack/plugins/infra/common/http_api/index.ts b/x-pack/plugins/infra/common/http_api/index.ts index 90afdcb43ffb1..eafa371fb8dec 100644 --- a/x-pack/plugins/infra/common/http_api/index.ts +++ b/x-pack/plugins/infra/common/http_api/index.ts @@ -4,5 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ +export * from './health_snapshot_api'; export * from './search_results_api'; export * from './search_summary_api'; diff --git a/x-pack/plugins/infra/public/containers/health_snapshot.ts b/x-pack/plugins/infra/public/containers/health_snapshot.ts new file mode 100644 index 0000000000000..8ce91311f2a5d --- /dev/null +++ b/x-pack/plugins/infra/public/containers/health_snapshot.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { failure } from 'io-ts/lib/PathReporter'; +import { useState, useEffect } from 'react'; + +import { + HealthCheck, + healthSnapshotApiPath, + healthSnapshotApiRequestPayloadType, + healthSnapshotApiResponsePayloadType, +} from '../../common/http_api'; + +export const useHealthSnapshot = ({ sourceId, time }: { sourceId: string; time: number }) => { + const [healthSnapshot, setHealthSnapshot] = useState([]); + + useEffect( + () => { + fetchHealthSnapshot(sourceId, time) + .then(result => + healthSnapshotApiResponsePayloadType.decode(result.json()).getOrElseL(errors => { + throw new Error(failure(errors).join('\n')); + }) + ) + .then(decodedResult => setHealthSnapshot(decodedResult.data.healthSnapshot)); + }, + [sourceId, time] + ); + + return { + isAllHealthy: healthSnapshot.every(healthCheck => healthCheck.health === 'healthy'), + }; +}; + +const fetchHealthSnapshot = (sourceId: string, time: number) => + fetch(healthSnapshotApiPath, { + method: 'POST', + body: JSON.stringify( + healthSnapshotApiRequestPayloadType.encode({ + sourceId, + time, + }) + ), + }); diff --git a/x-pack/plugins/infra/server/http_api_example/health_snapshot.ts b/x-pack/plugins/infra/server/http_api_example/health_snapshot.ts new file mode 100644 index 0000000000000..162d1f11ab1b4 --- /dev/null +++ b/x-pack/plugins/infra/server/http_api_example/health_snapshot.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { failure } from 'io-ts/lib/PathReporter'; + +import { InternalCoreSetup } from 'src/core/server'; +import { + HealthCheck, + healthSnapshotApiPath, + healthSnapshotApiRequestPayloadType, + healthSnapshotApiResponsePayloadType, +} from '../../common/http_api'; + +export const registerRoutes = (core: InternalCoreSetup) => { + const { server } = core.http; + + server.route({ + path: healthSnapshotApiPath, + method: 'POST', + async handler(request, response) { + const payload = healthSnapshotApiRequestPayloadType + .decode(request.payload) + .getOrElseL(errors => { + throw new Error(failure(errors).join('\n')); + }); + + const result = await getHealthSnapshot(payload.sourceId, payload.time); + + return response.response( + healthSnapshotApiResponsePayloadType.encode({ + params: payload, + data: { + healthSnapshot: result, + }, + }) + ); + }, + }); +}; + +const getHealthSnapshot = async (sourceId: string, time: number): Promise => + sourceId === 'default' + ? [ + { + id: 'check1', + health: 'healthy', + time, + }, + { + id: 'check2', + health: 'unhealthy', + time, + }, + ] + : []; diff --git a/x-pack/plugins/infra/server/http_api_example/index.ts b/x-pack/plugins/infra/server/http_api_example/index.ts new file mode 100644 index 0000000000000..bba3b6318a831 --- /dev/null +++ b/x-pack/plugins/infra/server/http_api_example/index.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { registerRoutes } from './health_snapshot';