From 50aa00aec249623e2e5bb95400cee303945d6c8c Mon Sep 17 00:00:00 2001 From: Utkarsh Mehta Date: Thu, 25 Apr 2024 19:29:39 +0530 Subject: [PATCH] feat: Add deleteTracesByProduct method to AdminController (#2617) * feat: Add deleteTracesByProduct method to AdminController This commit adds a new method, deleteTracesByProduct, to the AdminController class in the npm/src/controller/admin.ts file. This method allows for the deletion of traces by product. It uses the getTracesByProduct method to retrieve traces in batches of 50 and deletes them using the tracerStore. The method is also implemented in the pages/api/v1/sso-traces/product.ts file as a DELETE handler. * chore: Add DELETE handler for product API endpoint in product.ts file * chore: Add DELETE handler for product API endpoint in product.ts file * feat: Add countByProduct method to SSOTracer This commit adds a new method, countByProduct, to the SSOTracer class in the npm/src/sso-tracer/index.ts file. This method allows for counting the number of traces by product. It uses the tracerStore's getCount method to retrieve the count based on the product name. The method is also implemented in the pages/api/v1/sso-traces/product/count.ts file as a GET handler. --- npm/src/controller/admin.ts | 8 +++ npm/src/sso-tracer/index.ts | 25 ++++++++++ npm/src/typings.ts | 1 + .../{product.ts => product/count.ts} | 7 +-- pages/api/v1/sso-traces/product/index.ts | 49 +++++++++++++++++++ 5 files changed, 85 insertions(+), 5 deletions(-) rename pages/api/v1/sso-traces/{product.ts => product/count.ts} (75%) create mode 100644 pages/api/v1/sso-traces/product/index.ts diff --git a/npm/src/controller/admin.ts b/npm/src/controller/admin.ts index b7a409bb3..b5ecadc12 100644 --- a/npm/src/controller/admin.ts +++ b/npm/src/controller/admin.ts @@ -65,4 +65,12 @@ export class AdminController implements IAdminController { ) { return await this.ssoTracer.getTracesByProduct({ product, pageOffset, pageLimit, pageToken }); } + + public async deleteTracesByProduct(product: string) { + return await this.ssoTracer.deleteTracesByProduct(product); + } + + public async countByProduct(product: string) { + return await this.ssoTracer.countByProduct(product); + } } diff --git a/npm/src/sso-tracer/index.ts b/npm/src/sso-tracer/index.ts index c486cef2f..27e2a7e12 100644 --- a/npm/src/sso-tracer/index.ts +++ b/npm/src/sso-tracer/index.ts @@ -206,6 +206,31 @@ class SSOTracer { return traces; } + + public async deleteTracesByProduct(product: string) { + let pageToken; + do { + const res = await this.getTracesByProduct({ + product, + pageOffset: 0, + pageLimit: 50, + }); + if (!res.data || !res.data.length) { + break; + } + pageToken = res.pageToken; + // deleting traces in batches of 50 + // deleting in the loop right away as we get the traces + await this.tracerStore.deleteMany((res.data || []).map((t) => t.traceId)); + } while (pageToken); + } + + public async countByProduct(product: string) { + return await this.tracerStore.getCount({ + name: IndexNames.Product, + value: product, + }); + } } export default SSOTracer; diff --git a/npm/src/typings.ts b/npm/src/typings.ts index 4835d23f0..69e2ddcf3 100644 --- a/npm/src/typings.ts +++ b/npm/src/typings.ts @@ -212,6 +212,7 @@ export interface IAdminController { getAllSSOTraces(pageOffset: number, pageLimit: number, pageToken?: string); getSSOTraceById(traceId: string); getTracesByProduct(product: string, pageOffset: number, pageLimit: number, pageToken?: string); + deleteTracesByProduct(product: string); } export interface IHealthCheckController { diff --git a/pages/api/v1/sso-traces/product.ts b/pages/api/v1/sso-traces/product/count.ts similarity index 75% rename from pages/api/v1/sso-traces/product.ts rename to pages/api/v1/sso-traces/product/count.ts index 6e8295a69..f898ebfad 100644 --- a/pages/api/v1/sso-traces/product.ts +++ b/pages/api/v1/sso-traces/product/count.ts @@ -1,5 +1,4 @@ import jackson from '@lib/jackson'; -import { parsePaginateApiParams } from '@lib/utils'; import { NextApiRequest, NextApiResponse } from 'next'; export default async function handler(req: NextApiRequest, res: NextApiResponse) { @@ -26,9 +25,7 @@ const handleGET = async (req: NextApiRequest, res: NextApiResponse) => { product: string; }; - const { pageOffset, pageLimit, pageToken } = parsePaginateApiParams(req.query); + const count = await adminController.countByProduct(product); - const traces = await adminController.getTracesByProduct(product, pageOffset, pageLimit, pageToken); - - res.json(traces); + res.json({ count }); }; diff --git a/pages/api/v1/sso-traces/product/index.ts b/pages/api/v1/sso-traces/product/index.ts new file mode 100644 index 000000000..feb028fc5 --- /dev/null +++ b/pages/api/v1/sso-traces/product/index.ts @@ -0,0 +1,49 @@ +import jackson from '@lib/jackson'; +import { parsePaginateApiParams } from '@lib/utils'; +import { NextApiRequest, NextApiResponse } from 'next'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + try { + switch (req.method) { + case 'GET': + await handleGET(req, res); + break; + case 'DELETE': + await handleDelete(req, res); + break; + default: + res.setHeader('Allow', 'GET,DELETE'); + res.status(405).json({ error: { message: `Method ${req.method} Not Allowed` } }); + } + } catch (error: any) { + const { message, statusCode = 500 } = error; + res.status(statusCode).json({ error: { message } }); + } +} + +// Get the sso traces filtered by the product +const handleGET = async (req: NextApiRequest, res: NextApiResponse) => { + const { adminController } = await jackson(); + + const { product } = req.query as { + product: string; + }; + + const { pageOffset, pageLimit, pageToken } = parsePaginateApiParams(req.query); + + const traces = await adminController.getTracesByProduct(product, pageOffset, pageLimit, pageToken); + + res.json(traces); +}; + +const handleDelete = async (req: NextApiRequest, res: NextApiResponse) => { + const { adminController } = await jackson(); + + const { product } = req.query as { + product: string; + }; + + await adminController.deleteTracesByProduct(product); + + res.status(204).end(); +};