Skip to content

Commit

Permalink
[Workspace] Handle data sources and advanced settings as global objec…
Browse files Browse the repository at this point in the history
…t. (opensearch-project#6524)

* Handle data sources and advanced settings as global object. (#313)

* feat: POC implementation

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: add some comment

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: revert dependency

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: update comment

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: address one TODO

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: address TODO

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: add unit test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: some special logic on specific operation

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: add integration test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: declare workspaces as empty array for advanced settings

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: unified workspaces parameters when parsing from router

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: improve code coverage

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: declare workspaces as null

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: use unified types

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: update comment

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: remove null

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: address comments

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: use request app to store request workspace id

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: use app state to store request workspace id

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: remove workspaces when listing data sources

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: remove useless code change

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: throw error if the type is not allowed

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: add unit test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: add integration test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: change the implementation

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: remove useless change

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: remove useless change

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: add integration test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* fix: unit test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: add error message

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* fix: integration test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* fix: integration test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: remove useless change

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: add test case and add restrict on create method

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: change type

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: change comment

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: optimize test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* refactor: move logic to conflict check wrapper

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: remove useless change

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* fix: unit test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* fix: unit test

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

---------

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* Changeset file for PR opensearch-project#6524 created/updated

* Apply suggestions from code review

Co-authored-by: Lu Yu <nluyu@amazon.com>
Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: optimize based on comment

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

* feat: remove useless default value

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>

---------

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
Co-authored-by: Lu Yu <nluyu@amazon.com>
  • Loading branch information
3 people authored Apr 19, 2024
1 parent e34ca2b commit da88296
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 4 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/6524.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
feat:
- [Workspace] Handle data sources and advanced settings as global object. ([#6524](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6524))
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,30 @@

import { SavedObject } from 'src/core/types';
import { isEqual } from 'lodash';
import packageInfo from '../../../../../../package.json';
import * as osdTestServer from '../../../../../core/test_helpers/osd_server';
import { DATA_SOURCE_SAVED_OBJECT_TYPE } from '../../../../data_source/common';

const dashboard: Omit<SavedObject, 'id'> = {
type: 'dashboard',
attributes: {},
references: [],
};

const dataSource: Omit<SavedObject, 'id'> = {
type: DATA_SOURCE_SAVED_OBJECT_TYPE,
attributes: {
title: 'test data source',
},
references: [],
};

const advancedSettings: Omit<SavedObject, 'id'> = {
type: 'config',
attributes: {},
references: [],
};

interface WorkspaceAttributes {
id: string;
name?: string;
Expand All @@ -32,6 +48,9 @@ describe('saved_objects_wrapper_for_check_workspace_conflict integration test',
adjustTimeout: (t: number) => jest.setTimeout(t),
settings: {
osd: {
data_source: {
enabled: true,
},
workspace: {
enabled: true,
},
Expand Down Expand Up @@ -145,6 +164,40 @@ describe('saved_objects_wrapper_for_check_workspace_conflict integration test',
});
});

it('create disallowed types within workspace', async () => {
const createDataSourceResult = await osdTestServer.request
.post(root, `/api/saved_objects/${dataSource.type}`)
.send({
attributes: dataSource.attributes,
workspaces: [createdFooWorkspace.id],
})
.expect(400);

expect(createDataSourceResult.body).toMatchInlineSnapshot(`
Object {
"error": "Bad Request",
"message": "Unsupported type in workspace: 'data-source' is not allowed to be created in workspace.",
"statusCode": 400,
}
`);

const createConfigResult = await osdTestServer.request
.post(root, `/api/saved_objects/config`)
.send({
attributes: advancedSettings.attributes,
workspaces: [createdFooWorkspace.id],
})
.expect(400);

expect(createConfigResult.body).toMatchInlineSnapshot(`
Object {
"error": "Bad Request",
"message": "Unsupported type in workspace: 'config' is not allowed to be created in workspace.",
"statusCode": 400,
}
`);
});

it('bulk create', async () => {
await clearFooAndBar();
const createResultFoo = await osdTestServer.request
Expand Down Expand Up @@ -254,6 +307,80 @@ describe('saved_objects_wrapper_for_check_workspace_conflict integration test',
);
});

it('bulk create with disallowed types in workspace', async () => {
await clearFooAndBar();

// import advanced settings and data sources should throw error
const createResultFoo = await osdTestServer.request
.post(root, `/w/${createdFooWorkspace.id}/api/saved_objects/_bulk_create`)
.send([
{
...dataSource,
id: 'foo',
},
{
...advancedSettings,
id: packageInfo.version,
},
])
.expect(200);
expect(createResultFoo.body.saved_objects[0].error).toEqual(
expect.objectContaining({
message:
"Unsupported type in workspace: 'data-source' is not allowed to be imported in workspace.",
statusCode: 400,
})
);
expect(createResultFoo.body.saved_objects[1].error).toEqual(
expect.objectContaining({
message:
"Unsupported type in workspace: 'config' is not allowed to be imported in workspace.",
statusCode: 400,
})
);

// Data source should not be created
await osdTestServer.request
.get(
root,
`/w/${createdFooWorkspace.id}/api/saved_objects/${DATA_SOURCE_SAVED_OBJECT_TYPE}/foo`
)
.expect(404);

// Advanced settings should not be created within workspace
const findAdvancedSettings = await osdTestServer.request
.get(root, `/w/${createdFooWorkspace.id}/api/saved_objects/_find?type=config`)
.expect(200);
expect(findAdvancedSettings.body.total).toEqual(0);
});

it('bulk create with disallowed types out of workspace', async () => {
await clearFooAndBar();

// import advanced settings and data sources should throw error
const createResultFoo = await osdTestServer.request
.post(root, `/api/saved_objects/_bulk_create`)
.send([
{
...advancedSettings,
id: packageInfo.version,
},
])
.expect(200);
expect(createResultFoo.body).toEqual({
saved_objects: [
expect.objectContaining({
type: advancedSettings.type,
}),
],
});

const findAdvancedSettings = await osdTestServer.request
.get(root, `/api/saved_objects/_find?type=${advancedSettings.type}`)
.expect(200);
expect(findAdvancedSettings.body.total).toEqual(1);
});

it('checkConflicts when importing ndjson', async () => {
await clearFooAndBar();
const createResultFoo = await osdTestServer.request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { SavedObject } from '../../../../core/public';
import { httpServerMock, savedObjectsClientMock, coreMock } from '../../../../core/server/mocks';
import { WorkspaceConflictSavedObjectsClientWrapper } from './saved_objects_wrapper_for_check_workspace_conflict';
import { SavedObjectsSerializer } from '../../../../core/server';
import { DATA_SOURCE_SAVED_OBJECT_TYPE } from '../../../../plugins/data_source/common';

describe('WorkspaceConflictSavedObjectsClientWrapper', () => {
const requestHandlerContext = coreMock.createRequestHandlerContext();
Expand Down Expand Up @@ -115,6 +116,38 @@ describe('WorkspaceConflictSavedObjectsClientWrapper', () => {
})
);
});

it(`Should throw error when trying to create disallowed types in workspace`, async () => {
await expect(
wrapperClient.create(
DATA_SOURCE_SAVED_OBJECT_TYPE,
{
name: 'foo',
},

{
workspaces: ['foo'],
}
)
).rejects.toMatchInlineSnapshot(
`[Error: Unsupported type in workspace: 'data-source' is not allowed to be created in workspace.]`
);

await expect(
wrapperClient.create(
'config',
{
name: 'foo',
},

{
workspaces: ['foo'],
}
)
).rejects.toMatchInlineSnapshot(
`[Error: Unsupported type in workspace: 'config' is not allowed to be created in workspace.]`
);
});
});

describe('bulkCreateWithWorkspaceConflictCheck', () => {
Expand Down Expand Up @@ -291,6 +324,42 @@ describe('WorkspaceConflictSavedObjectsClientWrapper', () => {
}
`);
});
it(`Should return error when trying to create disallowed types within a workspace`, async () => {
mockedClient.bulkCreate.mockResolvedValueOnce({ saved_objects: [] });
const result = await wrapperClient.bulkCreate(
[
getSavedObject({
type: 'config',
id: 'foo',
}),
getSavedObject({
type: DATA_SOURCE_SAVED_OBJECT_TYPE,
id: 'foo',
}),
],
{
workspaces: ['foo'],
}
);

expect(mockedClient.bulkCreate).toBeCalledWith([], {
workspaces: ['foo'],
});
expect(result.saved_objects[0].error).toEqual(
expect.objectContaining({
message:
"Unsupported type in workspace: 'config' is not allowed to be imported in workspace.",
statusCode: 400,
})
);
expect(result.saved_objects[1].error).toEqual(
expect.objectContaining({
message:
"Unsupported type in workspace: 'data-source' is not allowed to be imported in workspace.",
statusCode: 400,
})
);
});
});

describe('checkConflictWithWorkspaceConflictCheck', () => {
Expand Down Expand Up @@ -393,4 +462,20 @@ describe('WorkspaceConflictSavedObjectsClientWrapper', () => {
`);
});
});

describe('find', () => {
beforeEach(() => {
mockedClient.find.mockClear();
});

it(`workspaces parameters should be removed when finding data sources`, async () => {
await wrapperClient.find({
type: DATA_SOURCE_SAVED_OBJECT_TYPE,
workspaces: ['foo'],
});
expect(mockedClient.find).toBeCalledWith({
type: DATA_SOURCE_SAVED_OBJECT_TYPE,
});
});
});
});
Loading

0 comments on commit da88296

Please sign in to comment.