Skip to content

Commit 7f9e110

Browse files
resolve conflicts
2 parents f8088a0 + 1162503 commit 7f9e110

55 files changed

Lines changed: 4049 additions & 136 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ node_modules/
55
/.idea
66
/.awcache
77
/.vscode
8+
*.code-workspace
89

910
# bundle
1011
packages/**/*.d.ts

integration/docker-compose.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,42 @@ services:
3131
- "3306:3306"
3232
restart: always
3333
mongodb:
34+
container_name: test-mongodb
3435
image: mongo:latest
3536
environment:
3637
- MONGODB_DATABASE="test"
3738
ports:
3839
- 27017:27017
3940
rabbit:
41+
container_name: test-rabbit
4042
hostname: rabbit
4143
image: "rabbitmq:management"
4244
ports:
4345
- "15672:15672"
4446
- "5672:5672"
4547
tty: true
48+
zookeeper:
49+
container_name: test-zookeeper
50+
hostname: zookeeper
51+
image: confluentinc/cp-zookeeper:5.3.0
52+
ports:
53+
- "2181:2181"
54+
environment:
55+
ZOOKEEPER_CLIENT_PORT: 2181
56+
ZOOKEEPER_TICK_TIME: 2000
57+
kafka:
58+
container_name: test-kafka
59+
hostname: kafka
60+
image: confluentinc/cp-kafka:5.3.0
61+
depends_on:
62+
- zookeeper
63+
ports:
64+
- "29092:29092"
65+
- "9092:9092"
66+
environment:
67+
KAFKA_BROKER_ID: 1
68+
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
69+
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
70+
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
71+
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
72+
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import {
2+
ArgumentsHost,
3+
Catch,
4+
ExceptionFilter,
5+
HttpException,
6+
INestApplication,
7+
RpcExceptionFilter,
8+
} from '@nestjs/common';
9+
import { RpcException, Transport } from '@nestjs/microservices';
10+
import { Test } from '@nestjs/testing';
11+
import { expect } from 'chai';
12+
import * as request from 'supertest';
13+
import { KafkaController } from '../src/kafka/kafka.controller';
14+
import { APP_FILTER } from '@nestjs/core';
15+
import { Observable, throwError } from 'rxjs';
16+
import { KafkaMessagesController } from '../src/kafka/kafka.messages.controller';
17+
import { UserDto } from '../src/kafka/dtos/user.dto';
18+
import { UserEntity } from '../src/kafka/entities/user.entity';
19+
import { BusinessDto } from '../src/kafka/dtos/business.dto';
20+
import { BusinessEntity } from '../src/kafka/entities/business.entity';
21+
22+
@Catch()
23+
class KafkaExceptionFilter implements ExceptionFilter {
24+
catch(exception: HttpException, host: ArgumentsHost): any {
25+
console.log(exception);
26+
}
27+
}
28+
@Catch()
29+
class RpcErrorFilter implements RpcExceptionFilter {
30+
catch(exception: RpcException): Observable<any> {
31+
console.log(exception);
32+
return throwError(exception);
33+
}
34+
}
35+
36+
describe('Kafka transport', () => {
37+
let server;
38+
let app: INestApplication;
39+
40+
it(`Start Kafka app`, async () => {
41+
const module = await Test.createTestingModule({
42+
controllers: [
43+
KafkaController,
44+
KafkaMessagesController,
45+
],
46+
providers: [
47+
{
48+
provide: APP_FILTER,
49+
useClass: RpcErrorFilter,
50+
},
51+
{
52+
provide: APP_FILTER,
53+
useClass: KafkaExceptionFilter,
54+
},
55+
],
56+
}).compile();
57+
58+
app = module.createNestApplication();
59+
server = app.getHttpAdapter().getInstance();
60+
61+
app.connectMicroservice({
62+
transport: Transport.KAFKA,
63+
options: {
64+
client: {
65+
brokers: ['localhost:9092'],
66+
},
67+
},
68+
});
69+
await app.startAllMicroservicesAsync();
70+
await app.init();
71+
}).timeout(30000);
72+
73+
it(`/POST (sync sum kafka message)`, () => {
74+
return request(server)
75+
.post('/mathSumSyncKafkaMessage')
76+
.send([1, 2, 3, 4, 5])
77+
.expect(200)
78+
.expect(200, '15');
79+
});
80+
81+
it(`/POST (sync sum kafka(ish) message without key and only the value)`, () => {
82+
return request(server)
83+
.post('/mathSumSyncWithoutKey')
84+
.send([1, 2, 3, 4, 5])
85+
.expect(200)
86+
.expect(200, '15');
87+
});
88+
89+
it(`/POST (sync sum plain object)`, () => {
90+
return request(server)
91+
.post('/mathSumSyncPlainObject')
92+
.send([1, 2, 3, 4, 5])
93+
.expect(200)
94+
.expect(200, '15');
95+
});
96+
97+
it(`/POST (sync sum array)`, () => {
98+
return request(server)
99+
.post('/mathSumSyncArray')
100+
.send([1, 2, 3, 4, 5])
101+
.expect(200)
102+
.expect(200, '15');
103+
});
104+
105+
it(`/POST (sync sum string)`, () => {
106+
return request(server)
107+
.post('/mathSumSyncString')
108+
.send([1, 2, 3, 4, 5])
109+
.expect(200)
110+
.expect(200, '15');
111+
});
112+
113+
it(`/POST (sync sum number)`, () => {
114+
return request(server)
115+
.post('/mathSumSyncNumber')
116+
.send([12345])
117+
.expect(200)
118+
.expect(200, '15');
119+
});
120+
121+
it(`/POST (async event notification)`, done => {
122+
request(server)
123+
.post('/notify')
124+
.send()
125+
.end(() => {
126+
setTimeout(() => {
127+
expect(KafkaController.IS_NOTIFIED).to.be.true;
128+
done();
129+
}, 1000);
130+
});
131+
});
132+
133+
const userDto: UserDto = {
134+
email: 'enriquebenavidesm@gmail.com',
135+
name: 'Ben',
136+
phone: '1112223331',
137+
years: 33,
138+
};
139+
const newUser: UserEntity = new UserEntity(userDto);
140+
const businessDto: BusinessDto = {
141+
name: 'Example',
142+
phone: '2233441122',
143+
user: newUser,
144+
};
145+
it(`/POST (sync command create user)`, () => {
146+
return request(server)
147+
.post('/user')
148+
.send(userDto)
149+
.expect(200);
150+
});
151+
152+
it(`/POST (sync command create business`, () => {
153+
return request(server)
154+
.post('/business')
155+
.send(businessDto)
156+
.expect(200);
157+
});
158+
159+
it(`/POST (sync command create user) Concurrency Test`, async () => {
160+
const promises = [];
161+
for (let concurrencyKey = 0; concurrencyKey < 100; concurrencyKey++) {
162+
const innerUserDto = JSON.parse(JSON.stringify(userDto));
163+
innerUserDto.name += `+${concurrencyKey}`;
164+
promises.push(request(server).post('/user').send(userDto).expect(200));
165+
}
166+
await Promise.all(promises);
167+
});
168+
169+
after(`Stopping Kafka app`, async () => {
170+
await app.close();
171+
});
172+
173+
}).timeout(30000);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { UserEntity } from '../entities/user.entity';
2+
3+
export class BusinessDto {
4+
name: string;
5+
phone: string;
6+
user: UserEntity;
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export class UserDto {
2+
name: string;
3+
email: string;
4+
phone: string;
5+
years: number;
6+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { UserEntity } from './user.entity';
2+
import { BusinessDto } from '../dtos/business.dto';
3+
4+
export class BusinessEntity {
5+
constructor(business: BusinessDto) {
6+
this.id = Math.random() * 99999999;
7+
this.name = business.name;
8+
this.phone = business.phone;
9+
this.createdBy = {
10+
id: business.user.id,
11+
};
12+
this.created = new Date();
13+
}
14+
id: number;
15+
name: string;
16+
phone: string;
17+
createdBy: Partial<UserEntity>;
18+
created: Date;
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { UserDto } from '../dtos/user.dto';
2+
3+
export class UserEntity {
4+
constructor(user: UserDto) {
5+
this.id = Math.random() * 99999999;
6+
this.name = user.name;
7+
this.email = user.email;
8+
this.phone = user.phone;
9+
this.years = user.years;
10+
this.created = new Date();
11+
}
12+
id: number;
13+
name: string;
14+
email: string;
15+
phone: string;
16+
years: number;
17+
created: Date;
18+
}

0 commit comments

Comments
 (0)