From bc83a4d66e0ea126da668ad90b1b2f270208d17a Mon Sep 17 00:00:00 2001 From: Mateusz Kwasniewski Date: Tue, 12 Mar 2024 10:15:24 +0100 Subject: [PATCH] refactor: rename proxy to frontend api in openapi schemas (#6511) --- .../frontend-api/frontend-api-controller.ts | 24 +++++++++---------- ...e.test.ts => frontend-api-service.test.ts} | 10 +++++++- .../frontend-api/frontend-api-service.ts | 14 ++++++----- .../frontend-api.concurrency.e2e.test.ts | 2 +- .../frontend-api/frontend-api.e2e.test.ts | 4 ++-- .../frontend-api/global-frontend-api-cache.ts | 2 +- src/lib/metric-events.ts | 2 ++ src/lib/metrics.ts | 8 +++++++ ...chema.ts => frontend-api-client-schema.ts} | 8 ++++--- ...hema.ts => frontend-api-feature-schema.ts} | 8 ++++--- ...ema.ts => frontend-api-features-schema.ts} | 14 ++++++----- src/lib/openapi/spec/index.ts | 6 ++--- 12 files changed, 64 insertions(+), 38 deletions(-) rename src/lib/features/frontend-api/{proxy-service.test.ts => frontend-api-service.test.ts} (83%) rename src/lib/openapi/spec/{proxy-client-schema.ts => frontend-api-client-schema.ts} (89%) rename src/lib/openapi/spec/{proxy-feature-schema.ts => frontend-api-feature-schema.ts} (93%) rename src/lib/openapi/spec/{proxy-features-schema.ts => frontend-api-features-schema.ts} (55%) diff --git a/src/lib/features/frontend-api/frontend-api-controller.ts b/src/lib/features/frontend-api/frontend-api-controller.ts index 86d8b834e87..671351bd23d 100644 --- a/src/lib/features/frontend-api/frontend-api-controller.ts +++ b/src/lib/features/frontend-api/frontend-api-controller.ts @@ -9,10 +9,10 @@ import { createResponseSchema, emptyResponse, getStandardResponses, - ProxyClientSchema, - ProxyFeatureSchema, - proxyFeaturesSchema, - ProxyFeaturesSchema, + FrontendApiClientSchema, + FrontendApiFeatureSchema, + frontendApiFeaturesSchema, + FrontendApiFeaturesSchema, } from '../../openapi'; import { Context } from 'unleash-client'; import { enrichContextWithIp } from './index'; @@ -61,13 +61,13 @@ export default class FrontendAPIController extends Controller { tags: ['Frontend API'], operationId: 'getFrontendFeatures', responses: { - 200: createResponseSchema('proxyFeaturesSchema'), + 200: createResponseSchema('frontendApiFeaturesSchema'), ...getStandardResponses(401, 404), }, summary: 'Retrieve enabled feature toggles for the provided context.', description: - 'This endpoint returns the list of feature toggles that the proxy evaluates to enabled for the given context. Context values are provided as query parameters. If the Frontend API is disabled 404 is returned.', + 'This endpoint returns the list of feature toggles that the frontend API evaluates to enabled for the given context. Context values are provided as query parameters. If the Frontend API is disabled 404 is returned.', }), ], }); @@ -126,7 +126,7 @@ export default class FrontendAPIController extends Controller { description: 'This is for future use. Currently Frontend client registration is not supported. Returning 200 for clients that expect this status code. If the Frontend API is disabled 404 is returned.', operationId: 'registerFrontendClient', - requestBody: createRequestSchema('proxyClientSchema'), + requestBody: createRequestSchema('frontendApiClientSchema'), responses: { 200: emptyResponse, ...getStandardResponses(400, 401, 404), @@ -170,13 +170,13 @@ export default class FrontendAPIController extends Controller { private async getFrontendApiFeatures( req: ApiUserRequest, - res: Response, + res: Response, ) { if (!this.config.flagResolver.isEnabled('embedProxy')) { throw new NotFoundError(); } - let toggles: ProxyFeatureSchema[]; - let newToggles: ProxyFeatureSchema[] = []; + let toggles: FrontendApiFeatureSchema[]; + let newToggles: FrontendApiFeatureSchema[] = []; if (this.config.flagResolver.isEnabled('globalFrontendApiCache')) { [toggles, newToggles] = await Promise.all([ this.services.frontendApiService.getFrontendApiFeatures( @@ -217,7 +217,7 @@ export default class FrontendAPIController extends Controller { this.services.openApiService.respondWithValidation( 200, res, - proxyFeaturesSchema.$id, + frontendApiFeaturesSchema.$id, { toggles: returnedToggles }, ); } @@ -244,7 +244,7 @@ export default class FrontendAPIController extends Controller { } private async registerFrontendApiClient( - req: ApiUserRequest, + req: ApiUserRequest, res: Response, ) { if (!this.config.flagResolver.isEnabled('embedProxy')) { diff --git a/src/lib/features/frontend-api/proxy-service.test.ts b/src/lib/features/frontend-api/frontend-api-service.test.ts similarity index 83% rename from src/lib/features/frontend-api/proxy-service.test.ts rename to src/lib/features/frontend-api/frontend-api-service.test.ts index fd068ecc6e1..043d4786110 100644 --- a/src/lib/features/frontend-api/proxy-service.test.ts +++ b/src/lib/features/frontend-api/frontend-api-service.test.ts @@ -4,6 +4,8 @@ import { IApiUser } from '../../types'; import { FeatureInterface } from 'unleash-client/lib/feature'; import noLogger from '../../../test/fixtures/no-logger'; import { ApiTokenType } from '../../types/models/api-token'; +import EventEmitter from 'events'; +import { FRONTEND_API_REPOSITORY_CREATED } from '../../metric-events'; test('frontend api service fetching features from global cache', async () => { const irrelevant = {} as any; @@ -38,8 +40,13 @@ test('frontend api service fetching features from global cache', async () => { ) as FeatureInterface; }, } as GlobalFrontendApiCache; + const eventBus = new EventEmitter(); + let createdFrontendRepositoriesCount = 0; + eventBus.on(FRONTEND_API_REPOSITORY_CREATED, () => { + createdFrontendRepositoriesCount++; + }); const frontendApiService = new FrontendApiService( - { getLogger: noLogger } as unknown as Config, + { getLogger: noLogger, eventBus } as unknown as Config, irrelevant, irrelevant, globalFrontendApiCache, @@ -56,4 +63,5 @@ test('frontend api service fetching features from global cache', async () => { expect(features).toMatchObject([{ name: 'toggleA' }]); expect(features).toHaveLength(1); + expect(createdFrontendRepositoriesCount).toBe(1); }); diff --git a/src/lib/features/frontend-api/frontend-api-service.ts b/src/lib/features/frontend-api/frontend-api-service.ts index ac43d090570..05ed8739502 100644 --- a/src/lib/features/frontend-api/frontend-api-service.ts +++ b/src/lib/features/frontend-api/frontend-api-service.ts @@ -1,6 +1,6 @@ import { IUnleashConfig, IUnleashServices, IUnleashStores } from '../../types'; import { Logger } from '../../logger'; -import { ClientMetricsSchema, ProxyFeatureSchema } from '../../openapi'; +import { ClientMetricsSchema, FrontendApiFeatureSchema } from '../../openapi'; import ApiUser, { IApiUser } from '../../types/api-user'; import { Context, @@ -15,7 +15,10 @@ import { } from '../../types/settings/frontend-settings'; import { validateOrigins } from '../../util'; import { BadDataError, InvalidTokenError } from '../../error'; -import { PROXY_REPOSITORY_CREATED } from '../../metric-events'; +import { + FRONTEND_API_REPOSITORY_CREATED, + PROXY_REPOSITORY_CREATED, +} from '../../metric-events'; import { FrontendApiRepository } from './frontend-api-repository'; import { GlobalFrontendApiCache } from './global-frontend-api-cache'; import { ProxyRepository } from './proxy-repository'; @@ -74,7 +77,7 @@ export class FrontendApiService { async getFrontendApiFeatures( token: IApiUser, context: Context, - ): Promise { + ): Promise { const client = await this.clientForFrontendApiToken(token); const definitions = client.getFeatureToggleDefinitions() || []; const sessionId = context.sessionId || String(Math.random()); @@ -100,7 +103,7 @@ export class FrontendApiService { async getNewFrontendApiFeatures( token: IApiUser, context: Context, - ): Promise { + ): Promise { const client = await this.newClientForFrontendApiToken(token); const definitions = client.getFeatureToggleDefinitions() || []; const sessionId = context.sessionId || String(Math.random()); @@ -168,8 +171,7 @@ export class FrontendApiService { if (!newClient) { newClient = this.createNewClientForFrontendApiToken(token); this.newClients.set(token.secret, newClient); - // TODO: do we need this twice? - // this.config.eventBus.emit(PROXY_REPOSITORY_CREATED); + this.config.eventBus.emit(FRONTEND_API_REPOSITORY_CREATED); } return newClient; diff --git a/src/lib/features/frontend-api/frontend-api.concurrency.e2e.test.ts b/src/lib/features/frontend-api/frontend-api.concurrency.e2e.test.ts index f053f6ce363..e0a9bff29b9 100644 --- a/src/lib/features/frontend-api/frontend-api.concurrency.e2e.test.ts +++ b/src/lib/features/frontend-api/frontend-api.concurrency.e2e.test.ts @@ -12,7 +12,7 @@ let db: ITestDb; let appErrorLogs: string[] = []; beforeAll(async () => { - db = await dbInit('proxy_concurrency', getLogger); + db = await dbInit('frontend_api_concurrency', getLogger); const baseLogger = getLogger(); const appLogger = { ...baseLogger, diff --git a/src/lib/features/frontend-api/frontend-api.e2e.test.ts b/src/lib/features/frontend-api/frontend-api.e2e.test.ts index 7696b3fb2b1..59e092e9b9a 100644 --- a/src/lib/features/frontend-api/frontend-api.e2e.test.ts +++ b/src/lib/features/frontend-api/frontend-api.e2e.test.ts @@ -24,7 +24,7 @@ let app: IUnleashTest; let db: ITestDb; const TEST_USER_ID = -9999; beforeAll(async () => { - db = await dbInit('proxy', getLogger); + db = await dbInit('frontend_api', getLogger); app = await setupAppWithAuth( db.stores, { @@ -347,7 +347,7 @@ test('should accept client registration requests', async () => { .expect((res) => expect(res.text).toEqual('OK')); }); -test('should store proxy client metrics', async () => { +test('should store frontend api client metrics', async () => { const now = new Date(); const appName = randomId(); const instanceId = randomId(); diff --git a/src/lib/features/frontend-api/global-frontend-api-cache.ts b/src/lib/features/frontend-api/global-frontend-api-cache.ts index 6551edc1073..08c94015c9f 100644 --- a/src/lib/features/frontend-api/global-frontend-api-cache.ts +++ b/src/lib/features/frontend-api/global-frontend-api-cache.ts @@ -47,7 +47,7 @@ export class GlobalFrontendApiCache extends EventEmitter { ) { super(); this.config = config; - this.logger = config.getLogger('proxy-repository.ts'); + this.logger = config.getLogger('global-frontend-api-cache.ts'); this.clientFeatureToggleReadModel = clientFeatureToggleReadModel; this.configurationRevisionService = configurationRevisionService; this.segmentReadModel = segmentReadModel; diff --git a/src/lib/metric-events.ts b/src/lib/metric-events.ts index fa8f9da3446..cc8e2352bb0 100644 --- a/src/lib/metric-events.ts +++ b/src/lib/metric-events.ts @@ -3,6 +3,7 @@ const DB_TIME = 'db_time'; const SCHEDULER_JOB_TIME = 'scheduler_job_time'; const FEATURES_CREATED_BY_PROCESSED = 'features_created_by_processed'; const EVENTS_CREATED_BY_PROCESSED = 'events_created_by_processed'; +const FRONTEND_API_REPOSITORY_CREATED = 'frontend_api_repository_created'; const PROXY_REPOSITORY_CREATED = 'proxy_repository_created'; const PROXY_FEATURES_FOR_TOKEN_TIME = 'proxy_features_for_token_time'; @@ -12,6 +13,7 @@ export { SCHEDULER_JOB_TIME, FEATURES_CREATED_BY_PROCESSED, EVENTS_CREATED_BY_PROCESSED, + FRONTEND_API_REPOSITORY_CREATED, PROXY_REPOSITORY_CREATED, PROXY_FEATURES_FOR_TOKEN_TIME, }; diff --git a/src/lib/metrics.ts b/src/lib/metrics.ts index fcf154c1f60..5be086282aa 100644 --- a/src/lib/metrics.ts +++ b/src/lib/metrics.ts @@ -236,6 +236,10 @@ export default class MetricsMonitor { name: 'proxy_repositories_created', help: 'Proxy repositories created', }); + const frontendApiRepositoriesCreated = createCounter({ + name: 'frontend_api_repositories_created', + help: 'Frontend API repositories created', + }); const mapFeaturesForClientDuration = createHistogram({ name: 'map_features_for_client_duration', help: 'Duration of mapFeaturesForClient function', @@ -417,6 +421,10 @@ export default class MetricsMonitor { proxyRepositoriesCreated.inc(); }); + eventBus.on(events.FRONTEND_API_REPOSITORY_CREATED, () => { + frontendApiRepositoriesCreated.inc(); + }); + eventBus.on(events.PROXY_FEATURES_FOR_TOKEN_TIME, ({ duration }) => { mapFeaturesForClientDuration.observe(duration); }); diff --git a/src/lib/openapi/spec/proxy-client-schema.ts b/src/lib/openapi/spec/frontend-api-client-schema.ts similarity index 89% rename from src/lib/openapi/spec/proxy-client-schema.ts rename to src/lib/openapi/spec/frontend-api-client-schema.ts index 59082cac752..3036d036731 100644 --- a/src/lib/openapi/spec/proxy-client-schema.ts +++ b/src/lib/openapi/spec/frontend-api-client-schema.ts @@ -1,7 +1,7 @@ import { FromSchema } from 'json-schema-to-ts'; -export const proxyClientSchema = { - $id: '#/components/schemas/proxyClientSchema', +export const frontendApiClientSchema = { + $id: '#/components/schemas/frontendApiClientSchema', type: 'object', required: ['appName', 'interval', 'started', 'strategies'], description: 'Frontend SDK client registration information', @@ -50,4 +50,6 @@ export const proxyClientSchema = { components: {}, } as const; -export type ProxyClientSchema = FromSchema; +export type FrontendApiClientSchema = FromSchema< + typeof frontendApiClientSchema +>; diff --git a/src/lib/openapi/spec/proxy-feature-schema.ts b/src/lib/openapi/spec/frontend-api-feature-schema.ts similarity index 93% rename from src/lib/openapi/spec/proxy-feature-schema.ts rename to src/lib/openapi/spec/frontend-api-feature-schema.ts index f9202a8b400..98a1a6eff81 100644 --- a/src/lib/openapi/spec/proxy-feature-schema.ts +++ b/src/lib/openapi/spec/frontend-api-feature-schema.ts @@ -1,7 +1,7 @@ import { FromSchema } from 'json-schema-to-ts'; -export const proxyFeatureSchema = { - $id: '#/components/schemas/proxyFeatureSchema', +export const frontendApiFeatureSchema = { + $id: '#/components/schemas/frontendApiFeatureSchema', type: 'object', required: ['name', 'enabled', 'impressionData'], additionalProperties: false, @@ -75,4 +75,6 @@ export const proxyFeatureSchema = { components: {}, } as const; -export type ProxyFeatureSchema = FromSchema; +export type FrontendApiFeatureSchema = FromSchema< + typeof frontendApiFeatureSchema +>; diff --git a/src/lib/openapi/spec/proxy-features-schema.ts b/src/lib/openapi/spec/frontend-api-features-schema.ts similarity index 55% rename from src/lib/openapi/spec/proxy-features-schema.ts rename to src/lib/openapi/spec/frontend-api-features-schema.ts index abaddaaadd0..56d173d111d 100644 --- a/src/lib/openapi/spec/proxy-features-schema.ts +++ b/src/lib/openapi/spec/frontend-api-features-schema.ts @@ -1,8 +1,8 @@ import { FromSchema } from 'json-schema-to-ts'; -import { proxyFeatureSchema } from './proxy-feature-schema'; +import { frontendApiFeatureSchema } from './frontend-api-feature-schema'; -export const proxyFeaturesSchema = { - $id: '#/components/schemas/proxyFeaturesSchema', +export const frontendApiFeaturesSchema = { + $id: '#/components/schemas/frontendApiFeaturesSchema', type: 'object', required: ['toggles'], additionalProperties: false, @@ -12,15 +12,17 @@ export const proxyFeaturesSchema = { description: 'The actual features returned to the Frontend SDK', type: 'array', items: { - $ref: proxyFeatureSchema.$id, + $ref: frontendApiFeatureSchema.$id, }, }, }, components: { schemas: { - proxyFeatureSchema, + frontendApiFeatureSchema, }, }, } as const; -export type ProxyFeaturesSchema = FromSchema; +export type FrontendApiFeaturesSchema = FromSchema< + typeof frontendApiFeaturesSchema +>; diff --git a/src/lib/openapi/spec/index.ts b/src/lib/openapi/spec/index.ts index ccb31b68c8c..df5ddd5a617 100644 --- a/src/lib/openapi/spec/index.ts +++ b/src/lib/openapi/spec/index.ts @@ -90,6 +90,9 @@ export * from './features-schema'; export * from './feedback-create-schema'; export * from './feedback-response-schema'; export * from './feedback-update-schema'; +export * from './frontend-api-client-schema'; +export * from './frontend-api-feature-schema'; +export * from './frontend-api-features-schema'; export * from './group-schema'; export * from './group-user-model-schema'; export * from './groups-schema'; @@ -134,9 +137,6 @@ export * from './project-overview-schema'; export * from './project-schema'; export * from './project-stats-schema'; export * from './projects-schema'; -export * from './proxy-client-schema'; -export * from './proxy-feature-schema'; -export * from './proxy-features-schema'; export * from './public-signup-token-create-schema'; export * from './public-signup-token-schema'; export * from './public-signup-token-update-schema';