From c2c2d95f10e4b3f8e6bee55ed48b9279cbe68f27 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Tue, 28 Apr 2020 15:18:15 +0100 Subject: [PATCH] Ensure alerts management page can access and load source config / status data --- .../components/alerting/logs/alert_flyout.tsx | 4 +- .../logs/expression_editor/editor.tsx | 78 +++++++++++++++---- .../api/fetch_log_source_configuration.ts | 9 ++- .../log_source/api/fetch_log_source_status.ts | 6 +- .../api/patch_log_source_configuration.ts | 7 +- .../containers/logs/log_source/log_source.ts | 24 ++++-- .../public/pages/logs/page_providers.tsx | 5 +- 7 files changed, 97 insertions(+), 36 deletions(-) diff --git a/x-pack/plugins/infra/public/components/alerting/logs/alert_flyout.tsx b/x-pack/plugins/infra/public/components/alerting/logs/alert_flyout.tsx index b18c2e5b8d69c..37cea9314cfe8 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/alert_flyout.tsx +++ b/x-pack/plugins/infra/public/components/alerting/logs/alert_flyout.tsx @@ -24,7 +24,9 @@ export const AlertFlyout = (props: Props) => { {triggersActionsUI && ( ; setAlertParams(key: string, value: any): void; setAlertProperty(key: string, value: any): void; + alertsContext: AlertsContextValue; } const DEFAULT_CRITERIA = { field: 'log.level', comparator: Comparator.EQ, value: 'error' }; @@ -48,32 +58,68 @@ const DEFAULT_EXPRESSION = { }; export const ExpressionEditor: React.FC = props => { + const isInternal = props.alertsContext.metadata?.isInternal; + const [sourceId] = useSourceId(); + + return ( + <> + {isInternal ? ( + + + + ) : ( + + + + + + )} + + ); +}; + +export const SourceConfigStatus: React.FC = props => { + const { initialize, isLoading, isUninitialized, hasFailedLoadingSource } = useLogSourceContext(); + const { children } = props; + + useMount(() => { + initialize(); + }); + + return ( + <> + {isLoading || isUninitialized + ? 'Loading source data' + : hasFailedLoadingSource + ? 'Error loading source data' + : children} + + ); +}; + +export const Editor: React.FC = props => { const { setAlertParams, alertParams, errors } = props; - const { createDerivedIndexPattern } = useSource({ sourceId: 'default' }); const [timeSize, setTimeSize] = useState(1); const [timeUnit, setTimeUnit] = useState('m'); const [hasSetDefaults, setHasSetDefaults] = useState(false); - const derivedIndexPattern = useMemo(() => createDerivedIndexPattern('logs'), [ - createDerivedIndexPattern, - ]); + const { sourceStatus } = useLogSourceContext(); + + useMount(() => { + for (const [key, value] of Object.entries(DEFAULT_EXPRESSION)) { + setAlertParams(key, value); + setHasSetDefaults(true); + } + }); const supportedFields = useMemo(() => { - if (derivedIndexPattern?.fields) { - return derivedIndexPattern.fields.filter(field => { + if (sourceStatus?.logIndexFields) { + return sourceStatus.logIndexFields.filter(field => { return (field.type === 'string' || field.type === 'number') && field.searchable; }); } else { return []; } - }, [derivedIndexPattern]); - - // Set the default expression (disables exhaustive-deps as we only want to run this once on mount) - useEffect(() => { - for (const [key, value] of Object.entries(DEFAULT_EXPRESSION)) { - setAlertParams(key, value); - setHasSetDefaults(true); - } - }, []); // eslint-disable-line react-hooks/exhaustive-deps + }, [sourceStatus]); const updateCount = useCallback( countParams => { @@ -127,7 +173,7 @@ export const ExpressionEditor: React.FC = props => { ); // Wait until field info has loaded - if (supportedFields.length === 0) return null; + // if (supportedFields.length === 0) return null; // Wait until the alert param defaults have been set if (!hasSetDefaults) return null; diff --git a/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_configuration.ts b/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_configuration.ts index 786cb485b38dd..e847302a6d367 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_configuration.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_configuration.ts @@ -4,15 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ +import { HttpSetup } from 'src/core/public'; import { getLogSourceConfigurationPath, getLogSourceConfigurationSuccessResponsePayloadRT, } from '../../../../../common/http_api/log_sources'; import { decodeOrThrow } from '../../../../../common/runtime_types'; -import { npStart } from '../../../../legacy_singletons'; -export const callFetchLogSourceConfigurationAPI = async (sourceId: string) => { - const response = await npStart.http.fetch(getLogSourceConfigurationPath(sourceId), { +export const callFetchLogSourceConfigurationAPI = async ( + sourceId: string, + fetch: HttpSetup['fetch'] +) => { + const response = await fetch(getLogSourceConfigurationPath(sourceId), { method: 'GET', }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_status.ts b/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_status.ts index 2f1d15ffaf4d3..20e67a0a59c9f 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_status.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_status.ts @@ -4,15 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ +import { HttpSetup } from 'src/core/public'; import { getLogSourceStatusPath, getLogSourceStatusSuccessResponsePayloadRT, } from '../../../../../common/http_api/log_sources'; import { decodeOrThrow } from '../../../../../common/runtime_types'; -import { npStart } from '../../../../legacy_singletons'; -export const callFetchLogSourceStatusAPI = async (sourceId: string) => { - const response = await npStart.http.fetch(getLogSourceStatusPath(sourceId), { +export const callFetchLogSourceStatusAPI = async (sourceId: string, fetch: HttpSetup['fetch']) => { + const response = await fetch(getLogSourceStatusPath(sourceId), { method: 'GET', }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_source/api/patch_log_source_configuration.ts b/x-pack/plugins/infra/public/containers/logs/log_source/api/patch_log_source_configuration.ts index 848801ab3c7ce..4361e4bef827f 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_source/api/patch_log_source_configuration.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_source/api/patch_log_source_configuration.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { HttpSetup } from 'src/core/public'; import { getLogSourceConfigurationPath, patchLogSourceConfigurationSuccessResponsePayloadRT, @@ -11,13 +12,13 @@ import { LogSourceConfigurationPropertiesPatch, } from '../../../../../common/http_api/log_sources'; import { decodeOrThrow } from '../../../../../common/runtime_types'; -import { npStart } from '../../../../legacy_singletons'; export const callPatchLogSourceConfigurationAPI = async ( sourceId: string, - patchedProperties: LogSourceConfigurationPropertiesPatch + patchedProperties: LogSourceConfigurationPropertiesPatch, + fetch: HttpSetup['fetch'] ) => { - const response = await npStart.http.fetch(getLogSourceConfigurationPath(sourceId), { + const response = await fetch(getLogSourceConfigurationPath(sourceId), { method: 'PATCH', body: JSON.stringify( patchLogSourceConfigurationRequestBodyRT.encode({ diff --git a/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts b/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts index 8332018fddf90..654b5a639593e 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts @@ -6,6 +6,7 @@ import createContainer from 'constate'; import { useState, useMemo, useCallback } from 'react'; +import { HttpSetup } from 'src/core/public'; import { LogSourceConfiguration, LogSourceStatus, @@ -23,8 +24,15 @@ export { LogSourceConfigurationPropertiesPatch, LogSourceStatus, }; - -export const useLogSource = ({ sourceId }: { sourceId: string }) => { +import { npStart } from '../../../../legacy_singletons'; + +export const useLogSource = ({ + sourceId, + fetch, +}: { + sourceId: string; + fetch: HttpSetup['fetch']; +}) => { const [sourceConfiguration, setSourceConfiguration] = useState< LogSourceConfiguration | undefined >(undefined); @@ -35,40 +43,40 @@ export const useLogSource = ({ sourceId }: { sourceId: string }) => { { cancelPreviousOn: 'resolution', createPromise: async () => { - return await callFetchLogSourceConfigurationAPI(sourceId); + return await callFetchLogSourceConfigurationAPI(sourceId, fetch); }, onResolve: ({ data }) => { setSourceConfiguration(data); }, }, - [sourceId] + [sourceId, fetch] ); const [updateSourceConfigurationRequest, updateSourceConfiguration] = useTrackedPromise( { cancelPreviousOn: 'resolution', createPromise: async (patchedProperties: LogSourceConfigurationPropertiesPatch) => { - return await callPatchLogSourceConfigurationAPI(sourceId, patchedProperties); + return await callPatchLogSourceConfigurationAPI(sourceId, patchedProperties, fetch); }, onResolve: ({ data }) => { setSourceConfiguration(data); loadSourceStatus(); }, }, - [sourceId] + [sourceId, fetch] ); const [loadSourceStatusRequest, loadSourceStatus] = useTrackedPromise( { cancelPreviousOn: 'resolution', createPromise: async () => { - return await callFetchLogSourceStatusAPI(sourceId); + return await callFetchLogSourceStatusAPI(sourceId, fetch); }, onResolve: ({ data }) => { setSourceStatus(data); }, }, - [sourceId] + [sourceId, fetch] ); const logIndicesExist = useMemo(() => (sourceStatus?.logIndexNames?.length ?? 0) > 0, [ diff --git a/x-pack/plugins/infra/public/pages/logs/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/page_providers.tsx index d2db5002f4aa2..2bb28eb2eb897 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_providers.tsx @@ -5,6 +5,7 @@ */ import React from 'react'; +import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; import { LogAnalysisCapabilitiesProvider } from '../../containers/logs/log_analysis'; import { LogSourceProvider } from '../../containers/logs/log_source'; // import { SourceProvider } from '../../containers/source'; @@ -12,9 +13,9 @@ import { useSourceId } from '../../containers/source_id'; export const LogsPageProviders: React.FunctionComponent = ({ children }) => { const [sourceId] = useSourceId(); - + const { services } = useKibana(); return ( - + {children} );