-
Notifications
You must be signed in to change notification settings - Fork 918
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* initial commit for datasource * initial commit for datasource service * [Data Sources] Move datasource codebase from datasource plugin to data plugin * [Data Sources] Add datasource factory * datasource service * datasource with factory * datasource selector * exposes datasources from data plugin * index pattern datasource registration * add datasource selector to discover * remove unused files * add/exposes types for datasources as a set of services * add datasource selector unit tests * add metadata to selectable * redirection to observability for non-index-pattern datasource * add datasource factory tests * add datasource service test * datasources related fixes * add tests for datasource selectable * added types/interfaces for sidebar selector, and add a couple of enhancements * remove pill effect * change type for name display in selector for index patterns * remove legacy index selector * rename datasource change handler * remove unused constants * fix a redirection bug * add to change log * fix bg color issue in source selector * address oui and missing guard * add test subj * i18 and datasource interface default return * add default datasource tests * fix typo * modify wording * add experimental annotation to datasource * add type datasource filtering to remove type error hint * remove unused type * add 'type' to option type * Type fixes * cherry-pick type changes from remote and add partial fixes * add one type exports * remaining type errors fixed * addressing comments * address dedup * refactor datasource_selectable to address comments * remove unnecessary optional chaining * refactor variable names * move functnions out of selectable component * add comments for dedup/options list updates * add experimental annotation * callback and experimental annotation on types * handleSourceSelection callback * datasource annotation and import adjustment * remove pill effect * minor changes addressing latest comments * remove unused tests --------- (cherry picked from commit 1e980fa) Signed-off-by: Eric <menwe@amazon.com> Signed-off-by: Ashwin P Chandran <ashwinpc@amazon.com> Signed-off-by: Joshua Li <joshuali925@gmail.com> Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Josh Romero <rmerqg@amazon.com> Co-authored-by: Ashwin P Chandran <ashwinpc@amazon.com> Co-authored-by: Joshua Li <joshuali925@gmail.com>
- Loading branch information
1 parent
03bc3cc
commit 6fe4542
Showing
22 changed files
with
1,099 additions
and
79 deletions.
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
src/plugins/data/public/data_sources/datasource/datasource.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** | ||
* Abstract class representing a data source. This class provides foundational | ||
* interfaces for specific data sources. Any data source connection needs to extend | ||
* and implement from this base class | ||
* | ||
* DataSourceMetaData: Represents metadata associated with the data source. | ||
* SourceDataSet: Represents the dataset associated with the data source. | ||
* DataSourceQueryResult: Represents the result from querying the data source. | ||
*/ | ||
|
||
import { ConnectionStatus } from './types'; | ||
|
||
/** | ||
* @experimental this class is experimental and might change in future releases. | ||
*/ | ||
export abstract class DataSource< | ||
DataSourceMetaData, | ||
DataSetParams, | ||
SourceDataSet, | ||
DataSourceQueryParams, | ||
DataSourceQueryResult | ||
> { | ||
constructor( | ||
private readonly name: string, | ||
private readonly type: string, | ||
private readonly metadata: DataSourceMetaData | ||
) {} | ||
|
||
getName() { | ||
return this.name; | ||
} | ||
|
||
getType() { | ||
return this.type; | ||
} | ||
|
||
getMetadata() { | ||
return this.metadata; | ||
} | ||
|
||
/** | ||
* Abstract method to get the dataset associated with the data source. | ||
* Implementing classes need to provide the specific implementation. | ||
* | ||
* Data source selector needs to display data sources with pattern | ||
* group (connection name) - a list of datasets. For example, get | ||
* all available tables for flint datasources, and get all index | ||
* patterns for OpenSearch data source | ||
* | ||
* @experimental This API is experimental and might change in future releases. | ||
* @returns {SourceDataSet} Dataset associated with the data source. | ||
*/ | ||
abstract getDataSet(dataSetParams?: DataSetParams): SourceDataSet; | ||
|
||
/** | ||
* Abstract method to run a query against the data source. | ||
* Implementing classes need to provide the specific implementation. | ||
* | ||
* @experimental This API is experimental and might change in future releases. | ||
* @returns {DataSourceQueryResult} Result from querying the data source. | ||
*/ | ||
abstract runQuery(queryParams: DataSourceQueryParams): DataSourceQueryResult; | ||
|
||
/** | ||
* Abstract method to test the connection to the data source. | ||
* Implementing classes should provide the specific logic to determine | ||
* the connection status, typically indicating success or failure. | ||
* | ||
* @experimental This API is experimental and might change in future releases. | ||
* @returns {ConnectionStatus | Promise<void>} Status of the connection test. | ||
* @experimental | ||
*/ | ||
abstract testConnection(): ConnectionStatus | Promise<boolean>; | ||
} |
93 changes: 93 additions & 0 deletions
93
src/plugins/data/public/data_sources/datasource/factory.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { DataSourceFactory } from './factory'; | ||
import { DataSource } from './datasource'; | ||
import { IndexPattern, IndexPatternsService } from '../../index_patterns'; | ||
|
||
class MockDataSource extends DataSource<any, any, any, any, any> { | ||
private readonly indexPatterns; | ||
|
||
constructor({ | ||
name, | ||
type, | ||
metadata, | ||
indexPatterns, | ||
}: { | ||
name: string; | ||
type: string; | ||
metadata: any; | ||
indexPatterns: IndexPatternsService; | ||
}) { | ||
super(name, type, metadata); | ||
this.indexPatterns = indexPatterns; | ||
} | ||
|
||
async getDataSet(dataSetParams?: any) { | ||
await this.indexPatterns.ensureDefaultIndexPattern(); | ||
return await this.indexPatterns.getCache(); | ||
} | ||
|
||
async testConnection(): Promise<boolean> { | ||
return true; | ||
} | ||
|
||
async runQuery(queryParams: any) { | ||
return undefined; | ||
} | ||
} | ||
|
||
describe('DataSourceFactory', () => { | ||
beforeEach(() => { | ||
// Reset the DataSourceFactory's singleton instance before each test for isolation | ||
(DataSourceFactory as any).factory = undefined; | ||
}); | ||
|
||
it('returns a singleton instance', () => { | ||
const instance1 = DataSourceFactory.getInstance(); | ||
const instance2 = DataSourceFactory.getInstance(); | ||
expect(instance1).toBe(instance2); | ||
}); | ||
|
||
it('registers a new data source type correctly', () => { | ||
const factory = DataSourceFactory.getInstance(); | ||
expect(() => { | ||
factory.registerDataSourceType('mock', MockDataSource); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('throws error when registering an already registered data source type', () => { | ||
const factory = DataSourceFactory.getInstance(); | ||
factory.registerDataSourceType('mock', MockDataSource); | ||
expect(() => { | ||
factory.registerDataSourceType('mock', MockDataSource); | ||
}).toThrow('This data source type has already been registered'); | ||
}); | ||
|
||
it('creates and returns an instance of the registered data source type', () => { | ||
const factory = DataSourceFactory.getInstance(); | ||
const mockIndexPattern = {} as IndexPattern; | ||
const config = { | ||
name: 'test_datasource', | ||
type: 'mock', | ||
metadata: null, | ||
indexPattern: mockIndexPattern, | ||
}; | ||
factory.registerDataSourceType('mock', MockDataSource); | ||
|
||
const instance = factory.getDataSourceInstance('mock', config); | ||
expect(instance).toBeInstanceOf(MockDataSource); | ||
expect(instance.getName()).toEqual(config.name); | ||
expect(instance.getType()).toEqual(config.type); | ||
expect(instance.getMetadata()).toEqual(config.metadata); | ||
}); | ||
|
||
it('throws error when trying to get an instance of an unregistered data source type', () => { | ||
const factory = DataSourceFactory.getInstance(); | ||
expect(() => { | ||
factory.getDataSourceInstance('unregistered', {}); | ||
}).toThrow('Unsupported data source type'); | ||
}); | ||
}); |
80 changes: 80 additions & 0 deletions
80
src/plugins/data/public/data_sources/datasource/factory.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** | ||
* The DataSourceFactory is responsible for managing the registration and creation of data source classes. | ||
* It serves as a registry for different data source types and provides a way to instantiate them. | ||
*/ | ||
|
||
import { DataSourceType } from '../datasource_services'; | ||
import { DataSource } from '../datasource'; | ||
|
||
type DataSourceClass< | ||
MetaData = any, | ||
SetParams = any, | ||
DataSet = any, | ||
QueryParams = any, | ||
QueryResult = any | ||
> = new (config: any) => DataSource<MetaData, SetParams, DataSet, QueryParams, QueryResult>; | ||
|
||
export class DataSourceFactory { | ||
// Holds the singleton instance of the DataSourceFactory. | ||
private static factory: DataSourceFactory; | ||
|
||
// A dictionary holding the data source type as the key and its corresponding class constructor as the value. | ||
private dataSourceClasses: { [type: string]: DataSourceClass } = {}; | ||
|
||
/** | ||
* Private constructor to ensure only one instance of DataSourceFactory is created. | ||
*/ | ||
private constructor() {} | ||
|
||
/** | ||
* Returns the singleton instance of the DataSourceFactory. If it doesn't exist, it creates one. | ||
* | ||
* @experimental This API is experimental and might change in future releases. | ||
* @returns {DataSourceFactory} The single instance of DataSourceFactory. | ||
*/ | ||
static getInstance(): DataSourceFactory { | ||
if (!this.factory) { | ||
this.factory = new DataSourceFactory(); | ||
} | ||
return this.factory; | ||
} | ||
|
||
/** | ||
* Registers a new data source type with its associated class. | ||
* If the type has already been registered, an error is thrown. | ||
* | ||
* @experimental This API is experimental and might change in future releases. | ||
* @param {string} type - The identifier for the data source type. | ||
* @param {DataSourceClass} dataSourceClass - The constructor of the data source class. | ||
* @throws {Error} Throws an error if the data source type has already been registered. | ||
*/ | ||
registerDataSourceType(type: string, dataSourceClass: DataSourceClass): void { | ||
if (this.dataSourceClasses[type]) { | ||
throw new Error('This data source type has already been registered'); | ||
} | ||
this.dataSourceClasses[type] = dataSourceClass; | ||
} | ||
|
||
/** | ||
* Creates and returns an instance of the specified data source type with the given configuration. | ||
* If the type hasn't been registered, an error is thrown. | ||
* | ||
* @experimental This API is experimental and might change in future releases. | ||
* @param {string} type - The identifier for the data source type. | ||
* @param {any} config - The configuration for the data source instance. | ||
* @returns {DataSourceType} An instance of the specified data source type. | ||
* @throws {Error} Throws an error if the data source type is not supported. | ||
*/ | ||
getDataSourceInstance(type: string, config: any): DataSourceType { | ||
const DataSourceClass = this.dataSourceClasses[type]; | ||
if (!DataSourceClass) { | ||
throw new Error('Unsupported data source type'); | ||
} | ||
return new DataSourceClass(config); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
export { DataSource } from './datasource'; | ||
export { | ||
IDataSourceMetaData, | ||
ISourceDataSet, | ||
IDataSetParams, | ||
IDataSourceQueryParams, | ||
IDataSourceQueryResult, | ||
ConnectionStatus, | ||
DataSourceConfig, | ||
IndexPatternOption, | ||
} from './types'; | ||
export { DataSourceFactory } from './factory'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** | ||
* @experimental These interfaces are experimental and might change in future releases. | ||
*/ | ||
|
||
import { IndexPatternsService } from '../../index_patterns'; | ||
import { DataSourceType } from '../datasource_services'; | ||
|
||
export interface IndexPatternOption { | ||
title: string; | ||
id: string; | ||
} | ||
|
||
export interface IDataSourceMetaData { | ||
name: string; | ||
} | ||
|
||
export interface IDataSourceGroup { | ||
name: string; | ||
} | ||
|
||
export interface ISourceDataSet { | ||
ds: DataSourceType; | ||
data_sets: Array<string | IndexPatternOption>; | ||
} | ||
|
||
// to-dos: add common interfaces for datasource | ||
// eslint-disable-next-line @typescript-eslint/no-empty-interface | ||
export interface IDataSetParams {} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-empty-interface | ||
export interface IDataSourceQueryParams {} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-empty-interface | ||
export interface IDataSourceQueryResult {} | ||
|
||
export interface ConnectionStatus { | ||
success: boolean; | ||
info: string; | ||
} | ||
|
||
export interface DataSourceConfig { | ||
name: string; | ||
type: string; | ||
metadata: any; | ||
indexPatterns: IndexPatternsService; | ||
} |
Oops, something went wrong.