1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-22 19:07:54 +01:00

refactor: rename proxy to frontend api in openapi schemas (#6511)

This commit is contained in:
Mateusz Kwasniewski 2024-03-12 10:15:24 +01:00 committed by GitHub
parent 313cad5f00
commit bc83a4d66e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 64 additions and 38 deletions

View File

@ -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<ProxyFeaturesSchema>,
res: Response<FrontendApiFeaturesSchema>,
) {
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<unknown, unknown, ProxyClientSchema>,
req: ApiUserRequest<unknown, unknown, FrontendApiClientSchema>,
res: Response<string>,
) {
if (!this.config.flagResolver.isEnabled('embedProxy')) {

View File

@ -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);
});

View File

@ -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<ProxyFeatureSchema[]> {
): Promise<FrontendApiFeatureSchema[]> {
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<ProxyFeatureSchema[]> {
): Promise<FrontendApiFeatureSchema[]> {
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;

View File

@ -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,

View File

@ -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();

View File

@ -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;

View File

@ -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,
};

View File

@ -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);
});

View File

@ -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<typeof proxyClientSchema>;
export type FrontendApiClientSchema = FromSchema<
typeof frontendApiClientSchema
>;

View File

@ -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<typeof proxyFeatureSchema>;
export type FrontendApiFeatureSchema = FromSchema<
typeof frontendApiFeatureSchema
>;

View File

@ -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<typeof proxyFeaturesSchema>;
export type FrontendApiFeaturesSchema = FromSchema<
typeof frontendApiFeaturesSchema
>;

View File

@ -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';