diff --git a/changelogs/fragments/8226.yml b/changelogs/fragments/8226.yml deleted file mode 100644 index 65fba83f932a..000000000000 --- a/changelogs/fragments/8226.yml +++ /dev/null @@ -1,2 +0,0 @@ -fix: -- Remove unused enhancements APIs, clean up, and error handling ([#8226](/~https://github.com/opensearch-project/OpenSearch-Dashboards/pull/8226)) \ No newline at end of file diff --git a/src/plugins/data/common/constants.ts b/src/plugins/data/common/constants.ts index d612469cf035..199391630b25 100644 --- a/src/plugins/data/common/constants.ts +++ b/src/plugins/data/common/constants.ts @@ -44,7 +44,7 @@ export const DEFAULT_DATA = { } as DataStructure, LOCAL_DATASOURCE: { id: '', - title: 'Default Cluster', + title: 'Local Cluster', type: 'DATA_SOURCE', }, }, diff --git a/src/plugins/data/common/search/search_source/fetch/get_search_params.ts b/src/plugins/data/common/search/search_source/fetch/get_search_params.ts index d4beab6e8c71..9bb01c4c6023 100644 --- a/src/plugins/data/common/search/search_source/fetch/get_search_params.ts +++ b/src/plugins/data/common/search/search_source/fetch/get_search_params.ts @@ -53,16 +53,19 @@ export function getExternalSearchParamsFromRequest( searchRequest: SearchRequest, dependencies: { getConfig: GetConfigFn; + getDataFrame: GetDataFrameFn; } ): ISearchRequestParams { - const { getConfig } = dependencies; + const { getConfig, getDataFrame } = dependencies; const searchParams = getSearchParams(getConfig); + const dataFrame = getDataFrame(); const indexTitle = searchRequest.index.title || searchRequest.index; return { index: indexTitle, body: { ...searchRequest.body, + ...(dataFrame && dataFrame?.name === indexTitle ? { df: dataFrame } : {}), }, ...searchParams, }; diff --git a/src/plugins/data/public/query/query_string/dataset_service/lib/index_type.ts b/src/plugins/data/public/query/query_string/dataset_service/lib/index_type.ts index 2c7f4bbffb2e..73df7b1af556 100644 --- a/src/plugins/data/public/query/query_string/dataset_service/lib/index_type.ts +++ b/src/plugins/data/public/query/query_string/dataset_service/lib/index_type.ts @@ -64,7 +64,7 @@ export const indexTypeConfig: DatasetTypeConfig = { const dataSources = await fetchDataSources(services.savedObjects.client); return { ...dataStructure, - columnHeader: 'Clusters', + columnHeader: 'Cluster', hasNext: true, children: dataSources, }; diff --git a/src/plugins/query_enhancements/common/constants.ts b/src/plugins/query_enhancements/common/constants.ts index 769a03e0c0d0..99a3652bd82a 100644 --- a/src/plugins/query_enhancements/common/constants.ts +++ b/src/plugins/query_enhancements/common/constants.ts @@ -29,8 +29,9 @@ export const API = { GENERATE: `${BASE_API}/assist/generate`, }, DATA_SOURCE: { - ASYNC_JOBS: `${BASE_API}/jobs`, - CONNECTIONS: `${BASE_API}/connections`, + EXTERNAL: `${BASE_API}/datasource/external`, + ASYNC_JOBS: `${BASE_API}/datasource/jobs`, + CONNECTIONS: `${BASE_API}/datasource/connections`, }, }; diff --git a/src/plugins/query_enhancements/public/datasets/s3_type.ts b/src/plugins/query_enhancements/public/datasets/s3_type.ts index bedb2efc78a6..3d0caf0e1245 100644 --- a/src/plugins/query_enhancements/public/datasets/s3_type.ts +++ b/src/plugins/query_enhancements/public/datasets/s3_type.ts @@ -4,7 +4,6 @@ */ import { HttpSetup, SavedObjectsClientContract } from 'opensearch-dashboards/public'; -import { trimEnd } from 'lodash'; import { DATA_STRUCTURE_META_TYPES, DEFAULT_DATA, @@ -15,7 +14,7 @@ import { DatasetField, } from '../../../data/common'; import { DatasetTypeConfig, IDataPluginServices } from '../../../data/public'; -import { API, DATASET, handleQueryStatus } from '../../common'; +import { DATASET, handleQueryStatus } from '../../common'; import S3_ICON from '../assets/s3_mark.svg'; export const s3TypeConfig: DatasetTypeConfig = { @@ -116,9 +115,7 @@ const fetch = async ( try { const response = await handleQueryStatus({ fetchStatus: () => - http.fetch({ - method: 'GET', - path: trimEnd(`${API.DATA_SOURCE.ASYNC_JOBS}`), + http.fetch('../../api/enhancements/datasource/jobs', { query: { id: dataSource?.id, queryId: meta.queryId, @@ -174,13 +171,9 @@ const fetchConnections = async ( http: HttpSetup, dataSource: DataStructure ): Promise => { - const abortController = new AbortController(); - const query = - dataSource.id !== '' ? (dataSource.meta as DataStructureCustomMeta).query : undefined; - const response = await http.fetch({ - method: 'GET', - path: trimEnd(`${API.DATA_SOURCE.CONNECTIONS}/${query?.id || ''}`), - signal: abortController.signal, + const query = (dataSource.meta as DataStructureCustomMeta).query; + const response = await http.fetch(`../../api/enhancements/datasource/external`, { + query, }); return response @@ -197,13 +190,10 @@ const fetchConnections = async ( }; const fetchDatabases = async (http: HttpSetup, path: DataStructure[]): Promise => { - const abortController = new AbortController(); const dataSource = path.find((ds) => ds.type === 'DATA_SOURCE'); const connection = path[path.length - 1]; const meta = connection.meta as DataStructureCustomMeta; - const response = await http.fetch({ - method: 'POST', - path: trimEnd(`${API.DATA_SOURCE.ASYNC_JOBS}`), + const response = await http.post(`../../api/enhancements/datasource/jobs`, { body: JSON.stringify({ lang: 'sql', query: `SHOW DATABASES in ${connection.title}`, @@ -213,7 +203,6 @@ const fetchDatabases = async (http: HttpSetup, path: DataStructure[]): Promise => { - const abortController = new AbortController(); const dataSource = path.find((ds) => ds.type === 'DATA_SOURCE'); const connection = path.find((ds) => ds.type === 'CONNECTION'); const sessionId = (connection?.meta as DataStructureCustomMeta).sessionId; const database = path[path.length - 1]; - const response = await http.fetch({ - method: 'POST', - path: trimEnd(`${API.DATA_SOURCE.ASYNC_JOBS}`), + const response = await http.post(`../../api/enhancements/datasource/jobs`, { body: JSON.stringify({ lang: 'sql', query: `SHOW TABLES in ${database.title}`, @@ -239,7 +225,6 @@ const fetchTables = async (http: HttpSetup, path: DataStructure[]): Promise(undefined); + private isDataSourceEnabled = false; + private isDataSourceEnabled$ = new BehaviorSubject(this.isDataSourceEnabled); + private selectedConnection: Connection | undefined = undefined; + private selectedConnection$ = new BehaviorSubject( + this.selectedConnection + ); + + constructor(deps: ConnectionsServiceDeps) { + deps.startServices.then(([coreStart, depsStart]) => { + this.http = deps.http; + this.savedObjects = coreStart.savedObjects; + this.uiService$.next(depsStart.data.ui); + this.setIsDataSourceEnabled$(depsStart.dataSource?.dataSourceEnabled || false); + }); + } + + getSavedObjects = () => { + return this.savedObjects; + }; + + getIsDataSourceEnabled = () => { + return this.isDataSourceEnabled; + }; + + setIsDataSourceEnabled$ = (isDataSourceEnabled: boolean) => { + this.isDataSourceEnabled = isDataSourceEnabled; + this.isDataSourceEnabled$.next(this.isDataSourceEnabled); + }; + + getIsDataSourceEnabled$ = () => { + return this.isDataSourceEnabled$.asObservable(); + }; + + getUiService = () => { + return this.uiService$.asObservable(); + }; + + getConnections = (): Observable => { + return from( + this.http.fetch({ + method: 'GET', + path: API.DATA_SOURCE.CONNECTIONS, + }) + ); + }; + + getConnectionById = (id: string): Observable => { + const path = `${API.DATA_SOURCE.CONNECTIONS}/${id}`; + return from( + this.http.fetch({ + method: 'GET', + path, + }) + ); + }; + + getSelectedConnection = () => { + return this.selectedConnection; + }; + + setSelectedConnection$ = (connection: Connection | undefined) => { + this.selectedConnection = connection; + this.selectedConnection$.next(this.selectedConnection); + }; + + getSelectedConnection$ = () => { + return this.selectedConnection$.asObservable(); + }; +} diff --git a/src/plugins/query_enhancements/public/services/index.ts b/src/plugins/query_enhancements/public/services/index.ts index 276270c72cbb..23071cdbc86f 100644 --- a/src/plugins/query_enhancements/public/services/index.ts +++ b/src/plugins/query_enhancements/public/services/index.ts @@ -9,3 +9,5 @@ import { createGetterSetter } from '../../../opensearch_dashboards_utils/common' export const [getStorage, setStorage] = createGetterSetter('storage'); export const [getData, setData] = createGetterSetter('data'); + +export { ConnectionsService } from './connections_service'; diff --git a/src/plugins/query_enhancements/public/types.ts b/src/plugins/query_enhancements/public/types.ts index 365264ec11bd..c31da11e6b15 100644 --- a/src/plugins/query_enhancements/public/types.ts +++ b/src/plugins/query_enhancements/public/types.ts @@ -31,3 +31,8 @@ export interface Connection { auth?: any; }; } + +export interface ConnectionsServiceDeps { + http: CoreSetup['http']; + startServices: Promise<[CoreStart, QueryEnhancementsPluginStartDependencies, unknown]>; +} diff --git a/src/plugins/query_enhancements/server/routes/data_source_connection/routes.ts b/src/plugins/query_enhancements/server/routes/data_source_connection/routes.ts index 4084dcf1db8b..8407c20314bc 100644 --- a/src/plugins/query_enhancements/server/routes/data_source_connection/routes.ts +++ b/src/plugins/query_enhancements/server/routes/data_source_connection/routes.ts @@ -13,26 +13,62 @@ export function registerDataSourceConnectionsRoutes( ) { router.get( { - path: `${API.DATA_SOURCE.CONNECTIONS}/{id?}`, + path: API.DATA_SOURCE.CONNECTIONS, + validate: { + params: schema.object({}, { unknowns: 'allow' }), + }, + }, + async (context, request, response) => { + const fields = ['id', 'title', 'auth.type']; + const resp = await context.core.savedObjects.client.find({ + type: 'data-source', + fields, + perPage: 10000, + }); + + return response.ok({ body: { savedObjects: resp.saved_objects } }); + } + ); + + router.get( + { + path: `${API.DATA_SOURCE.CONNECTIONS}/{dataSourceId}`, validate: { params: schema.object({ - id: schema.maybe(schema.string()), + dataSourceId: schema.string(), + }), + }, + }, + async (context, request, response) => { + const resp = await context.core.savedObjects.client.get( + 'data-source', + request.params.dataSourceId + ); + return response.ok({ body: resp }); + } + ); + + router.get( + { + path: `${API.DATA_SOURCE.EXTERNAL}`, + validate: { + query: schema.object({ + id: schema.string(), + name: schema.nullable(schema.string()), }), }, }, async (context, request, response) => { - const client = request.params.id - ? context.dataSource.opensearch.legacy.getClient(request.params.id).callAPI + const client = request.query.id + ? context.dataSource.opensearch.legacy.getClient(request.query.id).callAPI : defaultClient.asScoped(request).callAsCurrentUser; - try { - const resp = await client('enhancements.getDataConnections'); - return response.ok({ body: resp }); - } catch (error) { - if (error.statusCode === 404 || error.statusCode === 400) { - return response.ok({ body: [] }); - } - return response.custom({ statusCode: error.statusCode || 500, body: error.message }); - } + + const resp = request.query.name + ? await client('enhancements.getDataConnectionById', { + dataconnection: request.query.name, + }) + : await client('enhancements.getDataConnections'); + return response.ok({ body: resp }); } ); diff --git a/src/plugins/query_enhancements/server/routes/index.ts b/src/plugins/query_enhancements/server/routes/index.ts index 7d64e2c12b1a..50bfa30f70ee 100644 --- a/src/plugins/query_enhancements/server/routes/index.ts +++ b/src/plugins/query_enhancements/server/routes/index.ts @@ -43,6 +43,10 @@ import { registerDataSourceConnectionsRoutes } from './data_source_connection'; * "aggConfig": { * // Optional aggregation configuration * }, + * @deprecated + * "df": { + * // Optional data frame configuration + * } * } * ``` */ @@ -68,6 +72,7 @@ function defineRoute( format: schema.string(), }), aggConfig: schema.nullable(schema.object({}, { unknowns: 'allow' })), + df: schema.nullable(schema.object({}, { unknowns: 'allow' })), }), }, }, @@ -87,6 +92,71 @@ function defineRoute( } } ); + + router.get( + { + path: `${path}/{queryId}`, + validate: { + params: schema.object({ + queryId: schema.string(), + }), + }, + }, + async (context, req, res): Promise => { + try { + const queryRes: IDataFrameResponse = await searchStrategies[searchStrategyId].search( + context, + req as any, + {} + ); + const result: any = { + body: { + ...queryRes, + }, + }; + return res.ok(result); + } catch (err) { + logger.error(err); + return res.custom({ + statusCode: 500, + body: err, + }); + } + } + ); + + router.get( + { + path: `${path}/{queryId}/{dataSourceId}`, + validate: { + params: schema.object({ + queryId: schema.string(), + dataSourceId: schema.string(), + }), + }, + }, + async (context, req, res): Promise => { + try { + const queryRes: IDataFrameResponse = await searchStrategies[searchStrategyId].search( + context, + req as any, + {} + ); + const result: any = { + body: { + ...queryRes, + }, + }; + return res.ok(result); + } catch (err) { + logger.error(err); + return res.custom({ + statusCode: 500, + body: err, + }); + } + } + ); } /**