diff --git a/apps/agent-service/src/agent-service.module.ts b/apps/agent-service/src/agent-service.module.ts index d8fe46193..85aa5ad31 100644 --- a/apps/agent-service/src/agent-service.module.ts +++ b/apps/agent-service/src/agent-service.module.ts @@ -1,4 +1,4 @@ -import { CommonModule } from '@credebl/common'; +import { CommonModule, NatsInterceptor } from '@credebl/common'; import { PrismaService } from '@credebl/prisma-service'; import { Logger, Module } from '@nestjs/common'; import { ClientsModule, Transport } from '@nestjs/microservices'; @@ -17,13 +17,15 @@ import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; import { GlobalConfigModule } from '@credebl/config/global-config.module'; import { ContextInterceptorModule } from '@credebl/context/contextInterceptorModule'; import { NATSClient } from '@credebl/common/NATSClient'; - +import { APP_INTERCEPTOR } from '@nestjs/core'; @Module({ imports: [ ConfigModule.forRoot(), GlobalConfigModule, - LoggerModule, PlatformConfig, ContextInterceptorModule, + LoggerModule, + PlatformConfig, + ContextInterceptorModule, ClientsModule.register([ { name: 'NATS_CLIENT', @@ -47,7 +49,11 @@ import { NATSClient } from '@credebl/common/NATSClient'; provide: MICRO_SERVICE_NAME, useValue: 'Agent-service' }, - NATSClient + NATSClient, + { + provide: APP_INTERCEPTOR, + useClass: NatsInterceptor + } ], exports: [AgentServiceService, AgentServiceRepository, AgentServiceModule] }) diff --git a/apps/api-gateway/src/main.ts b/apps/api-gateway/src/main.ts index e92468ce8..2b7239725 100644 --- a/apps/api-gateway/src/main.ts +++ b/apps/api-gateway/src/main.ts @@ -14,7 +14,6 @@ import { getNatsOptions } from '@credebl/common/nats.config'; import helmet from 'helmet'; import { CommonConstants } from '@credebl/common/common.constant'; import NestjsLoggerServiceAdapter from '@credebl/logger/nestjsLoggerServiceAdapter'; -import { NatsInterceptor } from '@credebl/common'; import { UpdatableValidationPipe } from '@credebl/common/custom-overrideable-validation-pipe'; import * as useragent from 'express-useragent'; @@ -117,7 +116,6 @@ async function bootstrap(): Promise { xssFilter: true }) ); - app.useGlobalInterceptors(new NatsInterceptor()); await app.listen(process.env.API_GATEWAY_PORT, `${process.env.API_GATEWAY_HOST}`); Logger.log(`API Gateway is listening on port ${process.env.API_GATEWAY_PORT}`); } diff --git a/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.controller.ts b/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.controller.ts index d3c5fd13a..ce8cb5850 100644 --- a/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.controller.ts +++ b/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.controller.ts @@ -54,7 +54,7 @@ import { Oid4vpPresentationWhDto } from '../oid4vc-issuance/dtos/oid4vp-presenta @ApiUnauthorizedResponse({ description: 'Unauthorized', type: UnauthorizedErrorDto }) @ApiForbiddenResponse({ description: 'Forbidden', type: ForbiddenErrorDto }) export class Oid4vcVerificationController { - private readonly logger = new Logger('Oid4vpVerificationController'); + private readonly logger = new Logger('Oid4vcVerificationController'); constructor(private readonly oid4vcVerificationService: Oid4vcVerificationService) {} /** diff --git a/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts b/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts index 6c6280ffd..e319f5674 100644 --- a/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts +++ b/apps/api-gateway/src/oid4vc-verification/oid4vc-verification.service.ts @@ -1,7 +1,6 @@ import { NATSClient } from '@credebl/common/NATSClient'; -import { Inject, Injectable } from '@nestjs/common'; +import { Inject, Injectable, Logger } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; -import { BaseService } from 'libs/service/base.service'; // eslint-disable-next-line camelcase import { oid4vp_verifier, user } from '@prisma/client'; import { CreateVerifierDto, UpdateVerifierDto } from './dtos/oid4vc-verifier.dto'; @@ -9,13 +8,13 @@ import { VerificationPresentationQueryDto } from './dtos/oid4vc-verifier-present import { Oid4vpPresentationWhDto } from '../oid4vc-issuance/dtos/oid4vp-presentation-wh.dto'; @Injectable() -export class Oid4vcVerificationService extends BaseService { +export class Oid4vcVerificationService { + private readonly logger = new Logger('Oid4vcVerificationService'); + constructor( @Inject('NATS_CLIENT') private readonly oid4vpProxy: ClientProxy, private readonly natsClient: NATSClient - ) { - super('Oid4vcVerificationService'); - } + ) {} async oid4vpCreateVerifier( createVerifier: CreateVerifierDto, diff --git a/apps/oid4vc-verification/src/main.ts b/apps/oid4vc-verification/src/main.ts index fbb4b7b91..e414e6a3f 100644 --- a/apps/oid4vc-verification/src/main.ts +++ b/apps/oid4vc-verification/src/main.ts @@ -1,5 +1,4 @@ import { NestFactory } from '@nestjs/core'; -import { HttpExceptionFilter } from 'libs/http-exception.filter'; import { Logger } from '@nestjs/common'; import { MicroserviceOptions, Transport } from '@nestjs/microservices'; import { getNatsOptions } from '@credebl/common/nats.config'; @@ -15,7 +14,8 @@ async function bootstrap(): Promise { options: getNatsOptions(CommonConstants.OIDC4VC_VERIFICATION_SERVICE, process.env.Verification_NKEY_SEED) }); app.useLogger(app.get(NestjsLoggerServiceAdapter)); - app.useGlobalFilters(new HttpExceptionFilter()); + // TODO: Not sure if we want the below + // app.useGlobalFilters(new HttpExceptionFilter()); await app.listen(); logger.log('OID4VC-Verification-Service Microservice is listening to NATS '); diff --git a/apps/oid4vc-verification/src/oid4vc-verification.controller.ts b/apps/oid4vc-verification/src/oid4vc-verification.controller.ts index 5422e7ff8..8f949a41e 100644 --- a/apps/oid4vc-verification/src/oid4vc-verification.controller.ts +++ b/apps/oid4vc-verification/src/oid4vc-verification.controller.ts @@ -8,8 +8,10 @@ import { Oid4vpPresentationWh } from '../interfaces/oid4vp-verification-sessions @Controller() export class Oid4vpVerificationController { - private readonly logger = new Logger('Oid4vpVerificationController'); - constructor(private readonly oid4vpVerificationService: Oid4vpVerificationService) {} + constructor( + private readonly oid4vpVerificationService: Oid4vpVerificationService, + private logger: Logger + ) {} @MessagePattern({ cmd: 'oid4vp-verifier-create' }) async oid4vpCreateVerifier(payload: { diff --git a/apps/oid4vc-verification/src/oid4vc-verification.module.ts b/apps/oid4vc-verification/src/oid4vc-verification.module.ts index 78b37ac7e..398b3482e 100644 --- a/apps/oid4vc-verification/src/oid4vc-verification.module.ts +++ b/apps/oid4vc-verification/src/oid4vc-verification.module.ts @@ -4,18 +4,24 @@ import { Oid4vpVerificationService } from './oid4vc-verification.service'; import { ClientsModule, Transport } from '@nestjs/microservices'; import { getNatsOptions } from '@credebl/common/nats.config'; import { CommonModule } from '@credebl/common'; -import { CommonConstants } from '@credebl/common/common.constant'; +import { CommonConstants, MICRO_SERVICE_NAME } from '@credebl/common/common.constant'; import { GlobalConfigModule } from '@credebl/config'; import { ContextInterceptorModule } from '@credebl/context'; -import { LoggerModule } from '@credebl/logger'; +import { LoggerModule } from '@credebl/logger/logger.module'; import { CacheModule } from '@nestjs/cache-manager'; import { ConfigModule as PlatformConfig } from '@credebl/config/config.module'; import { NATSClient } from '@credebl/common/NATSClient'; -import { PrismaService } from '@credebl/prisma-service'; +import { PrismaService, PrismaServiceModule } from '@credebl/prisma-service'; import { Oid4vpRepository } from './oid4vc-verification.repository'; +import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ + ConfigModule.forRoot(), + ContextInterceptorModule, + PlatformConfig, + LoggerModule, + CacheModule.register(), ClientsModule.register([ { name: 'NATS_CLIENT', @@ -28,12 +34,19 @@ import { Oid4vpRepository } from './oid4vc-verification.repository'; ]), CommonModule, GlobalConfigModule, - LoggerModule, - PlatformConfig, - ContextInterceptorModule, - CacheModule.register() + PrismaServiceModule ], controllers: [Oid4vpVerificationController], - providers: [Oid4vpVerificationService, Oid4vpRepository, PrismaService, Logger, NATSClient] + providers: [ + Oid4vpVerificationService, + Oid4vpRepository, + PrismaService, + Logger, + NATSClient, + { + provide: MICRO_SERVICE_NAME, + useValue: 'Oid4vc-verification-service' + } + ] }) export class Oid4vpModule {} diff --git a/apps/oid4vc-verification/src/oid4vc-verification.service.ts b/apps/oid4vc-verification/src/oid4vc-verification.service.ts index cff888e4a..de17c4dc9 100644 --- a/apps/oid4vc-verification/src/oid4vc-verification.service.ts +++ b/apps/oid4vc-verification/src/oid4vc-verification.service.ts @@ -9,11 +9,9 @@ import { BadRequestException, ConflictException, - HttpException, Inject, Injectable, InternalServerErrorException, - Logger, NotFoundException } from '@nestjs/common'; import { Oid4vpRepository } from './oid4vc-verification.repository'; @@ -27,6 +25,8 @@ import { CreateVerifier, UpdateVerifier, VerifierRecord } from '@credebl/common/ import { buildUrlWithQuery } from '@credebl/common/cast.helper'; import { VerificationSessionQuery } from '../interfaces/oid4vp-verifier.interfaces'; import { BaseService } from 'libs/service/base.service'; +import { NATSClient } from '@credebl/common/NATSClient'; + import { Oid4vpPresentationWh, RequestSigner } from '../interfaces/oid4vp-verification-sessions.interfaces'; import { X509CertificateRecord } from '@credebl/common/interfaces/x509.interface'; import { SignerMethodOption } from '@credebl/enum/enum'; @@ -34,6 +34,7 @@ import { SignerMethodOption } from '@credebl/enum/enum'; export class Oid4vpVerificationService extends BaseService { constructor( @Inject('NATS_CLIENT') private readonly oid4vpVerificationServiceProxy: ClientProxy, + private readonly natsClient: NATSClient, private readonly oid4vpRepository: Oid4vpRepository ) { super('Oid4vpVerificationService'); @@ -363,9 +364,12 @@ export class Oid4vpVerificationService extends BaseService { async _createOid4vpVerifier(verifierDetails: CreateVerifier, url: string, orgId: string): Promise { this.logger.debug(`[_createOid4vpVerifier] sending NATS message for orgId=${orgId}`); try { - const pattern = { cmd: 'agent-create-oid4vp-verifier' }; const payload = { verifierDetails, url, orgId }; - const response = await this.natsCall(pattern, payload); + const response = await this.natsClient.sendNatsMessage( + this.oid4vpVerificationServiceProxy, + 'agent-create-oid4vp-verifier', + payload + ); this.logger.debug(`[_createOid4vpVerifier] NATS response received`); return response; } catch (error) { @@ -379,9 +383,12 @@ export class Oid4vpVerificationService extends BaseService { async _deleteOid4vpVerifier(url: string, orgId: string): Promise { this.logger.debug(`[_deleteOid4vpVerifier] sending NATS message for orgId=${orgId}`); try { - const pattern = { cmd: 'agent-delete-oid4vp-verifier' }; const payload = { url, orgId }; - const response = await this.natsCall(pattern, payload); + const response = await this.natsClient.sendNatsMessage( + this.oid4vpVerificationServiceProxy, + 'agent-delete-oid4vp-verifier', + payload + ); this.logger.debug(`[_deleteOid4vpVerifier] NATS response received`); return response; } catch (error) { @@ -395,9 +402,12 @@ export class Oid4vpVerificationService extends BaseService { async _updateOid4vpVerifier(verifierDetails: UpdateVerifier, url: string, orgId: string): Promise { this.logger.debug(`[_updateOid4vpVerifier] sending NATS message for orgId=${orgId}`); try { - const pattern = { cmd: 'agent-update-oid4vp-verifier' }; const payload = { verifierDetails, url, orgId }; - const response = await this.natsCall(pattern, payload); + const response = await this.natsClient.sendNatsMessage( + this.oid4vpVerificationServiceProxy, + 'agent-update-oid4vp-verifier', + payload + ); this.logger.debug(`[_updateOid4vpVerifier] NATS response received`); return response; } catch (error) { @@ -411,9 +421,12 @@ export class Oid4vpVerificationService extends BaseService { async _createVerificationSession(sessionRequest: any, url: string, orgId: string): Promise { this.logger.debug(`[_createVerificationSession] sending NATS message for orgId=${orgId}`); try { - const pattern = { cmd: 'agent-create-oid4vp-verification-session' }; const payload = { sessionRequest, url, orgId }; - const response = await this.natsCall(pattern, payload); + const response = await this.natsClient.sendNatsMessage( + this.oid4vpVerificationServiceProxy, + 'agent-create-oid4vp-verification-session', + payload + ); this.logger.debug(`[_createVerificationSession] NATS response received`); return response; } catch (error) { @@ -427,9 +440,12 @@ export class Oid4vpVerificationService extends BaseService { async _getOid4vpVerifierSession(url: string, orgId: string): Promise { this.logger.debug(`[_getOid4vpVerifierSession] sending NATS message for orgId=${orgId}`); try { - const pattern = { cmd: 'agent-get-oid4vp-verifier-session' }; const payload = { url, orgId }; - const response = await this.natsCall(pattern, payload); + const response = await this.natsClient.sendNatsMessage( + this.oid4vpVerificationServiceProxy, + 'agent-get-oid4vp-verifier-session', + payload + ); this.logger.debug(`[_getOid4vpVerifierSession] NATS response received`); return response; } catch (error) { @@ -443,9 +459,12 @@ export class Oid4vpVerificationService extends BaseService { async _getVerificationSessionResponse(url: string, orgId: string): Promise { this.logger.debug(`[_getVerificationSessionResponse] sending NATS message for orgId=${orgId}`); try { - const pattern = { cmd: 'agent-get-oid4vp-verifier-session' }; const payload = { url, orgId }; - const response = await this.natsCall(pattern, payload); + const response = await this.natsClient.sendNatsMessage( + this.oid4vpVerificationServiceProxy, + 'agent-get-oid4vp-verifier-session', + payload + ); this.logger.debug(`[_getVerificationSessionResponse] NATS response received`); return response; } catch (error) { @@ -455,26 +474,4 @@ export class Oid4vpVerificationService extends BaseService { throw error; } } - - async natsCall(pattern: object, payload: object): Promise { - try { - return this.oid4vpVerificationServiceProxy - .send(pattern, payload) - .pipe(map((response) => response)) - .toPromise() - .catch((error) => { - this.logger.error(`catch: ${JSON.stringify(error)}`); - throw new HttpException( - { - status: error.statusCode, - error: error.message - }, - error.error - ); - }); - } catch (error) { - this.logger.error(`[natsCall] - error in nats call : ${JSON.stringify(error)}`); - throw error; - } - } } diff --git a/libs/context/src/contextInterceptorModule.ts b/libs/context/src/contextInterceptorModule.ts index a80a712f9..e9ff13139 100644 --- a/libs/context/src/contextInterceptorModule.ts +++ b/libs/context/src/contextInterceptorModule.ts @@ -1,14 +1,10 @@ -import { ExecutionContext, Global, Module} from '@nestjs/common'; -import { v4 } from 'uuid'; +import { ExecutionContext, Global, Logger, Module } from '@nestjs/common'; +import { v4 as uuid } from 'uuid'; import { ClsModule } from 'nestjs-cls'; import { ContextStorageServiceKey } from './contextStorageService.interface'; import NestjsClsContextStorageService from './nestjsClsContextStorageService'; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const isNullUndefinedOrEmpty = (obj: any): boolean => null === obj || obj === undefined || ('object' === typeof obj && 0 === Object.keys(obj).length); - @Global() @Module({ imports: [ @@ -17,17 +13,30 @@ const isNullUndefinedOrEmpty = (obj: any): boolean => null === obj || obj === un interceptor: { mount: true, - generateId: true, - idGenerator: (context: ExecutionContext) => { - const rpcContext = context.switchToRpc().getContext(); - const headers = rpcContext.getHeaders(); - if (!isNullUndefinedOrEmpty(headers)) { - return context.switchToRpc().getContext().getHeaders()['_description']; - } else { - return v4(); + generateId: true, + idGenerator: (context: ExecutionContext) => { + try { + const logger = new Logger('ContextInterceptorModule'); + const rpcContext = context.switchToRpc().getContext(); + const headers = rpcContext.getHeaders() ?? {}; + const contextId = headers.get?.('contextId'); + + if (contextId) { + logger.debug(`[idGenerator] Received contextId in headers: ${contextId}`); + return contextId; + } else { + const uuidGenerated = uuid(); + logger.debug( + '[idGenerator] Did not receive contextId in header, generated new contextId: ', + uuidGenerated + ); + return uuidGenerated; + } + } catch (error) { + // eslint-disable-next-line no-console + console.log('[idGenerator] Error in idGenerator: ', error); } - } - + } } }) ], @@ -40,6 +49,4 @@ const isNullUndefinedOrEmpty = (obj: any): boolean => null === obj || obj === un ], exports: [ContextStorageServiceKey] }) - export class ContextInterceptorModule {} - diff --git a/libs/context/src/contextModule.ts b/libs/context/src/contextModule.ts index 4bfb9e2c3..a03d046d1 100644 --- a/libs/context/src/contextModule.ts +++ b/libs/context/src/contextModule.ts @@ -13,7 +13,24 @@ import NestjsClsContextStorageService from './nestjsClsContextStorageService'; middleware: { mount: true, generateId: true, - idGenerator: (req: Request) => req.headers['x-correlation-id'] ?? v4() + idGenerator: (req: Request) => { + // TODO: Check if we want the x-correlation-id or the correlationId + const contextIdHeader = req.headers['contextid'] ?? req.headers['context-id'] ?? req.headers['contextId']; + const correlationIdHeader = req.headers['x-correlation-id']; + let resolvedContextId = + (Array.isArray(contextIdHeader) ? contextIdHeader[0] : contextIdHeader) ?? + (Array.isArray(correlationIdHeader) ? correlationIdHeader[0] : correlationIdHeader); + + if (resolvedContextId) { + // eslint-disable-next-line no-console + console.log('ContextId received in request headers::::', resolvedContextId); + } else { + resolvedContextId = v4(); + // eslint-disable-next-line no-console + console.log('ContextId not received in request headers, generated a new one::::', resolvedContextId); + } + return resolvedContextId; + } } }) ], diff --git a/libs/logger/src/logging.interceptor.ts b/libs/logger/src/logging.interceptor.ts index 6ac3a0611..74b7db289 100644 --- a/libs/logger/src/logging.interceptor.ts +++ b/libs/logger/src/logging.interceptor.ts @@ -17,26 +17,28 @@ export class LoggingInterceptor implements NestInterceptor { private readonly clsService: ClsService, @Inject(ContextStorageServiceKey) private readonly contextStorageService: ContextStorageService, - @Inject(LoggerKey) private readonly _logger: Logger + @Inject(LoggerKey) private readonly logger: Logger ) {} // eslint-disable-next-line @typescript-eslint/no-explicit-any intercept(context: ExecutionContext, next: CallHandler): Observable { return this.clsService.run(() => { - this._logger.info('In LoggingInterceptor configuration'); + this.logger.info('In LoggingInterceptor configuration'); const rpcContext = context.switchToRpc().getContext(); const headers = rpcContext.getHeaders(); - if (!isNullUndefinedOrEmpty(headers) && headers._description) { - this.contextStorageService.set('x-correlation-id', headers._description); - this.contextStorageService.setContextId(headers._description); + if (!isNullUndefinedOrEmpty(headers)) { + this.logger.debug('We found context Id in header of logger Interceptor', headers.get('contextId')); + this.contextStorageService.setContextId(headers.get('contextId')); } else { const newContextId = v4(); + this.logger.debug('Not found context Id in header of logger Interceptor, generating a new one: ', newContextId); this.contextStorageService.set('x-correlation-id', newContextId); + this.contextStorageService.set('contextId', newContextId); this.contextStorageService.setContextId(newContextId); } return next.handle().pipe( catchError((err) => { - this._logger.error(err); + this.logger.error('[intercept] Error in LoggingInterceptor', err); return throwError(() => err); }) );