Skip to content

Commit 096336c

Browse files
bugfix(microservices) fix rabbit mq transport, code refactor, add tests
1 parent 91be484 commit 096336c

13 files changed

Lines changed: 457 additions & 186 deletions

File tree

integration/docker-compose.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,11 @@ services:
3636
environment:
3737
- MONGODB_DATABASE="test"
3838
ports:
39-
- 27017:27017
39+
- 27017:27017
40+
rabbit:
41+
hostname: rabbit
42+
image: "rabbitmq:management"
43+
ports:
44+
- "15672:15672"
45+
- "5672:5672"
46+
tty: true

integration/microservices/e2e/broadcast-rmq.spec.ts

Lines changed: 0 additions & 49 deletions
This file was deleted.

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

Lines changed: 20 additions & 15 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 { RMQController } from '../src/rmq/rmq.controller';
77

88
describe('RabbimMQ transport', () => {
@@ -17,16 +17,16 @@ describe('RabbimMQ transport', () => {
1717
server = express();
1818
app = module.createNestApplication(server);
1919
app.connectMicroservice({
20-
transport: Transport.RMQ,
21-
options: {
22-
urls: [`amqp://admin:admin@localhost`],
23-
queue: 'test',
24-
queueOptions: { durable: false },
25-
},
20+
transport: Transport.RMQ,
21+
options: {
22+
urls: [`amqp://localhost:5672`],
23+
queue: 'test',
24+
queueOptions: { durable: false },
25+
},
2626
});
2727
await app.startAllMicroservicesAsync();
2828
await app.init();
29-
});
29+
});
3030

3131
it(`/POST`, () => {
3232
return request(server)
@@ -54,11 +54,16 @@ describe('RabbimMQ transport', () => {
5454
return request(server)
5555
.post('/concurrent')
5656
.send([
57-
[1, 2, 3, 4, 5],
58-
[6, 7, 8, 9, 10],
59-
[11, 12, 13, 14, 15],
60-
[16, 17, 18, 19, 20],
61-
[21, 22, 23, 24, 25],
57+
Array.from({ length: 10 }, (v, k) => k + 1),
58+
Array.from({ length: 10 }, (v, k) => k + 11),
59+
Array.from({ length: 10 }, (v, k) => k + 21),
60+
Array.from({ length: 10 }, (v, k) => k + 31),
61+
Array.from({ length: 10 }, (v, k) => k + 41),
62+
Array.from({ length: 10 }, (v, k) => k + 51),
63+
Array.from({ length: 10 }, (v, k) => k + 61),
64+
Array.from({ length: 10 }, (v, k) => k + 71),
65+
Array.from({ length: 10 }, (v, k) => k + 81),
66+
Array.from({ length: 10 }, (v, k) => k + 91),
6267
])
6368
.expect(200, 'true');
6469
});

integration/microservices/src/disconnected.controller.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,25 @@ import {
77
} from '@nestjs/common';
88
import { ClientProxyFactory } from '@nestjs/microservices';
99
import { Observable, throwError } from 'rxjs';
10-
import { catchError, tap } from 'rxjs/operators';
10+
import { catchError } from 'rxjs/operators';
1111

1212
@Controller()
1313
export class DisconnectedClientController {
1414
@Post()
1515
call(@Body() options): Observable<number> {
1616
const client = ClientProxyFactory.create(options);
17-
return client
18-
.send<number, number[]>({ cmd: 'none' }, [1, 2, 3])
19-
.pipe(
20-
tap(
17+
return client.send<number, number[]>({ cmd: 'none' }, [1, 2, 3]).pipe(
18+
/*tap(
2119
console.log.bind(console, 'data'),
2220
console.error.bind(console, 'error'),
21+
),*/
22+
catchError(({ code }) =>
23+
throwError(
24+
code === 'ECONNREFUSED' || code === 'CONN_ERR'
25+
? new RequestTimeoutException('ECONNREFUSED')
26+
: new InternalServerErrorException(),
2327
),
24-
catchError(({ code }) =>
25-
throwError(
26-
code === 'ECONNREFUSED' || code === 'CONN_ERR'
27-
? new RequestTimeoutException('ECONNREFUSED')
28-
: new InternalServerErrorException(),
29-
),
30-
),
31-
);
28+
),
29+
);
3230
}
3331
}

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

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { Controller, Get } from '@nestjs/common';
22
import {
3-
Client,
4-
MessagePattern,
53
ClientProxy,
6-
Transport,
74
ClientProxyFactory,
5+
MessagePattern,
6+
Transport,
87
} from '@nestjs/microservices';
98
import { Observable } from 'rxjs';
109
import { scan, take } from 'rxjs/operators';
@@ -15,13 +14,13 @@ export class RMQBroadcastController {
1514

1615
constructor() {
1716
this.client = ClientProxyFactory.create({
18-
transport: Transport.RMQ,
19-
options: {
20-
urls: [`amqp://admin:admin@localhost`],
21-
queue: 'test',
22-
queueOptions: { durable: false },
23-
},
24-
});
17+
transport: Transport.RMQ,
18+
options: {
19+
urls: [`amqp://localhost:5672`],
20+
queue: 'test_broadcast',
21+
queueOptions: { durable: false },
22+
},
23+
});
2524
}
2625

2726
@Get('broadcast')

integration/microservices/src/rmq/rmq.controller.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +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 {
3-
Client,
4-
MessagePattern,
53
ClientProxy,
6-
Transport,
74
ClientProxyFactory,
5+
MessagePattern,
6+
Transport,
87
} from '@nestjs/microservices';
9-
import { Observable, of, from } from 'rxjs';
8+
import { from, Observable, of } from 'rxjs';
109
import { scan } from 'rxjs/operators';
1110

1211
@Controller()
@@ -15,13 +14,13 @@ export class RMQController {
1514

1615
constructor() {
1716
this.client = ClientProxyFactory.create({
18-
transport: Transport.RMQ,
19-
options: {
20-
urls: [`amqp://admin:admin@localhost`],
21-
queue: 'test',
22-
queueOptions: { durable: false },
23-
},
24-
});
17+
transport: Transport.RMQ,
18+
options: {
19+
urls: [`amqp://localhost:5672`],
20+
queue: 'test',
21+
queueOptions: { durable: false },
22+
},
23+
});
2524
}
2625

2726
@Post()

packages/common/enums/transport.enum.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ export enum Transport {
44
NATS,
55
MQTT,
66
GRPC,
7-
RMQ
8-
}
7+
RMQ,
8+
}

packages/microservices/client/client-rmq.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,42 +59,39 @@ export class ClientRMQ extends ClientProxy {
5959
this.client && this.client.close();
6060
}
6161

62-
public listen() {
62+
public consumeChannel() {
6363
this.channel.addSetup(channel =>
6464
channel.consume(
6565
this.replyQueue,
66-
msg => {
67-
this.responseEmitter.emit(msg.properties.correlationId, msg);
68-
},
66+
msg => this.responseEmitter.emit(msg.properties.correlationId, msg),
6967
{ noAck: true },
7068
),
7169
);
7270
}
7371

7472
public connect(): Promise<any> {
75-
if (this.client && this.channel) {
73+
if (this.client) {
7674
return this.connection;
7775
}
7876
this.client = this.createClient();
7977
this.handleError(this.client);
8078

8179
const connect$ = this.connect$(this.client);
8280
this.connection = this.mergeDisconnectEvent(this.client, connect$)
83-
.pipe(
84-
switchMap(() => {
85-
return new Promise(resolve =>
86-
this.client.createChannel({
87-
json: false,
88-
setup: async channel => this.setupChannel(channel, resolve),
89-
}),
90-
);
91-
}),
92-
share(),
93-
)
81+
.pipe(switchMap(() => this.createChannel()), share())
9482
.toPromise();
9583
return this.connection;
9684
}
9785

86+
public createChannel(): Promise<void> {
87+
return new Promise(resolve => {
88+
this.channel = this.client.createChannel({
89+
json: false,
90+
setup: channel => this.setupChannel(channel, resolve),
91+
});
92+
});
93+
}
94+
9895
public createClient<T = any>(): T {
9996
return amqp.connect(this.urls) as T;
10097
}
@@ -114,13 +111,14 @@ export class ClientRMQ extends ClientProxy {
114111
public async setupChannel(channel: any, resolve: Function) {
115112
await channel.assertQueue(this.queue, this.queueOptions);
116113
await channel.prefetch(this.prefetchCount, this.isGlobalPrefetchCount);
114+
117115
this.replyQueue = (await channel.assertQueue('', {
118116
exclusive: true,
119117
})).queue;
120118

121119
this.responseEmitter = new EventEmitter();
122120
this.responseEmitter.setMaxListeners(0);
123-
this.listen();
121+
this.consumeChannel();
124122

125123
resolve();
126124
}
@@ -131,10 +129,9 @@ export class ClientRMQ extends ClientProxy {
131129
): Function {
132130
try {
133131
const correlationId = randomStringGenerator();
134-
const listener = msg => {
135-
const { content } = msg;
136-
this.handleMessage(content, callback);
137-
};
132+
const listener = ({ content }) =>
133+
this.handleMessage(JSON.parse(content.toString()), callback);
134+
138135
this.responseEmitter.on(correlationId, listener);
139136
this.channel.sendToQueue(
140137
this.queue,

packages/microservices/server/server-factory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { ServerMqtt } from './server-mqtt';
66
import { ServerNats } from './server-nats';
77
import { ServerRedis } from './server-redis';
88
import { ServerTCP } from './server-tcp';
9-
import { ServerRMQ } from './server-rqm';
9+
import { ServerRMQ } from './server-rmq';
1010

1111
export class ServerFactory {
1212
public static create(

0 commit comments

Comments
 (0)