Skip to content

Commit

Permalink
Enable data client with sample data server side (#4268)
Browse files Browse the repository at this point in the history
* Enable data client with sample data server side

* Add dataSourceId into savedObject

Signed-off-by: Kristen Tian <tyarong@amazon.com>

* Functional list, install uninstall

Signed-off-by: Kristen Tian <tyarong@amazon.com>

* add change log

Signed-off-by: Kristen Tian <tyarong@amazon.com>

* address comments

Signed-off-by: Kristen Tian <tyarong@amazon.com>

* add ut

Signed-off-by: Kristen Tian <tyarong@amazon.com>

---------

Signed-off-by: Kristen Tian <tyarong@amazon.com>
  • Loading branch information
kristenTian authored Jun 20, 2023
1 parent 1728318 commit b337bea
Show file tree
Hide file tree
Showing 18 changed files with 648 additions and 106 deletions.
1 change: 1 addition & 0 deletions .lycheeexclude
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,4 @@ https://yarnpkg.com/latest.msi
https://forum.opensearch.org/
https://facebook.github.io/jest/
https://facebook.github.io/jest/docs/cli.html
http://helpmenow.com/problem2
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Replace re2 with RegExp in timeline and add unit tests ([#3908](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3908))
- Add category option within groups for context menus ([#4144](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4144))
- [Saved Object Service] Add Repository Factory Provider ([#4149](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4149))
- [Multiple DataSource] Backend support for adding sample data ([#4268](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/4268))

### 🐛 Bug Fixes

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/data_source/server/client/configure_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const configureClient = async (
requireDecryption
);
} catch (error: any) {
logger.error(
logger.debug(
`Failed to get data source client for dataSourceId: [${dataSourceId}]. ${error}: ${error.stack}`
);
// Re-throw as DataSourceError
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const configureLegacyClient = async (
dataSourceId
);
} catch (error: any) {
logger.error(
logger.debug(
`Failed to get data source client for dataSourceId: [${dataSourceId}]. ${error}: ${error.stack}`
);
// Re-throw as DataSourceError
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/home/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"server": true,
"ui": true,
"requiredPlugins": ["data", "urlForwarding"],
"optionalPlugins": ["usageCollection", "telemetry"],
"optionalPlugins": ["usageCollection", "telemetry", "dataSource"],
"requiredBundles": [
"opensearchDashboardsReact"
]
Expand Down
25 changes: 19 additions & 6 deletions src/plugins/home/public/application/sample_data_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ function clearIndexPatternsCache() {
getServices().indexPatternService.clearCache();
}

export async function listSampleDataSets() {
return await getServices().http.get(sampleDataUrl);
export async function listSampleDataSets(dataSourceId) {
const query = buildQuery(dataSourceId);
return await getServices().http.get(sampleDataUrl, { query });
}

export async function installSampleDataSet(id, sampleDataDefaultIndex) {
await getServices().http.post(`${sampleDataUrl}/${id}`);
export async function installSampleDataSet(id, sampleDataDefaultIndex, dataSourceId) {
const query = buildQuery(dataSourceId);
await getServices().http.post(`${sampleDataUrl}/${id}`, { query });

if (getServices().uiSettings.isDefault('defaultIndex')) {
getServices().uiSettings.set('defaultIndex', sampleDataDefaultIndex);
Expand All @@ -50,8 +52,9 @@ export async function installSampleDataSet(id, sampleDataDefaultIndex) {
clearIndexPatternsCache();
}

export async function uninstallSampleDataSet(id, sampleDataDefaultIndex) {
await getServices().http.delete(`${sampleDataUrl}/${id}`);
export async function uninstallSampleDataSet(id, sampleDataDefaultIndex, dataSourceId) {
const query = buildQuery(dataSourceId);
await getServices().http.delete(`${sampleDataUrl}/${id}`, { query });

const uiSettings = getServices().uiSettings;

Expand All @@ -64,3 +67,13 @@ export async function uninstallSampleDataSet(id, sampleDataDefaultIndex) {

clearIndexPatternsCache();
}

function buildQuery(dataSourceId) {
const query = {};

if (dataSourceId) {
query.data_source_id = dataSourceId;
}

return query;
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { i18n } from '@osd/i18n';
import { getSavedObjects } from './saved_objects';
import { fieldMappings } from './field_mappings';
import { SampleDatasetSchema, AppLinkSchema } from '../../lib/sample_dataset_registry_types';
import { getSavedObjectsWithDataSource, appendDataSourceId } from '../util';

const ecommerceName = i18n.translate('home.sampleData.ecommerceSpecTitle', {
defaultMessage: 'Sample eCommerce orders',
Expand All @@ -42,17 +43,21 @@ const ecommerceDescription = i18n.translate('home.sampleData.ecommerceSpecDescri
});
const initialAppLinks = [] as AppLinkSchema[];

const DEFAULT_INDEX = 'ff959d40-b880-11e8-a6d9-e546fe2bba5f';
const DASHBOARD_ID = '722b74f0-b882-11e8-a6d9-e546fe2bba5f';

export const ecommerceSpecProvider = function (): SampleDatasetSchema {
return {
id: 'ecommerce',
name: ecommerceName,
description: ecommerceDescription,
previewImagePath: '/plugins/home/assets/sample_data_resources/ecommerce/dashboard.png',
darkPreviewImagePath: '/plugins/home/assets/sample_data_resources/ecommerce/dashboard_dark.png',
overviewDashboard: '722b74f0-b882-11e8-a6d9-e546fe2bba5f',
overviewDashboard: appendDataSourceId(DASHBOARD_ID),
appLinks: initialAppLinks,
defaultIndex: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f',
savedObjects: getSavedObjects(),
defaultIndex: appendDataSourceId(DEFAULT_INDEX),
savedObjects: (dataSourceId?: string, dataSourceTitle?: string) =>
getSavedObjectsWithDataSource(getSavedObjects(), dataSourceId, dataSourceTitle),
dataIndices: [
{
id: 'ecommerce',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { i18n } from '@osd/i18n';
import { getSavedObjects } from './saved_objects';
import { fieldMappings } from './field_mappings';
import { SampleDatasetSchema, AppLinkSchema } from '../../lib/sample_dataset_registry_types';
import { getSavedObjectsWithDataSource, appendDataSourceId } from '../util';

const flightsName = i18n.translate('home.sampleData.flightsSpecTitle', {
defaultMessage: 'Sample flight data',
Expand All @@ -42,17 +43,21 @@ const flightsDescription = i18n.translate('home.sampleData.flightsSpecDescriptio
});
const initialAppLinks = [] as AppLinkSchema[];

const DEFAULT_INDEX = 'd3d7af60-4c81-11e8-b3d7-01146121b73d';
const DASHBOARD_ID = '7adfa750-4c81-11e8-b3d7-01146121b73d';

export const flightsSpecProvider = function (): SampleDatasetSchema {
return {
id: 'flights',
name: flightsName,
description: flightsDescription,
previewImagePath: '/plugins/home/assets/sample_data_resources/flights/dashboard.png',
darkPreviewImagePath: '/plugins/home/assets/sample_data_resources/flights/dashboard_dark.png',
overviewDashboard: '7adfa750-4c81-11e8-b3d7-01146121b73d',
overviewDashboard: appendDataSourceId(DASHBOARD_ID),
appLinks: initialAppLinks,
defaultIndex: 'd3d7af60-4c81-11e8-b3d7-01146121b73d',
savedObjects: getSavedObjects(),
defaultIndex: appendDataSourceId(DEFAULT_INDEX),
savedObjects: (dataSourceId?: string, dataSourceTitle?: string) =>
getSavedObjectsWithDataSource(getSavedObjects(), dataSourceId, dataSourceTitle),
dataIndices: [
{
id: 'flights',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { i18n } from '@osd/i18n';
import { getSavedObjects } from './saved_objects';
import { fieldMappings } from './field_mappings';
import { SampleDatasetSchema, AppLinkSchema } from '../../lib/sample_dataset_registry_types';
import { appendDataSourceId, getSavedObjectsWithDataSource } from '../util';

const logsName = i18n.translate('home.sampleData.logsSpecTitle', {
defaultMessage: 'Sample web logs',
Expand All @@ -42,17 +43,21 @@ const logsDescription = i18n.translate('home.sampleData.logsSpecDescription', {
});
const initialAppLinks = [] as AppLinkSchema[];

const DEFAULT_INDEX = '90943e30-9a47-11e8-b64d-95841ca0b247';
const DASHBOARD_ID = 'edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b';

export const logsSpecProvider = function (): SampleDatasetSchema {
return {
id: 'logs',
name: logsName,
description: logsDescription,
previewImagePath: '/plugins/home/assets/sample_data_resources/logs/dashboard.png',
darkPreviewImagePath: '/plugins/home/assets/sample_data_resources/logs/dashboard_dark.png',
overviewDashboard: 'edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b',
overviewDashboard: appendDataSourceId(DASHBOARD_ID),
appLinks: initialAppLinks,
defaultIndex: '90943e30-9a47-11e8-b64d-95841ca0b247',
savedObjects: getSavedObjects(),
defaultIndex: appendDataSourceId(DEFAULT_INDEX),
savedObjects: (dataSourceId?: string, dataSourceTitle?: string) =>
getSavedObjectsWithDataSource(getSavedObjects(), dataSourceId, dataSourceTitle),
dataIndices: [
{
id: 'logs',
Expand Down
84 changes: 84 additions & 0 deletions src/plugins/home/server/services/sample_data/data_sets/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { SavedObject } from 'opensearch-dashboards/server';

export const appendDataSourceId = (id: string) => {
return (dataSourceId?: string) => (dataSourceId ? `${dataSourceId}_` + id : id);
};

export const getSavedObjectsWithDataSource = (
saveObjectList: SavedObject[],
dataSourceId?: string,
dataSourceTitle?: string
): SavedObject[] => {
if (dataSourceId) {
return saveObjectList.map((saveObject) => {
saveObject.id = `${dataSourceId}_` + saveObject.id;
// update reference
if (saveObject.type === 'dashboard') {
saveObject.references.map((reference) => {
if (reference.id) {
reference.id = `${dataSourceId}_` + reference.id;
}
});
}

// update reference
if (saveObject.type === 'visualization' || saveObject.type === 'search') {
const searchSourceString = saveObject.attributes?.kibanaSavedObjectMeta?.searchSourceJSON;
const visStateString = saveObject.attributes?.visState;

if (searchSourceString) {
const searchSource = JSON.parse(searchSourceString);
if (searchSource.index) {
searchSource.index = `${dataSourceId}_` + searchSource.index;
saveObject.attributes.kibanaSavedObjectMeta.searchSourceJSON = JSON.stringify(
searchSource
);
}
}

if (visStateString) {
const visState = JSON.parse(visStateString);
const controlList = visState.params?.controls;
if (controlList) {
controlList.map((control) => {
if (control.indexPattern) {
control.indexPattern = `${dataSourceId}_` + control.indexPattern;
}
});
}
saveObject.attributes.visState = JSON.stringify(visState);
}
}

// update reference
if (saveObject.type === 'index-pattern') {
saveObject.references = [
{
id: `${dataSourceId}`,
type: 'data-source',
name: 'dataSource',
},
];
}

if (dataSourceTitle) {
if (
saveObject.type === 'dashboard' ||
saveObject.type === 'visualization' ||
saveObject.type === 'search'
) {
saveObject.attributes.title = saveObject.attributes.title + `_${dataSourceTitle}`;
}
}

return saveObject;
});
}

return saveObjectList;
};
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@ export interface SampleDatasetSchema<T = unknown> {
darkPreviewImagePath: string;

// saved object id of main dashboard for sample data set
overviewDashboard: string;
overviewDashboard: (dataSourceId?: string) => string;
appLinks: AppLinkSchema[];

// saved object id of default index-pattern for sample data set
defaultIndex: string;
defaultIndex: (dataSourceId?: string) => string;

// OpenSearch Dashboards saved objects (index patter, visualizations, dashboard, ...)
// Should provide a nice demo of OpenSearch Dashboards's functionality with the sample data set
savedObjects: Array<SavedObject<T>>;
savedObjects: (dataSourceId?: string, dataSourceTitle?: string) => Array<SavedObject<T>>;
dataIndices: DataIndexSchema[];
status?: string | undefined;
statusMsg?: unknown;
Expand Down
Loading

0 comments on commit b337bea

Please sign in to comment.