forked from opensearch-project/OpenSearch-Dashboards
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Dynamic Config Service to Core Service (opensearch-project#7194)
* Add dynamic config service to core Signed-off-by: Huy Nguyen <[email protected]> * Add opensearch client implementation Signed-off-by: Huy Nguyen <[email protected]> * Add descriptions for the DAO clients Signed-off-by: Huy Nguyen <[email protected]> * Refactor DynamicConfigService Signed-off-by: Huy Nguyen <[email protected]> * Refactor dynamic config service start Signed-off-by: Huy Nguyen <[email protected]> --------- Signed-off-by: Huy Nguyen <[email protected]> (cherry picked from commit 8a96664) Fix issue when bootstrapping on 2.x (opensearch-project#7901) * Fix issue bootstrapping dynamic config service Signed-off-by: Huy Nguyen <[email protected]> * Changeset file for PR opensearch-project#7901 created/updated --------- Signed-off-by: Huy Nguyen <[email protected]> Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> (cherry picked from commit 07504f6) Fix mock import (opensearch-project#7922) Signed-off-by: Huy Nguyen <[email protected]> (cherry picked from commit b370871)
- Loading branch information
Showing
79 changed files
with
3,637 additions
and
260 deletions.
There are no files selected for viewing
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,2 @@ | ||
fix: | ||
- Fix bootstrap errors in 2.x ([#7901](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7901)) |
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
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
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,96 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { IDynamicConfigService } from './dynamic_config_service'; | ||
import { | ||
DynamicConfigurationClientMockProps, | ||
dynamicConfigurationClientMock, | ||
} from './service/configuration_client.mock'; | ||
import { | ||
AsyncLocalStorageContext, | ||
DynamicConfigServiceSetup, | ||
DynamicConfigServiceStart, | ||
InternalDynamicConfigServiceSetup, | ||
InternalDynamicConfigServiceStart, | ||
} from './types'; | ||
|
||
const createDynamicConfigServiceMock = ( | ||
mockClientReturnValues?: DynamicConfigurationClientMockProps, | ||
mockAsyncLocalStoreValues?: AsyncLocalStorageContext | ||
) => { | ||
const mocked: jest.Mocked<IDynamicConfigService> = { | ||
setup: jest.fn().mockReturnValue(createInternalSetupContractMock()), | ||
start: jest | ||
.fn() | ||
.mockReturnValue( | ||
createInternalStartContractMock(mockClientReturnValues, mockAsyncLocalStoreValues) | ||
), | ||
stop: jest.fn(), | ||
setSchema: jest.fn(), | ||
hasDefaultConfigs: jest.fn(), | ||
registerRoutesAndHandlers: jest.fn(), | ||
}; | ||
|
||
return mocked; | ||
}; | ||
|
||
const createSetupContractMock = () => { | ||
const mocked: jest.Mocked<DynamicConfigServiceSetup> = { | ||
registerDynamicConfigClientFactory: jest.fn(), | ||
registerAsyncLocalStoreRequestHeader: jest.fn(), | ||
getStartService: jest.fn(), | ||
}; | ||
|
||
return mocked; | ||
}; | ||
const createInternalSetupContractMock = () => { | ||
const mocked: jest.Mocked<InternalDynamicConfigServiceSetup> = { | ||
registerDynamicConfigClientFactory: jest.fn(), | ||
registerAsyncLocalStoreRequestHeader: jest.fn(), | ||
getStartService: jest.fn(), | ||
}; | ||
|
||
return mocked; | ||
}; | ||
const createStartContractMock = ( | ||
mockClientReturnValues?: DynamicConfigurationClientMockProps, | ||
mockAsyncLocalStoreValues?: AsyncLocalStorageContext | ||
) => { | ||
const client = mockClientReturnValues | ||
? dynamicConfigurationClientMock.create(mockClientReturnValues) | ||
: dynamicConfigurationClientMock.create(); | ||
|
||
const mocked: jest.Mocked<DynamicConfigServiceStart> = { | ||
getClient: jest.fn().mockReturnValue(client), | ||
getAsyncLocalStore: jest.fn().mockReturnValue(mockAsyncLocalStoreValues), | ||
createStoreFromRequest: jest.fn().mockRejectedValue(mockAsyncLocalStoreValues), | ||
}; | ||
|
||
return mocked; | ||
}; | ||
const createInternalStartContractMock = ( | ||
mockClientReturnValues?: DynamicConfigurationClientMockProps, | ||
mockAsyncLocalStoreValues?: AsyncLocalStorageContext | ||
) => { | ||
const client = mockClientReturnValues | ||
? dynamicConfigurationClientMock.create(mockClientReturnValues) | ||
: dynamicConfigurationClientMock.create(); | ||
|
||
const mocked: jest.Mocked<InternalDynamicConfigServiceStart> = { | ||
getClient: jest.fn().mockReturnValue(client), | ||
getAsyncLocalStore: jest.fn().mockReturnValue(mockAsyncLocalStoreValues), | ||
createStoreFromRequest: jest.fn().mockRejectedValue(mockAsyncLocalStoreValues), | ||
}; | ||
|
||
return mocked; | ||
}; | ||
|
||
export const dynamicConfigServiceMock = { | ||
create: createDynamicConfigServiceMock, | ||
createInternalSetupContract: createInternalSetupContractMock, | ||
createInternalStartContract: createInternalStartContractMock, | ||
createSetupContract: createSetupContractMock, | ||
createStartContract: createStartContractMock, | ||
}; |
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,103 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { DynamicConfigService, IDynamicConfigService } from './dynamic_config_service'; | ||
import { configServiceMock, httpServiceMock, opensearchServiceMock } from '../mocks'; | ||
import { loggerMock } from '../logging/logger.mock'; | ||
import { LoggerFactory } from '@osd/logging'; | ||
import { schema, Type } from '@osd/config-schema'; | ||
import { IDynamicConfigStoreClient } from 'opensearch-dashboards/server'; | ||
|
||
describe('DynamicConfigService', () => { | ||
let dynamicConfigService: IDynamicConfigService; | ||
const openSearchMock = opensearchServiceMock.createStart(); | ||
|
||
beforeEach(() => { | ||
const loggerFactoryMock = {} as LoggerFactory; | ||
loggerFactoryMock.get = jest.fn().mockReturnValue(loggerMock.create()); | ||
|
||
dynamicConfigService = new DynamicConfigService( | ||
configServiceMock.create(), | ||
{} as any, | ||
loggerFactoryMock | ||
); | ||
}); | ||
|
||
it('setup() and start() should return the same clients/async local stores', async () => { | ||
const dynamicConfigServiceSetup = await dynamicConfigService.setup(); | ||
expect(dynamicConfigServiceSetup.getStartService()).toBeDefined(); | ||
expect(dynamicConfigServiceSetup.registerDynamicConfigClientFactory).toBeDefined(); | ||
expect(dynamicConfigServiceSetup.registerAsyncLocalStoreRequestHeader).toBeDefined(); | ||
|
||
dynamicConfigServiceSetup.registerDynamicConfigClientFactory({ | ||
create: () => { | ||
return {} as IDynamicConfigStoreClient; | ||
}, | ||
}); | ||
|
||
const dynamicConfigServiceStart = await dynamicConfigService.start({ | ||
opensearch: openSearchMock, | ||
}); | ||
expect(dynamicConfigServiceStart.getAsyncLocalStore).toBeDefined(); | ||
expect(dynamicConfigServiceStart.getClient()).toBeDefined(); | ||
|
||
const actualGetStartServices = await dynamicConfigServiceSetup.getStartService(); | ||
|
||
expect(actualGetStartServices.getClient()).toMatchObject(dynamicConfigServiceStart.getClient()); | ||
expect(actualGetStartServices.getAsyncLocalStore).toBeDefined(); | ||
}); | ||
|
||
describe('After http is setup', () => { | ||
it('setupHTTP() should add the async local store preAuth middleware', () => { | ||
const httpSetupMock = httpServiceMock.createInternalSetupContract(); | ||
dynamicConfigService.registerRoutesAndHandlers({ http: httpSetupMock }); | ||
expect(httpSetupMock.registerOnPostAuth).toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
it('setSchema() and hasDefaultConfigs() should set and check if schemas have been registered', () => { | ||
const schemaList: Map<string, Type<unknown>> = new Map(); | ||
|
||
schemaList.set( | ||
'foo', | ||
schema.object({ | ||
a: schema.boolean(), | ||
b: schema.object({ | ||
c: schema.string(), | ||
}), | ||
}) | ||
); | ||
schemaList.set( | ||
'bar', | ||
schema.object({ | ||
a: schema.boolean(), | ||
b: schema.boolean(), | ||
c: schema.object({ | ||
d: schema.string(), | ||
}), | ||
}) | ||
); | ||
schemaList.set( | ||
'baz', | ||
schema.object({ | ||
a: schema.object({ | ||
c: schema.object({ | ||
d: schema.boolean(), | ||
}), | ||
}), | ||
}) | ||
); | ||
|
||
schemaList.forEach((value, key) => { | ||
dynamicConfigService.setSchema(key, value); | ||
}); | ||
|
||
[...schemaList.keys()].forEach((key) => { | ||
expect(dynamicConfigService.hasDefaultConfigs({ name: key })).toBe(true); | ||
}); | ||
|
||
expect(dynamicConfigService.hasDefaultConfigs({ name: 'nonexistent_config' })).toBe(false); | ||
}); | ||
}); |
Oops, something went wrong.