Skip to content

Commit f2c0686

Browse files
github-actions[bot]opensearch-changeset-bot[bot]Kapian1234wanglamruanyl
authored andcommitted
[Workspace] Enable direct query connections to support in workspace (#7839)
* add dqc Signed-off-by: yubonluo <yubonluo@amazon.com> * add dircet query connections on the detail page Signed-off-by: yubonluo <yubonluo@amazon.com> * Changeset file for PR #7839 created/updated * delete useless code Signed-off-by: yubonluo <yubonluo@amazon.com> * optimize the code Signed-off-by: yubonluo <yubonluo@amazon.com> * optimize the code Signed-off-by: yubonluo <yubonluo@amazon.com> * Refactor association modal Signed-off-by: Kapian1234 <wanjinch@amazon.com> * Integrate modal with workspace detail page Signed-off-by: Lin Wang <wonglam@amazon.com> * Fix parent data source unchecked Signed-off-by: Lin Wang <wonglam@amazon.com> * Remove all tab and sort connections by name alphabetical Signed-off-by: Lin Wang <wonglam@amazon.com> * optimzie Signed-off-by: yubonluo <yubonluo@amazon.com> * Fix checked status disappear after modal tab change Signed-off-by: Lin Wang <wonglam@amazon.com> * optimize the dqc table Signed-off-by: yubonluo <yubonluo@amazon.com> * optimize the code Signed-off-by: yubonluo <yubonluo@amazon.com> * update the table css Signed-off-by: yubonluo <yubonluo@amazon.com> * Simplify options update logic Signed-off-by: Lin Wang <wonglam@amazon.com> * Add unit tests for AssociationDataSourceModal Signed-off-by: Lin Wang <wonglam@amazon.com> * add unit test Signed-off-by: yubonluo <yubonluo@amazon.com> * optimize the code Signed-off-by: yubonluo <yubonluo@amazon.com> * Add nested support in associate data source modal Signed-off-by: Lin Wang <wonglam@amazon.com> * delete useless code Signed-off-by: yubonluo <yubonluo@amazon.com> * Change back type Signed-off-by: Lin Wang <wonglam@amazon.com> * Update type in modal UT Signed-off-by: Lin Wang <wonglam@amazon.com> * optimize the code Signed-off-by: yubonluo <yubonluo@amazon.com> --------- Signed-off-by: yubonluo <yubonluo@amazon.com> Signed-off-by: Kapian1234 <wanjinch@amazon.com> Signed-off-by: Lin Wang <wonglam@amazon.com> Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> Co-authored-by: Kapian1234 <wanjinch@amazon.com> Co-authored-by: Lin Wang <wonglam@amazon.com> Co-authored-by: Yulong Ruan <ruanyl@amazon.com> (cherry picked from commit 0798865) Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 4c64d81 commit f2c0686

24 files changed

+1426
-401
lines changed

changelogs/fragments/7839.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fix:
2+
- Enable direct query connections to support in workspace ([#7839](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7839))

src/plugins/data_source_management/public/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export function plugin() {
1111
return new DataSourceManagementPlugin();
1212
}
1313

14-
export { DataSourceManagementPluginStart } from './types';
14+
export { DataSourceManagementPluginStart, DirectQueryDatasourceDetails } from './types';
1515
export { DataSourceSelector, DataSourceOption } from './components/data_source_selector';
1616
export { DataSourceMenu } from './components/data_source_menu';
1717
export { DataSourceManagementPlugin, DataSourceManagementPluginSetup } from './plugin';
@@ -26,3 +26,4 @@ export {
2626
} from './components/data_source_menu';
2727
export { DataSourceSelectionService } from './service/data_source_selection_service';
2828
export { getDefaultDataSourceId, getDefaultDataSourceId$ } from './components/utils';
29+
export { DATACONNECTIONS_BASE, DatasourceTypeToDisplayName } from './constants';

src/plugins/workspace/common/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,8 @@ export const CURRENT_USER_PLACEHOLDER = '%me%';
148148
export const MAX_WORKSPACE_NAME_LENGTH = 40;
149149
export const MAX_WORKSPACE_DESCRIPTION_LENGTH = 200;
150150

151+
export enum AssociationDataSourceModalMode {
152+
OpenSearchConnections = 'opensearch-connections',
153+
DirectQueryConnections = 'direction-query-connections',
154+
}
151155
export const USE_CASE_PREFIX = 'use-case-';

src/plugins/workspace/common/types.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,18 @@ export type DataSource = Pick<
1212
// Id defined in SavedObjectAttribute could be single or array, here only should be single string.
1313
id: string;
1414
};
15+
16+
export enum DataSourceConnectionType {
17+
OpenSearchConnection,
18+
DirectQueryConnection,
19+
}
20+
21+
export interface DataSourceConnection {
22+
id: string;
23+
type: string | undefined;
24+
parentId?: string;
25+
connectionType: DataSourceConnectionType;
26+
name: string;
27+
description?: string;
28+
relatedConnections?: DataSourceConnection[];
29+
}

src/plugins/workspace/opensearch_dashboards.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
"navigation"
1010
],
1111
"optionalPlugins": ["savedObjectsManagement","management","dataSourceManagement","contentManagement"],
12-
"requiredBundles": ["opensearchDashboardsReact","dataSource","contentManagement"]
12+
"requiredBundles": ["opensearchDashboardsReact","dataSource", "dataSourceManagement","contentManagement"]
1313
}

src/plugins/workspace/public/assets/prometheus_logo.svg

Lines changed: 9 additions & 0 deletions
Loading

src/plugins/workspace/public/assets/s3_logo.svg

Lines changed: 9 additions & 0 deletions
Loading

src/plugins/workspace/public/components/workspace_detail/__snapshots__/workspace_detail.test.tsx.snap

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
6+
import React from 'react';
7+
import { IntlProvider } from 'react-intl';
8+
9+
import { DataSourceConnectionType } from '../../../common/types';
10+
import { chromeServiceMock, coreMock } from '../../../../../core/public/mocks';
11+
import * as utilsExports from '../../utils';
12+
13+
import {
14+
AssociationDataSourceModal,
15+
AssociationDataSourceModalProps,
16+
} from './association_data_source_modal';
17+
import { AssociationDataSourceModalMode } from 'src/plugins/workspace/common/constants';
18+
19+
const setupAssociationDataSourceModal = ({
20+
mode,
21+
assignedConnections,
22+
handleAssignDataSourceConnections,
23+
}: Partial<AssociationDataSourceModalProps> = {}) => {
24+
const coreServices = coreMock.createStart();
25+
jest.spyOn(utilsExports, 'getDataSourcesList').mockResolvedValue([]);
26+
jest.spyOn(utilsExports, 'fetchDataSourceConnections').mockResolvedValue([
27+
{
28+
id: 'ds1',
29+
name: 'Data Source 1',
30+
connectionType: DataSourceConnectionType.OpenSearchConnection,
31+
type: 'OpenSearch',
32+
relatedConnections: [
33+
{
34+
id: 'ds1-dqc1',
35+
name: 'dqc1',
36+
parentId: 'ds1',
37+
connectionType: DataSourceConnectionType.DirectQueryConnection,
38+
type: 'Amazon S3',
39+
},
40+
],
41+
},
42+
{
43+
id: 'ds1-dqc1',
44+
name: 'dqc1',
45+
parentId: 'ds1',
46+
connectionType: DataSourceConnectionType.DirectQueryConnection,
47+
type: 'Amazon S3',
48+
},
49+
{
50+
id: 'ds2',
51+
name: 'Data Source 2',
52+
connectionType: DataSourceConnectionType.OpenSearchConnection,
53+
type: 'OpenSearch',
54+
},
55+
]);
56+
const { logos } = chromeServiceMock.createStartContract();
57+
render(
58+
<IntlProvider locale="en">
59+
<AssociationDataSourceModal
60+
logos={logos}
61+
mode={mode ?? AssociationDataSourceModalMode.OpenSearchConnections}
62+
http={coreServices.http}
63+
notifications={coreServices.notifications}
64+
savedObjects={coreServices.savedObjects}
65+
closeModal={jest.fn()}
66+
assignedConnections={assignedConnections ?? []}
67+
handleAssignDataSourceConnections={handleAssignDataSourceConnections ?? jest.fn()}
68+
/>
69+
</IntlProvider>
70+
);
71+
return {};
72+
};
73+
74+
describe('AssociationDataSourceModal', () => {
75+
const originalOffsetHeight = Object.getOwnPropertyDescriptor(
76+
HTMLElement.prototype,
77+
'offsetHeight'
78+
);
79+
const originalOffsetWidth = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetWidth');
80+
beforeEach(() => {
81+
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
82+
configurable: true,
83+
value: 600,
84+
});
85+
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
86+
configurable: true,
87+
value: 600,
88+
});
89+
});
90+
91+
afterEach(() => {
92+
Object.defineProperty(
93+
HTMLElement.prototype,
94+
'offsetHeight',
95+
originalOffsetHeight as PropertyDescriptor
96+
);
97+
Object.defineProperty(
98+
HTMLElement.prototype,
99+
'offsetWidth',
100+
originalOffsetWidth as PropertyDescriptor
101+
);
102+
});
103+
104+
it('should display opensearch connections', async () => {
105+
setupAssociationDataSourceModal();
106+
expect(screen.getByText('Associate OpenSearch connections')).toBeInTheDocument();
107+
expect(
108+
screen.getByText(
109+
'Add data sources that will be available in the workspace. If a selected data source has related Direct Query connection, they will also be available in the workspace.'
110+
)
111+
).toBeInTheDocument();
112+
await waitFor(() => {
113+
expect(screen.getByRole('option', { name: 'Data Source 1' })).toBeInTheDocument();
114+
expect(screen.getByRole('option', { name: 'Data Source 2' })).toBeInTheDocument();
115+
});
116+
});
117+
118+
it('should display direct query connections after opensearch connection selected', async () => {
119+
setupAssociationDataSourceModal({
120+
mode: AssociationDataSourceModalMode.DirectQueryConnections,
121+
});
122+
expect(screen.getByText('Associate direct query connections')).toBeInTheDocument();
123+
await waitFor(() => {
124+
expect(screen.queryByRole('option', { name: 'dqc1' })).not.toBeInTheDocument();
125+
fireEvent.click(screen.getByRole('option', { name: 'Data Source 1' }));
126+
expect(screen.getByRole('option', { name: 'dqc1' })).toBeInTheDocument();
127+
});
128+
});
129+
130+
it('should hide associated connections', async () => {
131+
setupAssociationDataSourceModal({
132+
assignedConnections: [
133+
{
134+
id: 'ds2',
135+
name: 'Data Source 2',
136+
connectionType: DataSourceConnectionType.OpenSearchConnection,
137+
type: 'OpenSearch',
138+
},
139+
],
140+
});
141+
expect(
142+
screen.getByText(
143+
'Add data sources that will be available in the workspace. If a selected data source has related Direct Query connection, they will also be available in the workspace.'
144+
)
145+
).toBeInTheDocument();
146+
await waitFor(() => {
147+
expect(screen.getByRole('option', { name: 'Data Source 1' })).toBeInTheDocument();
148+
expect(screen.queryByRole('option', { name: 'Data Source 2' })).not.toBeInTheDocument();
149+
});
150+
});
151+
152+
it('should call handleAssignDataSourceConnections with opensearch connections after assigned', async () => {
153+
const handleAssignDataSourceConnectionsMock = jest.fn();
154+
setupAssociationDataSourceModal({
155+
handleAssignDataSourceConnections: handleAssignDataSourceConnectionsMock,
156+
});
157+
158+
await waitFor(() => {
159+
fireEvent.click(screen.getByRole('option', { name: 'Data Source 1' }));
160+
fireEvent.click(screen.getByRole('button', { name: 'Associate data sources' }));
161+
});
162+
163+
expect(handleAssignDataSourceConnectionsMock).toHaveBeenCalledWith([
164+
{
165+
id: 'ds1',
166+
name: 'Data Source 1',
167+
connectionType: DataSourceConnectionType.OpenSearchConnection,
168+
type: 'OpenSearch',
169+
relatedConnections: [
170+
{
171+
id: 'ds1-dqc1',
172+
name: 'dqc1',
173+
parentId: 'ds1',
174+
connectionType: DataSourceConnectionType.DirectQueryConnection,
175+
type: 'Amazon S3',
176+
},
177+
],
178+
},
179+
]);
180+
});
181+
});

0 commit comments

Comments
 (0)