├── .gitignore ├── README.md ├── docker-compose.yml ├── docker ├── Dockerfile.dev ├── env-app-sample ├── env-sample └── rabbitmq │ └── enabled_plugins └── src ├── app ├── .gitignore ├── .prettierrc ├── README.md ├── certs │ ├── server.crt │ └── server.key ├── nodemon-debug.json ├── nodemon.json ├── package-lock.json ├── package.json ├── src │ ├── app.module.ts │ ├── config │ │ └── global.env.ts │ ├── controllers │ │ └── contrived.controller.ts │ ├── event-bus-transport │ │ ├── abstract.publisher.ts │ │ ├── event.bus.transport.module.ts │ │ ├── event.bus.transport.ts │ │ ├── interface │ │ │ └── event.with.transport.interface.ts │ │ ├── publishers │ │ │ ├── rabbit.publisher.ts │ │ │ └── redis.publisher.ts │ │ └── transport.enum.ts │ ├── events │ │ └── contrived │ │ │ ├── contrived.event.handler.ts │ │ │ └── contrived.event.ts │ └── main.ts ├── tsconfig.build.json ├── tsconfig.json └── tslint.json ├── event-service-rabbit ├── .gitignore ├── .prettierrc ├── README.md ├── nodemon-debug.json ├── nodemon.json ├── package-lock.json ├── package.json ├── src │ ├── app.module.ts │ ├── config │ │ └── global.env.ts │ ├── events │ │ └── contrived │ │ │ ├── contrived.event.handler.ts │ │ │ └── contrived.event.ts │ ├── main.ts │ ├── pipes │ │ └── json.parse.pipe.ts │ └── services │ │ └── event.subscriber.service.ts ├── tsconfig.build.json ├── tsconfig.json └── tslint.json └── event-service-redis ├── .gitignore ├── .prettierrc ├── README.md ├── nodemon-debug.json ├── nodemon.json ├── package-lock.json ├── package.json ├── src ├── app.module.ts ├── config │ └── global.env.ts ├── events │ └── contrived │ │ ├── contrived.event.handler.ts │ │ └── contrived.event.ts ├── main.ts ├── pipes │ └── json.parse.pipe.ts └── services │ └── event.subscriber.service.ts ├── tsconfig.build.json ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | src/node_modules 5 | storage 6 | stats.json 7 | 8 | # Cruft 9 | .DS_Store 10 | npm-debug.log 11 | .idea 12 | .awcache 13 | .env 14 | .env.app 15 | .env.docker 16 | .vscode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nestjs-external-eventbus 2 | [done nestjs module](https://github.com/sergey-telpuk/nestjs-transport-eventbus) 3 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | 3 | services: 4 | 5 | app: 6 | container_name: nestjs-app 7 | restart: always 8 | build: 9 | context: ./docker 10 | dockerfile: Dockerfile.dev 11 | command: npm run start 12 | tty: true 13 | ports: 14 | - 3000:3000 15 | volumes: 16 | - ./src/app:/app 17 | links: 18 | - rabbitmq 19 | - redis 20 | depends_on: 21 | - rabbitmq 22 | - redis 23 | 24 | event-service-rabbit: 25 | container_name: nestjs-event-service-rabbit 26 | restart: always 27 | build: 28 | context: ./docker 29 | dockerfile: Dockerfile.dev 30 | command: npm run start 31 | tty: true 32 | volumes: 33 | - ./src/event-service-rabbit:/app 34 | links: 35 | - rabbitmq 36 | depends_on: 37 | - rabbitmq 38 | 39 | event-service-redis: 40 | container_name: nestjs-event-service-redis 41 | restart: always 42 | build: 43 | context: ./docker 44 | dockerfile: Dockerfile.dev 45 | command: npm run start 46 | tty: true 47 | volumes: 48 | - ./src/event-service-redis:/app 49 | links: 50 | - redis 51 | depends_on: 52 | - redis 53 | 54 | redis: 55 | image: redis:latest 56 | restart: always 57 | command: redis-server --requirepass password123 58 | environment: 59 | - REDIS_PASSWORD=password123 60 | 61 | rabbitmq: 62 | image: rabbitmq:3-management 63 | restart: always 64 | environment: 65 | RABBITMQ_ERLANG_COOKIE: SWQOKODSQALRPCLNMEQG 66 | RABBITMQ_DEFAULT_USER: rabbit 67 | RABBITMQ_DEFAULT_PASS: rabbit 68 | volumes: 69 | - ./docker/rabbitmq/enabled_plugins:/etc/rabbitmq/enabled_plugins -------------------------------------------------------------------------------- /docker/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM node:latest 2 | 3 | 4 | #RUN echo fs.inotify.max_user_watches=524288 | tee -a /etc/sysctl.conf && sysctl -p 5 | 6 | WORKDIR /app 7 | 8 | 9 | 10 | RUN npm install nodemon -g 11 | 12 | EXPOSE 9229 13 | 14 | CMD ["node","--v"] 15 | -------------------------------------------------------------------------------- /docker/env-app-sample: -------------------------------------------------------------------------------- 1 | ### RABBITMQ_ 2 | RABBITMQ_URL=amqp://rabbit:rabbit@rabbitmq:5672 3 | RABBITMQ_QUEUE=event_service_queue 4 | 5 | ### EVENT_SERVICE 6 | EVENT_SERVICE_PATTERN=event_bus -------------------------------------------------------------------------------- /docker/env-sample: -------------------------------------------------------------------------------- 1 | ### Mode of running 2 | MODE_RUNNING=dev #dev|debug 3 | 4 | ### Rabbit 5 | RABBITMQ_PORT=56720 6 | RABBITMQ_USER=rabbit 7 | RABBITMQ_PASSWORD=rabbit 8 | RABBITMQ_PORT_UI=8085 -------------------------------------------------------------------------------- /docker/rabbitmq/enabled_plugins: -------------------------------------------------------------------------------- 1 | [rabbitmq_management, rabbitmq_management_visualiser]. -------------------------------------------------------------------------------- /src/app/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | node_modules 5 | dist 6 | stats.json 7 | 8 | # Cruft 9 | .DS_Store 10 | npm-debug.log 11 | .idea 12 | .env 13 | -------------------------------------------------------------------------------- /src/app/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 4, 4 | "semi": true, 5 | "singleQuote": true 6 | } -------------------------------------------------------------------------------- /src/app/README.md: -------------------------------------------------------------------------------- 1 |

2 | Nest Logo 3 |

4 | 5 | [travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master 6 | [travis-url]: https://travis-ci.org/nestjs/nest 7 | [linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux 8 | [linux-url]: https://travis-ci.org/nestjs/nest 9 | 10 |

A progressive Node.js framework for building efficient and scalable server-side applications, heavily inspired by Angular.

11 |

12 | NPM Version 13 | Package License 14 | NPM Downloads 15 | Travis 16 | Linux 17 | Coverage 18 | Gitter 19 | Backers on Open Collective 20 | Sponsors on Open Collective 21 | 22 | 23 |

24 | 26 | 27 | ## Description 28 | 29 | [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. 30 | 31 | ## Installation 32 | 33 | ```bash 34 | $ npm install 35 | ``` 36 | 37 | ## Running the app 38 | 39 | ```bash 40 | # development 41 | $ npm run start 42 | 43 | # watch mode 44 | $ npm run start:dev 45 | 46 | # production mode 47 | $ npm run start:prod 48 | ``` 49 | 50 | ## Test 51 | 52 | ```bash 53 | # unit tests 54 | $ npm run test 55 | 56 | # e2e tests 57 | $ npm run test:e2e 58 | 59 | # test coverage 60 | $ npm run test:cov 61 | ``` 62 | 63 | ## Support 64 | 65 | Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). 66 | 67 | ## Stay in touch 68 | 69 | - Author - [Kamil Myśliwiec](https://kamilmysliwiec.com) 70 | - Website - [https://nestjs.com](https://nestjs.com/) 71 | - Twitter - [@nestframework](https://twitter.com/nestframework) 72 | 73 | ## License 74 | 75 | Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE). 76 | -------------------------------------------------------------------------------- /src/app/certs/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICXjCCAcegAwIBAgIJAPoZXCIUDVU9MA0GCSqGSIb3DQEBBQUAMEgxCzAJBgNV 3 | BAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMREwDwYDVQQHDAhUU05JRU1BTjER 4 | MA8GA1UECgwIVFNOSUVNQU4wHhcNMTgwNDE0MjMwMTMwWhcNMTkwNDE0MjMwMTMw 5 | WjBIMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTERMA8GA1UEBwwI 6 | VFNOSUVNQU4xETAPBgNVBAoMCFRTTklFTUFOMIGfMA0GCSqGSIb3DQEBAQUAA4GN 7 | ADCBiQKBgQCprHdYtD8jlBQwuVr5WEpWNb1bnGnmwFq4Ii3zh63Jd+stc3KXJhcJ 8 | ja0WjCAPHcksLBdNcpZAs7t16YhD5eKqrpPyPApcXAxgSg8lc1NcdKsgDvd1u5Dp 9 | HpoO4bYmnFKnEgaKhvPfWxulFWB/O9EjY+qwGwVh3vQwTN5+24ptGwIDAQABo1Aw 10 | TjAdBgNVHQ4EFgQUaDGJYVN2avltLh2WIlzj1ZkzGUkwHwYDVR0jBBgwFoAUaDGJ 11 | YVN2avltLh2WIlzj1ZkzGUkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOB 12 | gQAi2GipMiPG/FBLJaJjxVRccELcbKqViF5Ow3rPpODE8OLdsLn516dPoOBIMxas 13 | kajd9hPYgSgAHg4c60p3dHp19U47cFWOKk8vLdvaJVmDkVblYbCeAda98oR/oCMr 14 | YxWr4GZmxsq9mlnpLkeCocusaXMEZs+Gw1mSu80Hl3ofOQ== 15 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /src/app/certs/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXQIBAAKBgQCprHdYtD8jlBQwuVr5WEpWNb1bnGnmwFq4Ii3zh63Jd+stc3KX 3 | JhcJja0WjCAPHcksLBdNcpZAs7t16YhD5eKqrpPyPApcXAxgSg8lc1NcdKsgDvd1 4 | u5DpHpoO4bYmnFKnEgaKhvPfWxulFWB/O9EjY+qwGwVh3vQwTN5+24ptGwIDAQAB 5 | AoGAVjnQOOL4x0Lkc9JuehK1TFRpE5pMczjDoZm1EnKcDauEd4eY71krEe7OzIuP 6 | az8u0eTiPriBxQXRuV1ho2e7JUBASblX4prmWBLJOEdRMawd5Ky4FMR3AlAtKOYE 7 | +GzEP+CtuS7qYukyHsM+fy6PQFhw0reJ8ZED+hmSC+BYMKECQQDWvZ5BwjxoOqoQ 8 | H0MC/MNZiWInI3NWcHiUG99eBYvD6T7RWYBQdMN5gjbuFiuuMwfdjR/Xie9AiDPo 9 | s+QMg4PrAkEAykYm5CurbxSxRnLPCqRNIzisHzYls+hgMLffWaVBkXughrvsDb7u 10 | ePBzKYxVxi/qArWQwLTF6RG60DEcnanfkQJBANC6YxecC0dsrl0ZZfODaQag6U0N 11 | wlBk5m9gYE9tqJr3Ht4y1uxdcpurHGV0G2UpqR2KzUaehnX9bidko+gd9Z0CQQDJ 12 | Ok0KhV9BXMaXnTPYFGgg+ApT6pxLhIvdK69pEXxPbTvfjihh7GZ1rlADL3dNePFG 13 | zLY64Bxbp6W/5HvhZdPhAkA/sSS6kOMPCPY+IWnACviVyL10Gq62JQlavhk93vpp 14 | BneessNzgUosn1wBPEzJlrX4l9WNkihht4tCDmyoKkV2 15 | -----END RSA PRIVATE KEY----- -------------------------------------------------------------------------------- /src/app/nodemon-debug.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["src"], 3 | "ext": "ts", 4 | "ignore": ["src/**/*.spec.ts"], 5 | "exec": "node --inspect-brk=0.0.0.0:9229 -r tsconfig-paths/register -r ts-node/register src/main.ts" 6 | } -------------------------------------------------------------------------------- /src/app/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["dist"], 3 | "ext": "js", 4 | "exec": "node dist/main" 5 | } 6 | -------------------------------------------------------------------------------- /src/app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nest-typescript-starter", 3 | "version": "1.0.0", 4 | "description": "Nest TypeScript starter repository", 5 | "license": "MIT", 6 | "scripts": { 7 | "build": "tsc -p tsconfig.build.json", 8 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 9 | "start": "ts-node -r tsconfig-paths/register src/main.ts", 10 | "start:dev": "concurrently --handle-input \"wait-on dist/main.js && nodemon\" \"tsc -w -p tsconfig.build.json\" ", 11 | "start:debug": "nodemon --config nodemon-debug.json", 12 | "prestart:prod": "rimraf dist && npm run build", 13 | "start:prod": "node dist/main.js", 14 | "lint": "tslint -p tsconfig.json -c tslint.json", 15 | "lint:fix": "tslint -p tsconfig.json -c tslint.json --fix", 16 | "test": "jest --detectOpenHandles --config ./test/jest.json --forceExit", 17 | "test:watch": "jest --watch", 18 | "test:cov": "jest --coverage", 19 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 20 | "test:e2e": "jest --detectOpenHandles --config ./test/e2e/jest-e2e.json --forceExit", 21 | "test:int": "jest --detectOpenHandles --config ./test/int/jest-int.json --forceExit", 22 | "test:unit": "jest --detectOpenHandles --config ./test/unit/jest-unit.json --forceExit", 23 | "console:dev": "ts-node -r tsconfig-paths/register src/cli/cli.module.ts", 24 | "fixtures": "fixtures ./fixtures/entities --config ./fixtures/typeorm.config.ts --debug --sync --require=ts-node/register --require=tsconfig-paths/register" 25 | }, 26 | "dependencies": { 27 | "@elastic/elasticsearch": "^7.2.0", 28 | "@grpc/proto-loader": "^0.5.1", 29 | "@nestjs/common": "^6.5.2", 30 | "@nestjs/core": "^6.5.2", 31 | "@nestjs/cqrs": "^6.0.1", 32 | "@nestjs/jwt": "^6.1.1", 33 | "@nestjs/microservices": "^6.5.3", 34 | "@nestjs/passport": "^6.1.0", 35 | "@nestjs/platform-express": "^6.5.2", 36 | "@nestjs/platform-fastify": "^6.5.2", 37 | "@nestjs/typeorm": "^6.1.2", 38 | "@nestjsx/api-version": "^0.1.1", 39 | "@types/elasticsearch": "^5.0.34", 40 | "@types/faker": "^4.1.5", 41 | "@types/fastify-multipart": "^0.7.0", 42 | "@types/fs-extra": "^8.0.0", 43 | "@types/moment-timezone": "^0.5.12", 44 | "@types/multer": "^1.3.7", 45 | "@types/passport-jwt": "^3.0.1", 46 | "activedirectory": "^0.7.2", 47 | "amqp-connection-manager": "^3.0.0", 48 | "amqplib": "^0.5.5", 49 | "chai": "^4.2.0", 50 | "class-transformer": "^0.2.3", 51 | "class-validator": "^0.9.1", 52 | "cloneable-ts": "^1.0.18", 53 | "config": "^3.1.0", 54 | "csvtojson": "^2.0.10", 55 | "faker": "^4.1.0", 56 | "fastify-swagger": "^2.4.0", 57 | "grpc": "^1.22.2", 58 | "moment-timezone": "^0.5.26", 59 | "nestjs-i18n": "^3.0.0", 60 | "nestjs-redis": "^1.2.1", 61 | "npm": "^6.10.3", 62 | "ow": "^0.13.2", 63 | "passport": "^0.4.0", 64 | "passport-http-bearer": "^1.0.1", 65 | "passport-jwt": "^4.0.0", 66 | "pg": "^7.11.0", 67 | "pre-commit": "^1.2.2", 68 | "redis": "^2.8.0", 69 | "reflect-metadata": "0.1.13", 70 | "rimraf": "2.6.3", 71 | "rxjs": "6.5.2" 72 | }, 73 | "devDependencies": { 74 | "@nestjs/cli": "^6.5.0", 75 | "@nestjs/swagger": "^3.0.2", 76 | "@nestjs/testing": "6.3.2", 77 | "@types/express": "4.17.0", 78 | "@types/jest": "24.0.15", 79 | "@types/node": "12.0.10", 80 | "@types/supertest": "2.0.7", 81 | "concurrently": "^4.1.0", 82 | "jest": "24.8.0", 83 | "nestjs-console": "^1.1.4", 84 | "nodemon": "1.19.1", 85 | "prettier": "1.18.2", 86 | "supertest": "4.0.2", 87 | "swagger-ui-express": "^4.0.6", 88 | "ts-jest": "24.0.2", 89 | "ts-node": "^8.3.0", 90 | "tsconfig-paths": "3.8.0", 91 | "tslint": "5.18.0", 92 | "typeorm-fixtures-cli": "^1.3.5", 93 | "typescript": "^3.5.3", 94 | "wait-on": "^3.2.0" 95 | }, 96 | "jest": { 97 | "moduleFileExtensions": [ 98 | "js", 99 | "json", 100 | "ts" 101 | ], 102 | "rootDir": "src", 103 | "testRegex": ".spec.ts$", 104 | "transform": { 105 | "^.+\\.(t|j)s$": "ts-jest" 106 | }, 107 | "collectCoverageFrom": [ 108 | "**/*.(t|j)s" 109 | ], 110 | "coverageDirectory": "../coverage", 111 | "testEnvironment": "node" 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/app/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import {Module} from '@nestjs/common'; 2 | import {ContrivedController} from './controllers/contrived.controller'; 3 | import {EventBusTransportModule} from './event-bus-transport/event.bus.transport.module'; 4 | import {CqrsModule} from '@nestjs/cqrs'; 5 | import {RabbitPublisher} from './event-bus-transport/publishers/rabbit.publisher'; 6 | import {ContrivedEventHandler} from './events/contrived/contrived.event.handler'; 7 | import {RedisPublisher} from "./event-bus-transport/publishers/redis.publisher"; 8 | 9 | @Module({ 10 | imports: [ 11 | CqrsModule, 12 | EventBusTransportModule.forRoot( 13 | [ 14 | RabbitPublisher, 15 | RedisPublisher 16 | ], 17 | [ 18 | ContrivedEventHandler, 19 | ]), 20 | ], 21 | controllers: [ 22 | ContrivedController, 23 | ], 24 | providers: [ 25 | 26 | ], 27 | }) 28 | export class AppModule { 29 | } 30 | -------------------------------------------------------------------------------- /src/app/src/config/global.env.ts: -------------------------------------------------------------------------------- 1 | export const EVENT_SERVICE = { 2 | PATTERN: process.env.EVENT_SERVICE_PATTERN, 3 | }; 4 | 5 | export const RABBIT_SERVICE = { 6 | URLS: [ 7 | process.env.RABBITMQ_URL, 8 | ], 9 | QUEUE: process.env.RABBITMQ_QUEUE, 10 | QUEUE_OPTIONS: { 11 | durable: true, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /src/app/src/controllers/contrived.controller.ts: -------------------------------------------------------------------------------- 1 | import {Controller, Get} from '@nestjs/common'; 2 | import {EventBusTransport} from '../event-bus-transport/event.bus.transport'; 3 | import {ContrivedEvent} from '../events/contrived/contrived.event'; 4 | 5 | @Controller('/') 6 | export class ContrivedController { 7 | 8 | constructor( 9 | readonly eventBusTransport: EventBusTransport, 10 | ) {} 11 | 12 | @Get('/contrived') 13 | contrived() { 14 | this.eventBusTransport.publish(new ContrivedEvent()); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/app/src/event-bus-transport/abstract.publisher.ts: -------------------------------------------------------------------------------- 1 | import {IEvent, IEventPublisher} from '@nestjs/cqrs'; 2 | import {Transport} from './transport.enum'; 3 | import {Injectable, Logger} from '@nestjs/common'; 4 | 5 | @Injectable() 6 | export abstract class AbstractPublisher implements IEventPublisher { 7 | abstract TRANSPORT: Transport; 8 | abstract PATTERN: string; 9 | 10 | constructor( 11 | protected readonly log: Logger, 12 | ) { 13 | 14 | } 15 | 16 | publish(event: T): void { 17 | 18 | const data = { 19 | payload: event, 20 | event: event.constructor.name, 21 | }; 22 | 23 | this.send(this.PATTERN, data); 24 | } 25 | 26 | protected abstract send(pattern: any, data: any): any; 27 | } 28 | -------------------------------------------------------------------------------- /src/app/src/event-bus-transport/event.bus.transport.module.ts: -------------------------------------------------------------------------------- 1 | import {DynamicModule, Logger, Module} from '@nestjs/common'; 2 | import {RabbitPublisher} from './publishers/rabbit.publisher'; 3 | import {CqrsModule, EventBus} from '@nestjs/cqrs'; 4 | import {EventBusTransport} from './event.bus.transport'; 5 | import {DefaultPubSub} from '@nestjs/cqrs/dist/helpers/default-pubsub'; 6 | import {ModuleRef} from '@nestjs/core'; 7 | 8 | @Module({ 9 | imports: [ 10 | CqrsModule, 11 | ], 12 | providers: [ 13 | RabbitPublisher, 14 | DefaultPubSub, 15 | ], 16 | exports: [], 17 | 18 | }) 19 | export class EventBusTransportModule { 20 | 21 | static forRoot(publishers: any[], handlers: any[]): DynamicModule { 22 | 23 | return { 24 | module: EventBusTransportModule, 25 | providers: [ 26 | Logger, 27 | ...publishers, 28 | { 29 | provide: EventBusTransport, 30 | useFactory: (eventBus: EventBus, moduleRef: ModuleRef) => { 31 | return new EventBusTransport( 32 | eventBus, 33 | moduleRef, 34 | publishers, 35 | ); 36 | }, 37 | inject: [EventBus, ModuleRef], 38 | }, 39 | ...handlers, 40 | ], 41 | exports: [ 42 | EventBusTransport, 43 | ], 44 | }; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/app/src/event-bus-transport/event.bus.transport.ts: -------------------------------------------------------------------------------- 1 | import {EventBus, IEvent} from '@nestjs/cqrs'; 2 | import {Injectable} from '@nestjs/common'; 3 | import {ModuleRef} from '@nestjs/core'; 4 | import {AbstractPublisher} from './abstract.publisher'; 5 | import {Transport} from './transport.enum'; 6 | 7 | @Injectable() 8 | export class EventBusTransport { 9 | 10 | constructor( 11 | private readonly eventBus: EventBus, 12 | private readonly moduleRef: ModuleRef, 13 | private readonly publishers: any[], 14 | ) { 15 | } 16 | 17 | publish(event: T) { 18 | this.publishViaPublisher(event); 19 | } 20 | 21 | private publishViaPublisher(event: any) { 22 | const transports: [] = event.TRANSPORTS ? event.TRANSPORTS : []; 23 | 24 | delete event.TRANSPORTS; 25 | 26 | // @ts-ignore 27 | if (transports.length === 0 || transports.includes(Transport.DEF)) { 28 | this.eventBus.publish(event); 29 | } 30 | 31 | for (const publisher of this.publishers) { 32 | const pub = this.moduleRef.get(publisher); 33 | // @ts-ignore 34 | if (transports.includes(pub.TRANSPORT)) { 35 | pub.publish(event); 36 | } 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/app/src/event-bus-transport/interface/event.with.transport.interface.ts: -------------------------------------------------------------------------------- 1 | import {IEvent} from '@nestjs/cqrs'; 2 | import {Transport} from '../transport.enum'; 3 | 4 | export interface IEventWithTransport extends IEvent { 5 | TRANSPORTS: Transport[]; 6 | } 7 | -------------------------------------------------------------------------------- /src/app/src/event-bus-transport/publishers/rabbit.publisher.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@nestjs/common'; 2 | import {Client, ClientProxy, Transport} from '@nestjs/microservices'; 3 | import {AbstractPublisher} from '../abstract.publisher'; 4 | 5 | @Injectable() 6 | export class RabbitPublisher extends AbstractPublisher { 7 | TRANSPORT = Transport.RMQ; 8 | PATTERN = 'event_bus'; 9 | 10 | @Client({ 11 | transport: Transport.RMQ, 12 | options: { 13 | urls: ['amqp://rabbit:rabbit@rabbitmq:5672'], 14 | queue: 'event_service_queue', 15 | queueOptions: { 16 | durable: true, 17 | }, 18 | }, 19 | }) 20 | client: ClientProxy; 21 | 22 | protected async send(pattern: any, data: any) { 23 | try { 24 | await this.client.send(pattern, data).toPromise(); 25 | } catch (e) { 26 | this.log.error(e); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/app/src/event-bus-transport/publishers/redis.publisher.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@nestjs/common'; 2 | import {Client, ClientProxy, Transport} from '@nestjs/microservices'; 3 | import {AbstractPublisher} from '../abstract.publisher'; 4 | 5 | 6 | @Injectable() 7 | export class RedisPublisher extends AbstractPublisher { 8 | TRANSPORT = Transport.REDIS; 9 | PATTERN = 'event_bus'; 10 | 11 | @Client({ 12 | transport: Transport.REDIS, 13 | options: { 14 | url: 'redis://:password123@redis:6379', 15 | }, 16 | }) 17 | client: ClientProxy; 18 | 19 | protected async send(pattern: any, data: any) { 20 | // try { 21 | await this.client.send(pattern, data).toPromise(); 22 | console.log('============'); 23 | // } catch (e) { 24 | // this.log.error(e); 25 | // } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/app/src/event-bus-transport/transport.enum.ts: -------------------------------------------------------------------------------- 1 | 2 | export enum Transport { 3 | TCP = 0, 4 | REDIS = 1, 5 | NATS = 2, 6 | MQTT = 3, 7 | GRPC = 4, 8 | RMQ = 5, 9 | DEF = 6, 10 | } 11 | -------------------------------------------------------------------------------- /src/app/src/events/contrived/contrived.event.handler.ts: -------------------------------------------------------------------------------- 1 | import {EventsHandler, IEventHandler} from '@nestjs/cqrs'; 2 | import {ContrivedEvent} from './contrived.event'; 3 | import {Logger} from '@nestjs/common'; 4 | 5 | @EventsHandler(ContrivedEvent) 6 | export class ContrivedEventHandler implements IEventHandler { 7 | constructor( 8 | private readonly log: Logger, 9 | ) { 10 | 11 | } 12 | 13 | handle(event: ContrivedEvent) { 14 | this.log.verbose('ContrivedEventHandler: event\n'); 15 | this.log.log(event); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/app/src/events/contrived/contrived.event.ts: -------------------------------------------------------------------------------- 1 | import {IEventWithTransport} from '../../event-bus-transport/interface/event.with.transport.interface'; 2 | import {Transport} from '../../event-bus-transport/transport.enum'; 3 | 4 | export class ContrivedEvent implements IEventWithTransport { 5 | TRANSPORTS = [Transport.RMQ, Transport.DEF, Transport.REDIS]; 6 | 7 | constructor( 8 | ) {} 9 | } 10 | -------------------------------------------------------------------------------- /src/app/src/main.ts: -------------------------------------------------------------------------------- 1 | import {NestFactory} from '@nestjs/core'; 2 | import {AppModule} from './app.module'; 3 | import {INestApplication, Logger, ValidationPipe} from '@nestjs/common'; 4 | import fs from 'fs'; 5 | import {FastifyAdapter, NestFastifyApplication} from '@nestjs/platform-fastify'; 6 | const log = new Logger('app: '); 7 | 8 | (async function bootstrap() { 9 | const fastifyAdapter = new FastifyAdapter({ 10 | http2: true, 11 | logger: log, 12 | https: { 13 | allowHTTP1: true, // fallback support for HTTP1 14 | key: fs.readFileSync('/app/certs/server.key'), 15 | cert: fs.readFileSync('/app/certs/server.crt'), 16 | }, 17 | }); 18 | 19 | const app: INestApplication = await NestFactory.create( 20 | AppModule, 21 | fastifyAdapter, 22 | ); 23 | app.enableCors(); 24 | app.useGlobalPipes( 25 | new ValidationPipe({ 26 | disableErrorMessages: false, 27 | }), 28 | ); 29 | 30 | await app.listen(3000, '0.0.0.0'); 31 | })(); 32 | -------------------------------------------------------------------------------- /src/app/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [ 4 | "node_modules", 5 | "dist", 6 | "test", 7 | "fixtures", 8 | "grpc", 9 | "cli", 10 | "**/*spec.ts" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /src/app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "esModuleInterop": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "target": "es6", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true 14 | }, 15 | "exclude": [ 16 | "node_modules", 17 | "dist", 18 | "test", 19 | "fixtures", 20 | "grpc" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/app/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": ["tslint:recommended"], 4 | "jsRules": { 5 | "no-unused-expression": true 6 | }, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "member-access": [false], 10 | "ordered-imports": [false], 11 | "max-line-length": [true, 150], 12 | "member-ordering": [false], 13 | "interface-name": [false], 14 | "arrow-parens": false, 15 | "object-literal-sort-keys": false 16 | }, 17 | "rulesDirectory": [] 18 | } 19 | -------------------------------------------------------------------------------- /src/event-service-rabbit/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | node_modules 5 | dist 6 | stats.json 7 | 8 | # Cruft 9 | .DS_Store 10 | npm-debug.log 11 | .idea 12 | .env 13 | -------------------------------------------------------------------------------- /src/event-service-rabbit/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 4, 4 | "semi": true, 5 | "singleQuote": true 6 | } -------------------------------------------------------------------------------- /src/event-service-rabbit/README.md: -------------------------------------------------------------------------------- 1 |

2 | Nest Logo 3 |

4 | 5 | [travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master 6 | [travis-url]: https://travis-ci.org/nestjs/nest 7 | [linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux 8 | [linux-url]: https://travis-ci.org/nestjs/nest 9 | 10 |

A progressive Node.js framework for building efficient and scalable server-side applications, heavily inspired by Angular.

11 |

12 | NPM Version 13 | Package License 14 | NPM Downloads 15 | Travis 16 | Linux 17 | Coverage 18 | Gitter 19 | Backers on Open Collective 20 | Sponsors on Open Collective 21 | 22 | 23 |

24 | 26 | 27 | ## Description 28 | 29 | [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. 30 | 31 | ## Installation 32 | 33 | ```bash 34 | $ npm install 35 | ``` 36 | 37 | ## Running the app 38 | 39 | ```bash 40 | # development 41 | $ npm run start 42 | 43 | # watch mode 44 | $ npm run start:dev 45 | 46 | # production mode 47 | $ npm run start:prod 48 | ``` 49 | 50 | ## Test 51 | 52 | ```bash 53 | # unit tests 54 | $ npm run test 55 | 56 | # e2e tests 57 | $ npm run test:e2e 58 | 59 | # test coverage 60 | $ npm run test:cov 61 | ``` 62 | 63 | ## Support 64 | 65 | Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). 66 | 67 | ## Stay in touch 68 | 69 | - Author - [Kamil Myśliwiec](https://kamilmysliwiec.com) 70 | - Website - [https://nestjs.com](https://nestjs.com/) 71 | - Twitter - [@nestframework](https://twitter.com/nestframework) 72 | 73 | ## License 74 | 75 | Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE). 76 | -------------------------------------------------------------------------------- /src/event-service-rabbit/nodemon-debug.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["src"], 3 | "ext": "ts", 4 | "ignore": ["src/**/*.spec.ts"], 5 | "exec": "node --inspect-brk=0.0.0.0:9229 -r tsconfig-paths/register -r ts-node/register src/main.ts" 6 | } -------------------------------------------------------------------------------- /src/event-service-rabbit/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["dist"], 3 | "ext": "js", 4 | "exec": "node dist/main" 5 | } 6 | -------------------------------------------------------------------------------- /src/event-service-rabbit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nest-typescript-starter", 3 | "version": "1.0.0", 4 | "description": "Nest TypeScript starter repository", 5 | "license": "MIT", 6 | "scripts": { 7 | "build": "tsc -p tsconfig.build.json", 8 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 9 | "start": "ts-node -r tsconfig-paths/register src/main.ts", 10 | "start:dev": "concurrently --handle-input \"wait-on dist/main.js && nodemon\" \"tsc -w -p tsconfig.build.json\" ", 11 | "start:debug": "nodemon --config nodemon-debug.json", 12 | "prestart:prod": "rimraf dist && npm run build", 13 | "start:prod": "node dist/main.js", 14 | "lint": "tslint -p tsconfig.json -c tslint.json", 15 | "lint:fix": "tslint -p tsconfig.json -c tslint.json --fix", 16 | "test": "jest --detectOpenHandles --config ./test/jest.json --forceExit", 17 | "test:watch": "jest --watch", 18 | "test:cov": "jest --coverage", 19 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 20 | "test:e2e": "jest --detectOpenHandles --config ./test/e2e/jest-e2e.json --forceExit", 21 | "test:int": "jest --detectOpenHandles --config ./test/int/jest-int.json --forceExit", 22 | "test:unit": "jest --detectOpenHandles --config ./test/unit/jest-unit.json --forceExit", 23 | "console:dev": "ts-node -r tsconfig-paths/register src/cli/cli.module.ts", 24 | "fixtures": "fixtures ./fixtures/entities --config ./fixtures/typeorm.config.ts --debug --sync --require=ts-node/register --require=tsconfig-paths/register" 25 | }, 26 | "dependencies": { 27 | "@elastic/elasticsearch": "^7.2.0", 28 | "@grpc/proto-loader": "^0.5.1", 29 | "@nestjs/common": "^6.5.2", 30 | "@nestjs/core": "^6.5.2", 31 | "@nestjs/cqrs": "^6.0.1", 32 | "@nestjs/jwt": "^6.1.1", 33 | "@nestjs/microservices": "^6.5.3", 34 | "@nestjs/passport": "^6.1.0", 35 | "@nestjs/platform-express": "^6.5.2", 36 | "@nestjs/platform-fastify": "^6.5.2", 37 | "@nestjs/typeorm": "^6.1.2", 38 | "@nestjsx/api-version": "^0.1.1", 39 | "@types/elasticsearch": "^5.0.34", 40 | "@types/faker": "^4.1.5", 41 | "@types/fastify-multipart": "^0.7.0", 42 | "@types/fs-extra": "^8.0.0", 43 | "@types/moment-timezone": "^0.5.12", 44 | "@types/multer": "^1.3.7", 45 | "@types/passport-jwt": "^3.0.1", 46 | "activedirectory": "^0.7.2", 47 | "amqp-connection-manager": "^3.0.0", 48 | "amqplib": "^0.5.5", 49 | "chai": "^4.2.0", 50 | "class-transformer": "^0.2.3", 51 | "class-validator": "^0.9.1", 52 | "cloneable-ts": "^1.0.18", 53 | "config": "^3.1.0", 54 | "csvtojson": "^2.0.10", 55 | "faker": "^4.1.0", 56 | "fastify-swagger": "^2.4.0", 57 | "grpc": "^1.22.2", 58 | "moment-timezone": "^0.5.26", 59 | "nestjs-i18n": "^3.0.0", 60 | "nestjs-redis": "^1.2.1", 61 | "npm": "^6.10.3", 62 | "ow": "^0.13.2", 63 | "passport": "^0.4.0", 64 | "passport-http-bearer": "^1.0.1", 65 | "passport-jwt": "^4.0.0", 66 | "pg": "^7.11.0", 67 | "pre-commit": "^1.2.2", 68 | "redis": "^2.8.0", 69 | "reflect-metadata": "0.1.13", 70 | "rimraf": "2.6.3", 71 | "rxjs": "6.5.2" 72 | }, 73 | "devDependencies": { 74 | "@nestjs/cli": "^6.5.0", 75 | "@nestjs/swagger": "^3.0.2", 76 | "@nestjs/testing": "6.3.2", 77 | "@types/express": "4.17.0", 78 | "@types/jest": "24.0.15", 79 | "@types/node": "12.0.10", 80 | "@types/supertest": "2.0.7", 81 | "concurrently": "^4.1.0", 82 | "jest": "24.8.0", 83 | "nestjs-console": "^1.1.4", 84 | "nodemon": "1.19.1", 85 | "prettier": "1.18.2", 86 | "supertest": "4.0.2", 87 | "swagger-ui-express": "^4.0.6", 88 | "ts-jest": "24.0.2", 89 | "ts-node": "^8.3.0", 90 | "tsconfig-paths": "3.8.0", 91 | "tslint": "5.18.0", 92 | "typeorm-fixtures-cli": "^1.3.5", 93 | "typescript": "^3.5.3", 94 | "wait-on": "^3.2.0" 95 | }, 96 | "jest": { 97 | "moduleFileExtensions": [ 98 | "js", 99 | "json", 100 | "ts" 101 | ], 102 | "rootDir": "src", 103 | "testRegex": ".spec.ts$", 104 | "transform": { 105 | "^.+\\.(t|j)s$": "ts-jest" 106 | }, 107 | "collectCoverageFrom": [ 108 | "**/*.(t|j)s" 109 | ], 110 | "coverageDirectory": "../coverage", 111 | "testEnvironment": "node" 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/event-service-rabbit/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import {Logger, Module} from '@nestjs/common'; 2 | import {EventBusSubscriberService} from './services/event.subscriber.service'; 3 | import {ContrivedEventHandler} from './events/contrived/contrived.event.handler'; 4 | import {ContrivedEvent} from './events/contrived/contrived.event'; 5 | import {CqrsModule} from '@nestjs/cqrs'; 6 | 7 | // events handlers 8 | export const EventHandlers = [ 9 | ContrivedEventHandler, 10 | ]; 11 | 12 | // events 13 | export const Events = {ContrivedEvent}; 14 | 15 | @Module({ 16 | imports: [ 17 | CqrsModule, 18 | ], 19 | controllers: [ 20 | EventBusSubscriberService, 21 | ], 22 | providers: [ 23 | ...EventHandlers, 24 | Logger, 25 | ], 26 | }) 27 | export class AppModule { 28 | } 29 | -------------------------------------------------------------------------------- /src/event-service-rabbit/src/config/global.env.ts: -------------------------------------------------------------------------------- 1 | export const EVENT_SERVICE = { 2 | PATTERN: process.env.EVENT_SERVICE_PATTERN, 3 | }; 4 | 5 | export const RABBIT_SERVICE = { 6 | URLS: [ 7 | process.env.RABBITMQ_URL, 8 | ], 9 | QUEUE: process.env.RABBITMQ_QUEUE, 10 | QUEUE_OPTIONS: { 11 | durable: true, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /src/event-service-rabbit/src/events/contrived/contrived.event.handler.ts: -------------------------------------------------------------------------------- 1 | import {EventsHandler, IEventHandler} from '@nestjs/cqrs'; 2 | import {ContrivedEvent} from './contrived.event'; 3 | import {Logger} from '@nestjs/common'; 4 | 5 | @EventsHandler(ContrivedEvent) 6 | export class ContrivedEventHandler implements IEventHandler { 7 | constructor( 8 | private readonly log: Logger, 9 | ) { 10 | 11 | } 12 | 13 | handle(event: ContrivedEvent) { 14 | this.log.verbose('ContrivedEventHandler: event\n'); 15 | this.log.log(event); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/event-service-rabbit/src/events/contrived/contrived.event.ts: -------------------------------------------------------------------------------- 1 | 2 | export class ContrivedEvent { 3 | 4 | constructor( 5 | ) {} 6 | } 7 | -------------------------------------------------------------------------------- /src/event-service-rabbit/src/main.ts: -------------------------------------------------------------------------------- 1 | import {NestFactory} from '@nestjs/core'; 2 | import {AppModule} from './app.module'; 3 | import {Transport} from '@nestjs/microservices'; 4 | import {Logger} from '@nestjs/common'; 5 | 6 | const log = new Logger('event-service: '); 7 | 8 | (async function bootstrap() { 9 | const app = await NestFactory.createMicroservice(AppModule, { 10 | logger: log, 11 | transport: Transport.RMQ, 12 | options: { 13 | urls: ['amqp://rabbit:rabbit@rabbitmq:5672'], 14 | queue: 'event_service_queue', 15 | queueOptions: { 16 | durable: true, 17 | }, 18 | }, 19 | }); 20 | 21 | await app.listen(() => { 22 | log.verbose('Event Service is running.'); 23 | }); 24 | })(); 25 | -------------------------------------------------------------------------------- /src/event-service-rabbit/src/pipes/json.parse.pipe.ts: -------------------------------------------------------------------------------- 1 | import {ArgumentMetadata, Injectable, PipeTransform} from '@nestjs/common'; 2 | 3 | @Injectable() 4 | export class JsonParsePipe implements PipeTransform { 5 | transform(value: any, metadata: ArgumentMetadata) { 6 | if (typeof value === 'string') { 7 | return JSON.parse(value); 8 | } 9 | return value; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/event-service-rabbit/src/services/event.subscriber.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable, UsePipes} from '@nestjs/common'; 2 | import {EventPattern} from '@nestjs/microservices'; 3 | import {EventBus} from '@nestjs/cqrs'; 4 | import {plainToClass} from 'class-transformer'; 5 | import {Events} from '../app.module'; 6 | import {JsonParsePipe} from '../pipes/json.parse.pipe'; 7 | 8 | @Injectable() 9 | export class EventBusSubscriberService { 10 | 11 | constructor( 12 | private readonly eventBus: EventBus, 13 | ) { 14 | 15 | } 16 | 17 | @EventPattern('event_bus') 18 | @UsePipes(new JsonParsePipe()) 19 | async subscribe(data: any) { 20 | try { 21 | const event = Events[data.event]; 22 | 23 | if (!event) { 24 | throw new Error(`Not such ${data.event}.`); 25 | } 26 | 27 | this.eventBus.publish(plainToClass(event, data.payload)); 28 | } catch { 29 | // TODO 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/event-service-rabbit/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [ 4 | "node_modules", 5 | "dist", 6 | "test", 7 | "fixtures", 8 | "grpc", 9 | "cli", 10 | "**/*spec.ts" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /src/event-service-rabbit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "esModuleInterop": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "target": "es6", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true 14 | }, 15 | "exclude": [ 16 | "node_modules", 17 | "dist", 18 | "test", 19 | "fixtures", 20 | "grpc" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/event-service-rabbit/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": ["tslint:recommended"], 4 | "jsRules": { 5 | "no-unused-expression": true 6 | }, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "member-access": [false], 10 | "ordered-imports": [false], 11 | "max-line-length": [true, 150], 12 | "member-ordering": [false], 13 | "interface-name": [false], 14 | "arrow-parens": false, 15 | "object-literal-sort-keys": false 16 | }, 17 | "rulesDirectory": [] 18 | } 19 | -------------------------------------------------------------------------------- /src/event-service-redis/.gitignore: -------------------------------------------------------------------------------- 1 | # Don't check auto-generated stuff into git 2 | coverage 3 | build 4 | node_modules 5 | dist 6 | stats.json 7 | 8 | # Cruft 9 | .DS_Store 10 | npm-debug.log 11 | .idea 12 | .env 13 | -------------------------------------------------------------------------------- /src/event-service-redis/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 4, 4 | "semi": true, 5 | "singleQuote": true 6 | } -------------------------------------------------------------------------------- /src/event-service-redis/README.md: -------------------------------------------------------------------------------- 1 |

2 | Nest Logo 3 |

4 | 5 | [travis-image]: https://api.travis-ci.org/nestjs/nest.svg?branch=master 6 | [travis-url]: https://travis-ci.org/nestjs/nest 7 | [linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux 8 | [linux-url]: https://travis-ci.org/nestjs/nest 9 | 10 |

A progressive Node.js framework for building efficient and scalable server-side applications, heavily inspired by Angular.

11 |

12 | NPM Version 13 | Package License 14 | NPM Downloads 15 | Travis 16 | Linux 17 | Coverage 18 | Gitter 19 | Backers on Open Collective 20 | Sponsors on Open Collective 21 | 22 | 23 |

24 | 26 | 27 | ## Description 28 | 29 | [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. 30 | 31 | ## Installation 32 | 33 | ```bash 34 | $ npm install 35 | ``` 36 | 37 | ## Running the app 38 | 39 | ```bash 40 | # development 41 | $ npm run start 42 | 43 | # watch mode 44 | $ npm run start:dev 45 | 46 | # production mode 47 | $ npm run start:prod 48 | ``` 49 | 50 | ## Test 51 | 52 | ```bash 53 | # unit tests 54 | $ npm run test 55 | 56 | # e2e tests 57 | $ npm run test:e2e 58 | 59 | # test coverage 60 | $ npm run test:cov 61 | ``` 62 | 63 | ## Support 64 | 65 | Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). 66 | 67 | ## Stay in touch 68 | 69 | - Author - [Kamil Myśliwiec](https://kamilmysliwiec.com) 70 | - Website - [https://nestjs.com](https://nestjs.com/) 71 | - Twitter - [@nestframework](https://twitter.com/nestframework) 72 | 73 | ## License 74 | 75 | Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE). 76 | -------------------------------------------------------------------------------- /src/event-service-redis/nodemon-debug.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["src"], 3 | "ext": "ts", 4 | "ignore": ["src/**/*.spec.ts"], 5 | "exec": "node --inspect-brk=0.0.0.0:9229 -r tsconfig-paths/register -r ts-node/register src/main.ts" 6 | } -------------------------------------------------------------------------------- /src/event-service-redis/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["dist"], 3 | "ext": "js", 4 | "exec": "node dist/main" 5 | } 6 | -------------------------------------------------------------------------------- /src/event-service-redis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nest-typescript-starter", 3 | "version": "1.0.0", 4 | "description": "Nest TypeScript starter repository", 5 | "license": "MIT", 6 | "scripts": { 7 | "build": "tsc -p tsconfig.build.json", 8 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 9 | "start": "ts-node -r tsconfig-paths/register src/main.ts", 10 | "start:dev": "concurrently --handle-input \"wait-on dist/main.js && nodemon\" \"tsc -w -p tsconfig.build.json\" ", 11 | "start:debug": "nodemon --config nodemon-debug.json", 12 | "prestart:prod": "rimraf dist && npm run build", 13 | "start:prod": "node dist/main.js", 14 | "lint": "tslint -p tsconfig.json -c tslint.json", 15 | "lint:fix": "tslint -p tsconfig.json -c tslint.json --fix", 16 | "test": "jest --detectOpenHandles --config ./test/jest.json --forceExit", 17 | "test:watch": "jest --watch", 18 | "test:cov": "jest --coverage", 19 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 20 | "test:e2e": "jest --detectOpenHandles --config ./test/e2e/jest-e2e.json --forceExit", 21 | "test:int": "jest --detectOpenHandles --config ./test/int/jest-int.json --forceExit", 22 | "test:unit": "jest --detectOpenHandles --config ./test/unit/jest-unit.json --forceExit", 23 | "console:dev": "ts-node -r tsconfig-paths/register src/cli/cli.module.ts", 24 | "fixtures": "fixtures ./fixtures/entities --config ./fixtures/typeorm.config.ts --debug --sync --require=ts-node/register --require=tsconfig-paths/register" 25 | }, 26 | "dependencies": { 27 | "@elastic/elasticsearch": "^7.2.0", 28 | "@grpc/proto-loader": "^0.5.1", 29 | "@nestjs/common": "^6.5.2", 30 | "@nestjs/core": "^6.5.2", 31 | "@nestjs/cqrs": "^6.0.1", 32 | "@nestjs/jwt": "^6.1.1", 33 | "@nestjs/microservices": "^6.5.3", 34 | "@nestjs/passport": "^6.1.0", 35 | "@nestjs/platform-express": "^6.5.2", 36 | "@nestjs/platform-fastify": "^6.5.2", 37 | "@nestjs/typeorm": "^6.1.2", 38 | "@nestjsx/api-version": "^0.1.1", 39 | "@types/elasticsearch": "^5.0.34", 40 | "@types/faker": "^4.1.5", 41 | "@types/fastify-multipart": "^0.7.0", 42 | "@types/fs-extra": "^8.0.0", 43 | "@types/moment-timezone": "^0.5.12", 44 | "@types/multer": "^1.3.7", 45 | "@types/passport-jwt": "^3.0.1", 46 | "activedirectory": "^0.7.2", 47 | "amqp-connection-manager": "^3.0.0", 48 | "amqplib": "^0.5.5", 49 | "chai": "^4.2.0", 50 | "class-transformer": "^0.2.3", 51 | "class-validator": "^0.9.1", 52 | "cloneable-ts": "^1.0.18", 53 | "config": "^3.1.0", 54 | "csvtojson": "^2.0.10", 55 | "faker": "^4.1.0", 56 | "fastify-swagger": "^2.4.0", 57 | "grpc": "^1.22.2", 58 | "moment-timezone": "^0.5.26", 59 | "nestjs-i18n": "^3.0.0", 60 | "nestjs-redis": "^1.2.1", 61 | "npm": "^6.10.3", 62 | "ow": "^0.13.2", 63 | "passport": "^0.4.0", 64 | "passport-http-bearer": "^1.0.1", 65 | "passport-jwt": "^4.0.0", 66 | "pg": "^7.11.0", 67 | "pre-commit": "^1.2.2", 68 | "redis": "^2.8.0", 69 | "reflect-metadata": "0.1.13", 70 | "rimraf": "2.6.3", 71 | "rxjs": "6.5.2" 72 | }, 73 | "devDependencies": { 74 | "@nestjs/cli": "^6.5.0", 75 | "@nestjs/swagger": "^3.0.2", 76 | "@nestjs/testing": "6.3.2", 77 | "@types/express": "4.17.0", 78 | "@types/jest": "24.0.15", 79 | "@types/node": "12.0.10", 80 | "@types/supertest": "2.0.7", 81 | "concurrently": "^4.1.0", 82 | "jest": "24.8.0", 83 | "nestjs-console": "^1.1.4", 84 | "nodemon": "1.19.1", 85 | "prettier": "1.18.2", 86 | "supertest": "4.0.2", 87 | "swagger-ui-express": "^4.0.6", 88 | "ts-jest": "24.0.2", 89 | "ts-node": "^8.3.0", 90 | "tsconfig-paths": "3.8.0", 91 | "tslint": "5.18.0", 92 | "typeorm-fixtures-cli": "^1.3.5", 93 | "typescript": "^3.5.3", 94 | "wait-on": "^3.2.0" 95 | }, 96 | "jest": { 97 | "moduleFileExtensions": [ 98 | "js", 99 | "json", 100 | "ts" 101 | ], 102 | "rootDir": "src", 103 | "testRegex": ".spec.ts$", 104 | "transform": { 105 | "^.+\\.(t|j)s$": "ts-jest" 106 | }, 107 | "collectCoverageFrom": [ 108 | "**/*.(t|j)s" 109 | ], 110 | "coverageDirectory": "../coverage", 111 | "testEnvironment": "node" 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/event-service-redis/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import {Logger, Module} from '@nestjs/common'; 2 | import {EventBusSubscriberService} from './services/event.subscriber.service'; 3 | import {ContrivedEventHandler} from './events/contrived/contrived.event.handler'; 4 | import {ContrivedEvent} from './events/contrived/contrived.event'; 5 | import {CqrsModule} from '@nestjs/cqrs'; 6 | 7 | // events handlers 8 | export const EventHandlers = [ 9 | ContrivedEventHandler, 10 | ]; 11 | 12 | // events 13 | export const Events = {ContrivedEvent}; 14 | 15 | @Module({ 16 | imports: [ 17 | CqrsModule, 18 | ], 19 | controllers: [ 20 | EventBusSubscriberService, 21 | ], 22 | providers: [ 23 | ...EventHandlers, 24 | Logger, 25 | ], 26 | }) 27 | export class AppModule { 28 | } 29 | -------------------------------------------------------------------------------- /src/event-service-redis/src/config/global.env.ts: -------------------------------------------------------------------------------- 1 | export const EVENT_SERVICE = { 2 | PATTERN: process.env.EVENT_SERVICE_PATTERN, 3 | }; 4 | 5 | export const RABBIT_SERVICE = { 6 | URLS: [ 7 | process.env.RABBITMQ_URL, 8 | ], 9 | QUEUE: process.env.RABBITMQ_QUEUE, 10 | QUEUE_OPTIONS: { 11 | durable: true, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /src/event-service-redis/src/events/contrived/contrived.event.handler.ts: -------------------------------------------------------------------------------- 1 | import {EventsHandler, IEventHandler} from '@nestjs/cqrs'; 2 | import {ContrivedEvent} from './contrived.event'; 3 | import {Logger} from '@nestjs/common'; 4 | 5 | @EventsHandler(ContrivedEvent) 6 | export class ContrivedEventHandler implements IEventHandler { 7 | constructor( 8 | private readonly log: Logger, 9 | ) { 10 | 11 | } 12 | 13 | handle(event: ContrivedEvent) { 14 | this.log.verbose('ContrivedEventHandler: event\n'); 15 | this.log.log(event); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/event-service-redis/src/events/contrived/contrived.event.ts: -------------------------------------------------------------------------------- 1 | 2 | export class ContrivedEvent { 3 | 4 | constructor( 5 | ) {} 6 | } 7 | -------------------------------------------------------------------------------- /src/event-service-redis/src/main.ts: -------------------------------------------------------------------------------- 1 | import {NestFactory} from '@nestjs/core'; 2 | import {AppModule} from './app.module'; 3 | import {Transport} from '@nestjs/microservices'; 4 | import {Logger} from '@nestjs/common'; 5 | 6 | const log = new Logger('event-service: '); 7 | 8 | (async function bootstrap() { 9 | const app = await NestFactory.createMicroservice(AppModule, { 10 | logger: log, 11 | transport: Transport.REDIS, 12 | options: { 13 | url: 'redis://:password123@redis:6379', 14 | }, 15 | }); 16 | 17 | await app.listen(() => { 18 | log.verbose('Redis Event Service is running.'); 19 | }); 20 | })(); 21 | -------------------------------------------------------------------------------- /src/event-service-redis/src/pipes/json.parse.pipe.ts: -------------------------------------------------------------------------------- 1 | import {ArgumentMetadata, Injectable, PipeTransform} from '@nestjs/common'; 2 | 3 | @Injectable() 4 | export class JsonParsePipe implements PipeTransform { 5 | transform(value: any, metadata: ArgumentMetadata) { 6 | if (typeof value === 'string') { 7 | return JSON.parse(value); 8 | } 9 | return value; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/event-service-redis/src/services/event.subscriber.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable, UsePipes} from '@nestjs/common'; 2 | import {EventPattern} from '@nestjs/microservices'; 3 | import {EventBus} from '@nestjs/cqrs'; 4 | import {plainToClass} from 'class-transformer'; 5 | import {Events} from '../app.module'; 6 | import {JsonParsePipe} from '../pipes/json.parse.pipe'; 7 | 8 | @Injectable() 9 | export class EventBusSubscriberService { 10 | 11 | constructor( 12 | private readonly eventBus: EventBus, 13 | ) { 14 | 15 | } 16 | 17 | @EventPattern('event_bus') 18 | @UsePipes(new JsonParsePipe()) 19 | async subscribe(data: any) { 20 | console.log('===dsdsd========',data); 21 | try { 22 | const event = Events[data.event]; 23 | 24 | if (!event) { 25 | throw new Error(`Not such ${data.event}.`); 26 | } 27 | 28 | this.eventBus.publish(plainToClass(event, data.payload)); 29 | } catch { 30 | // TODO 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/event-service-redis/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [ 4 | "node_modules", 5 | "dist", 6 | "test", 7 | "fixtures", 8 | "grpc", 9 | "cli", 10 | "**/*spec.ts" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /src/event-service-redis/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "esModuleInterop": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "target": "es6", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true 14 | }, 15 | "exclude": [ 16 | "node_modules", 17 | "dist", 18 | "test", 19 | "fixtures", 20 | "grpc" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/event-service-redis/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": ["tslint:recommended"], 4 | "jsRules": { 5 | "no-unused-expression": true 6 | }, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "member-access": [false], 10 | "ordered-imports": [false], 11 | "max-line-length": [true, 150], 12 | "member-ordering": [false], 13 | "interface-name": [false], 14 | "arrow-parens": false, 15 | "object-literal-sort-keys": false 16 | }, 17 | "rulesDirectory": [] 18 | } 19 | --------------------------------------------------------------------------------