From af7e86f656f48b8c47f00997050494c48a7e36c3 Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Mon, 17 Jun 2024 15:16:57 +0530 Subject: [PATCH 01/17] Added: Feature for create cache on load --- src/app.ts | 28 +-- src/middlewares/schemaValidator.middleware.ts | 181 ++++++++++++++---- 2 files changed, 157 insertions(+), 52 deletions(-) diff --git a/src/app.ts b/src/app.ts index d5b2752..e173f28 100644 --- a/src/app.ts +++ b/src/app.ts @@ -4,7 +4,7 @@ import { Exception } from "./models/exception.model"; import { BecknErrorDataType, becknErrorSchema, - BecknErrorType, + BecknErrorType } from "./schemas/becknError.schema"; import { RequestActions } from "./schemas/configs/actions.app.config.schema"; import { LookupCache } from "./utils/cache/lookup.cache.utils"; @@ -16,12 +16,13 @@ import { ClientUtils } from "./utils/client.utils"; import { getConfig } from "./utils/config.utils"; import { GatewayUtils } from "./utils/gateway.utils"; import logger from "./utils/logger.utils"; +import { OpenApiValidatorMiddleware } from "./middlewares/schemaValidator.middleware"; const app = Express(); app.use( Express.json({ - limit: "200kb", + limit: "200kb" }) ); @@ -35,13 +36,13 @@ const initializeExpress = async (successCallback: Function) => { origin: "*", optionsSuccessStatus: 200, credentials: true, - methods: ["GET", "PUT", "POST", "PATCH", "DELETE", "OPTIONS"], + methods: ["GET", "PUT", "POST", "PATCH", "DELETE", "OPTIONS"] }) ); app.use( cors({ origin: "*", - methods: ["GET", "PUT", "POST", "PATCH", "DELETE", "OPTIONS"], + methods: ["GET", "PUT", "POST", "PATCH", "DELETE", "OPTIONS"] }) ); @@ -50,10 +51,10 @@ const initializeExpress = async (successCallback: Function) => { Express.json({ verify: (req: Request, res: Response, buf: Buffer) => { res.locals = { - rawBody: buf.toString(), + rawBody: buf.toString() }; }, - limit: "200kb", + limit: "200kb" }) ); @@ -83,24 +84,24 @@ const initializeExpress = async (successCallback: Function) => { code: err.code, message: err.message, data: err.errorData, - type: BecknErrorType.domainError, + type: BecknErrorType.domainError } as BecknErrorDataType; res.status(err.code).json({ message: { ack: { - status: "NACK", - }, + status: "NACK" + } }, - error: errorData, + error: errorData }); } else { res.status(err.code || 500).json({ message: { ack: { - status: "NACK", - }, + status: "NACK" + } }, - error: err, + error: err }); } }); @@ -116,6 +117,7 @@ const main = async () => { try { await ClientUtils.initializeConnection(); await GatewayUtils.getInstance().initialize(); + await OpenApiValidatorMiddleware.getInstance().initOpenApiMiddleware(); if (getConfig().responseCache.enabled) { await ResponseCache.getInstance().initialize(); } diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index e0fdab8..b414267 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -1,52 +1,150 @@ -import { NextFunction, Request, Response } from "express"; +import express, { NextFunction, Request, Response } from "express"; import * as OpenApiValidator from "express-openapi-validator"; -import { Exception, ExceptionType } from "../models/exception.model"; -import { Locals } from "../interfaces/locals.interface"; -import { getConfig } from "../utils/config.utils"; import fs from "fs"; import path from "path"; import { OpenAPIV3 } from "express-openapi-validator/dist/framework/types"; import YAML from "yaml"; -const protocolServerLevel = `${getConfig().app.mode.toUpperCase()}-${getConfig().app.gateway.mode.toUpperCase()}`; -import express from "express"; +import { Exception, ExceptionType } from "../models/exception.model"; +import { Locals } from "../interfaces/locals.interface"; +import { getConfig } from "../utils/config.utils"; import logger from "../utils/logger.utils"; -// Cache object -const apiSpecCache: { [filename: string]: OpenAPIV3.Document } = {}; +const protocolServerLevel = `${getConfig().app.mode.toUpperCase()}-${getConfig().app.gateway.mode.toUpperCase()}`; +const specFolder = "schemas"; + +export class OpenApiValidatorMiddleware { + private static instance: OpenApiValidatorMiddleware; + private static cachedOpenApiValidator: { + [filename: string]: { + count: number; + requestHandler: express.RequestHandler[]; + apiSpec: OpenAPIV3.Document; + }; + } = {}; + private static cachedFileLimit: number; + + private constructor() { + OpenApiValidatorMiddleware.cachedFileLimit = 100; + } + + public static getInstance(): OpenApiValidatorMiddleware { + if (!OpenApiValidatorMiddleware.instance) { + OpenApiValidatorMiddleware.instance = new OpenApiValidatorMiddleware(); + } + return OpenApiValidatorMiddleware.instance; + } -// Function to load and cache the API spec -const loadApiSpec = (specFile: string): OpenAPIV3.Document => { - if (!apiSpecCache[specFile]) { - logger.info(`Cache Not found loadApiSpec file. Loading.... ${specFile}`); + private getApiSpec(specFile: string): OpenAPIV3.Document { const apiSpecYAML = fs.readFileSync(specFile, "utf8"); const apiSpec = YAML.parse(apiSpecYAML); - apiSpecCache[specFile] = apiSpec; + return apiSpec; } - return apiSpecCache[specFile]; -}; -let cachedOpenApiValidator: express.RequestHandler[] | null = null; -let cachedSpecFile: string | null = null; + public initOpenApiMiddleware(): void { + try { + const files = fs.readdirSync(specFolder); + const fileNames = files.filter( + (file) => + fs.lstatSync(path.join(specFolder, file)).isFile() && + (file.endsWith(".yaml") || file.endsWith(".yml")) + ); + const cachedFileLimit: number = + OpenApiValidatorMiddleware.cachedFileLimit; + logger.info(`OpenAPIValidator Cache count ${cachedFileLimit}`); + for (let i = 0; i < cachedFileLimit && fileNames[i]; i++) { + const file = `${specFolder}/${fileNames[i]}`; + if (!OpenApiValidatorMiddleware.cachedOpenApiValidator[file]) { + logger.info( + `Intially cache Not found loadApiSpec file. Loading.... ${file}` + ); + const apiSpec = this.getApiSpec(file); + OpenApiValidatorMiddleware.cachedOpenApiValidator[file] = { + apiSpec, + count: 0, + requestHandler: OpenApiValidator.middleware({ + apiSpec, + validateRequests: true, + validateResponses: false, + $refParser: { + mode: "dereference" + } + }) + }; + } + } + } catch (err) { + logger.error("Error in initializing open API middleware", err); + } + } -// Function to initialize and cache the OpenAPI validator middleware -const getOpenApiValidatorMiddleware = (specFile: string) => { - if (!cachedOpenApiValidator || cachedSpecFile !== specFile) { - logger.info( - `Cache Not found for OpenApiValidator middleware. Loading.... ${specFile}` - ); - const apiSpec = loadApiSpec(specFile); - cachedOpenApiValidator = OpenApiValidator.middleware({ - apiSpec, - validateRequests: true, - validateResponses: false, - $refParser: { - mode: "dereference" + public getOpenApiMiddleware(specFile: string): express.RequestHandler[] { + try { + let requestHandler: express.RequestHandler[]; + if (OpenApiValidatorMiddleware.cachedOpenApiValidator[specFile]) { + const cachedValidator = + OpenApiValidatorMiddleware.cachedOpenApiValidator[specFile]; + cachedValidator.count = + cachedValidator.count > 1000 + ? cachedValidator.count + : cachedValidator.count + 1; + logger.info(`Cache found for spec ${specFile}`); + requestHandler = cachedValidator.requestHandler; + } else { + const cashedSpec = Object.entries( + OpenApiValidatorMiddleware.cachedOpenApiValidator + ); + const cachedFileLimit: number = + OpenApiValidatorMiddleware.cachedFileLimit; + if (cashedSpec.length >= cachedFileLimit) { + const specWithLeastCount = + cashedSpec.reduce((minEntry, currentEntry) => { + return currentEntry[1].count < minEntry[1].count + ? currentEntry + : minEntry; + }) || cashedSpec[0]; + logger.info( + `Cache count reached limit. Deleting from cache.... ${specWithLeastCount[0]}` + ); + delete OpenApiValidatorMiddleware.cachedOpenApiValidator[ + specWithLeastCount[0] + ]; + } + logger.info( + `Cache Not found loadApiSpec file. Loading.... ${specFile}` + ); + const apiSpec = this.getApiSpec(specFile); + OpenApiValidatorMiddleware.cachedOpenApiValidator[specFile] = { + apiSpec, + count: 1, + requestHandler: OpenApiValidator.middleware({ + apiSpec, + validateRequests: true, + validateResponses: false, + $refParser: { + mode: "dereference" + } + }) + }; + requestHandler = + OpenApiValidatorMiddleware.cachedOpenApiValidator[specFile] + .requestHandler; } - }); - cachedSpecFile = specFile; + const cacheStats = Object.entries( + OpenApiValidatorMiddleware.cachedOpenApiValidator + ).map((cache) => { + return { + count: cache[1].count, + specFile: cache[0] + }; + }); + console.table(cacheStats); + return requestHandler; + } catch (err) { + logger.error("Error in getOpenApiMiddleware", err); + return []; + } } - return cachedOpenApiValidator; -}; +} export const schemaErrorHandler = ( err: any, @@ -54,6 +152,7 @@ export const schemaErrorHandler = ( res: Response, next: NextFunction ) => { + logger.error("OpenApiValidator Error", err); if (err instanceof Exception) { next(err); } else { @@ -76,7 +175,7 @@ export const openApiValidatorMiddleware = async ( const version = req?.body?.context?.core_version ? req?.body?.context?.core_version : req?.body?.context?.version; - let specFile = `schemas/core_${version}.yaml`; + let specFile = `${specFolder}/core_${version}.yaml`; if (getConfig().app.useLayer2Config) { let doesLayer2ConfigExist = false; @@ -86,19 +185,22 @@ export const openApiValidatorMiddleware = async ( try { doesLayer2ConfigExist = ( await fs.promises.readdir( - `${path.join(path.resolve(__dirname, "../../"))}/schemas` + `${path.join(path.resolve(__dirname, "../../"))}/${specFolder}` ) ).includes(layer2ConfigFilename); } catch (error) { doesLayer2ConfigExist = false; } - if (doesLayer2ConfigExist) specFile = `schemas/${layer2ConfigFilename}`; + if (doesLayer2ConfigExist) + specFile = `${specFolder}/${layer2ConfigFilename}`; else { if (getConfig().app.mandateLayer2Config) { + const message = `Layer 2 config file ${layer2ConfigFilename} is not installed and it is marked as required in configuration`; + logger.error(message); return next( new Exception( ExceptionType.Config_AppConfig_Layer2_Missing, - `Layer 2 config file ${layer2ConfigFilename} is not installed and it is marked as required in configuration`, + message, 422 ) ); @@ -106,7 +208,8 @@ export const openApiValidatorMiddleware = async ( } } - const openApiValidator = getOpenApiValidatorMiddleware(specFile); + const openApiValidator = + OpenApiValidatorMiddleware.getInstance().getOpenApiMiddleware(specFile); const walkSubstack = function ( stack: any, From cb80785d6bb0e7ffc079e4d11981feaa571daebc Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 14:09:16 +0530 Subject: [PATCH 02/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/middlewares/schemaValidator.middleware.ts | 116 +++++++++++++----- 1 file changed, 84 insertions(+), 32 deletions(-) diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index b414267..a1783e1 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -8,7 +8,14 @@ import { Exception, ExceptionType } from "../models/exception.model"; import { Locals } from "../interfaces/locals.interface"; import { getConfig } from "../utils/config.utils"; import logger from "../utils/logger.utils"; - +import { + RequestActions, + ResponseActions +} from "../schemas/configs/actions.app.config.schema"; +import httpMocks from "node-mocks-http"; +import { v4 as uuid_v4 } from "uuid"; +import { AppMode } from "../schemas/configs/app.config.schema"; +import { GatewayMode } from "../schemas/configs/gateway.app.config.schema"; const protocolServerLevel = `${getConfig().app.mode.toUpperCase()}-${getConfig().app.gateway.mode.toUpperCase()}`; const specFolder = "schemas"; @@ -58,18 +65,20 @@ export class OpenApiValidatorMiddleware { `Intially cache Not found loadApiSpec file. Loading.... ${file}` ); const apiSpec = this.getApiSpec(file); + const requestHandler = OpenApiValidator.middleware({ + apiSpec, + validateRequests: true, + validateResponses: false, + $refParser: { + mode: "dereference" + } + }); OpenApiValidatorMiddleware.cachedOpenApiValidator[file] = { apiSpec, count: 0, - requestHandler: OpenApiValidator.middleware({ - apiSpec, - validateRequests: true, - validateResponses: false, - $refParser: { - mode: "dereference" - } - }) + requestHandler: requestHandler }; + initializeOpenApiValidatorCache(requestHandler); } } } catch (err) { @@ -129,6 +138,7 @@ export class OpenApiValidatorMiddleware { OpenApiValidatorMiddleware.cachedOpenApiValidator[specFile] .requestHandler; } + const cacheStats = Object.entries( OpenApiValidatorMiddleware.cachedOpenApiValidator ).map((cache) => { @@ -146,13 +156,77 @@ export class OpenApiValidatorMiddleware { } } +const initializeOpenApiValidatorCache = async (stack: any) => { + let actions: string[] = []; + if ( + (getConfig().app.mode === AppMode.bap && + getConfig().app.gateway.mode === GatewayMode.client) || + (getConfig().app.mode === AppMode.bpp && + getConfig().app.gateway.mode === GatewayMode.network) + ) { + actions = Object.keys(RequestActions); + } else { + actions = Object.keys(ResponseActions); + } + actions.forEach((action) => { + const mockRequest = (body: any) => { + const req = httpMocks.createRequest({ + method: "POST", + url: `/${action}`, + headers: { + "Content-Type": "application/json", + Authorization: uuid_v4() + }, + body: body + }); + + req.app = { + enabled: (setting: any) => { + if ( + setting === "strict routing" || + setting === "case sensitive routing" + ) { + return true; + } + return false; + } + } as any; + return req; + }; + const reqObj = mockRequest({ context: {}, message: {} }); + walkSubstack(stack, reqObj, {}, () => { + return; + }); + }); +}; + +const walkSubstack = function ( + stack: any, + req: any, + res: any, + next: NextFunction +) { + if (typeof stack === "function") { + stack = [stack]; + } + const walkStack = function (i: any, err?: any) { + if (err) { + return schemaErrorHandler(err, req, res, next); + } + if (i >= stack.length) { + return next(); + } + stack[i](req, res, walkStack.bind(null, i + 1)); + }; + walkStack(0); +}; + export const schemaErrorHandler = ( err: any, req: Request, res: Response, next: NextFunction ) => { - logger.error("OpenApiValidator Error", err); if (err instanceof Exception) { next(err); } else { @@ -207,29 +281,7 @@ export const openApiValidatorMiddleware = async ( } } } - const openApiValidator = OpenApiValidatorMiddleware.getInstance().getOpenApiMiddleware(specFile); - - const walkSubstack = function ( - stack: any, - req: any, - res: any, - next: NextFunction - ) { - if (typeof stack === "function") { - stack = [stack]; - } - const walkStack = function (i: any, err?: any) { - if (err) { - return schemaErrorHandler(err, req, res, next); - } - if (i >= stack.length) { - return next(); - } - stack[i](req, res, walkStack.bind(null, i + 1)); - }; - walkStack(0); - }; walkSubstack([...openApiValidator], req, res, next); }; From 66332c681fbd55bc5076bf0cce8e6f3464e96fca Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 14:23:23 +0530 Subject: [PATCH 03/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/middlewares/schemaValidator.middleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index a1783e1..28a9a27 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -12,7 +12,7 @@ import { RequestActions, ResponseActions } from "../schemas/configs/actions.app.config.schema"; -import httpMocks from "node-mocks-http"; +import * as httpMocks from "node-mocks-http"; import { v4 as uuid_v4 } from "uuid"; import { AppMode } from "../schemas/configs/app.config.schema"; import { GatewayMode } from "../schemas/configs/gateway.app.config.schema"; From 3ce6979474b24cd01bcd3792e824fb5e19a8f131 Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 14:25:41 +0530 Subject: [PATCH 04/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/middlewares/schemaValidator.middleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index 28a9a27..a2e908f 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -12,7 +12,7 @@ import { RequestActions, ResponseActions } from "../schemas/configs/actions.app.config.schema"; -import * as httpMocks from "node-mocks-http"; +const httpMocks = require("node-mocks-http"); import { v4 as uuid_v4 } from "uuid"; import { AppMode } from "../schemas/configs/app.config.schema"; import { GatewayMode } from "../schemas/configs/gateway.app.config.schema"; From aab4737034b0111426470ae7cd0c2e9c320ffe52 Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 14:30:44 +0530 Subject: [PATCH 05/17] Added: Feature For load OpenAPIValidator Cache on app boot --- package.json | 3 ++- src/middlewares/schemaValidator.middleware.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index db22d37..677144e 100644 --- a/package.json +++ b/package.json @@ -33,14 +33,15 @@ "dotenv": "^16.4.1", "express": "^4.18.1", "express-openapi-validator": "^5.1.6", - "yaml": "^2.4.2", "ioredis": "^5.0.6", "libsodium-wrappers": "^0.7.9", "mongodb": "^4.7.0", + "node-mocks-http": "^1.14.1", "request-ip": "^3.3.0", "uuid": "^8.3.2", "winston": "^3.7.2", "winston-daily-rotate-file": "^4.7.1", + "yaml": "^2.4.2", "zod": "^3.14.2" } } diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index a2e908f..28a9a27 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -12,7 +12,7 @@ import { RequestActions, ResponseActions } from "../schemas/configs/actions.app.config.schema"; -const httpMocks = require("node-mocks-http"); +import * as httpMocks from "node-mocks-http"; import { v4 as uuid_v4 } from "uuid"; import { AppMode } from "../schemas/configs/app.config.schema"; import { GatewayMode } from "../schemas/configs/gateway.app.config.schema"; From df9d50c1f1dff54d79002f8d08d7a57f70711ece Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 14:48:31 +0530 Subject: [PATCH 06/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/middlewares/schemaValidator.middleware.ts | 80 ++++++++++--------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index 28a9a27..9628628 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -157,47 +157,51 @@ export class OpenApiValidatorMiddleware { } const initializeOpenApiValidatorCache = async (stack: any) => { - let actions: string[] = []; - if ( - (getConfig().app.mode === AppMode.bap && - getConfig().app.gateway.mode === GatewayMode.client) || - (getConfig().app.mode === AppMode.bpp && - getConfig().app.gateway.mode === GatewayMode.network) - ) { - actions = Object.keys(RequestActions); - } else { - actions = Object.keys(ResponseActions); - } - actions.forEach((action) => { - const mockRequest = (body: any) => { - const req = httpMocks.createRequest({ - method: "POST", - url: `/${action}`, - headers: { - "Content-Type": "application/json", - Authorization: uuid_v4() - }, - body: body - }); + try { + let actions: string[] = []; + if ( + (getConfig().app.mode === AppMode.bap && + getConfig().app.gateway.mode === GatewayMode.client) || + (getConfig().app.mode === AppMode.bpp && + getConfig().app.gateway.mode === GatewayMode.network) + ) { + actions = Object.keys(RequestActions); + } else { + actions = Object.keys(ResponseActions); + } + actions.forEach((action) => { + const mockRequest = (body: any) => { + const req = httpMocks.createRequest({ + method: "POST", + url: `/${action}`, + headers: { + "Content-Type": "application/json", + Authorization: uuid_v4() + }, + body: body + }); - req.app = { - enabled: (setting: any) => { - if ( - setting === "strict routing" || - setting === "case sensitive routing" - ) { - return true; + req.app = { + enabled: (setting: any) => { + if ( + setting === "strict routing" || + setting === "case sensitive routing" + ) { + return true; + } + return false; } - return false; - } - } as any; - return req; - }; - const reqObj = mockRequest({ context: {}, message: {} }); - walkSubstack(stack, reqObj, {}, () => { - return; + } as any; + return req; + }; + const reqObj = mockRequest({ context: {}, message: {} }); + walkSubstack(stack, reqObj, {}, () => { + return; + }); }); - }); + } catch (error) { + console.log(error); + } }; const walkSubstack = function ( From 7897d9a4abdafe4897e37f308ae816b83e44fbef Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 14:57:40 +0530 Subject: [PATCH 07/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/middlewares/schemaValidator.middleware.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index 9628628..b9ed1e8 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -215,6 +215,7 @@ const walkSubstack = function ( } const walkStack = function (i: any, err?: any) { if (err) { + console.log(err); return schemaErrorHandler(err, req, res, next); } if (i >= stack.length) { From 1b1c85b1db2ece6d40024211b0cda9920eb113b9 Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 15:10:28 +0530 Subject: [PATCH 08/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/app.ts | 1 + src/middlewares/schemaValidator.middleware.ts | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/app.ts b/src/app.ts index e173f28..dfb1053 100644 --- a/src/app.ts +++ b/src/app.ts @@ -118,6 +118,7 @@ const main = async () => { await ClientUtils.initializeConnection(); await GatewayUtils.getInstance().initialize(); await OpenApiValidatorMiddleware.getInstance().initOpenApiMiddleware(); + console.log("After Open API middleware"); if (getConfig().responseCache.enabled) { await ResponseCache.getInstance().initialize(); } diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index b9ed1e8..d98cac3 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -47,7 +47,7 @@ export class OpenApiValidatorMiddleware { return apiSpec; } - public initOpenApiMiddleware(): void { + public async initOpenApiMiddleware() { try { const files = fs.readdirSync(specFolder); const fileNames = files.filter( @@ -78,7 +78,7 @@ export class OpenApiValidatorMiddleware { count: 0, requestHandler: requestHandler }; - initializeOpenApiValidatorCache(requestHandler); + await initializeOpenApiValidatorCache(requestHandler); } } } catch (err) { @@ -194,7 +194,10 @@ const initializeOpenApiValidatorCache = async (stack: any) => { } as any; return req; }; - const reqObj = mockRequest({ context: {}, message: {} }); + const reqObj = mockRequest({ + context: { action: `${action}` }, + message: {} + }); walkSubstack(stack, reqObj, {}, () => { return; }); From 7ea982960fdbe787768bac02c8e328dce94d0d72 Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 15:24:12 +0530 Subject: [PATCH 09/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/middlewares/schemaValidator.middleware.ts | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index d98cac3..afafe47 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -78,7 +78,7 @@ export class OpenApiValidatorMiddleware { count: 0, requestHandler: requestHandler }; - await initializeOpenApiValidatorCache(requestHandler); + await initializeOpenApiValidatorCache(requestHandler, file); } } } catch (err) { @@ -156,7 +156,10 @@ export class OpenApiValidatorMiddleware { } } -const initializeOpenApiValidatorCache = async (stack: any) => { +const initializeOpenApiValidatorCache = async ( + stack: any, + specFile: string +) => { try { let actions: string[] = []; if ( @@ -169,7 +172,8 @@ const initializeOpenApiValidatorCache = async (stack: any) => { } else { actions = Object.keys(ResponseActions); } - actions.forEach((action) => { + + actions.slice(0, 10).forEach((action) => { const mockRequest = (body: any) => { const req = httpMocks.createRequest({ method: "POST", @@ -198,12 +202,20 @@ const initializeOpenApiValidatorCache = async (stack: any) => { context: { action: `${action}` }, message: {} }); - walkSubstack(stack, reqObj, {}, () => { - return; - }); + console.log("This is for specfile: ", specFile); + + walkSubstack( + stack, + reqObj, + {}, + () => { + return; + }, + false + ); }); - } catch (error) { - console.log(error); + } catch (error: any) { + console.log(error.message); } }; @@ -211,14 +223,14 @@ const walkSubstack = function ( stack: any, req: any, res: any, - next: NextFunction + next: NextFunction, + showError = true ) { if (typeof stack === "function") { stack = [stack]; } const walkStack = function (i: any, err?: any) { - if (err) { - console.log(err); + if (err && showError) { return schemaErrorHandler(err, req, res, next); } if (i >= stack.length) { From e47dc10665a157925b842a9623ebb76b63580a23 Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 15:38:27 +0530 Subject: [PATCH 10/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.ts b/src/app.ts index dfb1053..aa9b542 100644 --- a/src/app.ts +++ b/src/app.ts @@ -78,7 +78,7 @@ const initializeExpress = async (successCallback: Function) => { // Error Handler. app.use((err: any, req: Request, res: Response, next: NextFunction) => { - console.log(err); + console.log("In Error Handler---->middleware", err); if (err instanceof Exception) { const errorData = { code: err.code, From 282c724bdca86ce321b4bc60d1244623103571e9 Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 15:40:39 +0530 Subject: [PATCH 11/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/middlewares/schemaValidator.middleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index afafe47..88a6fc2 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -173,7 +173,7 @@ const initializeOpenApiValidatorCache = async ( actions = Object.keys(ResponseActions); } - actions.slice(0, 10).forEach((action) => { + actions.slice(0, 2).forEach((action) => { const mockRequest = (body: any) => { const req = httpMocks.createRequest({ method: "POST", From 3fff448638a51f6619bfaaddc3984884fd1b1377 Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 15:49:26 +0530 Subject: [PATCH 12/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/middlewares/schemaValidator.middleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index 88a6fc2..e9feaec 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -78,7 +78,7 @@ export class OpenApiValidatorMiddleware { count: 0, requestHandler: requestHandler }; - await initializeOpenApiValidatorCache(requestHandler, file); + // await initializeOpenApiValidatorCache(requestHandler, file); } } } catch (err) { From 6d1f612faba1c6666cf61f7b999f60e6088c901a Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 15:56:09 +0530 Subject: [PATCH 13/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/middlewares/schemaValidator.middleware.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index e9feaec..20a6591 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -78,7 +78,7 @@ export class OpenApiValidatorMiddleware { count: 0, requestHandler: requestHandler }; - // await initializeOpenApiValidatorCache(requestHandler, file); + await initializeOpenApiValidatorCache(requestHandler, file); } } } catch (err) { @@ -174,6 +174,7 @@ const initializeOpenApiValidatorCache = async ( } actions.slice(0, 2).forEach((action) => { + console.log("Action is:", action); const mockRequest = (body: any) => { const req = httpMocks.createRequest({ method: "POST", @@ -198,12 +199,12 @@ const initializeOpenApiValidatorCache = async ( } as any; return req; }; + const reqObj = mockRequest({ context: { action: `${action}` }, message: {} }); - console.log("This is for specfile: ", specFile); - + console.log(`Mock created for action ${action} and domain ${specFile}`); walkSubstack( stack, reqObj, @@ -211,7 +212,7 @@ const initializeOpenApiValidatorCache = async ( () => { return; }, - false + true ); }); } catch (error: any) { @@ -231,9 +232,11 @@ const walkSubstack = function ( } const walkStack = function (i: any, err?: any) { if (err && showError) { + console.log(`Walk Stack Error at ${i}`); return schemaErrorHandler(err, req, res, next); } if (i >= stack.length) { + console.log("Going out of this walkstack"); return next(); } stack[i](req, res, walkStack.bind(null, i + 1)); From 049acd4f21508cbb2b803b09ff2c68209929d368 Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 16:07:28 +0530 Subject: [PATCH 14/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/utils/mongo.utils.ts | 75 +++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/src/utils/mongo.utils.ts b/src/utils/mongo.utils.ts index 0c4b4f3..2313ac0 100644 --- a/src/utils/mongo.utils.ts +++ b/src/utils/mongo.utils.ts @@ -2,41 +2,52 @@ import { Db, MongoClient } from "mongodb"; import { Exception, ExceptionType } from "../models/exception.model"; import logger from "./logger.utils"; -export class DBClient{ - private db: Db; - private client: MongoClient; - public isConnected: boolean = false; - - constructor(dbURL: string){ - this.client = new MongoClient(dbURL, { - minPoolSize: 10, - maxPoolSize: 15, - }); - - this.db = this.client.db(); +export class DBClient { + private db: Db; + private client: MongoClient; + public isConnected: boolean = false; + + constructor(dbURL: string) { + this.client = new MongoClient(dbURL, { + minPoolSize: 10, + maxPoolSize: 15 + }); + + this.db = this.client.db(); + } + + public async connect(): Promise { + try { + this.client = await this.client.connect(); + this.db = this.client.db(); + this.isConnected = true; + logger.info(`Mongo Client Connected For DB: ${this.db.databaseName}`); + } catch (error: any) { + console.log(error); } - - public async connect(): Promise { - this.client = await this.client.connect(); - this.db = this.client.db(); - this.isConnected = true; - logger.info(`Mongo Client Connected For DB: ${this.db.databaseName}`); - } - - public getDB(): Db{ - if(!this.isConnected){ - throw new Exception(ExceptionType.Mongo_ClientNotInitialized, "Mongo client is not connected.", 500); - } - - return this.db; + } + + public getDB(): Db { + if (!this.isConnected) { + throw new Exception( + ExceptionType.Mongo_ClientNotInitialized, + "Mongo client is not connected.", + 500 + ); } - public getClient(): MongoClient{ - if(!this.isConnected){ - throw new Exception(ExceptionType.Mongo_ClientNotInitialized, "Mongo client is not connected.", 500); - } + return this.db; + } - return this.client; + public getClient(): MongoClient { + if (!this.isConnected) { + throw new Exception( + ExceptionType.Mongo_ClientNotInitialized, + "Mongo client is not connected.", + 500 + ); } -} \ No newline at end of file + return this.client; + } +} From ba9e1a121ade5334616d13d50107d60d3b049c5b Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 16:14:38 +0530 Subject: [PATCH 15/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/app.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app.ts b/src/app.ts index aa9b542..deaddcb 100644 --- a/src/app.ts +++ b/src/app.ts @@ -117,7 +117,7 @@ const main = async () => { try { await ClientUtils.initializeConnection(); await GatewayUtils.getInstance().initialize(); - await OpenApiValidatorMiddleware.getInstance().initOpenApiMiddleware(); + console.log("After Open API middleware"); if (getConfig().responseCache.enabled) { await ResponseCache.getInstance().initialize(); @@ -134,6 +134,7 @@ const main = async () => { getConfig().app.gateway.mode.toLocaleUpperCase().substring(1) ); }); + await OpenApiValidatorMiddleware.getInstance().initOpenApiMiddleware(); } catch (err) { if (err instanceof Exception) { logger.error(err.toString()); From e29fcdad8103fc0f71aca8f9c78cd7be142cecef Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 16:20:57 +0530 Subject: [PATCH 16/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/app.ts | 4 +-- src/middlewares/schemaValidator.middleware.ts | 26 +++++-------------- src/utils/mongo.utils.ts | 4 +-- 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/src/app.ts b/src/app.ts index deaddcb..e14903d 100644 --- a/src/app.ts +++ b/src/app.ts @@ -78,7 +78,7 @@ const initializeExpress = async (successCallback: Function) => { // Error Handler. app.use((err: any, req: Request, res: Response, next: NextFunction) => { - console.log("In Error Handler---->middleware", err); + console.log(err); if (err instanceof Exception) { const errorData = { code: err.code, @@ -117,8 +117,6 @@ const main = async () => { try { await ClientUtils.initializeConnection(); await GatewayUtils.getInstance().initialize(); - - console.log("After Open API middleware"); if (getConfig().responseCache.enabled) { await ResponseCache.getInstance().initialize(); } diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index 20a6591..6009b66 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -174,7 +174,6 @@ const initializeOpenApiValidatorCache = async ( } actions.slice(0, 2).forEach((action) => { - console.log("Action is:", action); const mockRequest = (body: any) => { const req = httpMocks.createRequest({ method: "POST", @@ -204,39 +203,28 @@ const initializeOpenApiValidatorCache = async ( context: { action: `${action}` }, message: {} }); - console.log(`Mock created for action ${action} and domain ${specFile}`); - walkSubstack( - stack, - reqObj, - {}, - () => { - return; - }, - true - ); + + walkSubstack(stack, reqObj, {}, () => { + return; + }); }); - } catch (error: any) { - console.log(error.message); - } + } catch (error: any) {} }; const walkSubstack = function ( stack: any, req: any, res: any, - next: NextFunction, - showError = true + next: NextFunction ) { if (typeof stack === "function") { stack = [stack]; } const walkStack = function (i: any, err?: any) { - if (err && showError) { - console.log(`Walk Stack Error at ${i}`); + if (err) { return schemaErrorHandler(err, req, res, next); } if (i >= stack.length) { - console.log("Going out of this walkstack"); return next(); } stack[i](req, res, walkStack.bind(null, i + 1)); diff --git a/src/utils/mongo.utils.ts b/src/utils/mongo.utils.ts index 2313ac0..8137f0d 100644 --- a/src/utils/mongo.utils.ts +++ b/src/utils/mongo.utils.ts @@ -22,9 +22,7 @@ export class DBClient { this.db = this.client.db(); this.isConnected = true; logger.info(`Mongo Client Connected For DB: ${this.db.databaseName}`); - } catch (error: any) { - console.log(error); - } + } catch (error: any) {} } public getDB(): Db { From 01b7d0ca6765a97254ca63031ea1d61f5d26b43b Mon Sep 17 00:00:00 2001 From: shreyvishal Date: Tue, 18 Jun 2024 16:29:13 +0530 Subject: [PATCH 17/17] Added: Feature For load OpenAPIValidator Cache on app boot --- src/middlewares/schemaValidator.middleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middlewares/schemaValidator.middleware.ts b/src/middlewares/schemaValidator.middleware.ts index 6009b66..667730b 100644 --- a/src/middlewares/schemaValidator.middleware.ts +++ b/src/middlewares/schemaValidator.middleware.ts @@ -173,7 +173,7 @@ const initializeOpenApiValidatorCache = async ( actions = Object.keys(ResponseActions); } - actions.slice(0, 2).forEach((action) => { + actions.forEach((action) => { const mockRequest = (body: any) => { const req = httpMocks.createRequest({ method: "POST",