Skip to content

Commit

Permalink
[Refractor] Feature flag (opensearch-project#102)
Browse files Browse the repository at this point in the history
* feat: add some flag

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

* refractor: add enabled$ in server side

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

* feat: add logic check in public side

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

* feature: remove useless property

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

* feat: some modify

* feat: merge

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

* feat: remove useless code

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

* feat: remove useless code

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

* feat: optimize code

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

---------

Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
  • Loading branch information
SuZhou-Joe committed Aug 31, 2023
1 parent acca4b2 commit db33da9
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 10 deletions.
3 changes: 2 additions & 1 deletion src/plugins/workspace/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import { schema, TypeOf } from '@osd/config-schema';

export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: false }),
dashboardAdmin: schema.object(
{
backendRoles: schema.arrayOf(schema.string(), {
Expand All @@ -22,3 +21,5 @@ export const configSchema = schema.object({
});

export type ConfigSchema = TypeOf<typeof configSchema>;

export const FEATURE_FLAG_KEY_IN_UI_SETTING = 'workspace_enabled';
14 changes: 13 additions & 1 deletion src/plugins/workspace/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,16 @@ export class WorkspacePlugin implements Plugin<{}, {}, WorkspacePluginSetupDeps>
) {
const workspaceClient = new WorkspaceClient(core.http, core.workspaces);
workspaceClient.init();
core.workspaces.workspaceEnabled$.next(true);
const featureFlagResp = await workspaceClient.getSettings();
if (featureFlagResp.success) {
core.workspaces.workspaceEnabled$.next(featureFlagResp.result.enabled);
} else {
core.workspaces.workspaceEnabled$.next(false);
}

if (!core.workspaces.workspaceEnabled$.getValue()) {
return {};
}

core.workspaces.registerWorkspaceMenuRender(renderWorkspaceMenu);

Expand Down Expand Up @@ -241,6 +250,9 @@ export class WorkspacePlugin implements Plugin<{}, {}, WorkspacePluginSetupDeps>
}

public start(core: CoreStart) {
if (!core.workspaces.workspaceEnabled$.getValue()) {
return {};
}
this.coreStart = core;

mountDropdownList({
Expand Down
12 changes: 12 additions & 0 deletions src/plugins/workspace/public/workspace_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,18 @@ export class WorkspaceClient {
return result;
}

public async getSettings(): Promise<
IResponse<{
enabled: boolean;
}>
> {
const result = await this.safeFetch(this.getPath(['settings']), {
method: 'get',
});

return result;
}

public stop() {
this.workspaces.workspaceList$.unsubscribe();
this.workspaces.currentWorkspaceId$.unsubscribe();
Expand Down
76 changes: 68 additions & 8 deletions src/plugins/workspace/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { i18n } from '@osd/i18n';
import { Observable } from 'rxjs';
import { BehaviorSubject, Observable } from 'rxjs';

import {
PluginInitializerContext,
Expand All @@ -26,19 +26,28 @@ import { IWorkspaceDBImpl } from './types';
import { WorkspaceClientWithSavedObject } from './workspace_client';
import { WorkspaceSavedObjectsClientWrapper } from './saved_objects';
import { registerRoutes } from './routes';
import { ConfigSchema } from '../config';
import { WORKSPACE_OVERVIEW_APP_ID } from '../common/constants';
import { ConfigSchema, FEATURE_FLAG_KEY_IN_UI_SETTING } from '../config';

export class WorkspacePlugin implements Plugin<{}, {}> {
private readonly logger: Logger;
private client?: IWorkspaceDBImpl;
private coreStart?: CoreStart;
private config$: Observable<ConfigSchema>;
private enabled$: BehaviorSubject<boolean> = new BehaviorSubject(false);

private get isEnabled() {
return this.enabled$.getValue();
}

private proxyWorkspaceTrafficToRealHandler(setupDeps: CoreSetup) {
/**
* Proxy all {basePath}/w/{workspaceId}{osdPath*} paths to {basePath}{osdPath*}
*/
setupDeps.http.registerOnPreRouting(async (request, response, toolkit) => {
if (!this.isEnabled) {
return toolkit.next();
}
const regexp = /\/w\/([^\/]*)/;
const matchedResult = request.url.pathname.match(regexp);

Expand Down Expand Up @@ -81,14 +90,27 @@ export class WorkspacePlugin implements Plugin<{}, {}> {
http: core.http,
logger: this.logger,
client: this.client as IWorkspaceDBImpl,
enabled$: this.enabled$,
config$: this.config$,
});

core.savedObjects.setClientFactoryProvider((repositoryFactory) => () =>
new SavedObjectsClient(repositoryFactory.createInternalRepository())
core.savedObjects.setClientFactoryProvider(
(repositoryFactory) => ({ request, includedHiddenTypes }) => {
const enabled = this.isEnabled;
if (enabled) {
return new SavedObjectsClient(repositoryFactory.createInternalRepository());
}

return new SavedObjectsClient(
repositoryFactory.createScopedRepository(request, includedHiddenTypes)
);
}
);

return {
client: this.client,
enabled$: this.enabled$,
setWorkspaceFeatureFlag: this.setWorkspaceFeatureFlag,
};
}

Expand Down Expand Up @@ -120,8 +142,11 @@ export class WorkspacePlugin implements Plugin<{}, {}> {
}
}

private async setupWorkspaces(startDeps: CoreStart) {
const internalRepository = startDeps.savedObjects.createInternalRepository();
private async setupWorkspaces() {
if (!this.coreStart) {
throw new Error('UI setting client can not be found');
}
const internalRepository = this.coreStart.savedObjects.createInternalRepository();
const publicWorkspaceACL = new ACL().addPermission(
[WorkspacePermissionMode.LibraryRead, WorkspacePermissionMode.LibraryWrite],
{
Expand Down Expand Up @@ -158,15 +183,50 @@ export class WorkspacePlugin implements Plugin<{}, {}> {
]);
}

private async getUISettingClient() {
if (!this.coreStart) {
throw new Error('UI setting client can not be found');
}
const { uiSettings, savedObjects } = this.coreStart as CoreStart;
const internalRepository = savedObjects.createInternalRepository();
const savedObjectClient = new SavedObjectsClient(internalRepository);
return uiSettings.asScopedToClient(savedObjectClient);
}

private async setWorkspaceFeatureFlag(featureFlag: boolean) {
const uiSettingClient = await this.getUISettingClient();
await uiSettingClient.set(FEATURE_FLAG_KEY_IN_UI_SETTING, featureFlag);
this.enabled$.next(featureFlag);
}

private async setupWorkspaceFeatureFlag() {
const uiSettingClient = await this.getUISettingClient();
const workspaceEnabled = await uiSettingClient.get(FEATURE_FLAG_KEY_IN_UI_SETTING);
this.enabled$.next(!!workspaceEnabled);
return workspaceEnabled;
}

public start(core: CoreStart) {
this.logger.debug('Starting SavedObjects service');

this.setupWorkspaces(core);
this.coreStart = core;

this.setupWorkspaceFeatureFlag();

this.enabled$.subscribe((enabled) => {
if (enabled) {
this.setupWorkspaces();
}
});

return {
client: this.client as IWorkspaceDBImpl,
enabled$: this.enabled$,
setWorkspaceFeatureFlag: this.setWorkspaceFeatureFlag,
};
}

public stop() {}
public stop() {
this.enabled$.unsubscribe();
}
}
26 changes: 26 additions & 0 deletions src/plugins/workspace/server/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { schema } from '@osd/config-schema';
import { BehaviorSubject, Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import { ensureRawRequest } from '../../../../core/server';

import {
Expand All @@ -13,6 +15,7 @@ import {
WorkspacePermissionMode,
} from '../../../../core/server';
import { IWorkspaceDBImpl, WorkspaceRoutePermissionItem } from '../types';
import { ConfigSchema } from '../../config';

const WORKSPACES_API_BASE_URL = '/api/workspaces';

Expand Down Expand Up @@ -82,10 +85,14 @@ export function registerRoutes({
client,
logger,
http,
enabled$,
config$,
}: {
client: IWorkspaceDBImpl;
logger: Logger;
http: CoreSetup['http'];
enabled$: BehaviorSubject<boolean>;
config$: Observable<ConfigSchema>;
}) {
const router = http.createRouter();
router.post(
Expand Down Expand Up @@ -255,4 +262,23 @@ export function registerRoutes({
return res.ok({ body: result });
})
);

router.get(
{
path: `${WORKSPACES_API_BASE_URL}/settings`,
validate: {},
},
router.handleLegacyErrors(async (context, req, res) => {
const config = await config$.pipe(first()).toPromise();
return res.ok({
body: {
success: true,
result: {
...config,
enabled: enabled$.getValue(),
},
},
});
})
);
}

0 comments on commit db33da9

Please sign in to comment.