Skip to content

Commit 9ad7927

Browse files
Merge pull request nestjs#974 from nestjs/bugfix/948-nats-wildcards
bugfix(@nestjs/microservices) fix nats wildcards
2 parents e967ba1 + 62e733c commit 9ad7927

15 files changed

Lines changed: 212 additions & 159 deletions

File tree

integration/microservices/e2e/sum-nats.spec.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import * as express from 'express';
2-
import * as request from 'supertest';
3-
import { Test } from '@nestjs/testing';
41
import { INestApplication } from '@nestjs/common';
52
import { Transport } from '@nestjs/microservices';
3+
import { Test } from '@nestjs/testing';
4+
import * as express from 'express';
5+
import * as request from 'supertest';
66
import { NatsController } from '../src/nats/nats.controller';
77

88
describe('NATS transport', () => {
@@ -19,7 +19,7 @@ describe('NATS transport', () => {
1919
app.connectMicroservice({
2020
transport: Transport.NATS,
2121
options: {
22-
url: 'nats://localhost:4222'
22+
url: 'nats://localhost:4222',
2323
},
2424
});
2525
await app.startAllMicroservicesAsync();
@@ -28,22 +28,22 @@ describe('NATS transport', () => {
2828

2929
it(`/POST`, () => {
3030
return request(server)
31-
.post('/?command=sum')
31+
.post('/?command=math.sum')
3232
.send([1, 2, 3, 4, 5])
3333
.expect(200, '15');
3434
});
3535

3636
it(`/POST (Promise/async)`, () => {
3737
return request(server)
38-
.post('/?command=asyncSum')
38+
.post('/?command=async.sum')
3939
.send([1, 2, 3, 4, 5])
4040
.expect(200)
4141
.expect(200, '15');
4242
});
4343

4444
it(`/POST (Observable stream)`, () => {
4545
return request(server)
46-
.post('/?command=streamSum')
46+
.post('/?command=stream.sum')
4747
.send([1, 2, 3, 4, 5])
4848
.expect(200, '15');
4949
});

integration/microservices/src/nats/nats-broadcast.controller.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Controller, Get } from '@nestjs/common';
22
import {
33
Client,
4-
MessagePattern,
54
ClientProxy,
5+
MessagePattern,
66
Transport,
77
} from '@nestjs/microservices';
88
import { Observable } from 'rxjs';
@@ -16,11 +16,11 @@ export class NatsBroadcastController {
1616
@Get('broadcast')
1717
multicats() {
1818
return this.client
19-
.send<number>({ cmd: 'broadcast' }, {})
19+
.send<number>('broadcast.test', {})
2020
.pipe(scan((a, b) => a + b), take(2));
2121
}
2222

23-
@MessagePattern({ cmd: 'broadcast' })
23+
@MessagePattern('broadcast.*')
2424
replyBroadcast(): Observable<number> {
2525
return new Observable(observer => observer.next(1));
2626
}

integration/microservices/src/nats/nats.controller.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { Controller, Get, Post, Body, Query, HttpCode } from '@nestjs/common';
1+
import { Body, Controller, HttpCode, Post, Query } from '@nestjs/common';
22
import {
33
Client,
4-
MessagePattern,
54
ClientProxy,
5+
MessagePattern,
66
Transport,
77
} from '@nestjs/microservices';
8-
import { Observable, of, from } from 'rxjs';
8+
import { from, Observable, of } from 'rxjs';
99
import { scan } from 'rxjs/operators';
1010

1111
@Controller()
@@ -21,14 +21,14 @@ export class NatsController {
2121
@Post()
2222
@HttpCode(200)
2323
call(@Query('command') cmd, @Body() data: number[]): Observable<number> {
24-
return this.client.send<number>({ cmd }, data);
24+
return this.client.send<number>(cmd, data);
2525
}
2626

2727
@Post('stream')
2828
@HttpCode(200)
2929
stream(@Body() data: number[]): Observable<number> {
3030
return this.client
31-
.send<number>({ cmd: 'streaming' }, data)
31+
.send<number>('streaming.sum', data)
3232
.pipe(scan((a, b) => a + b));
3333
}
3434

@@ -38,7 +38,7 @@ export class NatsController {
3838
const send = async (tab: number[]) => {
3939
const expected = tab.reduce((a, b) => a + b);
4040
const result = await this.client
41-
.send<number>({ cmd: 'sum' }, tab)
41+
.send<number>('math.sum', tab)
4242
.toPromise();
4343

4444
return result === expected;
@@ -48,22 +48,22 @@ export class NatsController {
4848
.reduce(async (a, b) => (await a) && (await b));
4949
}
5050

51-
@MessagePattern({ cmd: 'sum' })
51+
@MessagePattern('math.*')
5252
sum(data: number[]): number {
5353
return (data || []).reduce((a, b) => a + b);
5454
}
5555

56-
@MessagePattern({ cmd: 'asyncSum' })
56+
@MessagePattern('async.*')
5757
async asyncSum(data: number[]): Promise<number> {
5858
return (data || []).reduce((a, b) => a + b);
5959
}
6060

61-
@MessagePattern({ cmd: 'streamSum' })
61+
@MessagePattern('stream.*')
6262
streamSum(data: number[]): Observable<number> {
6363
return of((data || []).reduce((a, b) => a + b));
6464
}
6565

66-
@MessagePattern({ cmd: 'streaming' })
66+
@MessagePattern('streaming.*')
6767
streaming(data: number[]): Observable<number> {
6868
return from(data);
6969
}

packages/common/services/logger.service.ts

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,93 @@
11
import * as clc from 'cli-color';
2+
import { Injectable, Optional } from '../decorators';
23
import { NestEnvironment } from '../enums/nest-environment.enum';
3-
import { Constructor } from '../utils/merge-with-values.util';
4+
import { isObject } from '../utils/shared.utils';
45

56
declare const process;
67

78
export interface LoggerService {
8-
log(message: string);
9-
error(message: string, trace: string);
10-
warn(message: string);
9+
log(message: any, context?: string);
10+
error(message: any, trace?: string, context?: string);
11+
warn(message: any, context?: string);
1112
}
1213

14+
@Injectable()
1315
export class Logger implements LoggerService {
1416
private static prevTimestamp = null;
15-
private static contextEnv = NestEnvironment.RUN;
17+
private static contextEnvironment = NestEnvironment.RUN;
1618
private static logger: typeof Logger | LoggerService = Logger;
17-
1819
private static readonly yellow = clc.xterm(3);
1920

2021
constructor(
21-
private readonly context: string,
22-
private readonly isTimeDiffEnabled = false,
22+
@Optional() private readonly context: string,
23+
@Optional() private readonly isTimeDiffEnabled = false,
2324
) {}
2425

25-
log(message: string) {
26+
log(message: any, context?: string) {
2627
const { logger } = Logger;
28+
if (logger === this) {
29+
Logger.log(message, context || this.context, this.isTimeDiffEnabled);
30+
return;
31+
}
2732
logger &&
28-
logger.log.call(logger, message, this.context, this.isTimeDiffEnabled);
33+
logger.log.call(
34+
logger,
35+
message,
36+
context || this.context,
37+
this.isTimeDiffEnabled,
38+
);
2939
}
3040

31-
error(message: string, trace = '') {
41+
error(message: any, trace = '', context?: string) {
3242
const { logger } = Logger;
43+
if (logger === this) {
44+
Logger.error(
45+
message,
46+
trace,
47+
context || this.context,
48+
this.isTimeDiffEnabled,
49+
);
50+
return;
51+
}
3352
logger &&
3453
logger.error.call(
3554
logger,
3655
message,
3756
trace,
38-
this.context,
57+
context || this.context,
3958
this.isTimeDiffEnabled,
4059
);
4160
}
4261

43-
warn(message: string) {
62+
warn(message: any, context?: string) {
4463
const { logger } = Logger;
64+
if (logger === this) {
65+
Logger.warn(message, context || this.context, this.isTimeDiffEnabled);
66+
return;
67+
}
4568
logger &&
46-
logger.warn.call(logger, message, this.context, this.isTimeDiffEnabled);
69+
logger.warn.call(
70+
logger,
71+
message,
72+
context || this.context,
73+
this.isTimeDiffEnabled,
74+
);
4775
}
4876

4977
static overrideLogger(logger: LoggerService | boolean) {
5078
this.logger = logger ? (logger as LoggerService) : null;
5179
}
5280

5381
static setMode(mode: NestEnvironment) {
54-
this.contextEnv = mode;
82+
this.contextEnvironment = mode;
5583
}
5684

57-
static log(message: string, context = '', isTimeDiffEnabled = true) {
85+
static log(message: any, context = '', isTimeDiffEnabled = true) {
5886
this.printMessage(message, clc.green, context, isTimeDiffEnabled);
5987
}
6088

6189
static error(
62-
message: string,
90+
message: any,
6391
trace = '',
6492
context = '',
6593
isTimeDiffEnabled = true,
@@ -68,22 +96,26 @@ export class Logger implements LoggerService {
6896
this.printStackTrace(trace);
6997
}
7098

71-
static warn(message: string, context = '', isTimeDiffEnabled = true) {
99+
static warn(message: any, context = '', isTimeDiffEnabled = true) {
72100
this.printMessage(message, clc.yellow, context, isTimeDiffEnabled);
73101
}
74102

75103
private static printMessage(
76-
message: string,
77-
color: (msg: string) => string,
104+
message: any,
105+
color: (message: string) => string,
78106
context: string = '',
79107
isTimeDiffEnabled?: boolean,
80108
) {
81-
if (Logger.contextEnv === NestEnvironment.TEST) return;
82-
109+
if (Logger.contextEnvironment === NestEnvironment.TEST) {
110+
return void 0;
111+
}
112+
const output =
113+
message && isObject(message) ? JSON.stringify(message, null, 2) : message;
83114
process.stdout.write(color(`[Nest] ${process.pid} - `));
84115
process.stdout.write(`${new Date(Date.now()).toLocaleString()} `);
85-
process.stdout.write(this.yellow(`[${context}] `));
86-
process.stdout.write(color(message));
116+
117+
context && process.stdout.write(this.yellow(`[${context}] `));
118+
process.stdout.write(color(output));
87119

88120
this.printTimestamp(isTimeDiffEnabled);
89121
process.stdout.write(`\n`);
@@ -100,8 +132,9 @@ export class Logger implements LoggerService {
100132
}
101133

102134
private static printStackTrace(trace: string) {
103-
if (this.contextEnv === NestEnvironment.TEST || !trace) return;
104-
135+
if (this.contextEnvironment === NestEnvironment.TEST || !trace) {
136+
return void 0;
137+
}
105138
process.stdout.write(trace);
106139
process.stdout.write(`\n`);
107140
}

packages/microservices/client/client-mqtt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export class ClientMqtt extends ClientProxy {
8585
): Function {
8686
try {
8787
const packet = this.assignPacketId(partialPacket);
88-
const pattern = JSON.stringify(partialPacket.pattern);
88+
const pattern = this.normalizePattern(partialPacket.pattern);
8989
const responseChannel = this.getResPatternName(pattern);
9090
const responseCallback = this.createResponseCallback(packet, callback);
9191

packages/microservices/client/client-nats.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,6 @@ export class ClientNats extends ClientProxy {
2121
natsPackage = loadPackage('nats', ClientNats.name);
2222
}
2323

24-
public getAckPatternName(pattern: string): string {
25-
return `${pattern}_ack`;
26-
}
27-
28-
public getResPatternName(pattern: string): string {
29-
return `${pattern}_res`;
30-
}
31-
3224
public close() {
3325
this.natsClient && this.natsClient.close();
3426
this.natsClient = null;
@@ -81,21 +73,24 @@ export class ClientNats extends ClientProxy {
8173
});
8274
};
8375
}
76+
8477
protected publish(
8578
partialPacket: ReadPacket,
8679
callback: (packet: WritePacket) => any,
8780
): Function {
8881
try {
8982
const packet = this.assignPacketId(partialPacket);
90-
const pattern = JSON.stringify(partialPacket.pattern);
91-
const responseChannel = this.getResPatternName(pattern);
83+
const channel = this.normalizePattern(partialPacket.pattern);
9284

93-
const subscriptionHandler = this.createSubscriptionHandler(packet, callback);
94-
const subscriptionId = this.natsClient.subscribe(
95-
responseChannel,
85+
const subscriptionHandler = this.createSubscriptionHandler(
86+
packet,
87+
callback,
88+
);
89+
const subscriptionId = this.natsClient.request(
90+
channel,
91+
packet as any,
9692
subscriptionHandler,
9793
);
98-
this.natsClient.publish(this.getAckPatternName(pattern), packet as any);
9994
return () => this.natsClient.unsubscribe(subscriptionId);
10095
} catch (err) {
10196
callback({ err });

packages/microservices/client/client-proxy.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1-
import { isNil } from '@nestjs/common/utils/shared.utils';
2-
import { defer, fromEvent, merge, Observable, Observer, throwError as _throw } from 'rxjs';
1+
import { isNil, isString } from '@nestjs/common/utils/shared.utils';
2+
import {
3+
defer,
4+
fromEvent,
5+
merge,
6+
Observable,
7+
Observer,
8+
throwError as _throw,
9+
} from 'rxjs';
310
import { map, mergeMap, take } from 'rxjs/operators';
411
import { CONNECT_EVENT, ERROR_EVENT } from '../constants';
512
import { InvalidMessageException } from '../exceptions/errors/invalid-message.exception';
6-
import { ClientOptions, PacketId, ReadPacket, WritePacket } from '../interfaces';
13+
import {
14+
ClientOptions,
15+
PacketId,
16+
ReadPacket,
17+
WritePacket,
18+
} from '../interfaces';
719

820
export abstract class ClientProxy {
921
public abstract connect(): Promise<any>;
@@ -74,4 +86,8 @@ export abstract class ClientProxy {
7486
) {
7587
return obj && obj.options ? obj.options[prop as any] : defaultValue;
7688
}
89+
90+
protected normalizePattern<T = any>(pattern: T): string {
91+
return pattern && isString(pattern) ? pattern : JSON.stringify(pattern);
92+
}
7793
}

0 commit comments

Comments
 (0)