mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-18 01:18:23 +02:00
feat: persist client application usage (#4534)
Closes # [1-1256](https://linear.app/unleash/issue/1-1256/backend-to-save-application-usage) Adds client application usage persisting on upsert and bulkUpsert functions --------- Signed-off-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
parent
68273da213
commit
d19d97cf18
@ -21,6 +21,8 @@ const COLUMNS = [
|
|||||||
];
|
];
|
||||||
const TABLE = 'client_applications';
|
const TABLE = 'client_applications';
|
||||||
|
|
||||||
|
const TABLE_USAGE = 'client_applications_usage';
|
||||||
|
|
||||||
const mapRow: (any) => IClientApplication = (row) => ({
|
const mapRow: (any) => IClientApplication = (row) => ({
|
||||||
appName: row.app_name,
|
appName: row.app_name,
|
||||||
createdAt: row.created_at,
|
createdAt: row.created_at,
|
||||||
@ -57,6 +59,14 @@ const remapRow = (input) => {
|
|||||||
return temp;
|
return temp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const remapUsageRow = (input) => {
|
||||||
|
return {
|
||||||
|
app_name: input.appName,
|
||||||
|
project: input.project || '*',
|
||||||
|
environment: input.environment || '*',
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export default class ClientApplicationsStore
|
export default class ClientApplicationsStore
|
||||||
implements IClientApplicationsStore
|
implements IClientApplicationsStore
|
||||||
{
|
{
|
||||||
@ -72,11 +82,21 @@ export default class ClientApplicationsStore
|
|||||||
async upsert(details: Partial<IClientApplication>): Promise<void> {
|
async upsert(details: Partial<IClientApplication>): Promise<void> {
|
||||||
const row = remapRow(details);
|
const row = remapRow(details);
|
||||||
await this.db(TABLE).insert(row).onConflict('app_name').merge();
|
await this.db(TABLE).insert(row).onConflict('app_name').merge();
|
||||||
|
const usageRow = remapUsageRow(details);
|
||||||
|
await this.db(TABLE_USAGE)
|
||||||
|
.insert(usageRow)
|
||||||
|
.onConflict(['app_name', 'project', 'environment'])
|
||||||
|
.merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
async bulkUpsert(apps: Partial<IClientApplication>[]): Promise<void> {
|
async bulkUpsert(apps: Partial<IClientApplication>[]): Promise<void> {
|
||||||
const rows = apps.map(remapRow);
|
const rows = apps.map(remapRow);
|
||||||
|
const usageRows = apps.map(remapUsageRow);
|
||||||
await this.db(TABLE).insert(rows).onConflict('app_name').merge();
|
await this.db(TABLE).insert(rows).onConflict('app_name').merge();
|
||||||
|
await this.db(TABLE_USAGE)
|
||||||
|
.insert(usageRows)
|
||||||
|
.onConflict(['app_name', 'project', 'environment'])
|
||||||
|
.merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
async exists(appName: string): Promise<boolean> {
|
async exists(appName: string): Promise<boolean> {
|
||||||
|
@ -63,12 +63,23 @@ export default class RegisterController extends Controller {
|
|||||||
return 'default';
|
return 'default';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static extractProjectFromRequest(
|
||||||
|
req: IAuthRequest<unknown, void, ClientApplicationSchema>,
|
||||||
|
) {
|
||||||
|
const token = req.get('Authorisation');
|
||||||
|
if (token) {
|
||||||
|
return token.split(':')[0];
|
||||||
|
}
|
||||||
|
return 'default';
|
||||||
|
}
|
||||||
|
|
||||||
async registerClientApplication(
|
async registerClientApplication(
|
||||||
req: IAuthRequest<unknown, void, ClientApplicationSchema>,
|
req: IAuthRequest<unknown, void, ClientApplicationSchema>,
|
||||||
res: Response<void>,
|
res: Response<void>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { body: data, ip: clientIp, user } = req;
|
const { body: data, ip: clientIp, user } = req;
|
||||||
data.environment = RegisterController.resolveEnvironment(user, data);
|
data.environment = RegisterController.resolveEnvironment(user, data);
|
||||||
|
data.project = RegisterController.extractProjectFromRequest(req);
|
||||||
await this.clientInstanceService.registerClient(data, clientIp);
|
await this.clientInstanceService.registerClient(data, clientIp);
|
||||||
res.status(202).end();
|
res.status(202).end();
|
||||||
}
|
}
|
||||||
|
@ -91,4 +91,5 @@ export const clientRegisterSchema = joi
|
|||||||
started: joi.date().required(),
|
started: joi.date().required(),
|
||||||
interval: joi.number().required(),
|
interval: joi.number().required(),
|
||||||
environment: joi.string().optional(),
|
environment: joi.string().optional(),
|
||||||
|
project: joi.string().optional(),
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
exports.up = function (db, callback) {
|
||||||
|
db.runSql(
|
||||||
|
`
|
||||||
|
DROP TABLE IF EXISTS client_applications_usage;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS client_applications_usage (
|
||||||
|
app_name VARCHAR(255) REFERENCES client_applications(app_name) ON DELETE CASCADE,
|
||||||
|
project VARCHAR(255) NOT NULL ,
|
||||||
|
environment VARCHAR(100) NOT NULL ,
|
||||||
|
PRIMARY KEY(app_name, project, environment)
|
||||||
|
) ;
|
||||||
|
`,
|
||||||
|
callback,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = function (db, callback) {
|
||||||
|
db.runSql(
|
||||||
|
`
|
||||||
|
DROP TABLE IF EXISTS client_applications_usage;
|
||||||
|
CREATE TABLE IF NOT EXISTS client_applications_usage (
|
||||||
|
app_name VARCHAR(255) REFERENCES client_applications(app_name) ON DELETE CASCADE,
|
||||||
|
project VARCHAR(255) REFERENCES projects(id) ON DELETE CASCADE,
|
||||||
|
environment VARCHAR(100) REFERENCES environments(name) ON DELETE CASCADE,
|
||||||
|
PRIMARY KEY(app_name, project, environment)
|
||||||
|
) ;
|
||||||
|
`,
|
||||||
|
callback,
|
||||||
|
);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user