Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12111

Nest Interceptor brokes Azure Service Bus Integration

$
0
0

Context

In my project, I have a gateway REST application and several microservices that communicate via Azure Service Bus. I also use interceptors to handle some cross-cutting concerns in my services. However, I am facing an issue where the controllers in my microservices do not work when an interceptor is attached. When I comment out the interceptor, the controllers function as expected.

Issue

Whenever I send a message to a service from the gateway, the controller doesn't work if an interceptor is attached. When I comment out the interceptor from the service, the controller works as expected. I have already simplified the interceptor to the bare minimum and ensured that ClientProxyService is correctly injected.

Example response when interceptor disabled

RESULT{"maskedGsm":"53******45"}

Example response when interceptor disabled

RESULT{"source":{"source":{}}}

Detailed Description

Here is a brief overview of my setup:

Interceptor Code:

@Injectable()export class AnalyticInterceptor implements NestInterceptor {  constructor(private readonly client: ClientProxyService) {}  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {    const eventName = context.getHandler().name;    if (eventName === 'validate') {      return next.handle();    }    const message = context.switchToRpc().getData();    const sicil = message.id;    delete message.sicil;    return next.handle().pipe(      map((data) => {        const payload: IncomingEventPayload = {          eventName: eventName,          data: data,          event_date: new Date(),          sicil: sicil,        };        this.client.emitEvent('auth-event', payload);        return data;      }),      catchError((err) => {        const payload: IncomingEventErrorPayload = {          eventName: eventName,          err: err,          err_date: new Date(),          sicil: sicil,        };        this.client.emitEvent('auth-error', payload);        throw err;      })    );  }}interface IncomingEventPayload {  eventName: string;  data: any;  event_date: Date;  sicil: number;}interface IncomingEventErrorPayload {  eventName: string;  err: RpcException;  err_date: Date;  sicil: number;}

Custom Transport Strategy Code

export class AzureServiceBusClient extends Server implements CustomTransportStrategy {  private serviceBusClient: ServiceBusClient;  private queueSender: ServiceBusSender;  private queueReceiver: ServiceBusReceiver;  constructor(private readonly queueName: string) {    super();    this.serviceBusClient = new ServiceBusClient('Endpoint=sb://<namespace>.servicebus.windows.net/;SharedAccessKeyName=<KeyName>;SharedAccessKey=<AccessKey>');    this.queueSender = this.serviceBusClient.createSender(this.queueName);    this.queueReceiver = this.serviceBusClient.createReceiver(this.queueName);  }  async connect() {}  async close() {    await this.queueReceiver.close();    await this.queueSender.close();  }  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {    await this.queueSender.sendMessages({      body: packet.data,      sessionId: packet.pattern,    });  }  publish(packet: ReadPacket<any>, callback: (packet: WritePacket<any>) => void): () => void {    const subscription = this.queueReceiver.subscribe({      processMessage: async (message: any) => {        if (message.body.pattern === packet.pattern) {          callback({ response: message.body.result });        }      },      processError: async (args) => {        console.error('Error receiving message', args);      },    });    this.dispatchEvent(packet);    return () => {      subscription.close();    };  }  listen(callback: () => void) {    this.queueReceiver.subscribe({      processMessage: async (brokeredMessage) => {        const handler = this.getHandlerByPattern(brokeredMessage.sessionId);        if (!handler) {          console.error(`No handlers for pattern ${brokeredMessage.subject}`);          return;        } else {          const result = await handler(this.deserialize(brokeredMessage).data);          await this.queueSender.sendMessages({            body: result,            sessionId: brokeredMessage.sessionId,          });        }      },      processError: async (err) => {        console.error(err);      }    });    callback();  }  private deserialize(message: any): any {    return {      pattern: message.subject,      data: message.body,    };  }}

Example Controller

@Controller()@UseInterceptors(AnalyticInterceptor) // this broken my transport strategy export class AuthController {  constructor(private readonly authService: AuthService) {}  @MessagePattern('login')  async login(@Payload() loginDTO: LoginDTO): Promise<any> {    return this.authService.login(loginDTO);  }  @MessagePattern('getOtp')  async getOtp(@Payload() getOtpDto: GetOtpDTO): Promise<any> {    return this.authService.getOtp(getOtpDto);  }  @MessagePattern('loginWithGsm')  async loginWithGsm(@Payload() loginWithGsmDto: LoginViaGsmDTO): Promise<any> {    return this.authService.loginWithGsm(loginWithGsmDto);  }  @MessagePattern('checkOtp')  async checkOTP(@Payload() checkOtpDTO: CheckOtpDTO): Promise<any> {    return this.authService.checkOtp(checkOtpDTO);  }  @MessagePattern('refresh')  async refresh(@Payload() refreshDto: RefreshDTO): Promise<any> {    return this.authService.refresh(refreshDto);  }  @MessagePattern('validate')  async validate(@Payload() validateTokenDto: ValidateTokenDto): Promise<any> {    return this.authService.validate(validateTokenDto);  }  @MessagePattern('logout')  async logout(@Payload() logoutDto: LogoutDTO): Promise<any> {    return this.authService.logout(logoutDto);  }}

Viewing all articles
Browse latest Browse all 12111

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>