diff --git a/opensearch_dashboards.json b/opensearch_dashboards.json index 285a26cd57..88f0a9e399 100644 --- a/opensearch_dashboards.json +++ b/opensearch_dashboards.json @@ -18,6 +18,6 @@ "urlForwarding", "visualizations" ], - "optionalPlugins": ["managementOverview", "assistantDashboards", "securityDashboards"], + "optionalPlugins": ["managementOverview", "assistantDashboards", "securityDashboards", "dataSource", "dataSourceManagement"], "configPath": ["observability"] } diff --git a/public/components/app.tsx b/public/components/app.tsx index 4569c42615..1b7150a8cf 100644 --- a/public/components/app.tsx +++ b/public/components/app.tsx @@ -7,19 +7,20 @@ import { I18nProvider } from '@osd/i18n/react'; import { QueryManager } from 'common/query_manager'; import React from 'react'; import { Provider } from 'react-redux'; -import { CoreStart } from '../../../../src/core/public'; +import { CoreStart, MountPoint } from '../../../../src/core/public'; +import { DataSourceManagementPluginSetup } from '../../../../src/plugins/data_source_management/public'; import { observabilityID, observabilityTitle } from '../../common/constants/shared'; import { store } from '../framework/redux/store'; import { AppPluginStartDependencies } from '../types'; import { Home as ApplicationAnalyticsHome } from './application_analytics/home'; -import { Home as IntegrationsHome } from './integrations/home'; import { MetricsListener } from './common/metrics_listener'; import { Home as CustomPanelsHome } from './custom_panels/home'; +import { Home as DataConnectionsHome } from './datasources/home'; import { EventAnalytics } from './event_analytics'; +import { Home as IntegrationsHome } from './integrations/home'; import { Home as MetricsHome } from './metrics/index'; import { Main as NotebooksHome } from './notebooks/components/main'; import { Home as TraceAnalyticsHome } from './trace_analytics/home'; -import { Home as DataConnectionsHome } from './datasources/home'; interface ObservabilityAppDeps { CoreStartProp: CoreStart; @@ -30,6 +31,10 @@ interface ObservabilityAppDeps { timestampUtils: any; queryManager: QueryManager; startPage: string; + dataSourceEnabled: boolean; + dataSourceManagement: DataSourceManagementPluginSetup; + setActionMenu: (menuMount: MountPoint | undefined) => void; + savedObjectsMDSClient: CoreStart['savedObjects']; } // for cypress to test redux store @@ -58,6 +63,10 @@ export const App = ({ queryManager, startPage, dataSourcePluggables, + dataSourceManagement, + setActionMenu, + dataSourceEnabled, + savedObjectsMDSClient, }: ObservabilityAppDeps) => { const { chrome, http, notifications, savedObjects: coreSavedObjects } = CoreStartProp; const parentBreadcrumb = { @@ -89,6 +98,10 @@ export const App = ({ parentBreadcrumbs={[parentBreadcrumb]} setBreadcrumbs={chrome.setBreadcrumbs} dataSourcePluggables={dataSourcePluggables} + dataSourceManagement={dataSourceManagement} + dataSourceEnabled={dataSourceEnabled} + setActionMenu={setActionMenu} + savedObjectsMDSClient={savedObjectsMDSClient} /> diff --git a/public/components/application_analytics/components/config_components/service_config.tsx b/public/components/application_analytics/components/config_components/service_config.tsx index bfeb5029fa..181636aea2 100644 --- a/public/components/application_analytics/components/config_components/service_config.tsx +++ b/public/components/application_analytics/components/config_components/service_config.tsx @@ -15,15 +15,14 @@ import { EuiText, } from '@elastic/eui'; import DSLService from 'public/services/requests/dsl'; -import React, { useState } from 'react'; -import { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; +import { OptionType } from '../../../../../common/types/application_analytics'; import { FilterType } from '../../../trace_analytics/components/common/filters/filters'; import { ServiceObject } from '../../../trace_analytics/components/common/plots/service_map'; import { ServiceMap } from '../../../trace_analytics/components/services'; import { handleServiceMapRequest } from '../../../trace_analytics/requests/services_request_handler'; -import { AppAnalyticsComponentDeps } from '../../home'; -import { OptionType } from '../../../../../common/types/application_analytics'; import { getClearModal } from '../../helpers/modal_containers'; +import { AppAnalyticsComponentDeps } from '../../home'; interface ServiceConfigProps extends AppAnalyticsComponentDeps { dslService: DSLService; @@ -50,7 +49,7 @@ export const ServiceConfig = (props: ServiceConfigProps) => { const [modalLayout, setModalLayout] = useState(); useEffect(() => { - handleServiceMapRequest(http, dslService, mode, setServiceMap); + handleServiceMapRequest(http, dslService, mode, '', setServiceMap); }, []); useEffect(() => { diff --git a/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx b/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx index f17d46e1df..3e5c4c2e07 100644 --- a/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx +++ b/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx @@ -4,7 +4,6 @@ */ /* eslint-disable react-hooks/exhaustive-deps */ -import _ from 'lodash'; import { EuiFlyout, EuiFlyoutBody, @@ -14,19 +13,20 @@ import { EuiText, EuiTitle, } from '@elastic/eui'; +import _ from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; -import { - handleServiceMapRequest, - handleServiceViewRequest, -} from '../../../../../public/components/trace_analytics/requests/services_request_handler'; import { filtersToDsl, processTimeStamp, } from '../../../../../public/components/trace_analytics/components/common/helper_functions'; -import { ServiceMap } from '../../../../../public/components/trace_analytics/components/services'; import { ServiceObject } from '../../../../../public/components/trace_analytics/components/common/plots/service_map'; +import { ServiceMap } from '../../../../../public/components/trace_analytics/components/services'; import { SpanDetailTable } from '../../../../../public/components/trace_analytics/components/traces/span_detail_table'; import { TraceAnalyticsComponentDeps } from '../../../../../public/components/trace_analytics/home'; +import { + handleServiceMapRequest, + handleServiceViewRequest, +} from '../../../../../public/components/trace_analytics/requests/services_request_handler'; import { getListItem } from '../../helpers/utils'; interface ServiceFlyoutProps extends TraceAnalyticsComponentDeps { @@ -131,7 +131,7 @@ export function ServiceDetailFlyout(props: ServiceFlyoutProps) { appConfigs ); handleServiceViewRequest(serviceName, http, serviceDSL, setFields, mode); - handleServiceMapRequest(http, serviceDSL, mode, setServiceMap, serviceName); + handleServiceMapRequest(http, serviceDSL, mode, '', setServiceMap, serviceName); const spanDSL = filtersToDsl(mode, filters, query, startTime, endTime, 'app', appConfigs); spanDSL.query.bool.must.push({ term: { diff --git a/public/components/index.tsx b/public/components/index.tsx index 1058af43a0..b1ebf1211b 100644 --- a/public/components/index.tsx +++ b/public/components/index.tsx @@ -3,11 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { QueryManager } from 'common/query_manager'; import React from 'react'; import ReactDOM from 'react-dom'; -import { QueryManager } from 'common/query_manager'; import { AppMountParameters, CoreStart } from '../../../../src/core/public'; -import { AppPluginStartDependencies, SetupDependencies } from '../types'; +import { DataSourceManagementPluginSetup } from '../../../../src/plugins/data_source_management/public'; +import { AppPluginStartDependencies } from '../types'; import { App } from './app'; export const Observability = ( @@ -20,8 +21,12 @@ export const Observability = ( timestampUtils: any, queryManager: QueryManager, startPage: string, - dataSourcePluggables + dataSourcePluggables, + dataSourceManagement: DataSourceManagementPluginSetup, + savedObjectsMDSClient: CoreStart['savedObjects'] ) => { + const { setHeaderActionMenu } = AppMountParametersProp; + const { dataSource } = DepsStart; ReactDOM.render( , AppMountParametersProp.element ); diff --git a/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap b/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap index 1fff402475..79814b7afb 100644 --- a/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap +++ b/public/components/trace_analytics/components/dashboard/__tests__/__snapshots__/dashboard.test.tsx.snap @@ -149,6 +149,14 @@ exports[`Dashboard component renders dashboard 1`] = ` } } dataPrepperIndicesExist={true} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} @@ -479,6 +487,14 @@ exports[`Dashboard component renders dashboard 1`] = ` } } dataPrepperIndicesExist={true} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} @@ -1261,6 +1277,14 @@ exports[`Dashboard component renders empty dashboard 1`] = ` } } dataPrepperIndicesExist={true} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} @@ -1590,6 +1614,14 @@ exports[`Dashboard component renders empty dashboard 1`] = ` } } dataPrepperIndicesExist={true} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} @@ -2372,6 +2404,14 @@ exports[`Dashboard component renders empty jaeger dashboard 1`] = ` } } dataPrepperIndicesExist={false} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} @@ -2703,6 +2743,14 @@ exports[`Dashboard component renders empty jaeger dashboard 1`] = ` } } dataPrepperIndicesExist={false} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} diff --git a/public/components/trace_analytics/components/dashboard/__tests__/dashboard.test.tsx b/public/components/trace_analytics/components/dashboard/__tests__/dashboard.test.tsx index 703b0a0275..c0b599d550 100644 --- a/public/components/trace_analytics/components/dashboard/__tests__/dashboard.test.tsx +++ b/public/components/trace_analytics/components/dashboard/__tests__/dashboard.test.tsx @@ -7,7 +7,6 @@ import { configure, mount } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; import React from 'react'; import { Dashboard } from '..'; -import { CoreStart } from '../../../../../../../../src/core/public'; import { coreStartMock } from '../../../../../../test/__mocks__/coreMocks'; describe('Dashboard component', () => { @@ -56,6 +55,7 @@ describe('Dashboard component', () => { mode="data_prepper" dataPrepperIndicesExist={true} modes={modes} + dataSourceMDSId={[{ id: '', label: '' }]} /> ); @@ -102,6 +102,7 @@ describe('Dashboard component', () => { dataPrepperIndicesExist={false} jaegerIndicesExist={true} modes={modes} + dataSourceMDSId={[{ id: '', label: '' }]} /> ); @@ -147,6 +148,7 @@ describe('Dashboard component', () => { mode="data_prepper" dataPrepperIndicesExist={true} modes={modes} + dataSourceMDSId={[{ id: '', label: '' }]} /> ); diff --git a/public/components/trace_analytics/components/dashboard/dashboard.tsx b/public/components/trace_analytics/components/dashboard/dashboard.tsx index 71f656f978..4246605cac 100644 --- a/public/components/trace_analytics/components/dashboard/dashboard.tsx +++ b/public/components/trace_analytics/components/dashboard/dashboard.tsx @@ -6,7 +6,8 @@ import { EuiBreadcrumb, EuiTitle } from '@elastic/eui'; import { Toast } from '@elastic/eui/src/components/toast/global_toast_list'; import React from 'react'; -import { TraceAnalyticsComponentDeps, TraceAnalyticsMode } from '../../home'; +import { DataSourceOption } from '../../../../../../../src/plugins/data_source_management/public/components/data_source_menu/types'; +import { TraceAnalyticsComponentDeps } from '../../home'; import { DashboardContent } from './dashboard_content'; import { DataSourcePicker } from './mode_picker'; @@ -20,6 +21,7 @@ export interface DashboardProps extends TraceAnalyticsComponentDeps { text?: React.ReactChild | undefined, side?: string | undefined ) => void; + dataSourceMDSId: DataSourceOption[]; } export function Dashboard(props: DashboardProps) { diff --git a/public/components/trace_analytics/components/dashboard/dashboard_content.tsx b/public/components/trace_analytics/components/dashboard/dashboard_content.tsx index 1766435747..521ad0ccc7 100644 --- a/public/components/trace_analytics/components/dashboard/dashboard_content.tsx +++ b/public/components/trace_analytics/components/dashboard/dashboard_content.tsx @@ -8,6 +8,7 @@ import dateMath from '@elastic/datemath'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import _ from 'lodash'; import React, { useEffect, useState } from 'react'; +import { useToast } from '../../../../../public/components/common/toast'; import { handleDashboardErrorRatePltRequest, handleDashboardRequest, @@ -15,25 +16,21 @@ import { handleJaegerDashboardRequest, handleJaegerErrorDashboardRequest, } from '../../requests/dashboard_request_handler'; -import { handleServiceMapRequest } from '../../requests/services_request_handler'; -import { FilterType } from '../common/filters/filters'; import { getValidFilterFields } from '../common/filters/filter_helpers'; +import { FilterType } from '../common/filters/filters'; import { + MissingConfigurationMessage, filtersToDsl, getPercentileFilter, milliToNanoSec, minFixedInterval, - MissingConfigurationMessage, processTimeStamp, } from '../common/helper_functions'; import { ErrorRatePlt } from '../common/plots/error_rate_plt'; -import { ServiceMap, ServiceObject } from '../common/plots/service_map'; import { ThroughputPlt } from '../common/plots/throughput_plt'; -import { SearchBar } from '../common/search_bar'; import { DashboardProps } from './dashboard'; import { DashboardTable } from './dashboard_table'; import { TopGroupsPage } from './top_groups_page'; -import { useToast } from '../../../../../public/components/common/toast'; export function DashboardContent(props: DashboardProps) { const { @@ -55,6 +52,7 @@ export function DashboardContent(props: DashboardProps) { dataPrepperIndicesExist, jaegerIndicesExist, toasts, + dataSourceMDSId, } = props; const [tableItems, setTableItems] = useState([]); const [jaegerTableItems, setJaegerTableItems] = useState([]); @@ -173,6 +171,7 @@ export function DashboardContent(props: DashboardProps) { // setToast!('Query took too long to execute.', 'danger', 'Reduce time range or filter your data. If issue persists, consider increasing your cluster size.'); // } // }, + dataSourceMDSId[0].id, setPercentileMap ).finally(() => setLoading(false)); handleJaegerErrorDashboardRequest( @@ -189,9 +188,11 @@ export function DashboardContent(props: DashboardProps) { // setToast!('Query took too long to execute.', 'danger', 'Reduce time range or filter your data. If issue persists, consider increasing your cluster size.'); // } // }, + dataSourceMDSId[0].id, setPercentileMap ).finally(() => setLoading(false)); } else if (mode === 'data_prepper') { + console.log(dataSourceMDSId, 'traces page'); handleDashboardRequest( http, DSL, @@ -201,6 +202,7 @@ export function DashboardContent(props: DashboardProps) { setTableItems, mode, () => setShowTimeoutToast(true), + dataSourceMDSId[0].id, setPercentileMap ).then(() => setLoading(false)); // service map should not be filtered by service name (https://github.com/opensearch-project/observability/issues/442) @@ -216,7 +218,8 @@ export function DashboardContent(props: DashboardProps) { fixedInterval, throughputPltItems, setThroughputPltItems, - mode + mode, + dataSourceMDSId[0].id ); handleDashboardErrorRatePltRequest( @@ -225,7 +228,8 @@ export function DashboardContent(props: DashboardProps) { fixedInterval, errorRatePltItems, setErrorRatePltItems, - mode + mode, + dataSourceMDSId[0].id ); }; diff --git a/public/components/trace_analytics/components/services/__tests__/__snapshots__/service_view.test.tsx.snap b/public/components/trace_analytics/components/services/__tests__/__snapshots__/service_view.test.tsx.snap index c2ab99780c..0bea2dcc22 100644 --- a/public/components/trace_analytics/components/services/__tests__/__snapshots__/service_view.test.tsx.snap +++ b/public/components/trace_analytics/components/services/__tests__/__snapshots__/service_view.test.tsx.snap @@ -235,6 +235,7 @@ exports[`Service view component renders service view 1`] = `
{ setEndTime={setEndTime} addFilter={addFilter} mode="data_prepper" + dataSourceMDSId={[{ id: '', label: '' }]} /> ); diff --git a/public/components/trace_analytics/components/services/__tests__/services.test.tsx b/public/components/trace_analytics/components/services/__tests__/services.test.tsx index 5dca84b918..e4f782ed34 100644 --- a/public/components/trace_analytics/components/services/__tests__/services.test.tsx +++ b/public/components/trace_analytics/components/services/__tests__/services.test.tsx @@ -56,6 +56,7 @@ describe('Services component', () => { mode="data_prepper" dataPrepperIndicesExist={true} modes={modes} + dataSourceMDSId={[{ id: '', label: '' }]} /> ); @@ -102,6 +103,7 @@ describe('Services component', () => { mode="data_prepper" dataPrepperIndicesExist={true} modes={modes} + dataSourceMDSId={[{ id: '', label: '' }]} /> ); @@ -149,6 +151,7 @@ describe('Services component', () => { dataPrepperIndicesExist={false} jaegerIndicesExist={true} modes={modes} + dataSourceMDSId={[{ id: '', label: '' }]} /> ); diff --git a/public/components/trace_analytics/components/services/service_view.tsx b/public/components/trace_analytics/components/services/service_view.tsx index e81869d11a..dc88dcb9ed 100644 --- a/public/components/trace_analytics/components/services/service_view.tsx +++ b/public/components/trace_analytics/components/services/service_view.tsx @@ -20,21 +20,29 @@ import { } from '@elastic/eui'; import _ from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; -import { TraceAnalyticsComponentDeps, TraceAnalyticsMode } from '../../home'; +import { + DataSourceManagementPluginSetup, + DataSourceViewConfig, +} from '../../../../../../../src/plugins/data_source_management/public'; +import { DataSourceOption } from '../../../../../../../src/plugins/data_source_management/public/components/data_source_menu/types'; +import { TraceAnalyticsComponentDeps } from '../../home'; import { handleServiceMapRequest, handleServiceViewRequest, } from '../../requests/services_request_handler'; import { FilterType } from '../common/filters/filters'; -import { filtersToDsl, PanelTitle, processTimeStamp } from '../common/helper_functions'; +import { PanelTitle, filtersToDsl, processTimeStamp } from '../common/helper_functions'; import { ServiceMap, ServiceObject } from '../common/plots/service_map'; -import { renderDatePicker, SearchBarProps } from '../common/search_bar'; +import { SearchBarProps, renderDatePicker } from '../common/search_bar'; import { SpanDetailFlyout } from '../traces/span_detail_flyout'; import { SpanDetailTable } from '../traces/span_detail_table'; interface ServiceViewProps extends TraceAnalyticsComponentDeps { serviceName: string; addFilter: (filter: FilterType) => void; + dataSourceMDSId: DataSourceOption[]; + dataSourceManagement: DataSourceManagementPluginSetup; + dataSourceEnabled: boolean; } export function ServiceView(props: ServiceViewProps) { @@ -54,9 +62,23 @@ export function ServiceView(props: ServiceViewProps) { processTimeStamp(props.startTime, mode), processTimeStamp(props.endTime, mode) ); - handleServiceViewRequest(props.serviceName, props.http, DSL, setFields, mode); + handleServiceViewRequest( + props.serviceName, + props.http, + DSL, + setFields, + mode, + props.dataSourceMDSId[0].id + ); if (mode === 'data_prepper') { - handleServiceMapRequest(props.http, DSL, mode, setServiceMap, props.serviceName); + handleServiceMapRequest( + props.http, + DSL, + mode, + props.dataSourceMDSId[0].id, + setServiceMap, + props.serviceName + ); } }; @@ -88,7 +110,7 @@ export function ServiceView(props: ServiceViewProps) { setStartTime: SearchBarProps['setStartTime'], endTime: SearchBarProps['endTime'], setEndTime: SearchBarProps['setEndTime'], - addFilter: (filter: FilterType) => void + _addFilter: (filter: FilterType) => void ) => { return ( <> @@ -104,110 +126,122 @@ export function ServiceView(props: ServiceViewProps) { ); }; - + const DataSourceMenu = props.dataSourceManagement?.ui?.getDataSourceMenu(); const renderOverview = () => { return ( - - - - - - - - Name - - {props.serviceName || '-'} - - - {mode === 'data_prepper' ? ( + <> + {props.dataSourceEnabled && ( + + )} + + + + + + - Number of connected services + Name - {fields.number_of_connected_services !== undefined - ? fields.number_of_connected_services - : 0} + {props.serviceName || '-'} - ) : ( - - )} - {mode === 'data_prepper' ? ( + {mode === 'data_prepper' ? ( + + Number of connected services + + {fields.number_of_connected_services !== undefined + ? fields.number_of_connected_services + : 0} + + + ) : ( + + )} + {mode === 'data_prepper' ? ( + + Connected services + + {fields.connected_services && fields.connected_services.length + ? fields.connected_services + .map((service: string) => ( + + {service} + + )) + .reduce((prev: React.ReactNode, curr: React.ReactNode) => { + return [prev, ', ', curr]; + }) + : '-'} + + + ) : ( + + )} + + + + - Connected services + Average duration (ms) - {fields.connected_services && fields.connected_services.length - ? fields.connected_services - .map((service: string) => ( - - {service} - - )) - .reduce((prev: React.ReactNode, curr: React.ReactNode) => { - return [prev, ', ', curr]; - }) + {fields.average_latency !== undefined ? fields.average_latency : '-'} + + + + Error rate + + {fields.error_rate !== undefined + ? _.round(fields.error_rate, 2).toString() + '%' : '-'} - ) : ( - - )} - - - - - - Average duration (ms) - - {fields.average_latency !== undefined ? fields.average_latency : '-'} - - - - Error rate - - {fields.error_rate !== undefined - ? _.round(fields.error_rate, 2).toString() + '%' - : '-'} - - - - Request rate - - {fields.throughput !== undefined ? ( - - ) : ( - '-' - )} - - - - Traces - - {fields.traces === 0 || fields.traces ? ( - { - setRedirect(true); - props.addFilter({ - field: 'process.serviceName', - operator: 'is', - value: props.serviceName, - inverted: false, - disabled: false, - }); - location.assign('#/traces'); - }} - > - - - ) : ( - '-' - )} - - - - - - - + + Request rate + + {fields.throughput !== undefined ? ( + + ) : ( + '-' + )} + + + + Traces + + {fields.traces === 0 || fields.traces ? ( + { + setRedirect(true); + props.addFilter({ + field: 'process.serviceName', + operator: 'is', + value: props.serviceName, + inverted: false, + disabled: false, + }); + location.assign('#/traces'); + }} + > + + + ) : ( + '-' + )} + + + + + + + + ); }; @@ -321,6 +355,7 @@ export function ServiceView(props: ServiceViewProps) { openFlyout={(spanId: string) => setCurrentSpan(spanId)} setTotal={setTotal} mode={mode} + dataSourceMDSId={props.dataSourceMDSId[0].id} /> ), [DSL, setCurrentSpan] @@ -374,6 +409,7 @@ export function ServiceView(props: ServiceViewProps) { closeFlyout={() => setCurrentSpan('')} addSpanFilter={addSpanFilter} mode={mode} + dataSourceMDSId={props.dataSourceMDSId[0].id} /> )} diff --git a/public/components/trace_analytics/components/services/services.tsx b/public/components/trace_analytics/components/services/services.tsx index 2029cdfb82..412d3c476a 100644 --- a/public/components/trace_analytics/components/services/services.tsx +++ b/public/components/trace_analytics/components/services/services.tsx @@ -4,9 +4,9 @@ */ import { EuiBreadcrumb } from '@elastic/eui'; -import _ from 'lodash'; -import React from 'react'; import { Toast } from '@elastic/eui/src/components/toast/global_toast_list'; +import React from 'react'; +import { DataSourceOption } from '../../../../../../../src/plugins/data_source_management/public/components/data_source_menu/types'; import { TraceAnalyticsComponentDeps } from '../../home'; import { DataSourcePicker } from '../dashboard/mode_picker'; import { ServicesContent } from './services_content'; @@ -17,6 +17,7 @@ export interface ServicesProps extends TraceAnalyticsComponentDeps { traceColumnAction: any; page: 'services' | 'app'; toasts: Toast[]; + dataSourceMDSId: DataSourceOption[]; } export function Services(props: ServicesProps) { diff --git a/public/components/trace_analytics/components/services/services_content.tsx b/public/components/trace_analytics/components/services/services_content.tsx index 0552c567e8..2250fa793e 100644 --- a/public/components/trace_analytics/components/services/services_content.tsx +++ b/public/components/trace_analytics/components/services/services_content.tsx @@ -10,17 +10,15 @@ import React, { useEffect, useState } from 'react'; import { handleServiceMapRequest, handleServicesRequest, - handleTraceGroupsRequest, } from '../../requests/services_request_handler'; -import { FilterType } from '../common/filters/filters'; import { getValidFilterFields } from '../common/filters/filter_helpers'; +import { FilterType } from '../common/filters/filters'; import { filtersToDsl, processTimeStamp } from '../common/helper_functions'; import { ServiceMap, ServiceObject } from '../common/plots/service_map'; import { SearchBar } from '../common/search_bar'; +import { DashboardContent } from '../dashboard/dashboard_content'; import { ServicesProps } from './services'; import { ServicesTable } from './services_table'; -import { OptionType } from '../../../../../common/types/application_analytics'; -import { DashboardContent } from '../dashboard/dashboard_content'; export function ServicesContent(props: ServicesProps) { const { @@ -43,6 +41,7 @@ export function ServicesContent(props: ServicesProps) { mode, dataPrepperIndicesExist, jaegerIndicesExist, + dataSourceMDSId, } = props; const [tableItems, setTableItems] = useState([]); @@ -107,11 +106,12 @@ export function ServicesContent(props: ServicesProps) { (must: any) => must?.term?.serviceName == null ); await Promise.all([ - handleServicesRequest(http, DSL, setTableItems, mode), + handleServicesRequest(http, DSL, setTableItems, mode, dataSourceMDSId[0].id), handleServiceMapRequest( http, serviceMapDSL, mode, + dataSourceMDSId[0].id, setServiceMap, currService || filteredService ), diff --git a/public/components/trace_analytics/components/traces/__tests__/__snapshots__/trace_view.test.tsx.snap b/public/components/trace_analytics/components/traces/__tests__/__snapshots__/trace_view.test.tsx.snap index 0a58afeeb2..3874c4a497 100644 --- a/public/components/trace_analytics/components/traces/__tests__/__snapshots__/trace_view.test.tsx.snap +++ b/public/components/trace_analytics/components/traces/__tests__/__snapshots__/trace_view.test.tsx.snap @@ -137,6 +137,7 @@ exports[`Trace view component renders trace view 1`] = ` "table": Array [], } } + dataSourceMDSId="" http={[MockFunction]} mode="data_prepper" setData={[Function]} diff --git a/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap b/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap index eb5619545b..57d673b457 100644 --- a/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap +++ b/public/components/trace_analytics/components/traces/__tests__/__snapshots__/traces.test.tsx.snap @@ -152,6 +152,14 @@ exports[`Traces component renders empty traces page 1`] = ` } } dataPrepperIndicesExist={true} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} @@ -469,6 +477,14 @@ exports[`Traces component renders empty traces page 1`] = ` } } dataPrepperIndicesExist={true} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} @@ -1638,6 +1654,14 @@ exports[`Traces component renders jaeger traces page 1`] = ` } } dataPrepperIndicesExist={false} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} @@ -1956,6 +1980,14 @@ exports[`Traces component renders jaeger traces page 1`] = ` } } dataPrepperIndicesExist={false} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} @@ -3132,6 +3164,14 @@ exports[`Traces component renders traces page 1`] = ` } } dataPrepperIndicesExist={true} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} @@ -3449,6 +3489,14 @@ exports[`Traces component renders traces page 1`] = ` } } dataPrepperIndicesExist={true} + dataSourceMDSId={ + Array [ + Object { + "id": "", + "label": "", + }, + ] + } endTime="now" filters={Array []} http={[MockFunction]} diff --git a/public/components/trace_analytics/components/traces/__tests__/trace_view.test.tsx b/public/components/trace_analytics/components/traces/__tests__/trace_view.test.tsx index be3d1c1b93..6d62bd5b93 100644 --- a/public/components/trace_analytics/components/traces/__tests__/trace_view.test.tsx +++ b/public/components/trace_analytics/components/traces/__tests__/trace_view.test.tsx @@ -21,6 +21,7 @@ describe('Trace view component', () => { parentBreadcrumbs={[{ text: 'test', href: 'test#/' }]} traceId="test" mode="data_prepper" + dataSourceMDSId={[{ id: '', label: '' }]} /> ); expect(wrapper).toMatchSnapshot(); diff --git a/public/components/trace_analytics/components/traces/__tests__/traces.test.tsx b/public/components/trace_analytics/components/traces/__tests__/traces.test.tsx index cfd56c99f1..6fb61be1db 100644 --- a/public/components/trace_analytics/components/traces/__tests__/traces.test.tsx +++ b/public/components/trace_analytics/components/traces/__tests__/traces.test.tsx @@ -3,9 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React from 'react'; import { configure, mount } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; +import React from 'react'; import { Traces } from '..'; import { coreStartMock } from '../../../../../../test/__mocks__/coreMocks'; @@ -54,6 +54,7 @@ describe('Traces component', () => { mode="data_prepper" dataPrepperIndicesExist={true} modes={modes} + dataSourceMDSId={[{ id: '', label: '' }]} /> ); @@ -98,6 +99,7 @@ describe('Traces component', () => { page="traces" modes={modes} dataPrepperIndicesExist={true} + dataSourceMDSId={[{ id: '', label: '' }]} /> ); @@ -143,6 +145,7 @@ describe('Traces component', () => { modes={modes} dataPrepperIndicesExist={false} jaegerIndicesExist={true} + dataSourceMDSId={[{ id: '', label: '' }]} /> ); diff --git a/public/components/trace_analytics/components/traces/span_detail_flyout.tsx b/public/components/trace_analytics/components/traces/span_detail_flyout.tsx index b569a0141e..5ac3f3cdb2 100644 --- a/public/components/trace_analytics/components/traces/span_detail_flyout.tsx +++ b/public/components/trace_analytics/components/traces/span_detail_flyout.tsx @@ -66,12 +66,13 @@ export function SpanDetailFlyout(props: { closeFlyout: () => void; addSpanFilter: (field: string, value: any) => void; mode: TraceAnalyticsMode; + dataSourceMDSId: string; }) { const { mode } = props; const [span, setSpan] = useState({}); useEffect(() => { - handleSpansFlyoutRequest(props.http, props.spanId, setSpan, mode); + handleSpansFlyoutRequest(props.http, props.spanId, setSpan, mode, props.dataSourceMDSId); }, [props.spanId]); const getListItem = ( diff --git a/public/components/trace_analytics/components/traces/span_detail_panel.tsx b/public/components/trace_analytics/components/traces/span_detail_panel.tsx index 4c2ebedb63..ba24c78bc7 100644 --- a/public/components/trace_analytics/components/traces/span_detail_panel.tsx +++ b/public/components/trace_analytics/components/traces/span_detail_panel.tsx @@ -27,7 +27,8 @@ export function SpanDetailPanel(props: { http: HttpSetup; traceId: string; colorMap: any; - mode: TraceAnalyticsMode + mode: TraceAnalyticsMode; + dataSourceMDSId: string; page?: string; openSpanFlyout?: any; data?: { gantt: any[]; table: any[]; ganttMaxX: number }; @@ -81,41 +82,52 @@ export function SpanDetailPanel(props: { if (_.isEmpty(props.colorMap)) return; const refreshDSL = spanFiltersToDSL(); setDSL(refreshDSL); - handleSpansGanttRequest(props.traceId, props.http, setData, props.colorMap, refreshDSL, mode); + handleSpansGanttRequest( + props.traceId, + props.http, + setData, + props.colorMap, + refreshDSL, + mode, + props.dataSourceMDSId + ); }, 150); const spanFiltersToDSL = () => { - const spanDSL: any = mode === 'jaeger' ? { - query: { - bool: { - must: [ - { - term: { - traceID: props.traceId, + const spanDSL: any = + mode === 'jaeger' + ? { + query: { + bool: { + must: [ + { + term: { + traceID: props.traceId, + }, + }, + ], + filter: [], + should: [], + must_not: [], }, }, - ], - filter: [], - should: [], - must_not: [], - }, - }, - } : { - query: { - bool: { - must: [ - { - term: { - traceId: props.traceId, + } + : { + query: { + bool: { + must: [ + { + term: { + traceId: props.traceId, + }, + }, + ], + filter: [], + should: [], + must_not: [], }, }, - ], - filter: [], - should: [], - must_not: [], - }, - }, - }; + }; spanFilters.map(({ field, value }) => { if (value != null) { spanDSL.query.bool.must.push({ @@ -164,10 +176,10 @@ export function SpanDetailPanel(props: { }; }; - const layout = useMemo( - () => getSpanDetailLayout(data.gantt, data.ganttMaxX), - [data.gantt, data.ganttMaxX] - ); + const layout = useMemo(() => getSpanDetailLayout(data.gantt, data.ganttMaxX), [ + data.gantt, + data.ganttMaxX, + ]); const [currentSpan, setCurrentSpan] = useState(''); @@ -239,7 +251,7 @@ export function SpanDetailPanel(props: { return ( <> - + diff --git a/public/components/trace_analytics/components/traces/span_detail_table.tsx b/public/components/trace_analytics/components/traces/span_detail_table.tsx index 30f60010f8..90a0e0e80f 100644 --- a/public/components/trace_analytics/components/traces/span_detail_table.tsx +++ b/public/components/trace_analytics/components/traces/span_detail_table.tsx @@ -12,7 +12,7 @@ import { HttpSetup } from '../../../../../../../src/core/public'; import { TRACE_ANALYTICS_DATE_FORMAT } from '../../../../../common/constants/trace_analytics'; import { TraceAnalyticsMode } from '../../home'; import { handleSpansRequest } from '../../requests/traces_request_handler'; -import { microToMilliSec, nanoToMilliSec, NoMatchMessage } from '../common/helper_functions'; +import { NoMatchMessage, microToMilliSec, nanoToMilliSec } from '../common/helper_functions'; interface SpanDetailTableProps { http: HttpSetup; @@ -21,6 +21,7 @@ interface SpanDetailTableProps { mode: TraceAnalyticsMode; DSL?: any; setTotal?: (total: number) => void; + dataSourceMDSId: string; } export interface SpanSearchParams { @@ -50,7 +51,15 @@ export function SpanDetailTable(props: SpanDetailTableProps) { size: tableParams.size, sortingColumns: tableParams.sortingColumns.map(({ id, direction }) => ({ [id]: direction })), }; - handleSpansRequest(props.http, setItems, setTotal, spanSearchParams, props.DSL, mode); + handleSpansRequest( + props.http, + setItems, + setTotal, + spanSearchParams, + props.DSL, + mode, + props.dataSourceMDSId + ); }, [tableParams, props.DSL]); useEffect(() => { diff --git a/public/components/trace_analytics/components/traces/trace_view.tsx b/public/components/trace_analytics/components/traces/trace_view.tsx index c150a19ff5..c1c5e0a9c3 100644 --- a/public/components/trace_analytics/components/traces/trace_view.tsx +++ b/public/components/trace_analytics/components/traces/trace_view.tsx @@ -20,6 +20,12 @@ import { } from '@elastic/eui'; import _ from 'lodash'; import React, { useEffect, useState } from 'react'; +import { MountPoint } from '../../../../../../../src/core/public'; +import { + DataSourceManagementPluginSetup, + DataSourceViewConfig, +} from '../../../../../../../src/plugins/data_source_management/public'; +import { DataSourceOption } from '../../../../../../../src/plugins/data_source_management/public/components/data_source_menu/types'; import { TraceAnalyticsCoreDeps, TraceAnalyticsMode } from '../../home'; import { handleServiceMapRequest } from '../../requests/services_request_handler'; import { @@ -27,7 +33,7 @@ import { handleServicesPieChartRequest, handleTraceViewRequest, } from '../../requests/traces_request_handler'; -import { filtersToDsl, PanelTitle, processTimeStamp } from '../common/helper_functions'; +import { PanelTitle, filtersToDsl, processTimeStamp } from '../common/helper_functions'; import { ServiceMap, ServiceObject } from '../common/plots/service_map'; import { ServiceBreakdownPanel } from './service_breakdown_panel'; import { SpanDetailPanel } from './span_detail_panel'; @@ -35,6 +41,9 @@ import { SpanDetailPanel } from './span_detail_panel'; interface TraceViewProps extends TraceAnalyticsCoreDeps { traceId: string; mode: TraceAnalyticsMode; + dataSourceMDSId: DataSourceOption[]; + dataSourceManagement: DataSourceManagementPluginSetup; + setActionMenu: (menuMount: MountPoint | undefined) => void; } export function TraceView(props: TraceViewProps) { @@ -51,6 +60,7 @@ export function TraceView(props: TraceViewProps) { ); }; + const DataSourceMenu = props.dataSourceManagement?.ui?.getDataSourceMenu(); const renderOverview = (fields: any) => { return ( @@ -160,16 +170,31 @@ export function TraceView(props: TraceViewProps) { processTimeStamp('now', mode), page ); - handleTraceViewRequest(props.traceId, props.http, fields, setFields, mode); - handlePayloadRequest(props.traceId, props.http, payloadData, setPayloadData, mode); + handleTraceViewRequest( + props.traceId, + props.http, + fields, + setFields, + mode, + props.dataSourceMDSId[0].id + ); + handlePayloadRequest( + props.traceId, + props.http, + payloadData, + setPayloadData, + mode, + props.dataSourceMDSId[0].id + ); handleServicesPieChartRequest( props.traceId, props.http, setServiceBreakdownData, setColorMap, - mode + mode, + props.dataSourceMDSId[0].id ); - handleServiceMapRequest(props.http, DSL, mode, setServiceMap); + handleServiceMapRequest(props.http, DSL, mode, props.dataSourceMDSId[0].id, setServiceMap); }; useEffect(() => { @@ -222,10 +247,19 @@ export function TraceView(props: TraceViewProps) { ]); refresh(); }, [props.mode]); - return ( <> + {props.dataSourceEnabled && ( + + )} {renderTitle(props.traceId)} @@ -246,6 +280,7 @@ export function TraceView(props: TraceViewProps) { mode={mode} data={ganttData} setData={setGanttData} + dataSourceMDSId={props.dataSourceMDSId[0].id} /> diff --git a/public/components/trace_analytics/components/traces/traces.tsx b/public/components/trace_analytics/components/traces/traces.tsx index b000a39547..b21034999e 100644 --- a/public/components/trace_analytics/components/traces/traces.tsx +++ b/public/components/trace_analytics/components/traces/traces.tsx @@ -5,6 +5,7 @@ import { EuiBreadcrumb } from '@elastic/eui'; import React from 'react'; +import { DataSourceOption } from '../../../../../../../src/plugins/data_source_management/public/components/data_source_menu/types'; import { TraceAnalyticsComponentDeps } from '../../home'; import { DataSourcePicker } from '../dashboard/mode_picker'; import { TracesContent } from './traces_content'; @@ -13,6 +14,7 @@ export interface TracesProps extends TraceAnalyticsComponentDeps { page: 'traces' | 'app'; childBreadcrumbs: EuiBreadcrumb[]; traceIdColumnAction: any; + dataSourceMDSId: DataSourceOption[]; } export function Traces(props: TracesProps) { diff --git a/public/components/trace_analytics/components/traces/traces_content.tsx b/public/components/trace_analytics/components/traces/traces_content.tsx index 2efc70ec76..7478fb5299 100644 --- a/public/components/trace_analytics/components/traces/traces_content.tsx +++ b/public/components/trace_analytics/components/traces/traces_content.tsx @@ -6,6 +6,7 @@ import { EuiSpacer, PropertySort } from '@elastic/eui'; import React, { useEffect, useState } from 'react'; +import { DataSourceViewConfig } from '../../../../../../../src/plugins/data_source_management/public'; import { handleTracesRequest } from '../../requests/traces_request_handler'; import { getValidFilterFields } from '../common/filters/filter_helpers'; import { filtersToDsl, processTimeStamp } from '../common/helper_functions'; @@ -33,11 +34,14 @@ export function TracesContent(props: TracesProps) { mode, dataPrepperIndicesExist, jaegerIndicesExist, + dataSourceManagement, + dataSourceMDSId, } = props; const [tableItems, setTableItems] = useState([]); const [redirect, setRedirect] = useState(true); const [loading, setLoading] = useState(false); + const DataSourceMenu = dataSourceManagement?.ui?.getDataSourceMenu(); useEffect(() => { chrome.setBreadcrumbs([parentBreadcrumb, ...childBreadcrumbs]); const validFilters = getValidFilterFields(mode, 'traces'); @@ -78,12 +82,31 @@ export function TracesContent(props: TracesProps) { processTimeStamp(endTime, mode), page ); - await handleTracesRequest(http, DSL, timeFilterDSL, tableItems, setTableItems, mode, sort); + await handleTracesRequest( + http, + DSL, + timeFilterDSL, + tableItems, + setTableItems, + mode, + props.dataSourceMDSId[0].id, + sort + ); setLoading(false); }; return ( <> + {props.dataSourceEnabled && ( + + )} void; + savedObjectsMDSClient: SavedObjectsStart; } interface HomeProps extends RouteComponentProps, TraceAnalyticsCoreDeps {} @@ -76,15 +92,21 @@ export const Home = (props: HomeProps) => { }; const [toasts, setToasts] = useState([]); - const setToast = (title: string, color = 'success', text?: ReactChild, side?: string) => { + const _setToast = (title: string, color = 'success', text?: ReactChild, _side?: string) => { if (!text) text = ''; setToasts([...toasts, { id: new Date().toISOString(), title, text, color } as Toast]); }; + const [dataSourceMDSId, setDataSourceMDSId] = useState([{ id: '', label: '' }]); + useEffect(() => { - handleDataPrepperIndicesExistRequest(props.http, setDataPrepperIndicesExist); - handleJaegerIndicesExistRequest(props.http, setJaegerIndicesExist); - }, []); + handleDataPrepperIndicesExistRequest( + props.http, + setDataPrepperIndicesExist, + dataSourceMDSId[0].id + ); + handleJaegerIndicesExistRequest(props.http, setJaegerIndicesExist, dataSourceMDSId[0].id); + }, [dataSourceMDSId]); const modes = [ { id: 'jaeger', title: 'Jaeger', 'data-test-subj': 'jaeger-mode' }, @@ -131,7 +153,6 @@ export const Home = (props: HomeProps) => { location.assign(`#/traces/${encodeURIComponent(item)}`); const [appConfigs, _] = useState([]); - const commonProps: TraceAnalyticsComponentDeps = { parentBreadcrumb: props.parentBreadcrumb, http: props.http, @@ -152,10 +173,37 @@ export const Home = (props: HomeProps) => { }, jaegerIndicesExist, dataPrepperIndicesExist, + notifications: props.notifications, + dataSourceEnabled: props.dataSourceEnabled, + dataSourceManagement: props.dataSourceManagement, + setActionMenu: props.setActionMenu, + savedObjectsMDSClient: props.savedObjectsMDSClient, + }; + const onSelectedDataSource = async (dataSources: DataSourceOption[]) => { + const { id = '', label = '' } = dataSources[0] || {}; + if (dataSourceMDSId[0].id !== id || dataSourceMDSId[0].label !== label) { + setDataSourceMDSId([{ id, label }]); + } }; + const DataSourceMenu = props.dataSourceManagement?.ui?.getDataSourceMenu< + DataSourceSelectableConfig + >(); return ( <> + {props.dataSourceEnabled && ( + + )} { @@ -167,12 +215,13 @@ export const Home = (props: HomeProps) => { ( + render={(_routerProps) => ( @@ -187,13 +236,19 @@ export const Home = (props: HomeProps) => { http={props.http} traceId={decodeURIComponent(routerProps.match.params.id)} mode={mode} + dataSourceMDSId={dataSourceMDSId} + dataSourceManagement={props.dataSourceManagement} + setActionMenu={props.setActionMenu} + notifications={props.notifications} + dataSourceEnabled={props.dataSourceEnabled} + savedObjectsMDSClient={props.savedObjectsMDSClient} /> )} /> ( + render={(_routerProps) => ( { nameColumnAction={nameColumnAction} traceColumnAction={traceColumnAction} toasts={toasts} + dataSourceMDSId={dataSourceMDSId} {...commonProps} /> @@ -225,6 +281,7 @@ export const Home = (props: HomeProps) => { const newFilters = [...filters, filter]; setFiltersWithStorage(newFilters); }} + dataSourceMDSId={dataSourceMDSId} /> )} /> diff --git a/public/components/trace_analytics/requests/dashboard_request_handler.ts b/public/components/trace_analytics/requests/dashboard_request_handler.ts index d9316bca07..33b0d22de3 100644 --- a/public/components/trace_analytics/requests/dashboard_request_handler.ts +++ b/public/components/trace_analytics/requests/dashboard_request_handler.ts @@ -6,7 +6,11 @@ import _ from 'lodash'; import moment from 'moment'; import { TRACE_ANALYTICS_PLOTS_DATE_FORMAT } from '../../../../common/constants/trace_analytics'; -import { fixedIntervalToMilli, microToMilliSec, nanoToMilliSec } from '../components/common/helper_functions'; +import { + fixedIntervalToMilli, + microToMilliSec, + nanoToMilliSec, +} from '../components/common/helper_functions'; import { getDashboardQuery, getDashboardThroughputPltQuery, @@ -29,6 +33,7 @@ export const handleDashboardRequest = async ( setItems, mode, setShowTimeoutToast, + dataSourceMDSId?, setPercentileMap? ) => { // latency_variance should only be affected by timefilter @@ -36,7 +41,8 @@ export const handleDashboardRequest = async ( http, timeFilterDSL, getDashboardTraceGroupPercentiles(mode), - mode + mode, + dataSourceMDSId ) .then((response) => { const map: any = {}; @@ -50,7 +56,13 @@ export const handleDashboardRequest = async ( .catch((error) => console.error(error)); if (setPercentileMap) setPercentileMap(latencyVariances); - const latencyTrends = await handleDslRequest(http, latencyTrendDSL, getLatencyTrendQuery(), mode, setShowTimeoutToast) + const latencyTrends = await handleDslRequest( + http, + latencyTrendDSL, + getLatencyTrendQuery(), + mode, + setShowTimeoutToast + ) .then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -105,7 +117,7 @@ export const handleDashboardRequest = async ( }) .catch((error) => console.error(error)); - await handleDslRequest(http, DSL, getDashboardQuery(), mode, setShowTimeoutToast) + await handleDslRequest(http, DSL, getDashboardQuery(), mode, dataSourceMDSId, setShowTimeoutToast) .then((response) => { return Promise.all( response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -136,9 +148,17 @@ export const handleJaegerDashboardRequest = async ( setItems, mode, setShowTimeoutToast, + dataSourceMDSId?, setPercentileMap? ) => { - const latencyTrends = await handleDslRequest(http, latencyTrendDSL, getJaegerLatencyTrendQuery(), mode, setShowTimeoutToast) + const latencyTrends = await handleDslRequest( + http, + latencyTrendDSL, + getJaegerLatencyTrendQuery(), + mode, + dataSourceMDSId, + setShowTimeoutToast + ) .then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -195,7 +215,14 @@ export const handleJaegerDashboardRequest = async ( console.error(error); }); - await handleDslRequest(http, DSL, getJaegerDashboardQuery(), mode, setShowTimeoutToast) + await handleDslRequest( + http, + DSL, + getJaegerDashboardQuery(), + mode, + dataSourceMDSId, + setShowTimeoutToast + ) .then((response) => { return Promise.all( response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -215,10 +242,13 @@ export const handleJaegerDashboardRequest = async ( const latencies = await handleDslRequest( http, timeFilterDSL, - getDashboardTraceGroupPercentiles(mode, newItems.map(a => a.dashboard_trace_group_name)), + getDashboardTraceGroupPercentiles( + mode, + newItems.map((a) => a.dashboard_trace_group_name) + ), mode, true, - setShowTimeoutToast, + setShowTimeoutToast ) .then((response) => { const map: any = {}; @@ -230,10 +260,10 @@ export const handleJaegerDashboardRequest = async ( return map; }) .catch((error) => console.error(error)); - newItems.forEach((item) => { - item.dashboard_latency_variance = latencies[item.dashboard_key_as_string] - }) - setItems(newItems); + newItems.forEach((item) => { + item.dashboard_latency_variance = latencies[item.dashboard_key_as_string]; + }); + setItems(newItems); }) .catch((error) => console.error(error)); }; @@ -247,9 +277,17 @@ export const handleJaegerErrorDashboardRequest = async ( setItems, mode, setShowTimeoutToast, + dataSourceMDSId?, setPercentileMap? ) => { - const errorTrends = await handleDslRequest(http, latencyTrendDSL, getJaegerErrorTrendQuery(), mode, setShowTimeoutToast) + const errorTrends = await handleDslRequest( + http, + latencyTrendDSL, + getJaegerErrorTrendQuery(), + mode, + dataSourceMDSId, + setShowTimeoutToast + ) .then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -304,7 +342,14 @@ export const handleJaegerErrorDashboardRequest = async ( }) .catch((error) => console.error(error)); - await handleDslRequest(http, DSL, getJaegerErrorDashboardQuery(), mode, setShowTimeoutToast) + await handleDslRequest( + http, + DSL, + getJaegerErrorDashboardQuery(), + mode, + dataSourceMDSId, + setShowTimeoutToast + ) .then((response) => { return Promise.all( response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -325,8 +370,22 @@ export const handleJaegerErrorDashboardRequest = async ( .catch((error) => console.error(error)); }; -export const handleDashboardThroughputPltRequest = (http, DSL, fixedInterval, items, setItems, mode) => { - return handleDslRequest(http, DSL, getDashboardThroughputPltQuery(mode, fixedInterval), mode) +export const handleDashboardThroughputPltRequest = ( + http, + DSL, + fixedInterval, + items, + setItems, + mode, + dataSourceMDSId? +) => { + return handleDslRequest( + http, + DSL, + getDashboardThroughputPltQuery(mode, fixedInterval), + mode, + dataSourceMDSId + ) .then((response) => { const buckets = response.aggregations.throughput.buckets; const texts = buckets.map( @@ -358,8 +417,22 @@ export const handleDashboardThroughputPltRequest = (http, DSL, fixedInterval, it .catch((error) => console.error(error)); }; -export const handleDashboardErrorRatePltRequest = (http, DSL, fixedInterval, items, setItems, mode) => { - return handleDslRequest(http, DSL, getErrorRatePltQuery(mode, fixedInterval), mode) +export const handleDashboardErrorRatePltRequest = ( + http, + DSL, + fixedInterval, + items, + setItems, + mode, + dataSourceMDSId? +) => { + return handleDslRequest( + http, + DSL, + getErrorRatePltQuery(mode, fixedInterval), + mode, + dataSourceMDSId + ) .then((response) => { const buckets = response.aggregations.error_rate.buckets; const texts = buckets.map( @@ -389,4 +462,4 @@ export const handleDashboardErrorRatePltRequest = (http, DSL, fixedInterval, ite setItems({ items: newItems, fixedInterval: fixedInterval }); }) .catch((error) => console.error(error)); -}; \ No newline at end of file +}; diff --git a/public/components/trace_analytics/requests/request_handler.ts b/public/components/trace_analytics/requests/request_handler.ts index bb687183d2..5babe0a33a 100644 --- a/public/components/trace_analytics/requests/request_handler.ts +++ b/public/components/trace_analytics/requests/request_handler.ts @@ -5,11 +5,11 @@ import { CoreStart } from '../../../../../../src/core/public'; import { - TRACE_ANALYTICS_DSL_ROUTE, + DATA_PREPPER_INDEX_NAME, + JAEGER_INDEX_NAME, TRACE_ANALYTICS_DATA_PREPPER_INDICES_ROUTE, + TRACE_ANALYTICS_DSL_ROUTE, TRACE_ANALYTICS_JAEGER_INDICES_ROUTE, - JAEGER_INDEX_NAME, - DATA_PREPPER_INDEX_NAME, } from '../../../../common/constants/trace_analytics'; import { TraceAnalyticsMode } from '../home'; @@ -18,6 +18,7 @@ export async function handleDslRequest( DSL: any, bodyQuery: any, mode: TraceAnalyticsMode, + dataSourceMDSId?: string, setShowTimeoutToast?: () => void ) { if (DSL?.query) { @@ -32,12 +33,16 @@ export async function handleDslRequest( if (!bodyQuery.index) { body = { ...bodyQuery, index: mode === 'jaeger' ? JAEGER_INDEX_NAME : DATA_PREPPER_INDEX_NAME }; } + const query = { + dataSourceMDSId: dataSourceMDSId, + }; if (setShowTimeoutToast) { const id = setTimeout(() => setShowTimeoutToast(), 25000); // 25 seconds try { return await http.post(TRACE_ANALYTICS_DSL_ROUTE, { body: JSON.stringify(body), + query, }); } catch (error) { console.error(error); @@ -45,10 +50,10 @@ export async function handleDslRequest( clearTimeout(id); } } else { - try { return await http.post(TRACE_ANALYTICS_DSL_ROUTE, { body: JSON.stringify(body), + query, }); } catch (error_1) { console.error(error_1); @@ -58,20 +63,32 @@ export async function handleDslRequest( export async function handleJaegerIndicesExistRequest( http: CoreStart['http'], - setJaegerIndicesExist + setJaegerIndicesExist, + dataSourceMDSId?: string ) { + const query = { + dataSourceMDSId: dataSourceMDSId, + }; http - .post(TRACE_ANALYTICS_JAEGER_INDICES_ROUTE) + .post(TRACE_ANALYTICS_JAEGER_INDICES_ROUTE, { + query, + }) .then((exists) => setJaegerIndicesExist(exists)) .catch(() => setJaegerIndicesExist(false)); } export async function handleDataPrepperIndicesExistRequest( http: CoreStart['http'], - setDataPrepperIndicesExist + setDataPrepperIndicesExist, + dataSourceMDSId?: string ) { + const query = { + dataSourceMDSId: dataSourceMDSId, + }; http - .post(TRACE_ANALYTICS_DATA_PREPPER_INDICES_ROUTE) + .post(TRACE_ANALYTICS_DATA_PREPPER_INDICES_ROUTE, { + query, + }) .then((exists) => setDataPrepperIndicesExist(exists)) .catch(() => setDataPrepperIndicesExist(false)); } diff --git a/public/components/trace_analytics/requests/services_request_handler.ts b/public/components/trace_analytics/requests/services_request_handler.ts index 2c0152dff2..2e81e1dfc1 100644 --- a/public/components/trace_analytics/requests/services_request_handler.ts +++ b/public/components/trace_analytics/requests/services_request_handler.ts @@ -4,10 +4,12 @@ */ /* eslint-disable no-console */ -import _ from 'lodash'; import dateMath from '@elastic/datemath'; +import _ from 'lodash'; import DSLService from 'public/services/requests/dsl'; +import { HttpSetup } from '../../../../../../src/core/public'; import { ServiceObject } from '../components/common/plots/service_map'; +import { TraceAnalyticsMode } from '../home'; import { getRelatedServicesQuery, getServiceEdgesQuery, @@ -16,20 +18,31 @@ import { getServicesQuery, } from './queries/services_queries'; import { handleDslRequest } from './request_handler'; -import { HttpSetup } from '../../../../../../src/core/public'; -import { TraceAnalyticsMode } from '../home'; export const handleServicesRequest = async ( http: HttpSetup, DSL: any, setItems: any, mode: TraceAnalyticsMode, + dataSourceMDSId?: string, setServiceMap?: any, - serviceNameFilter?: string, + serviceNameFilter?: string ) => { - return handleDslRequest(http, DSL, getServicesQuery(mode, serviceNameFilter, DSL), mode) + return handleDslRequest( + http, + DSL, + getServicesQuery(mode, serviceNameFilter, DSL), + mode, + dataSourceMDSId + ) .then(async (response) => { - const serviceObject: ServiceObject = await handleServiceMapRequest(http, DSL, mode, setServiceMap); + const serviceObject: ServiceObject = await handleServiceMapRequest( + http, + DSL, + mode, + dataSourceMDSId, + setServiceMap + ); return Promise.all( response.aggregations.service.buckets .filter((bucket: any) => serviceObject[bucket.key]) @@ -60,8 +73,9 @@ export const handleServiceMapRequest = async ( http: HttpSetup, DSL: DSLService | any, mode: TraceAnalyticsMode, + dataSourceMDSId?: string, setItems?: any, - currService?: string, + currService?: string ) => { let minutesInDateRange: number; const startTime = DSL.custom?.timeFilter?.[0]?.range?.startTime; @@ -72,7 +86,7 @@ export const handleServiceMapRequest = async ( } const map: ServiceObject = {}; let id = 1; - await handleDslRequest(http, null, getServiceNodesQuery(mode), mode) + await handleDslRequest(http, null, getServiceNodesQuery(mode), mode, dataSourceMDSId) .then((response) => response.aggregations.service_name.buckets.map( (bucket: any) => @@ -91,7 +105,7 @@ export const handleServiceMapRequest = async ( .catch((error) => console.error(error)); const targets = {}; - await handleDslRequest(http, null, getServiceEdgesQuery('target', mode), mode) + await handleDslRequest(http, null, getServiceEdgesQuery('target', mode), mode, dataSourceMDSId) .then((response) => response.aggregations.service_name.buckets.map((bucket: any) => { bucket.resource.buckets.map((resource: any) => { @@ -102,7 +116,13 @@ export const handleServiceMapRequest = async ( }) ) .catch((error) => console.error(error)); - await handleDslRequest(http, null, getServiceEdgesQuery('destination', mode), mode) + await handleDslRequest( + http, + null, + getServiceEdgesQuery('destination', mode), + mode, + dataSourceMDSId + ) .then((response) => Promise.all( response.aggregations.service_name.buckets.map((bucket: any) => { @@ -126,8 +146,9 @@ export const handleServiceMapRequest = async ( const latencies = await handleDslRequest( http, DSL, - getServiceMetricsQuery(DSL, Object.keys(map), map, mode), + getServiceMetricsQuery(DSL, Object.keys(map), map, mode), mode, + dataSourceMDSId ); latencies.aggregations.service_name.buckets.map((bucket: any) => { map[bucket.key].latency = bucket.average_latency.value; @@ -138,7 +159,7 @@ export const handleServiceMapRequest = async ( }); if (currService) { - await handleDslRequest(http, DSL, getRelatedServicesQuery(currService), mode) + await handleDslRequest(http, DSL, getRelatedServicesQuery(currService), mode, dataSourceMDSId) .then((response) => response.aggregations.traces.buckets.filter((bucket: any) => bucket.service.doc_count > 0) ) @@ -164,12 +185,18 @@ export const handleServiceViewRequest = ( DSL: any, setFields: any, mode: TraceAnalyticsMode, + dataSourceMDSId?: string ) => { - handleDslRequest(http, DSL, getServicesQuery(mode, serviceName), mode) + handleDslRequest(http, DSL, getServicesQuery(mode, serviceName), mode, dataSourceMDSId) .then(async (response) => { const bucket = response.aggregations.service.buckets[0]; if (!bucket) return {}; - const serviceObject: ServiceObject = await handleServiceMapRequest(http, DSL, mode); + const serviceObject: ServiceObject = await handleServiceMapRequest( + http, + DSL, + mode, + dataSourceMDSId + ); const connectedServices = [ ...serviceObject[bucket.key].targetServices, ...serviceObject[bucket.key].destServices, diff --git a/public/components/trace_analytics/requests/traces_request_handler.ts b/public/components/trace_analytics/requests/traces_request_handler.ts index 80b42a7642..cb2358d76c 100644 --- a/public/components/trace_analytics/requests/traces_request_handler.ts +++ b/public/components/trace_analytics/requests/traces_request_handler.ts @@ -6,11 +6,12 @@ import _ from 'lodash'; import moment from 'moment'; import { v1 as uuid } from 'uuid'; -import { BarOrientation } from '../../../../common/constants/shared'; import { HttpSetup } from '../../../../../../src/core/public'; +import { BarOrientation } from '../../../../common/constants/shared'; import { TRACE_ANALYTICS_DATE_FORMAT } from '../../../../common/constants/trace_analytics'; import { microToMilliSec, nanoToMilliSec } from '../components/common/helper_functions'; import { SpanSearchParams } from '../components/traces/span_detail_table'; +import { TraceAnalyticsMode } from '../home'; import { getPayloadQuery, getServiceBreakdownQuery, @@ -22,7 +23,6 @@ import { getValidTraceIdsQuery, } from './queries/traces_queries'; import { handleDslRequest } from './request_handler'; -import { TraceAnalyticsMode } from '../home'; export const handleValidTraceIds = (http: HttpSetup, DSL: any, mode: TraceAnalyticsMode) => { return handleDslRequest(http, {}, getValidTraceIdsQuery(DSL), mode) @@ -37,6 +37,7 @@ export const handleTracesRequest = async ( items: any, setItems: (items: any) => void, mode: TraceAnalyticsMode, + dataSourceMDSId?: string, sort?: any ) => { const binarySearch = (arr: number[], target: number) => { @@ -57,7 +58,8 @@ export const handleTracesRequest = async ( http, timeFilterDSL, getTraceGroupPercentilesQuery(), - mode + mode, + dataSourceMDSId ).then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.forEach((traceGroup: any) => { @@ -68,7 +70,7 @@ export const handleTracesRequest = async ( return map; }); - return handleDslRequest(http, DSL, getTracesQuery(mode, undefined, sort), mode) + return handleDslRequest(http, DSL, getTracesQuery(mode, undefined, sort), mode, dataSourceMDSId) .then((response) => { return Promise.all( response.aggregations.traces.buckets.map((bucket: any) => { @@ -107,9 +109,10 @@ export const handleTraceViewRequest = ( http: HttpSetup, fields: {}, setFields: (fields: any) => void, - mode: TraceAnalyticsMode + mode: TraceAnalyticsMode, + dataSourceMDSId?: string ) => { - handleDslRequest(http, null, getTracesQuery(mode, traceId), mode) + handleDslRequest(http, null, getTracesQuery(mode, traceId), mode, dataSourceMDSId) .then(async (response) => { const bucket = response.aggregations.traces.buckets[0]; return { @@ -136,7 +139,8 @@ export const handleServicesPieChartRequest = async ( http: HttpSetup, setServiceBreakdownData: (serviceBreakdownData: any) => void, setColorMap: (colorMap: any) => void, - mode: TraceAnalyticsMode + mode: TraceAnalyticsMode, + dataSourceMDSId?: string ) => { const colors = [ '#7492e7', @@ -154,7 +158,7 @@ export const handleServicesPieChartRequest = async ( ]; const colorMap: any = {}; let index = 0; - await handleDslRequest(http, null, getServiceBreakdownQuery(traceId, mode), mode) + await handleDslRequest(http, null, getServiceBreakdownQuery(traceId, mode), mode, dataSourceMDSId) .then((response) => Promise.all( response.aggregations.service_type.buckets.map((bucket: any) => { @@ -199,9 +203,10 @@ export const handleSpansGanttRequest = ( setSpanDetailData: (spanDetailData: any) => void, colorMap: any, spanFiltersDSL: any, - mode: TraceAnalyticsMode + mode: TraceAnalyticsMode, + dataSourceMDSId?: string ) => { - handleDslRequest(http, spanFiltersDSL, getSpanDetailQuery(mode, traceId), mode) + handleDslRequest(http, spanFiltersDSL, getSpanDetailQuery(mode, traceId), mode, dataSourceMDSId) .then((response) => hitsToSpanDetailData(response.hits.hits, colorMap, mode)) .then((newItems) => setSpanDetailData(newItems)) .catch((error) => console.error(error)); @@ -211,9 +216,10 @@ export const handleSpansFlyoutRequest = ( http: HttpSetup, spanId: string, setItems: (items: any) => void, - mode: TraceAnalyticsMode + mode: TraceAnalyticsMode, + dataSourceMDSId?: string ) => { - handleDslRequest(http, null, getSpanFlyoutQuery(mode, spanId), mode) + handleDslRequest(http, null, getSpanFlyoutQuery(mode, spanId), mode, dataSourceMDSId) .then((response) => { setItems(response?.hits.hits?.[0]?._source); }) @@ -310,9 +316,10 @@ export const handlePayloadRequest = ( http: HttpSetup, payloadData: any, setPayloadData: (payloadData: any) => void, - mode: TraceAnalyticsMode + mode: TraceAnalyticsMode, + dataSourceMDSId?: string ) => { - handleDslRequest(http, null, getPayloadQuery(mode, traceId), mode) + handleDslRequest(http, null, getPayloadQuery(mode, traceId), mode, dataSourceMDSId) .then((response) => setPayloadData(JSON.stringify(response.hits.hits, null, 2))) .catch((error) => console.error(error)); }; @@ -323,9 +330,10 @@ export const handleSpansRequest = ( setTotal: (total: number) => void, spanSearchParams: SpanSearchParams, DSL: any, - mode: TraceAnalyticsMode + mode: TraceAnalyticsMode, + dataSourceMDSId?: string ) => { - handleDslRequest(http, DSL, getSpansQuery(spanSearchParams), mode) + handleDslRequest(http, DSL, getSpansQuery(spanSearchParams), mode, dataSourceMDSId) .then((response) => { setItems(response.hits.hits.map((hit: any) => hit._source)); setTotal(response.hits.total?.value || 0); diff --git a/public/framework/core_refs.ts b/public/framework/core_refs.ts index ed378ae1da..b78240e01b 100644 --- a/public/framework/core_refs.ts +++ b/public/framework/core_refs.ts @@ -14,6 +14,7 @@ import { SavedObjectsClientContract, } from '../../../../src/core/public'; import { DashboardStart } from '../../../../src/plugins/dashboard/public'; +import { DataSourcePluginStart } from '../../../../src/plugins/data_source/public'; import PPLService from '../services/requests/ppl'; class CoreRefs { @@ -32,6 +33,7 @@ class CoreRefs { public dashboard?: DashboardStart; public dashboardProviders?: unknown; public overlays?: OverlayStart; + public dataSource?: DataSourcePluginStart; private constructor() { // ... } diff --git a/public/plugin.tsx b/public/plugin.tsx index 62876acdaf..74639f6e82 100644 --- a/public/plugin.tsx +++ b/public/plugin.tsx @@ -20,6 +20,7 @@ import { createGetterSetter } from '../../../src/plugins/opensearch_dashboards_u import { CREATE_TAB_PARAM, CREATE_TAB_PARAM_KEY, TAB_CHART_ID } from '../common/constants/explorer'; import { DATACONNECTIONS_BASE, + S3_DATASOURCE_TYPE, SECURITY_PLUGIN_ACCOUNT_API, observabilityApplicationsID, observabilityApplicationsPluginOrder, @@ -46,7 +47,6 @@ import { observabilityTracesID, observabilityTracesPluginOrder, observabilityTracesTitle, - S3_DATASOURCE_TYPE, } from '../common/constants/shared'; import { QueryManager } from '../common/query_manager'; import { AssociatedObject, CachedAcceleration } from '../common/types/data_connections'; @@ -241,6 +241,7 @@ export class ObservabilityPlugin const dslService = new DSLService(coreStart.http); const savedObjects = new SavedObjects(coreStart.http); const timestampUtils = new TimestampUtils(dslService, pplService); + const { dataSourceManagement } = setupDeps; return Observability( coreStart, depsStart as AppPluginStartDependencies, @@ -251,7 +252,9 @@ export class ObservabilityPlugin timestampUtils, qm, startPage, - dataSourcePluggables // just pass down for now due to time constraint, later may better expose this as context + dataSourcePluggables, // just pass down for now due to time constraint, later may better expose this as context + dataSourceManagement, + coreStart.savedObjects ); }; @@ -385,6 +388,7 @@ export class ObservabilityPlugin coreRefs.queryAssistEnabled = this.config.query_assist.enabled; coreRefs.summarizeEnabled = this.config.summarize.enabled; coreRefs.overlays = core.overlays; + coreRefs.dataSource = startDeps.dataSource; const { dataSourceService, dataSourceFactory } = startDeps.data.dataSources; diff --git a/public/types.ts b/public/types.ts index d276f0538e..d65e31a7af 100644 --- a/public/types.ts +++ b/public/types.ts @@ -6,6 +6,11 @@ import { SavedObjectsClient } from '../../../src/core/server'; import { DashboardStart } from '../../../src/plugins/dashboard/public'; import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../src/plugins/data/public'; +import { + DataSourcePluginSetup, + DataSourcePluginStart, +} from '../../../src/plugins/data_source/public'; +import { DataSourceManagementPluginSetup } from '../../../src/plugins/data_source_management/public'; import { EmbeddableSetup, EmbeddableStart } from '../../../src/plugins/embeddable/public'; import { ManagementOverViewPluginSetup } from '../../../src/plugins/management_overview/public'; import { NavigationPublicPluginStart } from '../../../src/plugins/navigation/public'; @@ -26,6 +31,7 @@ export interface AppPluginStartDependencies { savedObjectsClient: SavedObjectsClient; data: DataPublicPluginStart; securityDashboards?: {}; + dataSource: DataSourcePluginStart; } export interface SetupDependencies { @@ -35,6 +41,8 @@ export interface SetupDependencies { uiActions: UiActionsStart; managementOverview?: ManagementOverViewPluginSetup; assistantDashboards?: AssistantSetup; + dataSource: DataSourcePluginSetup; + dataSourceManagement: DataSourceManagementPluginSetup; } // eslint-disable-next-line @typescript-eslint/no-empty-interface diff --git a/server/plugin.ts b/server/plugin.ts index 1a7433b3da..7270a1141f 100644 --- a/server/plugin.ts +++ b/server/plugin.ts @@ -13,16 +13,23 @@ import { SavedObject, SavedObjectsType, } from '../../../src/core/server'; +import { DataSourcePluginSetup } from '../../../src/plugins/data_source/server/types'; +import { DataSourceManagementPlugin } from '../../../src/plugins/data_source_management/public/plugin'; +import { migrateV1IntegrationToV2Integration } from './adaptors/integrations/migrations'; import { OpenSearchObservabilityPlugin } from './adaptors/opensearch_observability_plugin'; import { PPLPlugin } from './adaptors/ppl_plugin'; +import { PPLParsers } from './parsers/ppl_parser'; import { setupRoutes } from './routes/index'; import { searchSavedObject, visualizationSavedObject, } from './saved_objects/observability_saved_object'; -import { ObservabilityPluginSetup, ObservabilityPluginStart, AssistantPluginSetup } from './types'; -import { PPLParsers } from './parsers/ppl_parser'; -import { migrateV1IntegrationToV2Integration } from './adaptors/integrations/migrations'; +import { AssistantPluginSetup, ObservabilityPluginSetup, ObservabilityPluginStart } from './types'; + +export interface ObservabilityPluginSetupDependencies { + dataSourceManagement: ReturnType; + dataSource: DataSourcePluginSetup; +} export class ObservabilityPlugin implements Plugin { @@ -36,18 +43,24 @@ export class ObservabilityPlugin core: CoreSetup, deps: { assistantDashboards?: AssistantPluginSetup; + dataSource: ObservabilityPluginSetupDependencies; } ) { - const { assistantDashboards } = deps; + const { assistantDashboards, dataSource } = deps; this.logger.debug('Observability: Setup'); const router = core.http.createRouter(); + + const dataSourceEnabled = !!dataSource; const openSearchObservabilityClient: ILegacyClusterClient = core.opensearch.legacy.createClient( 'opensearch_observability', { plugins: [PPLPlugin, OpenSearchObservabilityPlugin], } ); - + if (dataSourceEnabled) { + dataSource.registerCustomApiSchema(PPLPlugin); + dataSource.registerCustomApiSchema(OpenSearchObservabilityPlugin); + } // @ts-ignore core.http.registerRouteHandlerContext('observability_plugin', (_context, _request) => { return { @@ -201,7 +214,7 @@ export class ObservabilityPlugin core.savedObjects.registerType(integrationTemplateType); // Register server side APIs - setupRoutes({ router, client: openSearchObservabilityClient }); + setupRoutes({ router, client: openSearchObservabilityClient, dataSourceEnabled }); core.savedObjects.registerType(visualizationSavedObject); core.savedObjects.registerType(searchSavedObject); diff --git a/server/routes/index.ts b/server/routes/index.ts index 0e87b115b5..bc06a00851 100644 --- a/server/routes/index.ts +++ b/server/routes/index.ts @@ -11,8 +11,8 @@ import { QueryService } from '../services/queryService'; import { registerAppAnalyticsRouter } from './application_analytics/app_analytics_router'; import { PanelsRouter } from './custom_panels/panels_router'; import { VisualizationsRouter } from './custom_panels/visualizations_router'; -import { registerDatasourcesRoute } from './datasources/datasources_router'; import { registerDataConnectionsRoute } from './data_connections/data_connections_router'; +import { registerDatasourcesRoute } from './datasources/datasources_router'; import { registerDslRoute } from './dsl'; import { registerEventAnalyticsRouter } from './event_analytics/event_analytics_router'; import { registerIntegrationsRoute } from './integrations/integrations_router'; @@ -25,7 +25,15 @@ import { registerPplRoute } from './ppl'; import { registerQueryAssistRoutes } from './query_assist/routes'; import { registerTraceAnalyticsDslRouter } from './trace_analytics_dsl_router'; -export function setupRoutes({ router, client }: { router: IRouter; client: ILegacyClusterClient }) { +export function setupRoutes({ + router, + client, + dataSourceEnabled, +}: { + router: IRouter; + client: ILegacyClusterClient; + dataSourceEnabled: boolean; +}) { PanelsRouter(router); VisualizationsRouter(router); registerPplRoute({ router, facet: new PPLFacet(client) }); @@ -34,7 +42,7 @@ export function setupRoutes({ router, client }: { router: IRouter; client: ILega registerAppAnalyticsRouter(router); // TODO remove trace analytics route when DSL route for autocomplete is added - registerTraceAnalyticsDslRouter(router); + registerTraceAnalyticsDslRouter(router, dataSourceEnabled); // notebooks routes registerParaRoute(router); diff --git a/server/routes/trace_analytics_dsl_router.ts b/server/routes/trace_analytics_dsl_router.ts index 171483fd9b..4fe62ab5dc 100644 --- a/server/routes/trace_analytics_dsl_router.ts +++ b/server/routes/trace_analytics_dsl_router.ts @@ -11,28 +11,40 @@ import { DATA_PREPPER_SERVICE_INDEX_NAME, JAEGER_INDEX_NAME, JAEGER_SERVICE_INDEX_NAME, - TRACE_ANALYTICS_DSL_ROUTE, TRACE_ANALYTICS_DATA_PREPPER_INDICES_ROUTE, + TRACE_ANALYTICS_DSL_ROUTE, TRACE_ANALYTICS_JAEGER_INDICES_ROUTE, } from '../../common/constants/trace_analytics'; import { addRequestToMetric } from '../common/metrics/metrics_helper'; -export function registerTraceAnalyticsDslRouter(router: IRouter) { +export function registerTraceAnalyticsDslRouter(router: IRouter, dataSourceEnabled: boolean) { router.post( { path: TRACE_ANALYTICS_DATA_PREPPER_INDICES_ROUTE, - validate: false, + validate: { + body: schema.any(), + query: schema.object({ + dataSourceMDSId: schema.maybe(schema.string({ defaultValue: '' })), + }), + }, }, async (context, request, response) => { const params: RequestParams.IndicesExists = { index: [DATA_PREPPER_INDEX_NAME, DATA_PREPPER_SERVICE_INDEX_NAME], allow_no_indices: false, }; + const { dataSourceMDSId } = request.query; try { - const resp = await context.core.opensearch.legacy.client.callAsCurrentUser( - 'indices.exists', - params - ); + let resp; + if (dataSourceEnabled && dataSourceMDSId) { + const client = context.dataSource.opensearch.legacy.getClient(dataSourceMDSId); + resp = await client.callAPI('indices.exists', params); + } else { + resp = await context.core.opensearch.legacy.client.callAsCurrentUser( + 'indices.exists', + params + ); + } return response.ok({ body: resp, }); @@ -48,18 +60,30 @@ export function registerTraceAnalyticsDslRouter(router: IRouter) { router.post( { path: TRACE_ANALYTICS_JAEGER_INDICES_ROUTE, - validate: false, + validate: { + body: schema.any(), + query: schema.object({ + dataSourceMDSId: schema.maybe(schema.string({ defaultValue: '' })), + }), + }, }, async (context, request, response) => { + const { dataSourceMDSId } = request.query; const params: RequestParams.IndicesExists = { index: [JAEGER_INDEX_NAME, JAEGER_SERVICE_INDEX_NAME], allow_no_indices: false, }; try { - const resp = await context.core.opensearch.legacy.client.callAsCurrentUser( - 'indices.exists', - params - ); + let resp; + if (dataSourceEnabled && dataSourceMDSId) { + const client = context.dataSource.opensearch.legacy.getClient(dataSourceMDSId); + resp = await client.callAPI('indices.exists', params); + } else { + resp = await context.core.opensearch.legacy.client.callAsCurrentUser( + 'indices.exists', + params + ); + } return response.ok({ body: resp, }); @@ -103,21 +127,28 @@ export function registerTraceAnalyticsDslRouter(router: IRouter) { ), script_fields: schema.maybe(schema.any()), }), + query: schema.object({ + dataSourceMDSId: schema.maybe(schema.string({ defaultValue: '' })), + }), }, }, async (context, request, response) => { addRequestToMetric('trace_analytics', 'get', 'count'); const { index, size, ...rest } = request.body; + const { dataSourceMDSId } = request.query; const params: RequestParams.Search = { index: index || DATA_PREPPER_INDEX_NAME, size, body: rest, }; try { - const resp = await context.core.opensearch.legacy.client.callAsCurrentUser( - 'search', - params - ); + let resp; + if (dataSourceEnabled && dataSourceMDSId) { + const client = context.dataSource.opensearch.legacy.getClient(dataSourceMDSId); + resp = await client.callAPI('search', params); + } else { + resp = await context.core.opensearch.legacy.client.callAsCurrentUser('search', params); + } return response.ok({ body: resp, });