Skip to content

Commit

Permalink
Fix Datasource testing connection don't validate endpoints with path (o…
Browse files Browse the repository at this point in the history
…pensearch-project#5663)

* fix Datasource testing connection don't validate endpoints with path opensearch-project#5656
Signed-off-by: Xinrui Bai <[email protected]>
  • Loading branch information
xinruiba committed Jan 23, 2024
1 parent e83b7ee commit b5d39b6
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [BUG][Discover] Fix advanced setting `discover:modifyColumnsOnSwitch` ([#5508](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5508))
- [Discover] Fix missing index pattern field from breaking Discover [#5626](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5626)
- [BUG] Remove duplicate sample data as id 90943e30-9a47-11e8-b64d-95841ca0b247 ([5668](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5668))
- [BUG][Multiple Datasource] Fix datasource testing connection unexpectedly passed with wrong endpoint [#5663](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5663)

### 🚞 Infrastructure

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { opensearchServiceMock } from '../../../../core/server/mocks';
import { DataSourceConnectionValidator } from './data_source_connection_validator';
import { SigV4ServiceName } from '../../common/data_sources';

describe('DataSourceManagement: data_source_connection_validator.ts', () => {
describe('Test datasource connection without SigV4 auth', () => {
test('Success: opensearch client response code is 200 and response body have cluster name', async () => {
const opensearchClient = opensearchServiceMock.createOpenSearchClient();
opensearchClient.info.mockResolvedValue(
opensearchServiceMock.createApiResponse({
statusCode: 200,
body: {
cluster_name: 'This is the cluster name',
},
})
);
const dataSourceValidator = new DataSourceConnectionValidator(opensearchClient, {});
const validateDataSourcesResponse = await dataSourceValidator.validate();
expect(validateDataSourcesResponse.statusCode).toBe(200);
});

test('failure: opensearch client response code is 200 but response body not have cluster name', async () => {
try {
const opensearchClient = opensearchServiceMock.createOpenSearchClient();
opensearchClient.info.mockResolvedValue(
opensearchServiceMock.createApiResponse({
statusCode: 200,
body: {
Message: 'Response without cluster name.',
},
})
);
const dataSourceValidator = new DataSourceConnectionValidator(opensearchClient, {});
await dataSourceValidator.validate();
} catch (e) {
expect(e).toBeTruthy();
expect(e.message).toContain('Response without cluster name.');
}
});

test('failure: opensearch client response code is other than 200', async () => {
const statusCodeList = [100, 202, 300, 400, 500];
statusCodeList.forEach(async function (code) {
try {
const opensearchClient = opensearchServiceMock.createOpenSearchClient();
opensearchClient.info.mockResolvedValue(
opensearchServiceMock.createApiResponse({
statusCode: code,
body: {
Message: 'Your request is not correct.',
},
})
);
const dataSourceValidator = new DataSourceConnectionValidator(opensearchClient, {});
await dataSourceValidator.validate();
} catch (e) {
expect(e).toBeTruthy();
expect(e.message).toContain('Your request is not correct.');
}
});
});
});

describe('Test datasource connection for SigV4 auth', () => {
test('Success: opensearch client response code is 200 and response body is not empty', async () => {
const opensearchClient = opensearchServiceMock.createOpenSearchClient();
opensearchClient.cat.indices.mockResolvedValue(opensearchServiceMock.createApiResponse());
const dataSourceValidator = new DataSourceConnectionValidator(opensearchClient, {
auth: {
credentials: {
service: SigV4ServiceName.OpenSearchServerless,
},
},
});
const validateDataSourcesResponse = await dataSourceValidator.validate();
expect(validateDataSourcesResponse.statusCode).toBe(200);
});

test('failure: opensearch client response code is 200 and response body is empty', async () => {
try {
const opensearchClient = opensearchServiceMock.createOpenSearchClient();
opensearchClient.cat.indices.mockResolvedValue(opensearchServiceMock.createApiResponse());
const dataSourceValidator = new DataSourceConnectionValidator(opensearchClient, {
auth: {
statusCode: 200,
body: '',
credentials: {
service: SigV4ServiceName.OpenSearchServerless,
},
},
});
const validateDataSourcesResponse = await dataSourceValidator.validate();
expect(validateDataSourcesResponse.statusCode).toBe(200);
} catch (e) {
expect(e).toBeTruthy();
}
});

test('failure: opensearch client response code is other than 200', async () => {
const statusCodeList = [100, 202, 300, 400, 500];
statusCodeList.forEach(async function (code) {
try {
const opensearchClient = opensearchServiceMock.createOpenSearchClient();
opensearchClient.cat.indices.mockResolvedValue(
opensearchServiceMock.createApiResponse({
statusCode: code,
body: {
Message: 'Your request is not correct.',
},
})
);
const dataSourceValidator = new DataSourceConnectionValidator(opensearchClient, {
auth: {
credentials: {
service: SigV4ServiceName.OpenSearchServerless,
},
},
});
await dataSourceValidator.validate();
} catch (e) {
expect(e).toBeTruthy();
expect(e.message).toContain('Your request is not correct.');
}
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,23 @@ export class DataSourceConnectionValidator {

async validate() {
try {
let validationResponse;
// Amazon OpenSearch Serverless does not support .info() API
if (this.dataSourceAttr.auth?.credentials?.service === SigV4ServiceName.OpenSearchServerless)
return await this.callDataCluster.cat.indices();
return await this.callDataCluster.info();
if (
this.dataSourceAttr.auth?.credentials?.service === SigV4ServiceName.OpenSearchServerless
) {
validationResponse = await this.callDataCluster.cat.indices();
if (validationResponse?.statusCode === 200 && validationResponse?.body) {
return validationResponse;
}
} else {
validationResponse = await this.callDataCluster.info();
if (validationResponse?.statusCode === 200 && validationResponse?.body?.cluster_name) {
return validationResponse;
}
}

throw new Error(JSON.stringify(validationResponse?.body));
} catch (e) {
throw createDataSourceError(e);
}
Expand Down

0 comments on commit b5d39b6

Please sign in to comment.