├── README.md
├── api-gateway-and-service-doscovery
├── .gitignore
├── Microservices_Architecture.png
├── README.md
├── ServicesSetup.sh
├── ServicesStart.sh
├── api-gateway
│ ├── Dockerbuild.sh
│ ├── Dockerfile
│ ├── api-gateway.js
│ ├── api
│ │ ├── account
│ │ │ ├── login.js
│ │ │ └── signup.js
│ │ └── crm
│ │ │ └── orders
│ │ │ └── orders.js
│ ├── config.js
│ ├── config.json
│ ├── package-lock.json
│ ├── package.json
│ ├── server.js
│ └── services-helper.js
├── micro-node-api-gateway.gif
├── service-log
│ ├── Dockerbuild.sh
│ ├── Dockerfile
│ ├── config.js
│ ├── config.json
│ ├── log.js
│ ├── package-lock.json
│ ├── package.json
│ └── server.js
├── service-login
│ ├── Dockerbuild.sh
│ ├── Dockerfile
│ ├── config.js
│ ├── config.json
│ ├── login.js
│ ├── package-lock.json
│ ├── package.json
│ └── server.js
├── service-orders
│ ├── Dockerbuild.sh
│ ├── Dockerfile
│ ├── config.js
│ ├── config.json
│ ├── orders.js
│ ├── package-lock.json
│ ├── package.json
│ └── server.js
└── service-signup
│ ├── Dockerbuild.sh
│ ├── Dockerfile
│ ├── config.js
│ ├── config.json
│ ├── package-lock.json
│ ├── package.json
│ ├── server.js
│ └── signup.js
├── dockerized-containers
├── .eslintrc.js
├── .gitignore
├── .travis.yml
├── README.md
├── docker-compose.yml
├── e-Commerce-Admin
│ ├── Dockerfile
│ ├── README.md
│ ├── app
│ │ ├── config
│ │ │ ├── email.ts
│ │ │ └── environments
│ │ │ │ ├── dev.ts
│ │ │ │ ├── qa.ts
│ │ │ │ └── test.ts
│ │ ├── controller
│ │ │ └── UserController.ts
│ │ ├── events
│ │ │ └── notification.ts
│ │ ├── global
│ │ │ └── templates
│ │ │ │ ├── emails
│ │ │ │ ├── assets
│ │ │ │ │ └── images
│ │ │ │ │ │ └── logo.png
│ │ │ │ ├── password-reset-email
│ │ │ │ │ ├── html.pug
│ │ │ │ │ └── style.css
│ │ │ │ └── welcome-email
│ │ │ │ │ ├── html.pug
│ │ │ │ │ └── style.css
│ │ │ │ └── response
│ │ │ │ └── index.ts
│ │ ├── helper
│ │ │ ├── bcrypt.ts
│ │ │ ├── email.ts
│ │ │ ├── errorHandler.ts
│ │ │ ├── logger.ts
│ │ │ ├── responseTemplate.ts
│ │ │ └── twillo.ts
│ │ ├── lib
│ │ │ ├── logger.ts
│ │ │ ├── mongoose.ts
│ │ │ └── requestValidator.ts
│ │ ├── middleware
│ │ │ ├── authMiddleware.ts
│ │ │ └── requestValidator.ts
│ │ ├── models
│ │ │ ├── plugin
│ │ │ │ └── plugin.ts
│ │ │ └── user.ts
│ │ ├── routes.ts
│ │ ├── routes
│ │ │ ├── defaultRoutes.ts
│ │ │ ├── provider
│ │ │ │ ├── Facebook.ts
│ │ │ │ ├── Google.ts
│ │ │ │ ├── Linkedin.ts
│ │ │ │ ├── Locale.ts
│ │ │ │ └── Twitter.ts
│ │ │ ├── routes.ts
│ │ │ └── userRoutes.ts
│ │ ├── seed
│ │ │ ├── seedUsers.ts
│ │ │ └── seedVehicle.ts
│ │ ├── transformer
│ │ │ └── userTransformer.ts
│ │ └── types
│ │ │ ├── global.d.ts
│ │ │ └── vendor.d.ts
│ ├── env.sh
│ ├── express.ts
│ ├── package.json
│ ├── public
│ │ ├── images
│ │ │ ├── cinema.jpg
│ │ │ └── favicon.ico
│ │ ├── javascripts
│ │ │ └── script.js
│ │ └── style.scss
│ ├── server.ts
│ ├── tsconfig.json
│ ├── tslint.json
│ └── uploads
│ │ ├── documents
│ │ └── .gitkeep
│ │ └── profile
│ │ └── .gitkeep
├── e-Commerce-Auth
│ ├── Dockerfile
│ ├── README.md
│ ├── app
│ │ ├── config
│ │ │ ├── email.ts
│ │ │ └── environments
│ │ │ │ ├── dev.ts
│ │ │ │ ├── qa.ts
│ │ │ │ └── test.ts
│ │ ├── controller
│ │ │ └── UserController.ts
│ │ ├── events
│ │ │ └── notification.ts
│ │ ├── global
│ │ │ └── templates
│ │ │ │ ├── emails
│ │ │ │ ├── assets
│ │ │ │ │ └── images
│ │ │ │ │ │ └── logo.png
│ │ │ │ ├── password-reset-email
│ │ │ │ │ ├── html.pug
│ │ │ │ │ └── style.css
│ │ │ │ └── welcome-email
│ │ │ │ │ ├── html.pug
│ │ │ │ │ └── style.css
│ │ │ │ └── response
│ │ │ │ └── index.ts
│ │ ├── helper
│ │ │ ├── bcrypt.ts
│ │ │ ├── email.ts
│ │ │ ├── errorHandler.ts
│ │ │ ├── logger.ts
│ │ │ ├── responseTemplate.ts
│ │ │ └── twillo.ts
│ │ ├── lib
│ │ │ ├── logger.ts
│ │ │ ├── mongoose.ts
│ │ │ └── requestValidator.ts
│ │ ├── middleware
│ │ │ ├── authMiddleware.ts
│ │ │ └── requestValidator.ts
│ │ ├── models
│ │ │ ├── plugin
│ │ │ │ └── plugin.ts
│ │ │ └── user.ts
│ │ ├── routes.ts
│ │ ├── routes
│ │ │ ├── defaultRoutes.ts
│ │ │ ├── provider
│ │ │ │ ├── Facebook.ts
│ │ │ │ ├── Google.ts
│ │ │ │ ├── Linkedin.ts
│ │ │ │ ├── Locale.ts
│ │ │ │ └── Twitter.ts
│ │ │ ├── routes.ts
│ │ │ └── userRoutes.ts
│ │ ├── seed
│ │ │ ├── seedUsers.ts
│ │ │ └── seedVehicle.ts
│ │ ├── transformer
│ │ │ └── userTransformer.ts
│ │ └── types
│ │ │ ├── global.d.ts
│ │ │ └── vendor.d.ts
│ ├── env.sh
│ ├── express.ts
│ ├── package.json
│ ├── public
│ │ ├── images
│ │ │ ├── cinema.jpg
│ │ │ └── favicon.ico
│ │ ├── javascripts
│ │ │ └── script.js
│ │ └── style.scss
│ ├── server.ts
│ ├── tsconfig.json
│ ├── tslint.json
│ └── uploads
│ │ ├── documents
│ │ └── .gitkeep
│ │ └── profile
│ │ └── .gitkeep
├── e-Commerce-Cart
│ ├── .sequelizerc
│ ├── Dockerfile
│ ├── README.md
│ ├── app
│ │ ├── config
│ │ │ └── environments
│ │ │ │ ├── dev.ts
│ │ │ │ ├── qa.ts
│ │ │ │ └── test.ts
│ │ ├── events
│ │ │ └── processEvent.ts
│ │ ├── helper
│ │ │ ├── errorHandler.ts
│ │ │ ├── errors.ts
│ │ │ ├── logger.ts
│ │ │ └── responseTemplate.ts
│ │ ├── lib
│ │ │ ├── logger.ts
│ │ │ ├── mysql.ts
│ │ │ └── requestValidator.ts
│ │ ├── middleware
│ │ │ └── requestValidator.ts
│ │ ├── models
│ │ │ └── data
│ │ │ │ └── cart.ts
│ │ ├── routes.ts
│ │ ├── routes
│ │ │ └── defaultRoutes.ts
│ │ └── types
│ │ │ ├── global.d.ts
│ │ │ └── vendor.d.ts
│ ├── config
│ │ └── config.js
│ ├── env.sh
│ ├── express.ts
│ ├── mysql
│ │ └── schema.sql
│ ├── package.json
│ ├── public
│ │ ├── images
│ │ │ ├── cinema.jpg
│ │ │ └── favicon.ico
│ │ ├── javascripts
│ │ │ └── script.js
│ │ └── style.scss
│ ├── server.ts
│ ├── tsconfig.json
│ ├── tslint.json
│ └── uploads
│ │ ├── documents
│ │ └── .gitkeep
│ │ └── profile
│ │ └── .gitkeep
├── e-Commerce-Client
│ ├── Dockerfile
│ ├── README.md
│ ├── env.sh
│ ├── firebase.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── manifest.json
│ │ └── normalize.css
│ └── src
│ │ ├── api
│ │ └── index.js
│ │ ├── components
│ │ ├── App
│ │ │ └── index.js
│ │ ├── Checkbox
│ │ │ └── index.js
│ │ ├── FloatCart
│ │ │ ├── CartProduct
│ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ └── style.scss
│ │ ├── Selectbox
│ │ │ └── index.js
│ │ ├── Shelf
│ │ │ ├── Filter
│ │ │ │ ├── index.js
│ │ │ │ └── style.scss
│ │ │ ├── ProductList
│ │ │ │ ├── Product
│ │ │ │ │ └── index.js
│ │ │ │ └── index.js
│ │ │ ├── ShelfHeader
│ │ │ │ └── index.js
│ │ │ ├── Sort
│ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ └── style.scss
│ │ ├── Spinner
│ │ │ ├── index.js
│ │ │ └── style.scss
│ │ └── Thumb
│ │ │ └── index.js
│ │ ├── config
│ │ ├── index.js
│ │ └── server.js
│ │ ├── index.js
│ │ ├── index.scss
│ │ ├── layout
│ │ ├── Auth.js
│ │ └── Public.js
│ │ ├── services
│ │ ├── auth
│ │ │ ├── Login.js
│ │ │ ├── Logout.js
│ │ │ ├── Register.js
│ │ │ ├── ResetPassword.js
│ │ │ ├── ValidateToken.js
│ │ │ ├── action.js
│ │ │ ├── actionTypes.js
│ │ │ ├── auth.scss
│ │ │ └── reducer.js
│ │ ├── cart
│ │ │ ├── actionTypes.js
│ │ │ ├── actions.js
│ │ │ └── reducer.js
│ │ ├── filters
│ │ │ ├── actionTypes.js
│ │ │ ├── actions.js
│ │ │ └── reducer.js
│ │ ├── reducers.js
│ │ ├── shelf
│ │ │ ├── actionTypes.js
│ │ │ ├── actions.js
│ │ │ └── reducer.js
│ │ ├── sort
│ │ │ ├── actionTypes.js
│ │ │ ├── actions.js
│ │ │ └── reducer.js
│ │ ├── store.js
│ │ ├── total
│ │ │ ├── actionTypes.js
│ │ │ ├── actions.js
│ │ │ └── reducer.js
│ │ └── util.js
│ │ ├── setupTests.js
│ │ ├── static
│ │ ├── bag-icon.png
│ │ ├── products
│ │ │ ├── 100_1.jpg
│ │ │ ├── 100_2.jpg
│ │ │ ├── 101_1.jpg
│ │ │ ├── 101_2.jpg
│ │ │ ├── 10412368723880252_1.jpg
│ │ │ ├── 10412368723880252_2.jpg
│ │ │ ├── 10547961582846888_1.jpg
│ │ │ ├── 10547961582846888_2.jpg
│ │ │ ├── 10686354557628304_1.jpg
│ │ │ ├── 10686354557628304_2.jpg
│ │ │ ├── 11033926921508488_1.jpg
│ │ │ ├── 11033926921508488_2.jpg
│ │ │ ├── 11600983276356164_1.jpg
│ │ │ ├── 11600983276356164_2.jpg
│ │ │ ├── 11854078013954528_1.jpg
│ │ │ ├── 11854078013954528_2.jpg
│ │ │ ├── 12064273040195392_1.jpg
│ │ │ ├── 12064273040195392_2.jpg
│ │ │ ├── 18532669286405344_1.jpg
│ │ │ ├── 18532669286405344_2.jpg
│ │ │ ├── 18644119330491310_1.jpg
│ │ │ ├── 18644119330491310_2.jpg
│ │ │ ├── 27250082398145996_1.jpg
│ │ │ ├── 27250082398145996_2.jpg
│ │ │ ├── 39876704341265610_1.jpg
│ │ │ ├── 39876704341265610_2.jpg
│ │ │ ├── 51498472915966370_1.jpg
│ │ │ ├── 51498472915966370_2.jpg
│ │ │ ├── 5619496040738316_1.jpg
│ │ │ ├── 5619496040738316_2.jpg
│ │ │ ├── 6090484789343891_1.jpg
│ │ │ ├── 6090484789343891_2.jpg
│ │ │ ├── 8552515751438644_1.jpg
│ │ │ ├── 8552515751438644_2.jpg
│ │ │ ├── 876661122392077_1.jpg
│ │ │ ├── 876661122392077_2.jpg
│ │ │ ├── 9197907543445676_1.jpg
│ │ │ └── 9197907543445676_2.jpg
│ │ └── sprite_delete-icon.png
│ │ └── util
│ │ ├── helper
│ │ └── index.js
│ │ └── middleware
│ │ ├── auth.js
│ │ └── index.js
├── proxy
│ ├── default.conf
│ ├── hosts
│ └── ssl
│ │ ├── pac.crt
│ │ └── pac.key
└── screens
│ ├── 02.png
│ └── 03.png
├── event-driven-microservices-docker
├── .githooks
│ ├── pre-commit
│ ├── pre-commit.d
│ │ ├── articles-management-service
│ │ ├── events-management-service
│ │ ├── notification-service
│ │ └── user-management-service
│ ├── pre-push
│ └── pre-push.d
│ │ ├── articles-management-service
│ │ ├── events-management-service
│ │ ├── notification-service
│ │ └── user-management-service
├── .gitignore
├── docker-compose.yml
├── run_all_tests
└── services
│ ├── articles-management
│ ├── .dockerignore
│ ├── .eslintignore
│ ├── .eslintrc.yml
│ ├── .gitignore
│ ├── Dockerfile
│ ├── package.json
│ ├── src
│ │ ├── app.js
│ │ ├── controllers
│ │ │ ├── __mocks__
│ │ │ │ └── article.controller.js
│ │ │ └── article.controller.js
│ │ ├── environment
│ │ │ └── config.js
│ │ ├── message-bus
│ │ │ └── send
│ │ │ │ ├── __mocks__
│ │ │ │ └── article.added.js
│ │ │ │ └── article.added.js
│ │ ├── middlewares
│ │ │ ├── __mocks__
│ │ │ │ └── jwt.js
│ │ │ └── jwt.js
│ │ ├── models
│ │ │ ├── __mocks__
│ │ │ │ └── article.model.js
│ │ │ └── article.model.js
│ │ ├── routes
│ │ │ └── article.routes.js
│ │ └── server.js
│ └── tests
│ │ └── unit
│ │ ├── __snapshots__
│ │ └── article.added.message.send.test.js.snap
│ │ ├── app.test.js
│ │ ├── article.added.message.send.test.js
│ │ ├── article.controller.test.js
│ │ ├── article.model.test.js
│ │ ├── article.routes.test.js
│ │ ├── config.test.js
│ │ └── server.test.js
│ ├── authentication
│ ├── .dockerignore
│ ├── .env
│ ├── .eslintrc.yml
│ ├── .gitignore
│ ├── .gitkeep
│ ├── .snyk
│ ├── Dockerfile
│ ├── package-lock.json
│ ├── package.json
│ └── src
│ │ ├── app.js
│ │ ├── controllers
│ │ └── auth.controller.js
│ │ ├── environment
│ │ └── config.js
│ │ ├── message-bus
│ │ └── recieve
│ │ │ └── user.added.js
│ │ ├── models
│ │ └── auth.model.js
│ │ ├── routes
│ │ └── auth.routes.js
│ │ └── server.js
│ ├── events-management
│ ├── .dockerignore
│ ├── .eslintrc.yml
│ ├── .gitignore
│ ├── Dockerfile
│ ├── package.json
│ ├── src
│ │ ├── app.js
│ │ ├── controllers
│ │ │ ├── __mocks__
│ │ │ │ └── event.controller.js
│ │ │ └── event.controller.js
│ │ ├── environment
│ │ │ └── config.js
│ │ ├── middlewares
│ │ │ ├── __mocks__
│ │ │ │ └── jwt.js
│ │ │ └── jwt.js
│ │ ├── models
│ │ │ ├── __mocks__
│ │ │ │ └── event.model.js
│ │ │ └── event.model.js
│ │ ├── routes
│ │ │ └── event.routes.js
│ │ └── server.js
│ └── tests
│ │ └── unit
│ │ ├── app.test.js
│ │ ├── config.test.js
│ │ ├── event.controller.test.js
│ │ ├── event.model.test.js
│ │ ├── event.routes.test.js
│ │ └── server.test.js
│ ├── media-management
│ └── .gitkeep
│ ├── notification
│ ├── .eslintrc.yml
│ ├── .gitignore
│ ├── Dockerfile
│ ├── __mocks__
│ │ ├── amqp-ts-async.js
│ │ ├── koa.js
│ │ ├── nodemailer.js
│ │ └── winston.js
│ ├── package.json
│ ├── src
│ │ ├── environment
│ │ │ └── config.js
│ │ ├── message-controllers
│ │ │ ├── __mocks__
│ │ │ │ └── articles.js
│ │ │ └── articles.js
│ │ ├── modules
│ │ │ └── email
│ │ │ │ ├── __mocks__
│ │ │ │ ├── email.js
│ │ │ │ └── email.templates.js
│ │ │ │ ├── email.js
│ │ │ │ └── email.templates.js
│ │ ├── server.js
│ │ └── subscriptions
│ │ │ ├── __mocks__
│ │ │ └── article.added.js
│ │ │ └── article.added.js
│ └── tests
│ │ └── unit
│ │ ├── __snapshots__
│ │ ├── config.test.js.snap
│ │ ├── email.templates.test.js.snap
│ │ └── email.test.js.snap
│ │ ├── article.added.subscription.test.js
│ │ ├── article.message.controller.test.js
│ │ ├── config.test.js
│ │ ├── email.templates.test.js
│ │ ├── email.test.js
│ │ └── server.test.js
│ ├── search
│ └── .gitkeep
│ └── user-management
│ ├── .dockerignore
│ ├── .eslintrc.yml
│ ├── .gitignore
│ ├── .gitkeep
│ ├── Dockerfile
│ ├── __mocks__
│ ├── amqp-ts-async.js
│ └── winston.js
│ ├── package.json
│ ├── src
│ ├── app.js
│ ├── controllers
│ │ ├── __mocks__
│ │ │ └── user.controller.js
│ │ └── user.controller.js
│ ├── environment
│ │ └── config.js
│ ├── message-bus
│ │ └── send
│ │ │ └── user.added.js
│ ├── middlewares
│ │ ├── __mocks__
│ │ │ └── jwt.js
│ │ └── jwt.js
│ ├── models
│ │ ├── __mocks__
│ │ │ └── user.model.js
│ │ └── user.model.js
│ ├── routes
│ │ └── user.routes.js
│ └── server.js
│ └── tests
│ └── unit
│ ├── __snapshots__
│ ├── user.added.message.send.test.js.snap
│ └── user.controller.test.js.snap
│ ├── app.test.js
│ ├── config.test.js
│ ├── server.test.js
│ ├── user.added.message.send.test.js
│ ├── user.controller.test.js
│ ├── user.model.test.js
│ └── user.routes.test.js
├── node js-with-serverless
├── .gitignore
├── README.md
├── functions
│ ├── delete_item.ts
│ ├── edit_item.ts
│ ├── read_all.ts
│ ├── read_single_item.ts
│ └── write_item.ts
├── models
│ └── table_schema.ts
├── package-lock.json
├── package.json
├── serverless.yml
└── shared
│ ├── create_dynamo.ts
│ └── update_dynamo.ts
├── node-js-lambda-sqs-serverless
├── .gitignore
├── README.md
├── data.json
├── db.js
├── handler.js
├── models
│ └── note.js
├── package.json
├── serverless.yml
└── sqs.js
├── node-microservice-starter
├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .gitignore
├── README.md
├── docker-compose.yml
├── nginx
│ ├── Dockerfile
│ └── nginx.conf
└── users
│ ├── .eslintrc.js
│ ├── .prettierrc
│ ├── Dockerfile
│ ├── README.md
│ ├── nest-cli.json
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ ├── app.controller.spec.ts
│ ├── app.controller.ts
│ ├── app.module.ts
│ ├── app.service.ts
│ └── main.ts
│ ├── test
│ ├── app.e2e-spec.ts
│ └── jest-e2e.json
│ ├── tsconfig.build.json
│ └── tsconfig.json
├── nodejs-cqrs-pattern
├── .dockerignore
├── .env.example
├── .gitignore
├── Dockerfile
├── README.md
├── config.ts
├── docker-compose.yml
├── docs
│ └── README.md
├── githooks
│ └── README.md
├── nest-cli.json
├── nodemon-debug.json
├── nodemon.json
├── package.json
├── scripts
│ ├── down.sh
│ └── up.sh
├── src
│ ├── app.module.ts
│ ├── core
│ │ └── event-store
│ │ │ ├── event-store.class.ts
│ │ │ ├── event-store.interface.ts
│ │ │ ├── event-store.module.ts
│ │ │ ├── event-store.provider.ts
│ │ │ └── event-store.ts
│ ├── main.ts
│ └── users
│ │ ├── commands
│ │ ├── handlers
│ │ │ ├── create-user.handler.ts
│ │ │ ├── delete-user.handler.ts
│ │ │ ├── index.ts
│ │ │ ├── update-user.handler.ts
│ │ │ └── welcome-user.handler.ts
│ │ └── impl
│ │ │ ├── create-user.command.ts
│ │ │ ├── delete-user.command.ts
│ │ │ ├── update-user.command.ts
│ │ │ └── welcome-user.command.ts
│ │ ├── controllers
│ │ ├── users.controller.spec.ts
│ │ └── users.controller.ts
│ │ ├── dtos
│ │ └── users.dto.ts
│ │ ├── events
│ │ ├── handlers
│ │ │ ├── index.ts
│ │ │ ├── user-created.handler.ts
│ │ │ ├── user-deleted.handler.ts
│ │ │ ├── user-updated.handler.ts
│ │ │ └── user-welcomed.handler.ts
│ │ └── impl
│ │ │ ├── user-created.event.ts
│ │ │ ├── user-deleted.event.ts
│ │ │ ├── user-updated.event.ts
│ │ │ └── user-welcomed.event.ts
│ │ ├── models
│ │ └── user.model.ts
│ │ ├── repository
│ │ └── user.repository.ts
│ │ ├── sagas
│ │ └── users.sagas.ts
│ │ ├── services
│ │ └── users.service.ts
│ │ └── users.module.ts
├── test
│ ├── app.e2e-spec.ts
│ └── jest-e2e.json
├── tsconfig.json
├── tsconfig.spec.json
├── tslint.json
└── yarn.lock
├── nodejs-express-typescript
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .prettierrc.json
├── LICENSE
├── Procfile
├── README.md
├── jest.config.js
├── nodemon.json
├── package-lock.json
├── package.json
├── src
│ ├── api
│ │ ├── index.ts
│ │ ├── middlewares
│ │ │ ├── index.ts
│ │ │ └── isAuth.ts
│ │ └── routes
│ │ │ └── auth.ts
│ ├── app.ts
│ ├── config
│ │ └── index.ts
│ ├── interfaces
│ │ └── IUser.ts
│ ├── loaders
│ │ ├── dependencyInjector.ts
│ │ ├── express.ts
│ │ ├── index.ts
│ │ ├── logger.ts
│ │ └── mongoose.ts
│ ├── models
│ │ └── user.ts
│ ├── services
│ │ └── auth.ts
│ └── types
│ │ └── express
│ │ └── index.d.ts
├── tests
│ ├── .gitkeep
│ ├── sample.test.ts
│ └── services
│ │ └── .gitkeep
└── tsconfig.json
├── nodejs-microservice-using-docker-Part-1
├── .DS_Store
├── .gitignore
├── .travis.yml
├── docker-compose.yml
├── nginx
│ ├── Dockerfile
│ └── nginx.conf
└── server
│ ├── .babelrc
│ ├── .editorconfig
│ ├── .env.example
│ ├── .gitignore
│ ├── .jshintrc
│ ├── .jshintrc-spec
│ ├── Dockerfile
│ ├── Procfile
│ ├── api
│ ├── service
│ │ ├── index.js
│ │ ├── index.spec.js
│ │ ├── service.controller.js
│ │ ├── service.events.js
│ │ ├── service.integration.js
│ │ ├── service.model.js
│ │ └── service.socket.js
│ └── utils.js
│ ├── app.js
│ ├── config
│ ├── .env
│ ├── app.conf.js
│ ├── db.conf.js
│ ├── routes.conf.js
│ └── socket.conf.js
│ ├── gulpfile.babel.js
│ ├── index.js
│ ├── mocha.conf.js
│ └── package.json
└── nodejs-microservice-using-docker-Part-2
├── .gitignore
├── docker-compose.yml
├── nginx
├── Dockerfile
├── Dockerfile_custom
└── nginx.conf
├── node
├── Dockerfile
├── index.js
├── package.json
└── test
│ └── dummyTest.js
└── redis
└── Dockerfile
/README.md:
--------------------------------------------------------------------------------
1 | # nodejs-microservces-patterns
2 | nodejs-microservces-patterns
3 |
4 | - Simple Microservices Demo
5 | - Simple Auth and Autnz setup
6 | - CQRS Pattern
7 | - Event Driven Design Pattern
8 |
9 | ### Different examples for understanding node js with microservoces Patterns
10 |
11 | #### https://www.youtube.com/watch?v=_pO0sDeQrp0&list=PLIGDNOJWiL182j1bD_nQm-SxARR5s977O&ab_channel=CodeLabs
12 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | docs
3 |
4 | node/node_modules
5 | .DS_Store
6 |
7 | node/npm-debug.log
8 | .DS_Store
9 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/Microservices_Architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/api-gateway-and-service-doscovery/Microservices_Architecture.png
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/ServicesSetup.sh:
--------------------------------------------------------------------------------
1 | cd service-login
2 | sudo npm install
3 |
4 | cd ..
5 | cd service-orders
6 | sudo npm install
7 |
8 | cd ..
9 | cd service-signup
10 | sudo npm install
11 |
12 | cd ..
13 | cd service-log
14 | sudo npm install
15 |
16 | cd ..
17 | cd api-gateway
18 | sudo npm install
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/ServicesStart.sh:
--------------------------------------------------------------------------------
1 | cd service-login
2 | DEBUG=http node server &
3 |
4 | cd ..
5 | cd service-orders
6 | DEBUG=http node server &
7 |
8 | cd ..
9 | cd service-signup
10 | DEBUG=http node server &
11 |
12 | cd ..
13 | cd service-log
14 | DEBUG=http node server &
15 |
16 | cd ..
17 | cd api-gateway
18 | DEBUG=http node server
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/api-gateway/Dockerbuild.sh:
--------------------------------------------------------------------------------
1 | docker build -t micro-node-service-api-gateway:latest .
2 | winpty docker run -it --rm -p 8080:8080 --name micro-node-service-api-gateway micro-node-service-api-gateway:latest
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/api-gateway/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:6.2.0-onbuild
2 | EXPOSE 8080
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/api-gateway/api/account/login.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 10/07/16.
3 | */
4 |
5 | var express = require('express'),
6 | router = express.Router(),
7 | apiGateway = require('../.././api-gateway');
8 |
9 | router.post('/', function (req, res,next) {
10 | var request = new apiGateway();
11 | request.sendRequest("ServiceLogin","login",req, res,next);
12 | });
13 |
14 | module.exports = router;
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/api-gateway/api/account/signup.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 10/07/16.
3 | */
4 |
5 | var express = require('express'),
6 | router = express.Router(),
7 | apiGateway = require('../.././api-gateway');
8 |
9 | router.post('/', function (req, res,next) {
10 | var request = new apiGateway();
11 | request.sendRequest("ServiceSignup","signup",req, res,next);
12 | });
13 |
14 | module.exports = router;
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/api-gateway/api/crm/orders/orders.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 10/07/16.
3 | */
4 |
5 | var express = require('express'),
6 | router = express.Router(),
7 | apiGateway = require('../../.././api-gateway');
8 |
9 | router.post('/', function (req, res,next) {
10 | var request = new apiGateway();
11 | request.sendRequest("ServiceOrders","orders",req, res,next);
12 | });
13 |
14 | module.exports = router;
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/api-gateway/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 25/05/16.
3 | */
4 |
5 | var fs = require('fs');
6 |
7 | function Config() {
8 | var config = JSON.parse(fs.readFileSync(__dirname + '/config.json'), 'utf8');
9 | return{
10 | server:{
11 | id:config.server.id,
12 | port:config.server.port,
13 | isCluster:config.server.isCluster,
14 | https:config.server.https,
15 | headers:config.server.headers,
16 | httpsKeyContent:config.server.https.key ? fs.readFileSync(__dirname + "/" + config.server.https.key) :null,
17 | httpsCaContent:config.server.https.ca ? fs.readFileSync(__dirname + "/" + config.server.https.ca) :null,
18 | },
19 | api:{
20 | route:config.api.route,
21 | modules:config.api.modules
22 | },
23 | services:config.services,
24 | serviceRegistry:config.serviceRegistry
25 | };
26 |
27 | }
28 | module.exports=Config;
29 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/api-gateway/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DoorApiGateway",
3 | "version": "0.0.1",
4 | "description": "Api Gateway",
5 | "author": {
6 | "name": "Domenico Vacchiano",
7 | "email": "domenico@doorgames.com",
8 | "url": "http://www.doorgames.com"
9 | },
10 | "homepage": "http://www.doorgames.com/",
11 | "repository": {
12 | "type": "git",
13 | "url": ""
14 | },
15 | "engines": {
16 | "node": ">= 0.6.0",
17 | "npm": ">= 1.0.0"
18 | },
19 | "dependencies": {
20 | "express": "^4.13.4",
21 | "body-parser": "^1.15.1",
22 | "jsonwebtoken": "^7.0.0",
23 | "request": "^2.72.0",
24 | "morgan": "^1.7.0",
25 | "micro-node-net-lib": "git@github.com:alchimya/micro-node-net-lib.git",
26 | "micro-node-service-registry-lib": "git@github.com:alchimya/micro-node-service-registry-lib.git"
27 | },
28 | "private": true,
29 | "scripts": {
30 | "start": "node server.js"
31 | },
32 | "main": "server.js"
33 | }
34 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/api-gateway/services-helper.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 11/07/16.
3 | */
4 |
5 | function ServiceHelper(services) {
6 | return{
7 | getServiceWithName:function (serviceName) {
8 | var service=services.filter(function( item ) {
9 | return item.name == serviceName;
10 | });
11 | if (!service || !service[0] || service[0].length==0){
12 | return null;
13 | }
14 | return service[0];
15 | },
16 | getService:function (serviceName,serviceEndpointId) {
17 | var service=services.filter(function( item ) {
18 | return (item.name == serviceName && item.endpointId == serviceEndpointId);
19 | });
20 | if (!service || !service[0] || service[0].length==0){
21 | return null;
22 | }
23 | return service[0];
24 | }
25 | };
26 | };
27 |
28 | module.exports=ServiceHelper;
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/micro-node-api-gateway.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/api-gateway-and-service-doscovery/micro-node-api-gateway.gif
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-log/Dockerbuild.sh:
--------------------------------------------------------------------------------
1 | docker build -t micro-node-service-log:latest .
2 | winpty docker run -it --rm -p 8084:8084 --name micro-node-service-log micro-node-service-log:latest
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-log/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:6.2.0-onbuild
2 | EXPOSE 8084
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-log/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 07/07/16.
3 | */
4 |
5 | var fs = require('fs');
6 |
7 | function Config() {
8 | var config = JSON.parse(fs.readFileSync(__dirname + '/config.json'), 'utf8');
9 | return{
10 | server:{
11 | id:config.server.id,
12 | port:config.server.port,
13 | isCluster:config.server.isCluster,
14 | https:config.server.https,
15 | headers:config.server.headers,
16 | httpsKeyContent:config.server.https.key ? fs.readFileSync(__dirname + "/" + config.server.https.key) :null,
17 | httpsCaContent:config.server.https.ca ? fs.readFileSync(__dirname + "/" + config.server.https.ca) :null,
18 | },
19 | api:{
20 | route:config.api.route,
21 | modules:config.api.modules
22 | },
23 | serviceRegistry:config.serviceRegistry
24 |
25 | };
26 |
27 | }
28 | module.exports=Config;
29 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-log/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "server":{
3 | "id":"ServiceLog",
4 | "port":8084,
5 | "isCluster":true,
6 | "https":{
7 | "isEnabled":false,
8 | "key":"",
9 | "ca":""
10 | },
11 | "headers":[
12 | {"name":"Access-Control-Allow-Origin","value":"*"},
13 | {"name":"Access-Control-Allow-Headers","value":"Origin, X-Requested-With, Content-Type, Accept"},
14 | {"name":"Access-Control-Allow-Methods","value":"GET,PUT,POST,DELETE,OPTIONS"}
15 | ]
16 | },
17 | "api":{
18 | "route":"api",
19 | "modules":[
20 | {"name":"log", "route":"log"}
21 | ]
22 | },
23 | "serviceRegistry":{
24 | "watchDog":{
25 | "isEnabled":false,
26 | "timer":30000
27 | },
28 | "database":{
29 | "name":"my_mongo_db",
30 | "user":"my_mongo_db_user",
31 | "password":"my_mongo_db_password",
32 | "host":"my_mongo_db_host",
33 | "port":27017
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-log/log.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 07/07/16.
3 | */
4 |
5 | var express = require('express'),
6 | router = express.Router(),
7 | debug = require('debug')('http'),
8 | config= require ('./config')()
9 |
10 | router.post('/', function (req, res,next) {
11 | return res.status(200).send("## Log -> This is just a test response ;-)");
12 | });
13 |
14 | module.exports = router;
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-log/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "MicroNodeService",
3 | "version": "0.0.1",
4 | "description": "Micro Node Tutorial",
5 | "author": {
6 | "name": "Domenico Vacchiano",
7 | "email": "info@domenicovacchiano.com",
8 | "url": "http://www.domenicovacchiano.com"
9 | },
10 | "homepage": "http://www.domenicovacchiano.com/",
11 | "repository": {
12 | "type": "git",
13 | "url": ""
14 | },
15 | "engines": {
16 | "node": ">= 0.6.0",
17 | "npm": ">= 1.0.0"
18 | },
19 | "dependencies": {
20 | "express": "^4.13.4",
21 | "body-parser": "^1.15.1",
22 | "request": "^2.72.0",
23 | "morgan": "^1.7.0",
24 | "network-address": "^1.1.0",
25 | "micro-node-net-lib": "git@github.com:alchimya/micro-node-net-lib.git",
26 | "micro-node-service-registry-lib": "git@github.com:alchimya/micro-node-service-registry-lib.git"
27 | },
28 | "private": true,
29 | "scripts": {
30 | "start": "node server.js"
31 | },
32 | "main": "server.js"
33 | }
34 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-login/Dockerbuild.sh:
--------------------------------------------------------------------------------
1 | docker build -t micro-node-service-login:latest .
2 | winpty docker run -it --rm -p 8081:8081 --name micro-node-service-login micro-node-service-login:latest
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-login/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:6.2.0-onbuild
2 | EXPOSE 8081
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-login/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 07/07/16.
3 | */
4 |
5 | var fs = require('fs');
6 |
7 | function Config() {
8 | var config = JSON.parse(fs.readFileSync(__dirname + '/config.json'), 'utf8');
9 | return{
10 | server:{
11 | id:config.server.id,
12 | port:config.server.port,
13 | isCluster:config.server.isCluster,
14 | https:config.server.https,
15 | headers:config.server.headers,
16 | httpsKeyContent:config.server.https.key ? fs.readFileSync(__dirname + "/" + config.server.https.key) :null,
17 | httpsCaContent:config.server.https.ca ? fs.readFileSync(__dirname + "/" + config.server.https.ca) :null,
18 | },
19 | api:{
20 | route:config.api.route,
21 | modules:config.api.modules
22 | },
23 | serviceRegistry:config.serviceRegistry
24 |
25 | };
26 |
27 | }
28 | module.exports=Config;
29 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-login/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "server":{
3 | "id":"ServiceLogin",
4 | "port":8081,
5 | "isCluster":true,
6 | "https":{
7 | "isEnabled":false,
8 | "key":"",
9 | "ca":""
10 | },
11 | "headers":[
12 | {"name":"Access-Control-Allow-Origin","value":"*"},
13 | {"name":"Access-Control-Allow-Headers","value":"Origin, X-Requested-With, Content-Type, Accept"},
14 | {"name":"Access-Control-Allow-Methods","value":"GET,PUT,POST,DELETE,OPTIONS"}
15 | ]
16 | },
17 | "api":{
18 | "route":"api",
19 | "modules":[
20 | {"name":"login", "route":"login"}
21 | ]
22 | },
23 | "serviceRegistry":{
24 | "watchDog":{
25 | "isEnabled":false,
26 | "timer":30000
27 | },
28 | "database":{
29 | "name":"my_mongo_db",
30 | "user":"my_mongo_db_user",
31 | "password":"my_mongo_db_password",
32 | "host":"my_mongo_db_host",
33 | "port":27017
34 | }
35 | }
36 | }
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-login/login.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 07/07/16.
3 | */
4 |
5 | var express = require('express'),
6 | router = express.Router(),
7 | debug = require('debug')('http'),
8 | config= require ('./config')()
9 |
10 | router.post('/', function (req, res,next) {
11 | return res.status(200).send("## Login -> This is just a test response ;-)");
12 | });
13 |
14 | module.exports = router;
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-login/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "MicroNodeService",
3 | "version": "0.0.1",
4 | "description": "Micro Node Tutorial",
5 | "author": {
6 | "name": "Domenico Vacchiano",
7 | "email": "info@domenicovacchiano.com",
8 | "url": "http://www.domenicovacchiano.com"
9 | },
10 | "homepage": "http://www.domenicovacchiano.com/",
11 | "repository": {
12 | "type": "git",
13 | "url": ""
14 | },
15 | "engines": {
16 | "node": ">= 0.6.0",
17 | "npm": ">= 1.0.0"
18 | },
19 | "dependencies": {
20 | "express": "^4.13.4",
21 | "body-parser": "^1.15.1",
22 | "request": "^2.72.0",
23 | "morgan": "^1.7.0",
24 | "network-address": "^1.1.0",
25 | "micro-node-net-lib": "git@github.com:alchimya/micro-node-net-lib.git",
26 | "micro-node-service-registry-lib": "git@github.com:alchimya/micro-node-service-registry-lib.git"
27 | },
28 | "private": true,
29 | "scripts": {
30 | "start": "node server.js"
31 | },
32 | "main": "server.js"
33 | }
34 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-orders/Dockerbuild.sh:
--------------------------------------------------------------------------------
1 | docker build -t micro-node-service-orders:latest .
2 | winpty docker run -it --rm -p 8083:8083 --name micro-node-service-orders micro-node-service-orders:latest
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-orders/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:6.2.0-onbuild
2 | EXPOSE 8083
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-orders/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 07/07/16.
3 | */
4 |
5 | var fs = require('fs');
6 |
7 | function Config() {
8 | var config = JSON.parse(fs.readFileSync(__dirname + '/config.json'), 'utf8');
9 | return{
10 | server:{
11 | id:config.server.id,
12 | port:config.server.port,
13 | isCluster:config.server.isCluster,
14 | https:config.server.https,
15 | headers:config.server.headers,
16 | httpsKeyContent:config.server.https.key ? fs.readFileSync(__dirname + "/" + config.server.https.key) :null,
17 | httpsCaContent:config.server.https.ca ? fs.readFileSync(__dirname + "/" + config.server.https.ca) :null,
18 | },
19 | api:{
20 | route:config.api.route,
21 | modules:config.api.modules
22 | },
23 | serviceRegistry:config.serviceRegistry
24 |
25 | };
26 |
27 | }
28 | module.exports=Config;
29 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-orders/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "server":{
3 | "id":"ServiceOrders",
4 | "port":8083,
5 | "isCluster":true,
6 | "https":{
7 | "isEnabled":false,
8 | "key":"",
9 | "ca":""
10 | },
11 | "headers":[
12 | {"name":"Access-Control-Allow-Origin","value":"*"},
13 | {"name":"Access-Control-Allow-Headers","value":"Origin, X-Requested-With, Content-Type, Accept"},
14 | {"name":"Access-Control-Allow-Methods","value":"GET,PUT,POST,DELETE,OPTIONS"}
15 | ]
16 | },
17 | "api":{
18 | "route":"api",
19 | "modules":[
20 | {"name":"orders", "route":"orders"}
21 | ]
22 | },
23 | "serviceRegistry":{
24 | "watchDog":{
25 | "isEnabled":false,
26 | "timer":30000
27 | },
28 | "database":{
29 | "name":"my_mongo_db",
30 | "user":"my_mongo_db_user",
31 | "password":"my_mongo_db_password",
32 | "host":"my_mongo_db_host",
33 | "port":27017
34 | }
35 | }
36 | }
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-orders/orders.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 07/07/16.
3 | */
4 |
5 | var express = require('express'),
6 | router = express.Router(),
7 | debug = require('debug')('http'),
8 | config= require ('./config')()
9 |
10 | router.post('/', function (req, res,next) {
11 | return res.status(200).send("## Orders -> This is just a test response ;-)");
12 | });
13 |
14 | module.exports = router;
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-orders/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "MicroNodeService",
3 | "version": "0.0.1",
4 | "description": "Micro Node Tutorial",
5 | "author": {
6 | "name": "Domenico Vacchiano",
7 | "email": "info@domenicovacchiano.com",
8 | "url": "http://www.domenicovacchiano.com"
9 | },
10 | "homepage": "http://www.domenicovacchiano.com/",
11 | "repository": {
12 | "type": "git",
13 | "url": ""
14 | },
15 | "engines": {
16 | "node": ">= 0.6.0",
17 | "npm": ">= 1.0.0"
18 | },
19 | "dependencies": {
20 | "express": "^4.13.4",
21 | "body-parser": "^1.15.1",
22 | "request": "^2.72.0",
23 | "morgan": "^1.7.0",
24 | "network-address": "^1.1.0",
25 | "micro-node-net-lib": "git@github.com:alchimya/micro-node-net-lib.git",
26 | "micro-node-service-registry-lib": "git@github.com:alchimya/micro-node-service-registry-lib.git"
27 | },
28 | "private": true,
29 | "scripts": {
30 | "start": "node server.js"
31 | },
32 | "main": "server.js"
33 | }
34 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-signup/Dockerbuild.sh:
--------------------------------------------------------------------------------
1 | docker build -t micro-node-service-signup:latest .
2 | winpty docker run -it --rm -p 8082:8082 --name micro-node-service-signup micro-node-service-signup:latest
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-signup/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:6.2.0-onbuild
2 | EXPOSE 8082
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-signup/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 07/07/16.
3 | */
4 |
5 | var fs = require('fs');
6 |
7 | function Config() {
8 | var config = JSON.parse(fs.readFileSync(__dirname + '/config.json'), 'utf8');
9 | return{
10 | server:{
11 | id:config.server.id,
12 | port:config.server.port,
13 | isCluster:config.server.isCluster,
14 | https:config.server.https,
15 | headers:config.server.headers,
16 | httpsKeyContent:config.server.https.key ? fs.readFileSync(__dirname + "/" + config.server.https.key) :null,
17 | httpsCaContent:config.server.https.ca ? fs.readFileSync(__dirname + "/" + config.server.https.ca) :null,
18 | },
19 | api:{
20 | route:config.api.route,
21 | modules:config.api.modules
22 | },
23 | serviceRegistry:config.serviceRegistry
24 |
25 | };
26 |
27 | }
28 | module.exports=Config;
29 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-signup/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "server":{
3 | "id":"ServiceSignup",
4 | "port":8082,
5 | "isCluster":true,
6 | "https":{
7 | "isEnabled":false,
8 | "key":"",
9 | "ca":""
10 | },
11 | "headers":[
12 | {"name":"Access-Control-Allow-Origin","value":"*"},
13 | {"name":"Access-Control-Allow-Headers","value":"Origin, X-Requested-With, Content-Type, Accept"},
14 | {"name":"Access-Control-Allow-Methods","value":"GET,PUT,POST,DELETE,OPTIONS"}
15 | ]
16 | },
17 | "api":{
18 | "route":"api",
19 | "modules":[
20 | {"name":"signup", "route":"signup"}
21 | ]
22 | },
23 | "serviceRegistry":{
24 | "watchDog":{
25 | "isEnabled":false,
26 | "timer":30000
27 | },
28 | "database":{
29 | "name":"my_mongo_db",
30 | "user":"my_mongo_db_user",
31 | "password":"my_mongo_db_password",
32 | "host":"my_mongo_db_host",
33 | "port":27017
34 | }
35 | }
36 | }
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-signup/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "MicroNodeService",
3 | "version": "0.0.1",
4 | "description": "Micro Node Tutorial",
5 | "author": {
6 | "name": "Domenico Vacchiano",
7 | "email": "info@domenicovacchiano.com",
8 | "url": "http://www.domenicovacchiano.com"
9 | },
10 | "homepage": "http://www.domenicovacchiano.com/",
11 | "repository": {
12 | "type": "git",
13 | "url": ""
14 | },
15 | "engines": {
16 | "node": ">= 0.6.0",
17 | "npm": ">= 1.0.0"
18 | },
19 | "dependencies": {
20 | "express": "^4.13.4",
21 | "body-parser": "^1.15.1",
22 | "request": "^2.72.0",
23 | "morgan": "^1.7.0",
24 | "network-address": "^1.1.0",
25 | "micro-node-net-lib": "git@github.com:alchimya/micro-node-net-lib.git",
26 | "micro-node-service-registry-lib": "git@github.com:alchimya/micro-node-service-registry-lib.git"
27 | },
28 | "private": true,
29 | "scripts": {
30 | "start": "node server.js"
31 | },
32 | "main": "server.js"
33 | }
34 |
--------------------------------------------------------------------------------
/api-gateway-and-service-doscovery/service-signup/signup.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by domenicovacchiano on 07/07/16.
3 | */
4 |
5 | var express = require('express'),
6 | router = express.Router(),
7 | debug = require('debug')('http'),
8 | config= require ('./config')()
9 |
10 | router.post('/', function (req, res,next) {
11 | return res.status(200).send("## Signup -> This is just a test response ;-)");
12 | });
13 |
14 | module.exports = router;
--------------------------------------------------------------------------------
/dockerized-containers/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "extends": "airbnb-base",
3 | "rules": {
4 | "comma-dangle": 0,
5 | "no-console": 0,
6 | "no-unused-vars" :0
7 | }
8 | };
--------------------------------------------------------------------------------
/dockerized-containers/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | sudo: false
3 | node_js:
4 | - 10
5 | install:
6 | - npm install
7 | script:
8 | - npm test
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:carbon
2 |
3 | # Create app directory
4 | WORKDIR /usr/src/app
5 |
6 | # Bundle app source
7 | COPY . .
8 |
9 | # npm install
10 | RUN npm install
11 | # Run npm install --global grpc --unsafe-perm
12 |
13 | EXPOSE 3002 9202
14 | CMD [ "npm", "run", "watchserver" ]
15 | CMD [ "npm", "run", "startdev" ]
16 |
17 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/app/config/email.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | export default {
4 |
5 | global: {
6 | from: 'info@kpilibrary.com',
7 | },
8 | welcome: {
9 | subject: 'Welcome to KPI Library',
10 | },
11 | password_reset: {
12 | subject: 'KPI Library: Reset your password',
13 | },
14 | event_booked_guest: {
15 | subject: 'KPI Library: Your Booking Has Been Confirmed',
16 | },
17 | event_booked_host: {
18 | subject: 'KPI Library: Your Event Has Been Booked',
19 | },
20 | event_booked_guests_notification: {
21 | subject: 'KPI Library: Your Booking Has Been Confirmed',
22 | },
23 | message_received: {
24 | subject: 'KPI Library: New Message Received',
25 | },
26 | guest_review_email: {
27 | subject: 'KPI Library: Event Completed',
28 | },
29 | alacarte_booked_guest: {
30 | subject: 'KPI Library: Alacarte Booking Details',
31 | },
32 | alacarte_booked_host: {
33 | subject: 'KPI Library: Your Alacarte Has Been Booked',
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/app/events/notification.ts:
--------------------------------------------------------------------------------
1 |
2 | import Email from '../helper/email';
3 | declare function require(name: string);
4 |
5 | const events = require('events');
6 | const winston = require('winston');
7 | // import Twillo from '../helper/twillo';
8 |
9 | const eventEmitter = new events.EventEmitter();
10 | eventEmitter.on('welcome', (user) => {
11 | winston.log('info', `sending welcome email to ${user.email}`);
12 | // Twillo.default_notification(user.phone, 'welcome')
13 | Email.welcome(user);
14 | });
15 | eventEmitter.on('forgotPassword', (user, password, uuid) => {
16 | winston.log('info', `sending forgotPassword email to ${user.email}`);
17 | Email.password_reset(user, password);
18 | // Twillo.default_notification(user.phone, 'welcome')
19 | });
20 |
21 | export default eventEmitter;
22 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/app/global/templates/emails/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Admin/app/global/templates/emails/assets/images/logo.png
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/app/helper/logger.ts:
--------------------------------------------------------------------------------
1 | const winston = require('winston');
2 |
3 | // define the custom settings for each transport (file, console)
4 | const options = {
5 | console: {
6 | level: 'info',
7 | handleExceptions: true,
8 | json: true,
9 | colorize: true,
10 | prettyPrint: true,
11 | humanReadableUnhandledException: true
12 | }
13 | };
14 | const logger = new winston.Logger({
15 | transports: [
16 | // new winston.transports.File(options.file),
17 | new winston
18 | .transports
19 | .Console(options.console),
20 | ],
21 | exceptionHandlers: [
22 | // new winston.transports.File(options.errorLog)
23 | ],
24 | exitOnError: false, // do not exit on handled exceptions
25 | });
26 |
27 | // create a stream object with a 'write' function that will be used by `morgan`
28 | logger.stream = {
29 | write(message, encoding) {
30 | logger.info(message);
31 | }
32 | };
33 | export default logger;
34 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/app/lib/requestValidator.ts:
--------------------------------------------------------------------------------
1 | const Joi = require('joi');
2 |
3 | const validation = {
4 | loginUser : {
5 | body : {
6 | email: Joi.string().regex(/^[\w.]+@[\w]+?(\.[a-zA-Z]{2,3}){1,3}$/).required(),
7 | password: Joi.string().min(8).max(50).required()
8 | }
9 | },
10 | createUser: {
11 | body: {
12 | username: Joi.string().min(4).max(50).required(),
13 | password: Joi.string().min(8).max(50).required(),
14 | email: Joi.string().regex(/^[\w.]+@[\w]+?(\.[a-zA-Z]{2,3}){1,3}$/).required(),
15 | verify_password: Joi.string().min(6).max(50).required()
16 | },
17 | },
18 | resetPassword: {
19 | body: {
20 | email: Joi.string().regex(/^[\w.]+@[\w]+?(\.[a-zA-Z]{2,3}){1,3}$/).required(),
21 | }
22 | }
23 | };
24 | export default validation
25 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/app/middleware/requestValidator.ts:
--------------------------------------------------------------------------------
1 |
2 | module.exports = {
3 | validatePayload(req, res, next) {
4 | // validatr token here is its valid here
5 | const token = req.body;
6 | if ((req.method === 'POST' || req.method === 'PUT') && req.body !== null) {
7 | next();
8 | }
9 | res.status(403).json({ message: 'payload is required for HTTP Post & Put ' });
10 | }
11 | };
12 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/app/models/plugin/plugin.ts:
--------------------------------------------------------------------------------
1 | const datePlugin = function timestamp(schema) {
2 | // Add the two fields to the schema
3 | schema.add({
4 | createdAt: Date,
5 | updatedAt: Date
6 | })
7 |
8 | // Create a pre-save hook
9 | schema.pre('save', function (next) {
10 | let now = Date.now()
11 |
12 |
13 | this.updatedAt = now
14 | // Set a value for createdAt only if it is null
15 | if (!this.createdAt) {
16 | this.createdAt = now
17 | }
18 | // Call the next function in the pre-save chain
19 | next()
20 | })
21 | }
22 |
23 | export default datePlugin;
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/app/routes.ts:
--------------------------------------------------------------------------------
1 | /* eslint func-names: ["error", "never"] */
2 | /* eslint prefer-destructuring: 0 */
3 | import * as express from 'express';
4 | const expressRouter= express.Router();
5 | import authRoutes from './routes/routes';
6 | import userRoutes from './routes/userRoutes';
7 | import defaultRoutes from './routes/defaultRoutes';
8 | import validAuthTokenMiddleware from './middleware/authMiddleware';
9 | expressRouter.use('/', defaultRoutes);
10 | expressRouter.use('/uploads/', express.static('uploads'));
11 | expressRouter.use('/auth', authRoutes);
12 | expressRouter.use('/user',validAuthTokenMiddleware.validateToken, userRoutes);
13 |
14 |
15 |
16 | export default expressRouter;
17 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/app/types/global.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace NodeJS {
2 | export interface Global {
3 | configuration: any
4 | }
5 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/app/types/vendor.d.ts:
--------------------------------------------------------------------------------
1 |
2 | declare namespace NodeJS {
3 | export interface Global {
4 | configuration: any
5 | }
6 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/public/images/cinema.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Admin/public/images/cinema.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/public/javascripts/script.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('DOMContentLoaded', () => {
2 |
3 | console.log('IronGenerator JS imported successfully!');
4 |
5 | }, false);
6 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/public/style.scss:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
9 |
10 | .h1 {
11 | font-size: 40px;
12 | }
13 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "moduleResolution": "node",
5 | "pretty": true,
6 | "sourceMap": true,
7 | "target": "es6",
8 | "outDir": "./dist",
9 | "experimentalDecorators": false,
10 | "emitDecoratorMetadata": false,
11 | "skipDefaultLibCheck": false,
12 | "baseUrl": "./lib"
13 | },
14 | "files" : [
15 | "./app/types/vendor.d.ts"
16 | ],
17 | "include": [
18 | "/**/*.ts"
19 | ],
20 | "exclude": [
21 | "node_modules"
22 | ]
23 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/tslint.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Admin/tslint.json
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/uploads/documents/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Admin/uploads/documents/.gitkeep
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Admin/uploads/profile/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Admin/uploads/profile/.gitkeep
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:carbon
2 |
3 | # Create app directory
4 | WORKDIR /usr/src/app
5 |
6 | # Bundle app source
7 | COPY . .
8 |
9 | # npm install
10 | RUN npm install
11 |
12 | EXPOSE 3001 9201
13 | CMD [ "npm", "run", "watchserver" ]
14 | CMD [ "npm", "run", "startdev" ]
15 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/app/config/email.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | export default {
4 |
5 | global: {
6 | from: 'info@kpilibrary.com',
7 | },
8 | welcome: {
9 | subject: 'Welcome to KPI Library',
10 | },
11 | password_reset: {
12 | subject: 'KPI Library: Reset your password',
13 | },
14 | event_booked_guest: {
15 | subject: 'KPI Library: Your Booking Has Been Confirmed',
16 | },
17 | event_booked_host: {
18 | subject: 'KPI Library: Your Event Has Been Booked',
19 | },
20 | event_booked_guests_notification: {
21 | subject: 'KPI Library: Your Booking Has Been Confirmed',
22 | },
23 | message_received: {
24 | subject: 'KPI Library: New Message Received',
25 | },
26 | guest_review_email: {
27 | subject: 'KPI Library: Event Completed',
28 | },
29 | alacarte_booked_guest: {
30 | subject: 'KPI Library: Alacarte Booking Details',
31 | },
32 | alacarte_booked_host: {
33 | subject: 'KPI Library: Your Alacarte Has Been Booked',
34 | }
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/app/events/notification.ts:
--------------------------------------------------------------------------------
1 |
2 | import Email from '../helper/email';
3 | declare function require(name: string);
4 |
5 | const events = require('events');
6 | const winston = require('winston');
7 | // import Twillo from '../helper/twillo';
8 |
9 | const eventEmitter = new events.EventEmitter();
10 | eventEmitter.on('welcome', (user) => {
11 | winston.log('info', `sending welcome email to ${user.email}`);
12 | // Twillo.default_notification(user.phone, 'welcome')
13 | Email.welcome(user);
14 | });
15 | eventEmitter.on('forgotPassword', (user, password, uuid) => {
16 | winston.log('info', `sending forgotPassword email to ${user.email}`);
17 | Email.password_reset(user, password);
18 | // Twillo.default_notification(user.phone, 'welcome')
19 | });
20 |
21 | export default eventEmitter;
22 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/app/global/templates/emails/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Auth/app/global/templates/emails/assets/images/logo.png
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/app/helper/logger.ts:
--------------------------------------------------------------------------------
1 | const winston = require('winston');
2 |
3 | // define the custom settings for each transport (file, console)
4 | const options = {
5 | console: {
6 | level: 'info',
7 | handleExceptions: true,
8 | json: true,
9 | colorize: true,
10 | prettyPrint: true,
11 | humanReadableUnhandledException: true
12 | }
13 | };
14 | const logger = new winston.Logger({
15 | transports: [
16 | // new winston.transports.File(options.file),
17 | new winston
18 | .transports
19 | .Console(options.console),
20 | ],
21 | exceptionHandlers: [
22 | // new winston.transports.File(options.errorLog)
23 | ],
24 | exitOnError: false, // do not exit on handled exceptions
25 | });
26 |
27 | // create a stream object with a 'write' function that will be used by `morgan`
28 | logger.stream = {
29 | write(message, encoding) {
30 | logger.info(message);
31 | }
32 | };
33 | export default logger;
34 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/app/lib/requestValidator.ts:
--------------------------------------------------------------------------------
1 | const Joi = require('joi');
2 |
3 | const validation = {
4 | loginUser : {
5 | body : {
6 | email: Joi.string().regex(/^[\w.]+@[\w]+?(\.[a-zA-Z]{2,3}){1,3}$/).required(),
7 | password: Joi.string().min(8).max(50).required()
8 | }
9 | },
10 | createUser: {
11 | body: {
12 | username: Joi.string().min(4).max(50).required(),
13 | password: Joi.string().min(8).max(50).required(),
14 | email: Joi.string().regex(/^[\w.]+@[\w]+?(\.[a-zA-Z]{2,3}){1,3}$/).required(),
15 | verify_password: Joi.string().min(6).max(50).required()
16 | },
17 | },
18 | resetPassword: {
19 | body: {
20 | email: Joi.string().regex(/^[\w.]+@[\w]+?(\.[a-zA-Z]{2,3}){1,3}$/).required(),
21 | }
22 | }
23 | };
24 | export default validation
25 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/app/middleware/requestValidator.ts:
--------------------------------------------------------------------------------
1 |
2 | module.exports = {
3 | validatePayload(req, res, next) {
4 | // validatr token here is its valid here
5 | const token = req.body;
6 | if ((req.method === 'POST' || req.method === 'PUT') && req.body !== null) {
7 | next();
8 | }
9 | res.status(403).json({ message: 'payload is required for HTTP Post & Put ' });
10 | }
11 | };
12 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/app/models/plugin/plugin.ts:
--------------------------------------------------------------------------------
1 | const datePlugin = function timestamp(schema) {
2 | // Add the two fields to the schema
3 | schema.add({
4 | createdAt: Date,
5 | updatedAt: Date
6 | })
7 |
8 | // Create a pre-save hook
9 | schema.pre('save', function (next) {
10 | let now = Date.now()
11 |
12 |
13 | this.updatedAt = now
14 | // Set a value for createdAt only if it is null
15 | if (!this.createdAt) {
16 | this.createdAt = now
17 | }
18 | // Call the next function in the pre-save chain
19 | next()
20 | })
21 | }
22 |
23 | export default datePlugin;
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/app/routes.ts:
--------------------------------------------------------------------------------
1 | /* eslint func-names: ["error", "never"] */
2 | /* eslint prefer-destructuring: 0 */
3 | import * as express from 'express';
4 | const expressRouter= express.Router();
5 | import authRoutes from './routes/routes';
6 | import userRoutes from './routes/userRoutes';
7 | import defaultRoutes from './routes/defaultRoutes';
8 | import validAuthTokenMiddleware from './middleware/authMiddleware';
9 | expressRouter.use('/', defaultRoutes);
10 | expressRouter.use('/uploads/', express.static('uploads'));
11 | expressRouter.use('/auth', authRoutes);
12 | expressRouter.use('/user',validAuthTokenMiddleware.validateToken, userRoutes);
13 |
14 |
15 |
16 | export default expressRouter;
17 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/app/types/global.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace NodeJS {
2 | export interface Global {
3 | configuration: any
4 | }
5 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/app/types/vendor.d.ts:
--------------------------------------------------------------------------------
1 |
2 | declare namespace NodeJS {
3 | export interface Global {
4 | configuration: any
5 | }
6 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/public/images/cinema.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Auth/public/images/cinema.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/public/javascripts/script.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('DOMContentLoaded', () => {
2 |
3 | console.log('IronGenerator JS imported successfully!');
4 |
5 | }, false);
6 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/public/style.scss:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
9 |
10 | .h1 {
11 | font-size: 40px;
12 | }
13 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "moduleResolution": "node",
5 | "pretty": true,
6 | "sourceMap": true,
7 | "target": "es6",
8 | "outDir": "./dist",
9 | "experimentalDecorators": false,
10 | "emitDecoratorMetadata": false,
11 | "skipDefaultLibCheck": false,
12 | "baseUrl": "./lib"
13 | },
14 | "files" : [
15 | "./app/types/vendor.d.ts"
16 | ],
17 | "include": [
18 | "/**/*.ts"
19 | ],
20 | "exclude": [
21 | "node_modules"
22 | ]
23 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/tslint.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Auth/tslint.json
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/uploads/documents/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Auth/uploads/documents/.gitkeep
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Auth/uploads/profile/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Auth/uploads/profile/.gitkeep
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/.sequelizerc:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | 'config': path.resolve('config', 'config.js')
5 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:carbon
2 |
3 | # Create app directory
4 | WORKDIR /usr/src/app
5 |
6 | # Bundle app source
7 | COPY . .
8 |
9 | # npm install
10 | RUN npm install
11 | # Run npm install --global grpc --unsafe-perm
12 |
13 | EXPOSE 3004 9204
14 | CMD [ "npm", "run", "watchserver" ]
15 | CMD [ "npm", "run", "startdev" ]
16 |
17 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/app/events/processEvent.ts:
--------------------------------------------------------------------------------
1 | const events = require('events');
2 |
3 | const eventEmitter = new events.EventEmitter();
4 |
5 | export default eventEmitter;
6 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/app/helper/errors.ts:
--------------------------------------------------------------------------------
1 | class APIError extends Error {
2 | constructor(message, ErrorID, code = null) {
3 | super();
4 | Error.captureStackTrace(this, this.constructor);
5 | this.name = 'api error';
6 | this.message = message;
7 | if (ErrorID) this['ErrorID'] = ErrorID;
8 | if (code) this['code'] = code;
9 | }
10 | }
11 | export default APIError;
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/app/helper/logger.ts:
--------------------------------------------------------------------------------
1 | const log = require('loglevel');
2 |
3 | log.setLevel(global.configuration.logLevel);
4 | const logger = log;
5 | export default logger;
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/app/lib/logger.ts:
--------------------------------------------------------------------------------
1 | const log = require('loglevel');
2 |
3 | log.setLevel(global.configuration.logLevel);
4 | const logger = log;
5 | export default logger;
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/app/lib/requestValidator.ts:
--------------------------------------------------------------------------------
1 | const Joi = require('joi');
2 |
3 | const validation = {
4 | loginUser : {
5 | body : {
6 | email: Joi.string().regex(/^[\w.]+@[\w]+?(\.[a-zA-Z]{2,3}){1,3}$/).required(),
7 | password: Joi.string().min(8).max(50).required()
8 | }
9 | },
10 | createUser: {
11 | body: {
12 | username: Joi.string().min(4).max(50).required(),
13 | password: Joi.string().min(8).max(50).required(),
14 | email: Joi.string().regex(/^[\w.]+@[\w]+?(\.[a-zA-Z]{2,3}){1,3}$/).required(),
15 | verify_password: Joi.string().min(6).max(50).required()
16 | },
17 | },
18 | resetPassword: {
19 | body: {
20 | email: Joi.string().regex(/^[\w.]+@[\w]+?(\.[a-zA-Z]{2,3}){1,3}$/).required(),
21 | }
22 | }
23 | };
24 | export default validation
25 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/app/middleware/requestValidator.ts:
--------------------------------------------------------------------------------
1 |
2 | module.exports = {
3 | validatePayload(req, res, next) {
4 | // validatr token here is its valid here
5 | const token = req.body;
6 | if ((req.method === 'POST' || req.method === 'PUT') && req.body !== null) {
7 | next();
8 | }
9 | res.status(403).json({ message: 'payload is required for HTTP Post & Put ' });
10 | }
11 | };
12 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/app/routes.ts:
--------------------------------------------------------------------------------
1 | /* eslint func-names: ["error", "never"] */
2 | /* eslint prefer-destructuring: 0 */
3 | import * as express from 'express';
4 | const expressRouter= express.Router();
5 | import defaultRoutes from './routes/defaultRoutes';
6 | expressRouter.use('/', defaultRoutes);
7 |
8 |
9 |
10 | export default expressRouter;
11 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/app/types/global.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace NodeJS {
2 | export interface Global {
3 | configuration: any
4 | }
5 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/app/types/vendor.d.ts:
--------------------------------------------------------------------------------
1 |
2 | declare namespace NodeJS {
3 | export interface Global {
4 | configuration: any
5 | }
6 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/env.sh:
--------------------------------------------------------------------------------
1 | # this environment vairables needs to be set in .env file in applciaiton root directory
2 | # copy this file as .env and add the appropriate values as per environment.
3 | # node & mysql
4 | export NODE_ENV="dev"
5 | export PORT="3004"
6 | export USERNAME="root"
7 | export PASSWORD="root"
8 | export DATABASE="cartDB"
9 | export HOST="mysql"
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/public/images/cinema.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Cart/public/images/cinema.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/public/javascripts/script.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('DOMContentLoaded', () => {
2 |
3 | console.log('IronGenerator JS imported successfully!');
4 |
5 | }, false);
6 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/public/style.scss:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
9 |
10 | .h1 {
11 | font-size: 40px;
12 | }
13 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "moduleResolution": "node",
5 | "pretty": true,
6 | "sourceMap": true,
7 | "target": "es6",
8 | "outDir": "./dist",
9 | "experimentalDecorators": false,
10 | "emitDecoratorMetadata": false,
11 | "skipDefaultLibCheck": false,
12 | "baseUrl": "./lib"
13 | },
14 | "files" : [
15 | "./app/types/vendor.d.ts"
16 | ],
17 | "include": [
18 | "/**/*.ts"
19 | ],
20 | "exclude": [
21 | "node_modules"
22 | ]
23 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/tslint.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Cart/tslint.json
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/uploads/documents/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Cart/uploads/documents/.gitkeep
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Cart/uploads/profile/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Cart/uploads/profile/.gitkeep
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:carbon
2 |
3 | # Create app directory
4 | WORKDIR /usr/src/app
5 |
6 | # Bundle app source
7 | COPY . .
8 |
9 | # npm install
10 | RUN npm install
11 | # Run npm install --global grpc --unsafe-perm
12 |
13 | EXPOSE 3003
14 |
15 | CMD [ "npm", "run", "start" ]
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/env.sh:
--------------------------------------------------------------------------------
1 | # this environment vairables needs to be set in .env file in applciaiton root directory
2 | # copy this file as .env and add the appropriate values as per environment.
3 | # node & mysql
4 | export NODE_ENV="local"
5 | export PORT="3003"
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": {
3 | "public": "build",
4 | "ignore": [
5 | "firebase.json",
6 | "**/.*",
7 | "**/node_modules/**"
8 | ]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/public/favicon.ico
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/api/index.js:
--------------------------------------------------------------------------------
1 | import config from '../config/server';
2 | import axios from 'axios';
3 |
4 | export function url(resource) {
5 | if (!resource) {
6 | return `${config.url}`
7 | }
8 | console.log(`${config.url}${config[resource]}`);
9 | return `${config.url}${config[resource]}`
10 | }
11 | export function setAuthToken(token) {
12 | if (token) {
13 | axios.defaults.headers.common['authorization'] = `${token}`;
14 | } else {
15 | delete axios.defaults.headers.common['authorization'];
16 | }
17 | }
18 | export function setGeoLocation(location) {
19 | if (location) {
20 | axios.defaults.headers.common['Location'] = `${location.lng},${location.lat}`;
21 | } else {
22 | delete axios.defaults.headers.common['Location'];
23 | }
24 | }
25 | export function getAuthToken() {
26 | return localStorage.token;
27 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/components/App/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | import Shelf from '../Shelf';
4 | import Filter from '../Shelf/Filter';
5 | import FloatCart from '../FloatCart';
6 |
7 | class App extends Component {
8 | render() {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 | }
19 | }
20 |
21 | export default App;
22 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/components/Selectbox/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | class Selectbox extends Component {
5 | static propTypes = {
6 | options: PropTypes.array.isRequired,
7 | classes: PropTypes.string,
8 | handleOnChange: PropTypes.func.isRequired
9 | };
10 |
11 | state = {
12 | selected: ''
13 | };
14 |
15 | createOptions = options =>
16 | options.map(o => (
17 |
20 | ));
21 |
22 | onChange = e => {
23 | this.props.handleOnChange(e.target.value);
24 | };
25 |
26 | render() {
27 | const { classes, options } = this.props;
28 |
29 | return (
30 |
33 | );
34 | }
35 | }
36 |
37 | export default Selectbox;
38 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/components/Shelf/ProductList/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import Product from './Product';
4 |
5 | const ProductList = ({ products }) => {
6 | return products.map(p => {
7 | return ;
8 | });
9 | };
10 |
11 | export default ProductList;
12 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/components/Shelf/ShelfHeader/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | import Sort from '../Sort';
5 |
6 | const ShelfHeader = props => {
7 | return (
8 |
9 |
10 | {props.productsLength} Product(s) found.
11 |
12 |
13 |
14 | );
15 | };
16 |
17 | ShelfHeader.propTypes = {
18 | productsLength: PropTypes.number.isRequired
19 | };
20 |
21 | export default ShelfHeader;
22 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/components/Spinner/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import './style.scss';
4 |
5 | export default () => (
6 |
12 | );
13 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/components/Thumb/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | const Thumb = props => {
5 | return (
6 |
7 |

8 |
9 | );
10 | };
11 |
12 | Thumb.propTypes = {
13 | alt: PropTypes.string,
14 | title: PropTypes.string,
15 | classes: PropTypes.string,
16 | src: PropTypes.string.isRequired
17 | };
18 |
19 | export default Thumb;
20 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/config/index.js:
--------------------------------------------------------------------------------
1 | import server from '../config/server';
2 |
3 | export default {
4 | // server: server
5 |
6 | social: {
7 | facebook: server.url + 'auth/login/facebook',
8 | google: server.url + 'auth/login/google',
9 | twitter: server.url + 'auth/login/twitter',
10 | instagram: server.url + 'auth/login/instagram',
11 | },
12 |
13 | google: {
14 | api_key: '***',
15 | },
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/config/server.js:
--------------------------------------------------------------------------------
1 | export default {
2 | url: 'http://ms-commerce.com/api/v1/',
3 | register: 'auth/register',
4 | login: 'auth/login',
5 | validate_auth: 'auth/validate',
6 | reset_password: 'auth/reset-password',
7 | userfetch : 'user/fetch',
8 | users: 'users',
9 | user : 'user',
10 | changeRrole: 'user/change-role'
11 | }
12 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/layout/Auth.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | let AuthLayout = (props) => {
3 |
4 | let backgroundChoices = ['bg1', 'bg4', 'bg3', 'bg4', 'bg5'];
5 |
6 | let background_image;
7 | delete localStorage.auth_background;
8 | if (!localStorage.auth_background) {
9 | background_image = backgroundChoices[Math.floor(Math.random() * backgroundChoices.length)];
10 | localStorage.auth_background = background_image;
11 | } else {
12 | background_image = localStorage.auth_background;
13 | }
14 |
15 | return (
16 |
17 | {props.children}
18 |
19 | )
20 |
21 | }
22 |
23 | export default AuthLayout;
24 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/auth/auth.scss:
--------------------------------------------------------------------------------
1 | .errorMessage {
2 | color: #b83636
3 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/cart/actionTypes.js:
--------------------------------------------------------------------------------
1 | export const LOAD_CART = 'LOAD_CART';
2 | export const ADD_PRODUCT = 'ADD_PRODUCT';
3 | export const REMOVE_PRODUCT = 'REMOVE_PRODUCT';
4 | export const UPDATE_CART = 'UPDATE_CART';
5 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/cart/actions.js:
--------------------------------------------------------------------------------
1 | import { LOAD_CART, ADD_PRODUCT, REMOVE_PRODUCT } from './actionTypes';
2 |
3 | export const loadCart = products => ({
4 | type: LOAD_CART,
5 | payload: products
6 | });
7 |
8 | export const addProduct = product => ({
9 | type: ADD_PRODUCT,
10 | payload: product
11 | });
12 |
13 | export const removeProduct = product => ({
14 | type: REMOVE_PRODUCT,
15 | payload: product
16 | });
17 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/cart/reducer.js:
--------------------------------------------------------------------------------
1 | import { LOAD_CART, ADD_PRODUCT, REMOVE_PRODUCT } from './actionTypes';
2 |
3 | const initialState = {
4 | products: []
5 | };
6 |
7 | export default function(state = initialState, action) {
8 | switch (action.type) {
9 | case LOAD_CART:
10 | return {
11 | ...state,
12 | products: action.payload
13 | };
14 | case ADD_PRODUCT:
15 | return {
16 | ...state,
17 | productToAdd: Object.assign({}, action.payload)
18 | };
19 | case REMOVE_PRODUCT:
20 | return {
21 | ...state,
22 | productToRemove: Object.assign({}, action.payload)
23 | };
24 | default:
25 | return state;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/filters/actionTypes.js:
--------------------------------------------------------------------------------
1 | export const UPDATE_FILTER = 'UPDATE_FILTER';
2 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/filters/actions.js:
--------------------------------------------------------------------------------
1 | import { UPDATE_FILTER } from './actionTypes';
2 |
3 | export const updateFilters = filters => ({
4 | type: UPDATE_FILTER,
5 | payload: filters
6 | });
7 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/filters/reducer.js:
--------------------------------------------------------------------------------
1 | import { UPDATE_FILTER } from './actionTypes';
2 |
3 | const initialState = {
4 | item: []
5 | };
6 |
7 | export default function(state = initialState, action) {
8 | switch (action.type) {
9 | case UPDATE_FILTER:
10 | return {
11 | ...state,
12 | items: action.payload
13 | };
14 | default:
15 | return state;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/reducers.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux';
2 | import shelfReducer from './shelf/reducer';
3 | import cartReducer from './cart/reducer';
4 | import totalReducer from './total/reducer';
5 | import filtersReducer from './filters/reducer';
6 | import sortReducer from './sort/reducer';
7 | import authReducer from './auth/reducer';
8 |
9 |
10 | export default combineReducers({
11 | shelf: shelfReducer,
12 | cart: cartReducer,
13 | total: totalReducer,
14 | filters: filtersReducer,
15 | sort: sortReducer,
16 | auth:authReducer
17 | });
18 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/shelf/actionTypes.js:
--------------------------------------------------------------------------------
1 | export const FETCH_PRODUCTS = 'FETCH_PRODUCTS';
2 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/shelf/reducer.js:
--------------------------------------------------------------------------------
1 | import { FETCH_PRODUCTS } from './actionTypes';
2 |
3 | const initialState = {
4 | products: []
5 | };
6 |
7 | export default function(state = initialState, action) {
8 | switch (action.type) {
9 | case FETCH_PRODUCTS:
10 | return {
11 | ...state,
12 | products: action.payload
13 | };
14 | default:
15 | return state;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/sort/actionTypes.js:
--------------------------------------------------------------------------------
1 | export const UPDATE_SORT = 'UPDATE_SORT';
2 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/sort/actions.js:
--------------------------------------------------------------------------------
1 | import { UPDATE_SORT } from './actionTypes';
2 |
3 | export const updateSort = sort => ({
4 | type: UPDATE_SORT,
5 | payload: sort
6 | });
7 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/sort/reducer.js:
--------------------------------------------------------------------------------
1 | import { UPDATE_SORT } from './actionTypes';
2 |
3 | const initialState = {
4 | type: ''
5 | };
6 |
7 | export default function(state = initialState, action) {
8 | switch (action.type) {
9 | case UPDATE_SORT:
10 | return {
11 | ...state,
12 | type: action.payload
13 | };
14 | default:
15 | return state;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/store.js:
--------------------------------------------------------------------------------
1 | import { compose, createStore, applyMiddleware } from 'redux';
2 | import thunk from 'redux-thunk';
3 | import rootReducer from './reducers';
4 |
5 | export default initialState => {
6 | initialState =
7 | JSON.parse(window.localStorage.getItem('state')) || initialState;
8 |
9 | const store = createStore(
10 | rootReducer,
11 | initialState,
12 | compose( applyMiddleware(thunk), window.devToolsExtension ? window.devToolsExtension() : f => f )
13 | );
14 |
15 | store.subscribe(() => {
16 | const state = store.getState();
17 | const persist = {
18 | cart: state.cart,
19 | total: state.total
20 | };
21 |
22 | window.localStorage.setItem('state', JSON.stringify(persist));
23 | });
24 |
25 | return store;
26 | };
27 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/total/actionTypes.js:
--------------------------------------------------------------------------------
1 | export const UPDATE_CART = 'UPDATE_CART';
2 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/total/actions.js:
--------------------------------------------------------------------------------
1 | import { UPDATE_CART } from './actionTypes';
2 |
3 | export const updateCart = cartProducts => dispatch => {
4 | let productQuantity = cartProducts.reduce((sum, p) => {
5 | sum += p.quantity;
6 | return sum;
7 | }, 0);
8 |
9 | let totalPrice = cartProducts.reduce((sum, p) => {
10 | sum += p.price * p.quantity;
11 | return sum;
12 | }, 0);
13 |
14 | let installments = cartProducts.reduce((greater, p) => {
15 | greater = p.installments > greater ? p.installments : greater;
16 | return greater;
17 | }, 0);
18 |
19 | let cartTotal = {
20 | productQuantity,
21 | installments,
22 | totalPrice,
23 | currencyId: 'USD',
24 | currencyFormat: '$'
25 | };
26 |
27 | dispatch({
28 | type: UPDATE_CART,
29 | payload: cartTotal
30 | });
31 | };
32 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/total/reducer.js:
--------------------------------------------------------------------------------
1 | import { UPDATE_CART } from './actionTypes';
2 |
3 | const initialState = {
4 | data: {
5 | productQuantity: 0,
6 | installments: 0,
7 | totalPrice: 0,
8 | currencyId: 'USD',
9 | currencyFormat: '$'
10 | }
11 | };
12 |
13 | export default function(state = initialState, action) {
14 | switch (action.type) {
15 | case UPDATE_CART:
16 | return {
17 | ...state,
18 | data: action.payload
19 | };
20 | default:
21 | return state;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/services/util.js:
--------------------------------------------------------------------------------
1 | export const formatPrice = (x, currency) => {
2 | switch (currency) {
3 | case 'BRL':
4 | return x.toFixed(2).replace('.', ',');
5 | default:
6 | return x.toFixed(2);
7 | }
8 | };
9 |
10 | export const productsAPI =
11 | 'http://ms-commerce.com/cart/v1/products';
12 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/setupTests.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Enzyme, { shallow, render, mount } from 'enzyme';
3 | import adapter from 'enzyme-adapter-react-16';
4 |
5 | Enzyme.configure({ adapter: new adapter() });
6 |
7 | /* Globals only for tests */
8 | global.React = React;
9 | global.shallow = shallow;
10 | global.render = render;
11 | global.mount = mount;
12 |
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/bag-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/bag-icon.png
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/100_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/100_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/100_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/100_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/101_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/101_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/101_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/101_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/10412368723880252_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/10412368723880252_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/10412368723880252_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/10412368723880252_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/10547961582846888_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/10547961582846888_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/10547961582846888_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/10547961582846888_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/10686354557628304_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/10686354557628304_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/10686354557628304_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/10686354557628304_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/11033926921508488_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/11033926921508488_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/11033926921508488_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/11033926921508488_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/11600983276356164_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/11600983276356164_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/11600983276356164_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/11600983276356164_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/11854078013954528_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/11854078013954528_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/11854078013954528_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/11854078013954528_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/12064273040195392_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/12064273040195392_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/12064273040195392_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/12064273040195392_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/18532669286405344_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/18532669286405344_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/18532669286405344_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/18532669286405344_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/18644119330491310_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/18644119330491310_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/18644119330491310_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/18644119330491310_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/27250082398145996_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/27250082398145996_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/27250082398145996_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/27250082398145996_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/39876704341265610_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/39876704341265610_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/39876704341265610_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/39876704341265610_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/51498472915966370_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/51498472915966370_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/51498472915966370_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/51498472915966370_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/5619496040738316_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/5619496040738316_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/5619496040738316_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/5619496040738316_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/6090484789343891_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/6090484789343891_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/6090484789343891_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/6090484789343891_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/8552515751438644_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/8552515751438644_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/8552515751438644_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/8552515751438644_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/876661122392077_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/876661122392077_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/876661122392077_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/876661122392077_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/9197907543445676_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/9197907543445676_1.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/products/9197907543445676_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/products/9197907543445676_2.jpg
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/static/sprite_delete-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/e-Commerce-Client/src/static/sprite_delete-icon.png
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/util/helper/index.js:
--------------------------------------------------------------------------------
1 |
2 | export default class Util{
3 | static validateEmail(email){
4 | var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
5 | return re.test(email);
6 | }
7 | static getFileName( url ) {
8 | return url ? url.split('/').pop() : null;
9 | }
10 | static uid() {
11 | return Math.random().toString(34).slice(2);
12 | }
13 | }
--------------------------------------------------------------------------------
/dockerized-containers/e-Commerce-Client/src/util/middleware/auth.js:
--------------------------------------------------------------------------------
1 | import * as API from '../../api'
2 |
3 | export default {
4 |
5 | loggedIn: () => {
6 | return !! localStorage.token
7 | },
8 |
9 | setAccessToken: (token) => {
10 | localStorage.token = token;
11 | },
12 |
13 | getAccessToken: (token) => {
14 | return localStorage.token;
15 | },
16 |
17 |
18 | deleteAccessToken: () => {
19 | delete localStorage.token
20 | },
21 |
22 | logout: () => {
23 | delete localStorage.token;
24 | delete localStorage.user_hasPassword;
25 | delete localStorage.user_userType;
26 | delete localStorage.auth_background;
27 | delete sessionStorage.redirect_after_login;
28 | API.setAuthToken();
29 | },
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/dockerized-containers/proxy/hosts:
--------------------------------------------------------------------------------
1 | #
2 | # localhost is used to configure the loopback interface
3 | # when the system is booting. Do not change this entry.
4 | #
5 | 127.0.0.1 localhost ms-commerce.com
6 | 255.255.255.255 broadcasthost
7 | ::1 localhost
8 |
--------------------------------------------------------------------------------
/dockerized-containers/proxy/ssl/pac.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANUHyfNUPQ686RLo
3 | 696c+UtJL1610RFTT3ik3/nzfIia+mzJZmg3dCr1VyrdZ0SCcTlB0NQELijZUdS8
4 | uTPGy5OrtTCGGTcy5dcdOlF+dNTbYFV9ooOcGW3TjjXlK3iOUrOVbACWR4BUfMTU
5 | XnAXhvpaEFJo/WwCOneYpWP24b1dAgMBAAECgYA2ya0HtreJTc6HvX3EIA0Bbs4P
6 | BqXBVfLPbV/pMdTqcSlMxzNeRDzNO5HyhUSk2wNxnVqu3HBesx2Xn/3lsg/y71rt
7 | PIM2vd8ccOZL39hZCwEnixvhwr1VktGXUBtdi7ipMkYDLl9SUFMNKFexHSQ96Xl6
8 | bfcdhwK/dZxOVOGJRQJBAPci1ij7gEL8xsA8xxCzqDDPruFCI5+SUcco88vWkXZ5
9 | ZYJZVNOk0SAAdYw9dUjKjwQKBDQ+SbMyhx2nT5QDTicCQQDcq8y5ulkxdzUHHoxq
10 | j8iZlNmErRfofiyOTJcc4/9kqyIyQGGLSAuCmAVqKxKzjwFXN/UuJYbLBlKAMMOc
11 | kk7bAkAYZOrozrKBajwgG5+2qVUvxEBJ4eJsTOAfnY47D6n6HM+FR1YVMg6mbwUr
12 | W6GpFr15M5fopEFYG+O0bKBxRsY/AkACwRozD0Jhva0pw5XZFqZYVGVKpKZxvnFr
13 | 7UTNlYLwjLpGikstY97Q6HjY1GTNXPGVVxt2Uf2WtyN8eh9W6vSVAkEAxtiPp8w5
14 | sXiWHKKq9VkYpYgUF4WkhUCxx4crWpaIQgXJwtQ6bKJeBN8r+JklYsPtveNYZYbl
15 | bn8bkcfdRwxcog==
16 | -----END PRIVATE KEY-----
17 |
--------------------------------------------------------------------------------
/dockerized-containers/screens/02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/screens/02.png
--------------------------------------------------------------------------------
/dockerized-containers/screens/03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/dockerized-containers/screens/03.png
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.githooks/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo "Running Pre-Commit hook"
4 |
5 | # This script should be saved in a git repo as a hook file, e.g. .git/hooks/pre-receive.
6 | # It looks for scripts in the .git/hooks/pre-receive.d directory and executes them in order,
7 | # passing along stdin. If any script exits with a non-zero status, this script exits.
8 |
9 | script_dir=$(dirname $0)
10 | hook_name=$(basename $0)
11 |
12 | hook_dir="$script_dir/$hook_name.d"
13 |
14 | if [[ -d $hook_dir ]]; then
15 | stdin=$(cat /dev/stdin)
16 |
17 | for hook in $hook_dir/*; do
18 | echo "Running $hook_name/$hook hook"
19 | echo "$stdin" | $hook "$@"
20 |
21 | exit_code=$?
22 |
23 | if [ $exit_code != 0 ]; then
24 | exit $exit_code
25 | fi
26 | done
27 | fi
28 |
29 | exit 0
30 |
31 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.githooks/pre-commit.d/articles-management-service:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ./services/articles-management
4 | npm run lint
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.githooks/pre-commit.d/events-management-service:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ./services/events-management
4 | npm run lint
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.githooks/pre-commit.d/notification-service:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ./services/notification
4 | npm run lint
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.githooks/pre-commit.d/user-management-service:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ./services/user-management
4 | npm run lint
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.githooks/pre-push:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | echo "Running Pre-Push hook"
4 |
5 | # This script should be saved in a git repo as a hook file, e.g. .git/hooks/pre-receive.
6 | # It looks for scripts in the .git/hooks/pre-receive.d directory and executes them in order,
7 | # passing along stdin. If any script exits with a non-zero status, this script exits.
8 |
9 | script_dir=$(dirname $0)
10 | hook_name=$(basename $0)
11 |
12 | hook_dir="$script_dir/$hook_name.d"
13 |
14 | if [[ -d $hook_dir ]]; then
15 | stdin=$(cat /dev/stdin)
16 |
17 | for hook in $hook_dir/*; do
18 | echo "Running $hook_name/$hook hook"
19 | echo "$stdin" | $hook "$@"
20 |
21 | exit_code=$?
22 |
23 | if [ $exit_code != 0 ]; then
24 | exit $exit_code
25 | fi
26 | done
27 | fi
28 |
29 | exit 0
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.githooks/pre-push.d/articles-management-service:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ./services/articles-management
4 | npm run testOnly
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.githooks/pre-push.d/events-management-service:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ./services/events-management
4 | npm run testOnly
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.githooks/pre-push.d/notification-service:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ./services/notification
4 | npm run testOnly
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.githooks/pre-push.d/user-management-service:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ./services/user-management
4 | npm run testOnly
--------------------------------------------------------------------------------
/event-driven-microservices-docker/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | node/node_modules
3 | .DS_Store
4 |
5 | node/npm-debug.log
6 | .DS_Store
7 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/run_all_tests:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd ./services/articles-management
4 | npm test
5 | cd -
6 |
7 | cd ./services/events-management
8 | npm test
9 | cd -
10 |
11 | cd ./services/user-management
12 | npm test
13 | cd -
14 |
15 | cd ./services/notification
16 | npm test
17 | cd -
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .env
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | extends: airbnb-base
2 | env:
3 | jest: true
4 |
5 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .env
4 | coverage
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use Node v11.2 as the base image.
2 | FROM node:11.2.0-alpine
3 |
4 | #Set the working directory
5 | WORKDIR /usr/app
6 |
7 | # Copy everything in current directory to /server folder
8 | ADD . /server
9 |
10 | # Install dependencies
11 | RUN cd /server; \
12 | npm install
13 |
14 | EXPOSE 3000
15 |
16 | # Run node
17 | CMD ["node", "/server/src/server.js"]
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/src/app.js:
--------------------------------------------------------------------------------
1 | // Import the required npm packages
2 | const Koa = require('koa');
3 | const Logger = require('koa-logger');
4 | const Helmet = require('koa-helmet');
5 | const BodyParser = require('koa-bodyparser');
6 |
7 | // Get the API routes file
8 | const articleRouter = require('./routes/article.routes');
9 |
10 | // Init Koa API App
11 | const app = new Koa();
12 | app.use(Logger());
13 | app.use(BodyParser());
14 | app.use(Helmet());
15 |
16 | // Setup the API routes
17 | app.use(articleRouter.routes()).use(articleRouter.allowedMethods({ throw: true }));
18 |
19 | module.exports = app;
20 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/src/controllers/__mocks__/article.controller.js:
--------------------------------------------------------------------------------
1 | const articleController = {};
2 |
3 | articleController.find = jest.fn(async (ctx) => {
4 | ctx.status = 200;
5 | ctx.body = '';
6 | });
7 |
8 | articleController.findById = jest.fn(async (ctx) => {
9 | ctx.status = 200;
10 | ctx.body = ctx.params.id;
11 | });
12 |
13 | articleController.add = jest.fn(async (ctx) => {
14 | ctx.status = 200;
15 | ctx.body = '';
16 | });
17 |
18 | articleController.update = jest.fn(async (ctx) => {
19 | ctx.status = 200;
20 | ctx.body = ctx.params.id;
21 | });
22 |
23 | articleController.delete = jest.fn(async (ctx) => {
24 | ctx.status = 200;
25 | ctx.body = ctx.params.id;
26 | });
27 |
28 | module.exports = articleController;
29 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/src/environment/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | name: 'Article Management Service',
3 | baseAPIRoute: 'api',
4 | port: process.env.PORT || 8080,
5 | messagebus: process.env.MESSAGE_BUS || 'amqp://rabbitmq',
6 | environment: process.env.ENVIRONMENT || 'dev',
7 | db: {
8 | uri: process.env.DB_URI,
9 | username: process.env.DB_USERNAME ,
10 | password: process.env.DB_PASSWORD ,
11 | },
12 | services: {
13 | },
14 | messageTimeout: 500,
15 | jwtsecret: 'yoursecretkey',
16 | };
17 |
18 | config.startedMessage = `${config.name} is running on port ${config.port}/`;
19 |
20 | module.exports = config;
21 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/src/message-bus/send/__mocks__/article.added.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | const addedEventMessage = {};
3 |
4 | addedEventMessage.send = (article) => {
5 | };
6 |
7 | module.exports = addedEventMessage;
8 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/src/message-bus/send/article.added.js:
--------------------------------------------------------------------------------
1 | const logger = require('winston');
2 | const amqp = require('amqp-ts-async');
3 | const config = require('../../environment/config');
4 |
5 | const exchangeName = 'articles.added';
6 |
7 | module.exports = {
8 | send: (article) => {
9 | try {
10 | if (!article) {
11 | throw new Error('Sould send a valid article to message queue');
12 | }
13 | const connection = new amqp.Connection(config.messagebus);
14 | const exchange = connection.declareExchange(exchangeName, 'fanout', { durable: false });
15 | const message = new amqp.Message(JSON.stringify(article));
16 | exchange.send(message);
17 | setTimeout(() => {
18 | connection.close();
19 | }, config.messageTimeout);
20 | } catch (err) {
21 | logger.error(`Error Sending Article Added Event to ${exchangeName}: ${err}`);
22 | }
23 | },
24 | };
25 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/src/middlewares/__mocks__/jwt.js:
--------------------------------------------------------------------------------
1 | const jwt = jest.fn((ctx, next) => {
2 | next();
3 | });
4 |
5 | module.exports = jwt;
6 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/src/middlewares/jwt.js:
--------------------------------------------------------------------------------
1 | const koaJwt = require('koa-jwt');
2 | const config = require('../environment/config');
3 |
4 | module.exports = koaJwt({
5 | secret: config.jwtsecret,
6 | });
7 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/src/models/article.model.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | const ArticleSchema = new mongoose.Schema({
4 | authorUID: { type: String, require: true },
5 | createdDate: { type: Date, default: Date.now },
6 | updatedDate: { type: Date, default: Date.now },
7 | title: { type: String, require: true },
8 | description: { type: String, require: true },
9 | body: { type: String, require: true },
10 | meta: {
11 | likes: { type: Number, default: 0 },
12 | },
13 | status: { type: Number },
14 | imagesUID: [String],
15 | tags: [String],
16 | });
17 |
18 | module.exports = mongoose.model('Article', ArticleSchema);
19 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/src/routes/article.routes.js:
--------------------------------------------------------------------------------
1 | const KoaRouter = require('koa-router');
2 | const config = require('../environment/config');
3 | const articleController = require('../controllers/article.controller');
4 | const jwt = require('../middlewares/jwt');
5 |
6 | const api = 'articles';
7 |
8 | const router = new KoaRouter();
9 |
10 | router.prefix(`/${config.baseAPIRoute}/${api}`);
11 |
12 | // GET /api/articles
13 | router.get('/', articleController.find);
14 |
15 | // POST /api/articles
16 | router.post('/', articleController.add);
17 |
18 | // GET /api/articles/id
19 | router.get('/:id', articleController.findById);
20 |
21 | // PUT /api/articles/id
22 | router.put('/:id', articleController.update);
23 |
24 | // DELETE /api/articles/id
25 | router.delete('/:id', articleController.delete);
26 |
27 | module.exports = router;
28 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/src/server.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | // Init the environment variables and server configurations
4 | require('dotenv').config();
5 |
6 | // Import the required packages
7 | const Mongoose = require('mongoose');
8 | const config = require('./environment/config');
9 | const app = require('./app');
10 |
11 | // Init Database Connection
12 | Mongoose.connect('mongodb://mongo/test');
13 | Mongoose.connection.on('error', console.error);
14 |
15 | // Run the API Server
16 | app.listen(config.port, () => {
17 | console.log(config.startedMessage);
18 | });
19 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/tests/unit/__snapshots__/article.added.message.send.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Send Should correcly parse the json object 1`] = `mockConstructor {}`;
4 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/tests/unit/app.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable arrow-body-style */
2 | /* eslint-disable no-unused-vars */
3 | /* eslint-disable global-require */
4 |
5 | const Koa = require('koa');
6 | const articleRouter = require('../../src/routes/article.routes');
7 |
8 | const mockArticleRoutes = jest.fn(() => { return async (ctx, next) => {}; });
9 | articleRouter.routes = mockArticleRoutes;
10 |
11 | describe('Koa App', () => {
12 | test('Should return valid koa application', () => {
13 | const app = require('../../src/app');
14 | expect(app).toBeInstanceOf(Koa);
15 | });
16 |
17 | test('Should have article routes', () => {
18 | require('../../src/app');
19 | expect(mockArticleRoutes.mock.calls.length).toBe(1);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/articles-management/tests/unit/config.test.js:
--------------------------------------------------------------------------------
1 | const config = require('../../src/environment/config');
2 |
3 | describe('config', () => {
4 | test('should load default values', () => {
5 | expect(config.name).not.toBeNull();
6 | expect(config.port).not.toBeNull();
7 | expect(config.baseAPIRoute).not.toBeNull();
8 | expect(config.environment).not.toBeNull();
9 | expect(config.messagebus).not.toBeNull();
10 | expect(config.db.uri).not.toBeNull();
11 | expect(config.db.username).not.toBeNull();
12 | expect(config.db.password).not.toBeNull();
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .env
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/.env:
--------------------------------------------------------------------------------
1 | PORT="8081"
2 | MESSAGE_BUS="amqp://localhost"
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | extends: airbnb-base
2 | env:
3 | jest: true
4 |
5 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/event-driven-microservices-docker/services/authentication/.gitkeep
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/.snyk:
--------------------------------------------------------------------------------
1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
2 | version: v1.19.0
3 | ignore: {}
4 | # patches apply the minimum changes required to fix a vulnerability
5 | patch:
6 | SNYK-JS-LODASH-567746:
7 | - winston > async > lodash:
8 | patched: '2020-08-04T12:02:15.835Z'
9 | - mongoose > async > lodash:
10 | patched: '2020-08-04T12:02:15.835Z'
11 | - amqp-ts-async > winston > async > lodash:
12 | patched: '2020-08-04T12:02:15.835Z'
13 | - amqp-ts-async > @types/winston > winston > async > lodash:
14 | patched: '2020-08-04T12:02:15.835Z'
15 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use Node v11.2 as the base image.
2 | FROM node:11.2.0-alpine
3 |
4 | #Set the working directory
5 | WORKDIR /usr/app
6 |
7 | # Copy everything in current directory to /server folder
8 | ADD . /server
9 |
10 | # Install dependencies
11 | RUN cd /server; \
12 | npm install
13 |
14 | EXPOSE 3000
15 |
16 | # Run node
17 | CMD ["node", "/server/src/server.js"]
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/src/app.js:
--------------------------------------------------------------------------------
1 | // Import the required npm packages
2 | const Koa = require('koa');
3 | const Logger = require('koa-logger');
4 | const Helmet = require('koa-helmet');
5 | const BodyParser = require('koa-bodyparser');
6 |
7 | // Get the API routes file
8 | const authRouter = require('./routes/auth.routes');
9 |
10 | // Init Koa API App
11 | const app = new Koa();
12 | app.use(Logger());
13 | app.use(BodyParser());
14 | app.use(Helmet());
15 |
16 | // Setup the API routes
17 | app.use(authRouter.routes()).use(authRouter.allowedMethods({ throw: true }));
18 |
19 | module.exports = app;
20 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/src/environment/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | name: 'Authentication Service',
3 | baseAPIRoute: 'api',
4 | port: process.env.PORT || 8080,
5 | messagebus: process.env.MESSAGE_BUS || 'amqp://rabbitmq',
6 | environment: process.env.ENVIRONMENT || 'dev',
7 | db: {
8 | uri: process.env.DB_URI
9 | },
10 | jwtsecret: 'yoursecretkey',
11 | };
12 |
13 | config.startedMessage = `${config.name} is running on port ${config.port}/`;
14 |
15 | module.exports = config;
16 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/src/message-bus/recieve/user.added.js:
--------------------------------------------------------------------------------
1 | const logger = require('winston');
2 | const amqp = require('amqp-ts-async');
3 | const config = require('../../environment/config');
4 | const authController = require('../../controllers/auth.controller');
5 |
6 | const exchangeName = 'user.added';
7 | const queueName = '';
8 |
9 | const connection = new amqp.Connection(config.messagebus);
10 | const exchange = connection.declareExchange(exchangeName, 'fanout', { durable: false });
11 | const queue = connection.declareQueue(queueName, { exclusive: true });
12 | queue.bind(exchange);
13 |
14 | module.exports = {
15 | start: () => {
16 | try {
17 | queue.activateConsumer(authController.add);
18 | } catch (err) {
19 | logger.error(`Error Listening to ${exchangeName}, ${queueName}: ${err}`);
20 | }
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/src/models/auth.model.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | const AuthSchema = new mongoose.Schema({
4 | createdDate: { type: Date, default: Date.now },
5 | updatedDate: { type: Date, default: Date.now },
6 | emailAddress: { type: String, require: true },
7 | password: { type: String, require: true },
8 | role: { type: String, require: true, default: 'regular' },
9 | status: { type: String, default: 'active' },
10 | });
11 |
12 | module.exports = mongoose.model('Auth', AuthSchema);
13 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/src/routes/auth.routes.js:
--------------------------------------------------------------------------------
1 | const KoaRouter = require('koa-router');
2 | const config = require('../environment/config');
3 | const authController = require('../controllers/auth.controller');
4 |
5 | const api = 'auth';
6 |
7 | const router = new KoaRouter();
8 |
9 | router.prefix(`/${config.baseAPIRoute}/${api}`);
10 |
11 | // POST /api/auth
12 | router.post('/', authController.authenticate);
13 |
14 | module.exports = router;
15 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/authentication/src/server.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | // Init the environment variables and server configurations
4 | require('dotenv').config();
5 |
6 | // Import the required packages
7 | const Mongoose = require('mongoose');
8 | const config = require('./environment/config');
9 | const app = require('./app');
10 |
11 | // Init Database Connection
12 | Mongoose.connect('mongodb://mongo/test');
13 | Mongoose.connection.on('error', console.error);
14 |
15 | // Start Listening to Subscribed Events
16 | require('./message-bus/recieve/user.added').start();
17 |
18 | // Run the API Server
19 | app.listen(config.port, () => {
20 | console.log(config.startedMessage);
21 | });
22 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .env
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | extends: airbnb-base
2 | env:
3 | jest: true
4 |
5 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .env
4 | coverage
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use Node v11.2 as the base image.
2 | FROM node:11.2.0-alpine
3 |
4 | #Set the working directory
5 | WORKDIR /usr/app
6 |
7 | # Copy everything in current directory to /server folder
8 | ADD . /server
9 |
10 | # Install dependencies
11 | RUN cd /server; \
12 | npm install
13 |
14 | EXPOSE 3000
15 |
16 | # Run node
17 | CMD ["node", "/server/src/server.js"]
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/src/app.js:
--------------------------------------------------------------------------------
1 | // Import the required npm packages
2 | const Koa = require('koa');
3 | const Logger = require('koa-logger');
4 | const Helmet = require('koa-helmet');
5 | const BodyParser = require('koa-bodyparser');
6 |
7 | // Get the API routes file
8 | const eventRouter = require('./routes/event.routes');
9 |
10 | // Init Koa API App
11 | const app = new Koa();
12 | app.use(Logger());
13 | app.use(BodyParser());
14 | app.use(Helmet());
15 |
16 | // Setup the API routes
17 | app.use(eventRouter.routes()).use(eventRouter.allowedMethods({ throw: true }));
18 |
19 | module.exports = app;
20 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/src/controllers/__mocks__/event.controller.js:
--------------------------------------------------------------------------------
1 | const eventController = {};
2 |
3 | eventController.find = jest.fn(async (ctx) => {
4 | ctx.status = 200;
5 | ctx.body = '';
6 | });
7 |
8 | eventController.findById = jest.fn(async (ctx) => {
9 | ctx.status = 200;
10 | ctx.body = ctx.params.id;
11 | });
12 |
13 | eventController.add = jest.fn(async (ctx) => {
14 | ctx.status = 200;
15 | ctx.body = '';
16 | });
17 |
18 | eventController.update = jest.fn(async (ctx) => {
19 | ctx.status = 200;
20 | ctx.body = ctx.params.id;
21 | });
22 |
23 | eventController.delete = jest.fn(async (ctx) => {
24 | ctx.status = 200;
25 | ctx.body = ctx.params.id;
26 | });
27 |
28 | module.exports = eventController;
29 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/src/environment/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | name: 'Events Management Service',
3 | baseAPIRoute: 'api',
4 | port: process.env.PORT || 8080,
5 | messagebus: process.env.MESSAGE_BUS || 'amqp://rabbitmq',
6 | environment: process.env.ENVIRONMENT || 'dev',
7 | db: {
8 | uri: process.env.DB_URI
9 | },
10 | services: {
11 | },
12 | jwtsecret: 'yoursecretkey',
13 | };
14 |
15 | config.startedMessage = `${config.name} is running on port ${config.port}/`;
16 |
17 | module.exports = config;
18 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/src/middlewares/__mocks__/jwt.js:
--------------------------------------------------------------------------------
1 | const jwt = jest.fn((ctx, next) => {
2 | next();
3 | });
4 |
5 | module.exports = jwt;
6 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/src/middlewares/jwt.js:
--------------------------------------------------------------------------------
1 | const koaJwt = require('koa-jwt');
2 | const config = require('../environment/config');
3 |
4 | module.exports = koaJwt({
5 | secret: config.jwtsecret,
6 | });
7 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/src/models/__mocks__/event.model.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable arrow-body-style */
2 |
3 | const eventModel = {};
4 |
5 | let data = [];
6 |
7 | eventModel.find = jest.fn(() => data);
8 |
9 | eventModel.findById = jest.fn((id) => {
10 | return data.find(event => event.id === id);
11 | });
12 |
13 | eventModel.create = jest.fn((event) => {
14 | data.push(event);
15 | return event;
16 | });
17 |
18 | eventModel.findByIdAndUpdate = jest.fn((id, updatedEvent) => {
19 | const index = data.findIndex(event => event.id === id);
20 | if (index >= 0) {
21 | data[index] = updatedEvent;
22 | }
23 | return updatedEvent;
24 | });
25 |
26 | eventModel.findByIdAndRemove = jest.fn((id) => {
27 | const index = data.findIndex(event => event.id === id);
28 | data.splice(index, 1);
29 | return id;
30 | });
31 |
32 | eventModel.count = () => data.length;
33 | eventModel.reset = () => { data = []; };
34 |
35 | module.exports = eventModel;
36 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/src/models/event.model.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | const EventSchema = new mongoose.Schema({
4 | authorUID: { type: String, require: true },
5 | createdDate: { type: Date, default: Date.now },
6 | updatedDate: { type: Date, default: Date.now },
7 | eventDate: { type: Date, require: true },
8 | title: { type: String, require: true },
9 | description: { type: String, require: true },
10 | body: { type: String, require: true },
11 | meta: {
12 | attending: { type: Number, default: 0 },
13 | },
14 | status: { type: Number },
15 | imagesUID: [String],
16 | tags: [String],
17 | });
18 |
19 | module.exports = mongoose.model('Event', EventSchema);
20 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/src/routes/event.routes.js:
--------------------------------------------------------------------------------
1 | const KoaRouter = require('koa-router');
2 | const config = require('../environment/config');
3 | const eventsController = require('../controllers/event.controller');
4 | const jwt = require('../middlewares/jwt');
5 |
6 | const api = 'events';
7 |
8 | const router = new KoaRouter();
9 |
10 | router.prefix(`/${config.baseAPIRoute}/${api}`);
11 |
12 | // GET /api/events
13 | router.get('/', eventsController.find);
14 |
15 | // POST /api/events
16 | router.post('/', eventsController.add);
17 |
18 | // GET /api/events/id
19 | router.get('/:id', eventsController.findById);
20 |
21 | // PUT /api/events/id
22 | router.put('/:id', eventsController.update);
23 |
24 | // DELETE /api/events/id
25 | router.delete('/:id', eventsController.delete);
26 |
27 | module.exports = router;
28 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/src/server.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | // Init the environment variables and server configurations
4 | require('dotenv').config();
5 |
6 | // Import the required packages
7 | const Mongoose = require('mongoose');
8 | const config = require('./environment/config');
9 | const app = require('./app');
10 |
11 | // Init Database Connection
12 | Mongoose.connect('mongodb://mongo/test');
13 | Mongoose.connection.on('error', console.error);
14 |
15 | // Run the API Server
16 | app.listen(config.port, () => {
17 | console.log(config.startedMessage);
18 | });
19 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/tests/unit/app.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable arrow-body-style */
2 | /* eslint-disable no-unused-vars */
3 | /* eslint-disable global-require */
4 |
5 | const Koa = require('koa');
6 | const eventRouter = require('../../src/routes/event.routes');
7 |
8 | const mockEventRoutes = jest.fn(() => { return async (ctx, next) => {}; });
9 | eventRouter.routes = mockEventRoutes;
10 |
11 | describe('Koa App', () => {
12 | test('Should return valid koa application', () => {
13 | const app = require('../../src/app');
14 | expect(app).toBeInstanceOf(Koa);
15 | });
16 |
17 | test('Should have article routes', () => {
18 | require('../../src/app');
19 | expect(mockEventRoutes.mock.calls.length).toBe(1);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/events-management/tests/unit/config.test.js:
--------------------------------------------------------------------------------
1 | const config = require('../../src/environment/config');
2 |
3 | describe('config', () => {
4 | test('should load default values', () => {
5 | expect(config.name).not.toBeNull();
6 | expect(config.port).not.toBeNull();
7 | expect(config.baseAPIRoute).not.toBeNull();
8 | expect(config.environment).not.toBeNull();
9 | expect(config.messagebus).not.toBeNull();
10 | expect(config.db.uri).not.toBeNull();
11 | expect(config.db.username).not.toBeNull();
12 | expect(config.db.password).not.toBeNull();
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/media-management/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/event-driven-microservices-docker/services/media-management/.gitkeep
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | extends: airbnb-base
2 | env:
3 | jest: true
4 |
5 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .env
4 | coverage
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use Node v11.2 as the base image.
2 | FROM node:11.2.0-alpine
3 |
4 | #Set the working directory
5 | WORKDIR /usr/app
6 |
7 | # Copy everything in current directory to /server folder
8 | ADD . /server
9 |
10 | # Install dependencies
11 | RUN cd /server; \
12 | npm install
13 |
14 | # Run node
15 | CMD ["node", "/server/src/server.js"]
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/__mocks__/amqp-ts-async.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable arrow-body-style */
2 | /* eslint-disable no-unused-vars */
3 |
4 |
5 | const bind = jest.fn((exchange) => {
6 | });
7 |
8 | const activateConsumer = jest.fn((onRecieve) => {
9 | onRecieve();
10 | });
11 |
12 | const declareExchange = jest.fn((exchangeName, type, options) => {
13 | return exchangeName;
14 | });
15 |
16 | const declareQueue = jest.fn((exchangeName, type, options) => {
17 | return {
18 | bind,
19 | activateConsumer,
20 | };
21 | });
22 |
23 | const connection = jest.fn((url) => {
24 | return {
25 | connectionUrl: url,
26 | declareExchange,
27 | declareQueue,
28 | };
29 | });
30 |
31 | module.exports.Connection = connection;
32 | module.exports.activateConsumer = activateConsumer;
33 | module.exports.bind = bind;
34 | module.exports.declareExchange = declareExchange;
35 | module.exports.declareQueue = declareQueue;
36 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/__mocks__/koa.js:
--------------------------------------------------------------------------------
1 | const appListen = jest.fn(() => {
2 |
3 | });
4 |
5 | module.exports = jest.fn(() => ({
6 | listen: appListen,
7 | }));
8 |
9 | module.exports.appListen = appListen;
10 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/__mocks__/nodemailer.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 |
3 | const lib = {};
4 |
5 | const sendMail = jest.fn(options => true);
6 |
7 | lib.createTransport = jest.fn(options => ({
8 | sendMail,
9 | }));
10 |
11 | module.exports = lib;
12 | module.exports.sendMail = sendMail;
13 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/__mocks__/winston.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 |
3 | module.exports.info = jest.fn((message) => {
4 | });
5 |
6 | module.exports.error = jest.fn((message) => {
7 | });
8 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/src/environment/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | name: 'Notification Service',
3 | messagebus: process.env.MESSAGE_BUS || 'amqp://guest:guest@localhost',
4 | environment: process.env.ENVIRONMENT || 'dev',
5 | email: {
6 | service: process.env.EMAIL_SERVICE || '',
7 | username: process.env.EMAIL_ID || '',
8 | password: process.env.EMAIL_PASSWORD || '',
9 | adminEmailID: process.env.ADMIN_EMAIL || '',
10 | },
11 | };
12 |
13 | config.startedMessage = `${config.name} is running`;
14 |
15 | module.exports = config;
16 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/src/message-controllers/__mocks__/articles.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | const controller = {};
3 |
4 | controller.added = jest.fn(message => true);
5 |
6 | module.exports = controller;
7 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/src/message-controllers/articles.js:
--------------------------------------------------------------------------------
1 | const logger = require('winston');
2 | const emailModule = require('../modules/email/email');
3 |
4 | const controller = {};
5 |
6 | controller.added = async (message) => {
7 | try {
8 | const content = JSON.parse(message.content.toString());
9 | await emailModule.sendArticleAddedEmail(content);
10 | } catch (err) {
11 | logger.error(`Error in handling the recieved message - article.added - ${err}`);
12 | }
13 | };
14 |
15 | module.exports = controller;
16 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/src/modules/email/__mocks__/email.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | const email = {};
3 |
4 | email.sendArticleAddedEmail = jest.fn((message) => {
5 | });
6 |
7 | module.exports = email;
8 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/src/modules/email/__mocks__/email.templates.js:
--------------------------------------------------------------------------------
1 | const templates = {};
2 |
3 | templates.GetRenderedArticleAddedEmailHtml = jest.fn((title, description) => `${title}, ${description}`);
4 |
5 | module.exports = templates;
6 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/src/server.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 | const logger = require('winston');
3 | const Koa = require('koa');
4 | const config = require('./environment/config');
5 |
6 | require('./subscriptions/article.added').start();
7 |
8 | const app = new Koa();
9 | app.listen();
10 | logger.info(config.startedMessage);
11 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/src/subscriptions/__mocks__/article.added.js:
--------------------------------------------------------------------------------
1 | module.exports.start = jest.fn();
2 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/src/subscriptions/article.added.js:
--------------------------------------------------------------------------------
1 | const logger = require('winston');
2 | const amqp = require('amqp-ts-async');
3 | const config = require('../environment/config');
4 | const articleMessageController = require('../message-controllers/articles');
5 |
6 | const exchangeName = 'articles.added';
7 | const queueName = '';
8 |
9 | const connection = new amqp.Connection(config.messagebus);
10 | const exchange = connection.declareExchange(exchangeName, 'fanout', { durable: false });
11 | const queue = connection.declareQueue(queueName, { exclusive: true });
12 | queue.bind(exchange);
13 |
14 | module.exports = {
15 | start: () => {
16 | try {
17 | queue.activateConsumer(articleMessageController.added);
18 | } catch (err) {
19 | logger.error(`Error Listening to ${exchangeName}, ${queueName}: ${err}`);
20 | }
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/tests/unit/__snapshots__/config.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`config should load default values 1`] = `
4 | Object {
5 | "email": Object {
6 | "adminEmailID": "",
7 | "password": "",
8 | "service": "",
9 | "username": "",
10 | },
11 | "environment": "dev",
12 | "messagebus": "amqp://guest:guest@localhost",
13 | "name": "Notification Service",
14 | "startedMessage": "Notification Service is running",
15 | }
16 | `;
17 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/tests/unit/__snapshots__/email.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Email Options Shoud set the correct email credentials 1`] = `
4 | Object {
5 | "auth": Object {
6 | "pass": "",
7 | "user": "",
8 | },
9 | "service": "",
10 | }
11 | `;
12 |
13 | exports[`Send Article Added Email Shoud send email when correct details are provided 1`] = `
14 | Object {
15 | "from": "",
16 | "html": "Test Article, Test Text",
17 | "subject": "LocalNewsApplication - New Article Added!",
18 | "to": "",
19 | }
20 | `;
21 |
22 | exports[`Send Article Added Email Shoud throw an error when an exception occurs 1`] = `
23 | Object {
24 | "from": "",
25 | "html": "Test Article, Test Text",
26 | "subject": "LocalNewsApplication - New Article Added!",
27 | "to": "",
28 | }
29 | `;
30 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/tests/unit/config.test.js:
--------------------------------------------------------------------------------
1 | const config = require('../../src/environment/config');
2 |
3 | describe('config', () => {
4 | test('should load default values', () => {
5 | expect(config.name).not.toBeNull();
6 | expect(config.environment).not.toBeNull();
7 | expect(config.messagebus).not.toBeNull();
8 | expect(config.email.service).not.toBeNull();
9 | expect(config.email.username).not.toBeNull();
10 | expect(config.email.password).not.toBeNull();
11 | expect(config.email.adminEmailID).not.toBeNull();
12 | expect(config).toMatchSnapshot();
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/tests/unit/email.templates.test.js:
--------------------------------------------------------------------------------
1 | const template = require('../../src/modules/email/email.templates');
2 |
3 | describe('Article Added Email Template', () => {
4 | test('Should return correct email template', () => {
5 | const html = template.GetRenderedArticleAddedEmailHtml('Test Name', 'Test Text');
6 | expect(html).toMatchSnapshot();
7 | });
8 |
9 | test('Should return correct email template when no data is passed', () => {
10 | const html = template.GetRenderedArticleAddedEmailHtml();
11 | expect(html).toMatchSnapshot();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/notification/tests/unit/server.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable global-require */
2 | jest.mock('../../src/subscriptions/article.added');
3 | jest.mock('koa');
4 | jest.mock('winston');
5 |
6 | const koa = require('koa');
7 | const winston = require('winston');
8 | const articleAddedSubscription = require('../../src/subscriptions/article.added');
9 | const config = require('../../src/environment/config');
10 |
11 | test('Server works', async () => {
12 | require('../../src/server');
13 | expect(koa.appListen).toBeCalledTimes(1);
14 | expect(winston.info).toBeCalledTimes(1);
15 | expect(winston.info).toBeCalledWith(config.startedMessage);
16 | expect(articleAddedSubscription.start).toBeCalledTimes(1);
17 | });
18 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/search/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/event-driven-microservices-docker/services/search/.gitkeep
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .env
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | extends: airbnb-base
2 | env:
3 | jest: true
4 |
5 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .env
4 | coverage
5 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/event-driven-microservices-docker/services/user-management/.gitkeep
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use Node v11.2 as the base image.
2 | FROM node:11.2.0-alpine
3 |
4 | #Set the working directory
5 | WORKDIR /usr/app
6 |
7 | # Copy everything in current directory to /server folder
8 | ADD . /server
9 |
10 | # Install dependencies
11 | RUN cd /server; \
12 | npm install
13 |
14 | EXPOSE 3000
15 |
16 | # Run node
17 | CMD ["node", "/server/src/server.js"]
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/__mocks__/winston.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 |
3 | module.exports.info = jest.fn((message) => {
4 | });
5 |
6 | module.exports.error = jest.fn((message) => {
7 | });
8 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/src/app.js:
--------------------------------------------------------------------------------
1 | // Import the required npm packages
2 | const Koa = require('koa');
3 | const Logger = require('koa-logger');
4 | const Helmet = require('koa-helmet');
5 | const BodyParser = require('koa-bodyparser');
6 |
7 | // Get the API routes file
8 | const userRouter = require('./routes/user.routes');
9 |
10 | // Init Koa API App
11 | const app = new Koa();
12 | app.use(Logger());
13 | app.use(BodyParser());
14 | app.use(Helmet());
15 |
16 | // Setup the API routes
17 | app.use(userRouter.routes()).use(userRouter.allowedMethods({ throw: true }));
18 |
19 | module.exports = app;
20 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/src/controllers/__mocks__/user.controller.js:
--------------------------------------------------------------------------------
1 | const userController = {};
2 |
3 | userController.find = jest.fn(async (ctx) => {
4 | ctx.status = 200;
5 | ctx.body = '';
6 | });
7 |
8 | userController.findById = jest.fn(async (ctx) => {
9 | ctx.status = 200;
10 | ctx.body = ctx.params.id;
11 | });
12 |
13 | userController.add = jest.fn(async (ctx) => {
14 | ctx.status = 200;
15 | ctx.body = '';
16 | });
17 |
18 | userController.update = jest.fn(async (ctx) => {
19 | ctx.status = 200;
20 | ctx.body = ctx.params.id;
21 | });
22 |
23 | userController.delete = jest.fn(async (ctx) => {
24 | ctx.status = 200;
25 | ctx.body = ctx.params.id;
26 | });
27 |
28 | module.exports = userController;
29 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/src/environment/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | name: 'User Management Service',
3 | baseAPIRoute: 'api',
4 | port: process.env.PORT || 8080,
5 | messagebus: process.env.MESSAGE_BUS || 'amqp://rabbitmq',
6 | environment: process.env.ENVIRONMENT || 'dev',
7 | db: {
8 | uri: process.env.DB_URI
9 | },
10 | services: {
11 | },
12 | messageTimeout: 500,
13 | jwtsecret: 'yoursecretkey',
14 | };
15 |
16 | config.startedMessage = `${config.name} is running on port ${config.port}/`;
17 |
18 | module.exports = config;
19 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/src/message-bus/send/user.added.js:
--------------------------------------------------------------------------------
1 | const logger = require('winston');
2 | const amqp = require('amqp-ts-async');
3 | const config = require('../../environment/config');
4 |
5 | const exchangeName = 'user.added';
6 |
7 | module.exports = {
8 | send: (user) => {
9 | try {
10 | if (!user) {
11 | throw new Error('Sould send a valid user to message queue');
12 | }
13 | console.log('sedning message to MQ')
14 | const connection = new amqp.Connection(config.messagebus);
15 | const exchange = connection.declareExchange(exchangeName, 'fanout', { durable: false });
16 | const message = new amqp.Message(JSON.stringify(user));
17 | exchange.send(message);
18 | setTimeout(() => {
19 | connection.close();
20 | }, config.messageTimeout);
21 | } catch (err) {
22 | logger.error(`Error Sending Article Added Event to ${exchangeName}: ${err}`);
23 | }
24 | },
25 | };
26 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/src/middlewares/__mocks__/jwt.js:
--------------------------------------------------------------------------------
1 | const jwt = jest.fn((ctx, next) => {
2 | next();
3 | });
4 |
5 | module.exports = jwt;
6 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/src/middlewares/jwt.js:
--------------------------------------------------------------------------------
1 | const koaJwt = require('koa-jwt');
2 | const config = require('../environment/config');
3 |
4 | module.exports = koaJwt({
5 | secret: config.jwtsecret,
6 | });
7 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/src/models/__mocks__/user.model.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable arrow-body-style */
2 |
3 | const userModel = {};
4 |
5 | let data = [];
6 |
7 | userModel.find = jest.fn(() => data);
8 |
9 | userModel.findById = jest.fn((id) => {
10 | return data.find(user => user.id === id);
11 | });
12 |
13 | userModel.create = jest.fn((user) => {
14 | data.push(user);
15 | return user;
16 | });
17 |
18 | userModel.findByIdAndUpdate = jest.fn((id, updateduser) => {
19 | const index = data.findIndex(user => user.id === id);
20 | if (index >= 0) {
21 | data[index] = updateduser;
22 | }
23 | return updateduser;
24 | });
25 |
26 | userModel.findByIdAndRemove = jest.fn((id) => {
27 | const index = data.findIndex(user => user.id === id);
28 | data.splice(index, 1);
29 | return id;
30 | });
31 |
32 | userModel.count = () => data.length;
33 | userModel.reset = () => { data = []; };
34 |
35 | module.exports = userModel;
36 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/src/models/user.model.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 |
3 | const UserSchema = new mongoose.Schema({
4 | createdDate: { type: Date, default: Date.now },
5 | updatedDate: { type: Date, default: Date.now },
6 | firstName: { type: String, require: false },
7 | lastName: { type: String, require: false },
8 | emailAddress: { type: String, require: true },
9 | description: { type: String, require: false },
10 | meta: {
11 | likes: { type: Number, default: 0 },
12 | },
13 | role: { type: String, require: true, default: 'regular' },
14 | imagesUID: [String],
15 | tags: [String],
16 | });
17 |
18 | module.exports = mongoose.model('User', UserSchema);
19 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/src/routes/user.routes.js:
--------------------------------------------------------------------------------
1 | const KoaRouter = require('koa-router');
2 | const config = require('../environment/config');
3 | const usersController = require('../controllers/user.controller');
4 |
5 | const api = 'users';
6 |
7 | const router = new KoaRouter();
8 |
9 | router.prefix(`/${config.baseAPIRoute}/${api}`);
10 |
11 | // GET /api/users
12 | router.get('/', usersController.find);
13 |
14 | // POST /api/users
15 | router.post('/', usersController.add);
16 |
17 | // GET /api/users/id
18 | router.get('/:id', usersController.findById);
19 |
20 | // PUT /api/users/id
21 | router.put('/:id', usersController.update);
22 |
23 | // DELETE /api/users/id
24 | router.delete('/:id', usersController.delete);
25 |
26 | module.exports = router;
27 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/src/server.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | // Init the environment variables and server configurations
4 | require('dotenv').config();
5 |
6 | // Import the required packages
7 | const Mongoose = require('mongoose');
8 | const config = require('./environment/config');
9 | const app = require('./app');
10 |
11 | // Init Database Connection
12 | Mongoose.connect('mongodb://mongo/test');
13 | Mongoose.connection.on('error', console.error);
14 |
15 | // Run the API Server
16 | app.listen(config.port, () => {
17 | console.log(config.startedMessage);
18 | console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>');
19 | console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
20 |
21 | console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
22 |
23 | });
24 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/tests/unit/__snapshots__/user.added.message.send.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Send Should correcly parse the json object 1`] = `mockConstructor {}`;
4 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/tests/unit/__snapshots__/user.controller.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`findById should return user when correct id is passed 1`] = `
4 | Object {
5 | "emailAddress": "test@email.com",
6 | "firstName": "Test User",
7 | "id": 123,
8 | }
9 | `;
10 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/tests/unit/app.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable arrow-body-style */
2 | /* eslint-disable no-unused-vars */
3 | /* eslint-disable global-require */
4 |
5 | const Koa = require('koa');
6 | const userRouter = require('../../src/routes/user.routes');
7 |
8 | const mockUserRoutes = jest.fn(() => { return async (ctx, next) => {}; });
9 | userRouter.routes = mockUserRoutes;
10 |
11 | describe('Koa App', () => {
12 | test('Should return valid koa application', () => {
13 | const app = require('../../src/app');
14 | expect(app).toBeInstanceOf(Koa);
15 | });
16 |
17 | test('Should have user routes', () => {
18 | require('../../src/app');
19 | expect(mockUserRoutes.mock.calls.length).toBe(1);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/event-driven-microservices-docker/services/user-management/tests/unit/config.test.js:
--------------------------------------------------------------------------------
1 | const config = require('../../src/environment/config');
2 |
3 | describe('config', () => {
4 | test('should load default values', () => {
5 | expect(config.name).not.toBeNull();
6 | expect(config.port).not.toBeNull();
7 | expect(config.baseAPIRoute).not.toBeNull();
8 | expect(config.environment).not.toBeNull();
9 | expect(config.messagebus).not.toBeNull();
10 | expect(config.db.uri).not.toBeNull();
11 | expect(config.db.username).not.toBeNull();
12 | expect(config.db.password).not.toBeNull();
13 | expect(config).toMatchSnapshot();
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/node js-with-serverless/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
3 | npm-debug.log
4 | dist/
5 | coverage/
6 | mongo/db
7 |
--------------------------------------------------------------------------------
/node js-with-serverless/README.md:
--------------------------------------------------------------------------------
1 | # Serverless-Typescript-CRUD-DYNAMODB
2 | CRUD operations using serverless typescript plugin with node js 12.XX
3 |
--------------------------------------------------------------------------------
/node js-with-serverless/functions/delete_item.ts:
--------------------------------------------------------------------------------
1 | import { DynamoDB } from 'aws-sdk';
2 |
3 | const documentClient = new DynamoDB.DocumentClient({
4 | region: process.env.REGION
5 | });
6 |
7 | export const deleteItem = async (event) => {
8 |
9 | try {
10 | const { pathParameters: { id } } = event;
11 | const params = {
12 | TableName: process.env.TABLE_NAME,
13 | Key: { id }
14 | };
15 | await documentClient.delete(params).promise();
16 | const response = {
17 | statusCode: 200,
18 | body: JSON.stringify(
19 | {
20 | message: 'success deleted !'
21 | },
22 | null,
23 | 2
24 | )
25 | }
26 | return response;
27 | } catch (e) {
28 | return {
29 | statusCode: 500,
30 | body: JSON.stringify(e)
31 | };
32 | }
33 |
34 |
35 | }
--------------------------------------------------------------------------------
/node js-with-serverless/functions/edit_item.ts:
--------------------------------------------------------------------------------
1 | import {DynamoDB} from 'aws-sdk';
2 | import { eventData, dbItem } from '../models/table_schema';
3 | import { dynamoUpdatedParams } from '../shared/update_dynamo';
4 |
5 | const documentClient = new DynamoDB.DocumentClient({
6 | region:process.env.REGION
7 | });
8 |
9 | export const editItem = async(event)=> {
10 | try {
11 | const {pathParameters: { id } } = event;
12 | const eventItem:eventData =JSON.parse(event.body)
13 | const dbUpdateItem:dbItem = dynamoUpdatedParams(eventItem,id);
14 | await documentClient.put(dbUpdateItem).promise();
15 | const response = {
16 | statusCode: 200,
17 | body: JSON.stringify(
18 | {
19 | message: 'success updated !'
20 | })
21 | };
22 | return response;
23 | } catch (e) {
24 | return {
25 | statusCode: 500,
26 | body: JSON.stringify(e)
27 | };
28 | }
29 |
30 |
31 | }
--------------------------------------------------------------------------------
/node js-with-serverless/functions/read_all.ts:
--------------------------------------------------------------------------------
1 | import {DynamoDB} from 'aws-sdk';
2 |
3 | const documentClient = new DynamoDB.DocumentClient({
4 | region:process.env.REGION
5 | });
6 |
7 | export const readAll = async(event)=> {
8 | const params = {
9 | TableName: process.env.TABLE_NAME
10 | };
11 | try {
12 | const data = await documentClient.scan(params).promise();
13 | const response = {
14 | statusCode: 200,
15 | body: JSON.stringify(data.Items)
16 | };
17 | return response;
18 | } catch (e) {
19 | return {
20 | statusCode: 500,
21 | body: JSON.stringify(e)
22 | };
23 | }
24 |
25 |
26 | }
--------------------------------------------------------------------------------
/node js-with-serverless/functions/read_single_item.ts:
--------------------------------------------------------------------------------
1 | import {DynamoDB} from 'aws-sdk';
2 |
3 | const documentClient = new DynamoDB.DocumentClient({
4 | region:process.env.REGION
5 | });
6 |
7 | export const readSingleItem = async(event)=> {
8 | const {pathParameters: { id } } = event;
9 | const params = {
10 | TableName: process.env.TABLE_NAME,
11 | Key: {id}
12 | };
13 | try {
14 | const data = await documentClient.get(params).promise();
15 | const response = {
16 | statusCode: 200,
17 | body: JSON.stringify(data.Item? data.Item:{message:'Item not found'})
18 | };
19 | return response;
20 | } catch (e) {
21 | return {
22 | statusCode: 500,
23 | body: JSON.stringify(e)
24 | };
25 | }
26 |
27 |
28 | }
--------------------------------------------------------------------------------
/node js-with-serverless/functions/write_item.ts:
--------------------------------------------------------------------------------
1 | import {DynamoDB} from 'aws-sdk';
2 | import { eventData, dbItem } from '../models/table_schema';
3 | import { dynamoParams } from '../shared/create_dynamo';
4 |
5 | const documentClient = new DynamoDB.DocumentClient({
6 | region:process.env.REGION
7 | });
8 |
9 | export const writeItem = async(event)=> {
10 | try{
11 | const insertData:eventData =JSON.parse(event.body)
12 | const dbInsertItem:dbItem = dynamoParams(insertData);
13 | await documentClient.put(dbInsertItem).promise();
14 | const response = {
15 | statusCode: 200,
16 | body: JSON.stringify(
17 | {
18 | message: 'success inserted !'
19 | },
20 | null,
21 | 2
22 | )
23 | }
24 | return response;
25 | }catch (e) {
26 | return {
27 | statusCode: 500,
28 | body: JSON.stringify(e)
29 | };
30 | }
31 | }
--------------------------------------------------------------------------------
/node js-with-serverless/models/table_schema.ts:
--------------------------------------------------------------------------------
1 | export interface eventData {
2 | title: string,
3 | description:string,
4 | compl_time:string,
5 | creat_time:string
6 | }
7 |
8 | export interface schema extends eventData{
9 | id:string
10 | }
11 |
12 | export interface dbItem {
13 | TableName:string,
14 | Item:schema
15 | }
--------------------------------------------------------------------------------
/node js-with-serverless/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "xanalytics-android-server",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "handler.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "gully": "rm -rf .build && sls invoke local -f $1"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "aws-sdk": "^2.617.0",
14 | "serverless-offline": "^5.12.1",
15 | "serverless-plugin-typescript": "^1.1.9",
16 | "typescript": "^3.7.5",
17 | "@types/node": "^13.7.1"
18 | },
19 | "dependencies": {
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/node js-with-serverless/shared/create_dynamo.ts:
--------------------------------------------------------------------------------
1 | import {eventData, dbItem, schema} from '../models/table_schema'
2 | import {randomBytes} from 'crypto';
3 |
4 | export const dynamoParams= (Item:eventData)=>{
5 | const UUID = randomBytes(16).toString("hex");
6 | const item:schema={id:UUID,...Item}
7 | const dynamoTableItem:dbItem = {
8 | TableName:process.env.TABLE_NAME,
9 | Item:item
10 | }
11 | return dynamoTableItem;
12 | }
--------------------------------------------------------------------------------
/node js-with-serverless/shared/update_dynamo.ts:
--------------------------------------------------------------------------------
1 | import {eventData, dbItem, schema} from '../models/table_schema'
2 |
3 | export const dynamoUpdatedParams= (Item:eventData, id:string)=>{
4 | const item:schema={id:id,...Item}
5 | const dynamoTableItem:dbItem = {
6 | TableName:process.env.TABLE_NAME,
7 | Item:item
8 | }
9 | return dynamoTableItem;
10 | }
--------------------------------------------------------------------------------
/node-js-lambda-sqs-serverless/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
3 | npm-debug.log
4 | dist/
5 | coverage/
6 | mongo/db
7 |
--------------------------------------------------------------------------------
/node-js-lambda-sqs-serverless/README.md:
--------------------------------------------------------------------------------
1 | # AWSLambdaSQSNode
2 | AWS Lambda PoC over SQS using Node.js and MongoDB Atlas
3 |
--------------------------------------------------------------------------------
/node-js-lambda-sqs-serverless/data.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "ShishQueue",
3 | "description": "Shish REST API with Queue"
4 | }
--------------------------------------------------------------------------------
/node-js-lambda-sqs-serverless/models/note.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 | const NoteSchema = new mongoose.Schema({
3 | title: String,
4 | description: String
5 | });
6 | module.exports = mongoose.model('Note', NoteSchema);
--------------------------------------------------------------------------------
/node-js-lambda-sqs-serverless/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rest-api",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "handler.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "serverless-offline": "^3.20.1"
14 | },
15 | "dependencies": {
16 | "aws-sdk": "^2.222.1",
17 | "dotenv": "^5.0.1",
18 | "mongoose": "^5.0.13"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/node-microservice-starter/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 | .gitignore
3 | README.md
4 | docker-compose.yml
5 | node_modules
6 |
--------------------------------------------------------------------------------
/node-microservice-starter/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 |
11 | # 2 space indentation
12 | [**.*]
13 | indent_style = space
14 | indent_size = 2
15 |
16 | [*.yml]
17 | indent_style = space
18 | indent_size = 4
19 |
--------------------------------------------------------------------------------
/node-microservice-starter/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/node-microservice-starter/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
3 | npm-debug.log
4 | dist/
5 | coverage/
6 | mongo/db
7 |
--------------------------------------------------------------------------------
/node-microservice-starter/nginx/Dockerfile:
--------------------------------------------------------------------------------
1 | # Set nginx base image
2 | FROM nginx
3 |
4 | # File Author / Maintainer
5 | MAINTAINER Swimlane
6 |
7 | # Copy custom configuration file from the current directory
8 | COPY nginx.conf /etc/nginx/nginx.conf
9 |
--------------------------------------------------------------------------------
/node-microservice-starter/nginx/nginx.conf:
--------------------------------------------------------------------------------
1 | worker_processes 4;
2 |
3 | events { worker_connections 1024; }
4 |
5 | http {
6 |
7 | server {
8 | listen 80;
9 | charset utf-8;
10 |
11 | location / {
12 | proxy_pass http://store:8080;
13 | proxy_http_version 1.1;
14 | proxy_set_header Upgrade $http_upgrade;
15 | proxy_set_header Connection 'upgrade';
16 | proxy_set_header Host $host;
17 | proxy_cache_bypass $http_upgrade;
18 | }
19 |
20 | location ~ ^/users {
21 | rewrite ^/users/(.*) /$1 break;
22 | proxy_pass http://users:8080;
23 | proxy_http_version 1.1;
24 | proxy_set_header Upgrade $http_upgrade;
25 | proxy_set_header Connection 'upgrade';
26 | proxy_set_header Host $host;
27 | proxy_cache_bypass $http_upgrade;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: '@typescript-eslint/parser',
3 | parserOptions: {
4 | project: 'tsconfig.json',
5 | sourceType: 'module',
6 | },
7 | plugins: ['@typescript-eslint/eslint-plugin'],
8 | extends: [
9 | 'plugin:@typescript-eslint/eslint-recommended',
10 | 'plugin:@typescript-eslint/recommended',
11 | 'prettier',
12 | 'prettier/@typescript-eslint',
13 | ],
14 | root: true,
15 | env: {
16 | node: true,
17 | jest: true,
18 | },
19 | rules: {
20 | '@typescript-eslint/interface-name-prefix': 'off',
21 | '@typescript-eslint/explicit-function-return-type': 'off',
22 | '@typescript-eslint/explicit-module-boundary-types': 'off',
23 | '@typescript-eslint/no-explicit-any': 'off',
24 | },
25 | };
26 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all"
4 | }
--------------------------------------------------------------------------------
/node-microservice-starter/users/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:latest
2 |
3 | RUN npm i -g nodemon node-inspector npm-run-all rimraf
4 |
5 | RUN mkdir -p /usr/src/app
6 | WORKDIR /usr/src/app
7 |
8 | COPY package.json /usr/src/app/package.json
9 | RUN npm install
10 |
11 | COPY . /usr/src/app
12 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/nest-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "collection": "@nestjs/schematics",
3 | "sourceRoot": "src"
4 | }
5 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/src/app.controller.spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { AppController } from './app.controller';
3 | import { AppService } from './app.service';
4 |
5 | describe('AppController', () => {
6 | let appController: AppController;
7 |
8 | beforeEach(async () => {
9 | const app: TestingModule = await Test.createTestingModule({
10 | controllers: [AppController],
11 | providers: [AppService],
12 | }).compile();
13 |
14 | appController = app.get(AppController);
15 | });
16 |
17 | describe('root', () => {
18 | it('should return "Hello World!"', () => {
19 | expect(appController.getHello()).toBe('Hello World!');
20 | });
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/src/app.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get } from '@nestjs/common';
2 | import { AppService } from './app.service';
3 |
4 | @Controller()
5 | export class AppController {
6 | constructor(private readonly appService: AppService) {}
7 |
8 | @Get()
9 | getHello(): string {
10 | return this.appService.getHello();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/src/app.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { AppController } from './app.controller';
3 | import { AppService } from './app.service';
4 |
5 | @Module({
6 | imports: [],
7 | controllers: [AppController],
8 | providers: [AppService],
9 | })
10 | export class AppModule {}
11 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/src/app.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 |
3 | @Injectable()
4 | export class AppService {
5 | getHello(): string {
6 | return 'Hello World!';
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/src/main.ts:
--------------------------------------------------------------------------------
1 | import { NestFactory } from '@nestjs/core';
2 | import { AppModule } from './app.module';
3 |
4 | async function bootstrap() {
5 | const app = await NestFactory.create(AppModule);
6 | await app.listen(3000);
7 | }
8 | bootstrap();
9 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/test/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { INestApplication } from '@nestjs/common';
3 | import * as request from 'supertest';
4 | import { AppModule } from './../src/app.module';
5 |
6 | describe('AppController (e2e)', () => {
7 | let app: INestApplication;
8 |
9 | beforeEach(async () => {
10 | const moduleFixture: TestingModule = await Test.createTestingModule({
11 | imports: [AppModule],
12 | }).compile();
13 |
14 | app = moduleFixture.createNestApplication();
15 | await app.init();
16 | });
17 |
18 | it('/ (GET)', () => {
19 | return request(app.getHttpServer())
20 | .get('/')
21 | .expect(200)
22 | .expect('Hello World!');
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/test/jest-e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "moduleFileExtensions": ["js", "json", "ts"],
3 | "rootDir": ".",
4 | "testEnvironment": "node",
5 | "testRegex": ".e2e-spec.ts$",
6 | "transform": {
7 | "^.+\\.(t|j)s$": "ts-jest"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
4 | }
5 |
--------------------------------------------------------------------------------
/node-microservice-starter/users/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "declaration": true,
5 | "removeComments": true,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "allowSyntheticDefaultImports": true,
9 | "target": "es2017",
10 | "sourceMap": true,
11 | "outDir": "./dist",
12 | "baseUrl": "./",
13 | "incremental": true
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/.dockerignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | *.log
3 | npm-debug.log*
4 | yarn-debug.log*
5 | yarn-error.log*
6 |
7 | # Runtime data
8 | pids
9 | *.pid
10 | *.seed
11 | *.pid.lock
12 |
13 | # Dependency directories
14 | node_modules/
15 |
16 | # 0x directories
17 | *.0x/
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/.env.example:
--------------------------------------------------------------------------------
1 | # General
2 | APP_NAME=
3 | APP_TITLE=
4 | APP_DESCRIPTION=
5 | APP_IMAGE=
6 |
7 | # API
8 | APP_VERSION=1.0
9 | APP_PREFIX=v1
10 | APP_API_EXPLORER_PATH=/api
11 |
12 | # Server
13 | APP_HOST=
14 | APP_PORT=7070
15 |
16 | # Logger
17 | LOG_DIRECTORY=
18 | LOG_FILENAME=
19 | LOG_LEVEL=
20 |
21 | # Loggly
22 | LOGGLY_TOKEN=
23 | LOGGLY_SUBDOMAIN=
24 |
25 | # APM
26 | ELASTIC_APM_SERVICE_NAME=
27 | ELASTIC_APM_SECRET_TOKEN=
28 | ELASTIC_APM_SERVER_URL=
29 |
30 | # EVENT STORE
31 | EVENT_STORE_HOSTNAME=0.0.0.0
32 | EVENT_STORE_PORT=1113
33 | EVENT_STORE_CREDENTIALS_USERNAME=admin
34 | EVENT_STORE_CREDENTIALS_PASSWORD=changeit
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/Dockerfile:
--------------------------------------------------------------------------------
1 | ### BASE
2 | FROM node:dubnium-alpine AS base
3 | LABEL maintainer "Qasim Soomro "
4 | # Set the working directory
5 | WORKDIR /app
6 | # Copy project specification and dependencies lock files
7 | COPY package.json yarn.lock tsconfig.json /tmp/
8 | # Install yarn
9 | RUN apk --no-cache add yarn
10 |
11 | ### DEPENDENCIES
12 | FROM base AS dependencies
13 | # Install Node.js dependencies
14 | RUN cd /tmp && yarn --pure-lockfile
15 |
16 | ### RELEASE
17 | FROM base AS development
18 | # Copy app sources
19 | COPY . .
20 | # Copy dependencies
21 | COPY --from=dependencies /tmp/node_modules ./node_modules
22 | # Expose application port
23 | EXPOSE 7070
24 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/docs/README.md:
--------------------------------------------------------------------------------
1 | # `/docs`
2 |
3 | Design and user documents.
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/githooks/README.md:
--------------------------------------------------------------------------------
1 | # `/githooks`
2 |
3 | Git hooks.
4 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/nest-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "language": "ts",
3 | "collection": "@nestjs/schematics",
4 | "sourceRoot": "src"
5 | }
6 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/nodemon-debug.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch": ["src"],
3 | "ext": "ts",
4 | "ignore": ["src/**/*.spec.ts"],
5 | "exec": "node --inspect-brk -r ts-node/register src/main.ts"
6 | }
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/nodemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch": ["src"],
3 | "ext": "ts",
4 | "ignore": ["src/**/*.spec.ts"],
5 | "exec": "ts-node -r tsconfig-paths/register src/main.ts",
6 | "events": {
7 | "restart": "osascript -e 'display notification \"boilerplate-nodejs-cqrs-es-swagger restarted\" with title \"nodemon\"'"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/scripts/down.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | export DIR_DATA_PATH="$PWD"
4 |
5 | export CONTAINER_COMMAND="yarn start:dev"
6 | export CONTAINER_SCALE="1"
7 | export CONTAINER_PORT="7070"
8 |
9 | docker-compose down
10 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/scripts/up.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | export DIR_DATA_PATH="$PWD"
4 |
5 | export CONTAINER_COMMAND="yarn start:dev"
6 | export CONTAINER_SCALE="1"
7 | export CONTAINER_PORT="7070"
8 |
9 | docker-compose up --build
10 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/app.module.ts:
--------------------------------------------------------------------------------
1 | import { Module, OnModuleInit } from '@nestjs/common';
2 | import { UsersModule } from './users/users.module';
3 | import { EventStoreModule } from './core/event-store/event-store.module';
4 |
5 | @Module({
6 | imports: [
7 | EventStoreModule.forRoot(),
8 | /** ------------- */
9 | UsersModule,
10 | ],
11 | })
12 | export class AppModule implements OnModuleInit {
13 | async onModuleInit() {}
14 | }
15 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/core/event-store/event-store.class.ts:
--------------------------------------------------------------------------------
1 | import { TCPClient, EventFactory} from 'geteventstore-promise';
2 |
3 | /**
4 | * @class EventStore
5 | * @description EventStore.org
6 | */
7 | export class EventStore {
8 | [x: string]: any;
9 |
10 | /**
11 | * @constructor
12 | */
13 | constructor() {
14 | this.type = 'event-store';
15 | this.eventFactory = new EventFactory();
16 | }
17 |
18 | connect(config) {
19 | this.client = new TCPClient(config);
20 | return this;
21 | }
22 |
23 | getClient() {
24 | return this.client;
25 | }
26 |
27 | newEvent(name, payload) {
28 | return this.eventFactory.newEvent(name, payload);
29 | }
30 |
31 | close() {
32 | this.client.close();
33 | return this;
34 | }
35 | }
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/core/event-store/event-store.interface.ts:
--------------------------------------------------------------------------------
1 | export interface EventStoreMessage {
2 | streamId: string;
3 | eventId: string;
4 | eventNumber: number;
5 | eventType: string;
6 | created: Date;
7 | metadata: object;
8 | isJson: boolean;
9 | data: object;
10 | }
11 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/core/event-store/event-store.module.ts:
--------------------------------------------------------------------------------
1 | import { Global, Module, DynamicModule } from '@nestjs/common';
2 | import { EventStore } from './event-store';
3 | import { eventStoreProviders } from './event-store.provider';
4 |
5 | @Global()
6 | @Module({
7 | providers: [
8 | ...eventStoreProviders,
9 | {
10 | provide: 'EVENT_STORE_CONFIG',
11 | useValue: 'EVENT_STORE_CONFIG_USE_ENV',
12 | },
13 | ],
14 | exports: [
15 | ...eventStoreProviders,
16 | {
17 | provide: 'EVENT_STORE_CONFIG',
18 | useValue: 'EVENT_STORE_CONFIG_USE_ENV',
19 | },
20 | ],
21 | })
22 | export class EventStoreModule {
23 | static forRoot(): DynamicModule {
24 | return {
25 | module: EventStoreModule,
26 | };
27 | }
28 |
29 | static forFeature(): DynamicModule {
30 | return {
31 | module: EventStoreModule,
32 | providers: [
33 | EventStore,
34 | ],
35 | exports: [
36 | EventStore,
37 | ],
38 | };
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/core/event-store/event-store.provider.ts:
--------------------------------------------------------------------------------
1 | import {config} from '../../../config';
2 | import {EventStore} from './event-store.class';
3 |
4 | export const eventStoreProviders = [
5 | {
6 | provide: 'EVENT_STORE_PROVIDER',
7 | useFactory: (
8 | eventStoreConfig?: any,
9 | ): any => {
10 | if (eventStoreConfig === 'EVENT_STORE_CONFIG_USE_ENV') {
11 | return new EventStore();
12 | }
13 | },
14 | inject: ['EVENT_STORE_CONFIG'],
15 | },
16 | ];
17 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/commands/handlers/create-user.handler.ts:
--------------------------------------------------------------------------------
1 | import { EventPublisher, ICommandHandler, CommandHandler } from '@nestjs/cqrs';
2 | import { CreateUserCommand } from '../impl/create-user.command';
3 | import { UserRepository } from '../../repository/user.repository';
4 | import { Logger } from '@nestjs/common';
5 |
6 | @CommandHandler(CreateUserCommand)
7 | export class CreateUserHandler
8 | implements ICommandHandler {
9 | constructor(
10 | private readonly repository: UserRepository,
11 | private readonly publisher: EventPublisher,
12 | ) {}
13 |
14 | async execute(command: CreateUserCommand, resolve: (value?) => void) {
15 | Logger.log('Async CreateUserHandler...', 'CreateUserCommand');
16 |
17 | const {userDto} = command;
18 | const user = this.publisher.mergeObjectContext(
19 | await this.repository.createUser(userDto),
20 | );
21 | user.commit();
22 | resolve();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/commands/handlers/delete-user.handler.ts:
--------------------------------------------------------------------------------
1 | import { EventPublisher, ICommandHandler, CommandHandler } from '@nestjs/cqrs';
2 | import { DeleteUserCommand } from '../impl/delete-user.command';
3 | import { UserRepository } from '../../repository/user.repository';
4 | import { Logger } from '@nestjs/common';
5 |
6 | @CommandHandler(DeleteUserCommand)
7 | export class DeleteUserHandler
8 | implements ICommandHandler {
9 | constructor(
10 | private readonly repository: UserRepository,
11 | private readonly publisher: EventPublisher,
12 | ) {}
13 |
14 | async execute(command: DeleteUserCommand, resolve: (value?) => void) {
15 | Logger.log('Async DeleteUserHandler...', 'DeleteUserCommand');
16 | const {userDto} = command;
17 | const user = this.publisher.mergeObjectContext(
18 | await this.repository.deleteUser(userDto),
19 | );
20 | user.commit();
21 | resolve();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/commands/handlers/index.ts:
--------------------------------------------------------------------------------
1 | import { CreateUserHandler } from './create-user.handler';
2 | import { DeleteUserHandler } from './delete-user.handler';
3 | import { UpdateUserHandler } from './update-user.handler';
4 | import { WelcomeUserHandler } from './welcome-user.handler';
5 |
6 | export const CommandHandlers = [
7 | CreateUserHandler,
8 | DeleteUserHandler,
9 | UpdateUserHandler,
10 | WelcomeUserHandler,
11 | ];
12 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/commands/handlers/update-user.handler.ts:
--------------------------------------------------------------------------------
1 | import { EventPublisher, ICommandHandler, CommandHandler } from '@nestjs/cqrs';
2 | import { UpdateUserCommand } from '../impl/update-user.command';
3 | import { UserRepository } from '../../repository/user.repository';
4 | import { Logger } from '@nestjs/common';
5 |
6 | @CommandHandler(UpdateUserCommand)
7 | export class UpdateUserHandler
8 | implements ICommandHandler {
9 | constructor(
10 | private readonly repository: UserRepository,
11 | private readonly publisher: EventPublisher,
12 | ) {}
13 |
14 | async execute(command: UpdateUserCommand, resolve: (value?) => void) {
15 | Logger.log('Async UpdateUserHandler...', 'UpdateUserCommand');
16 |
17 | const {userDto} = command;
18 | const user = this.publisher.mergeObjectContext(
19 | await this.repository.updateUser(userDto),
20 | );
21 | user.commit();
22 | resolve();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/commands/handlers/welcome-user.handler.ts:
--------------------------------------------------------------------------------
1 | import { EventPublisher, ICommandHandler, CommandHandler } from '@nestjs/cqrs';
2 | import { WelcomeUserCommand } from '../impl/welcome-user.command';
3 | import { UserRepository } from '../../repository/user.repository';
4 | import { Logger } from '@nestjs/common';
5 |
6 | @CommandHandler(WelcomeUserCommand)
7 | export class WelcomeUserHandler
8 | implements ICommandHandler {
9 | constructor(
10 | private readonly repository: UserRepository,
11 | private readonly publisher: EventPublisher,
12 | ) {}
13 |
14 | async execute(command: WelcomeUserCommand, resolve: (value?) => void) {
15 | Logger.log('Async WelcomeUserHandler...', 'WelcomeUserCommand');
16 | const {userId} = command;
17 | const user = this.publisher.mergeObjectContext(
18 | await this.repository.welcomeUser({userId}),
19 | );
20 | user.commit();
21 | resolve();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/commands/impl/create-user.command.ts:
--------------------------------------------------------------------------------
1 | import { ICommand } from '@nestjs/cqrs';
2 | import { UserDto } from '../../dtos/users.dto';
3 |
4 | export class CreateUserCommand implements ICommand {
5 | constructor(
6 | public readonly userDto: UserDto,
7 | ) {}
8 | }
9 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/commands/impl/delete-user.command.ts:
--------------------------------------------------------------------------------
1 | import { ICommand } from '@nestjs/cqrs';
2 | import { UserIdRequestParamsDto } from '../../dtos/users.dto';
3 |
4 | export class DeleteUserCommand implements ICommand {
5 | constructor(
6 | public readonly userDto: UserIdRequestParamsDto,
7 | ) {}
8 | }
9 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/commands/impl/update-user.command.ts:
--------------------------------------------------------------------------------
1 | import { ICommand } from '@nestjs/cqrs';
2 | import { UserDto } from '../../dtos/users.dto';
3 |
4 | export class UpdateUserCommand implements ICommand {
5 | constructor(
6 | public readonly userDto: UserDto,
7 | ) {}
8 | }
9 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/commands/impl/welcome-user.command.ts:
--------------------------------------------------------------------------------
1 | import { ICommand } from '@nestjs/cqrs';
2 |
3 | export class WelcomeUserCommand implements ICommand {
4 | constructor(
5 | public readonly userId: string,
6 | ) {}
7 | }
8 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/controllers/users.controller.spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { UsersController } from './users.controller';
3 | import { UsersService } from '../services/users.service';
4 |
5 | describe('Users Controller', () => {
6 | let module: TestingModule;
7 | beforeAll(async () => {
8 | module = await Test.createTestingModule({
9 | controllers: [UsersController],
10 | providers: [UsersService],
11 | }).compile();
12 | });
13 | it('should be defined', () => {
14 | const controller: UsersController = module.get(UsersController);
15 | expect(controller).toBeDefined();
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/dtos/users.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsString } from 'class-validator';
2 |
3 | export class UserIdRequestParamsDto {
4 | @IsString()
5 | readonly userId!: string;
6 | }
7 |
8 | export class UserDto {
9 | @IsString()
10 | readonly userId!: string;
11 | @IsString()
12 | readonly firstName!: string;
13 | @IsString()
14 | readonly lastName!: string;
15 | }
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/events/handlers/index.ts:
--------------------------------------------------------------------------------
1 | import { UserCreatedHandler} from './user-created.handler';
2 | import { UserUpdatedHandler} from './user-updated.handler';
3 | import { UserDeletedHandler} from './user-deleted.handler';
4 | import { UserWelcomedHandler} from './user-welcomed.handler';
5 |
6 | export const EventHandlers = [
7 | UserCreatedHandler,
8 | UserUpdatedHandler,
9 | UserDeletedHandler,
10 | UserWelcomedHandler,
11 | ];
12 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/events/handlers/user-created.handler.ts:
--------------------------------------------------------------------------------
1 |
2 | import { IEventHandler, EventsHandler } from '@nestjs/cqrs';
3 | import { UserCreatedEvent } from '../impl/user-created.event';
4 | import { Logger } from '@nestjs/common';
5 |
6 | @EventsHandler(UserCreatedEvent)
7 | export class UserCreatedHandler
8 | implements IEventHandler {
9 | handle(event: UserCreatedEvent) {
10 | Logger.log(event, 'UserCreatedEvent'); // write here
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/events/handlers/user-deleted.handler.ts:
--------------------------------------------------------------------------------
1 | import { IEventHandler, EventsHandler } from '@nestjs/cqrs';
2 | import { UserDeletedEvent } from '../impl/user-deleted.event';
3 | import { Logger } from '@nestjs/common';
4 |
5 | @EventsHandler(UserDeletedEvent)
6 | export class UserDeletedHandler
7 | implements IEventHandler {
8 | handle(event: UserDeletedEvent) {
9 | Logger.log(event, 'UserDeletedEvent'); // write here
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/events/handlers/user-updated.handler.ts:
--------------------------------------------------------------------------------
1 | import { IEventHandler, EventsHandler } from '@nestjs/cqrs';
2 | import { UserUpdatedEvent } from '../impl/user-updated.event';
3 | import { Logger } from '@nestjs/common';
4 |
5 | @EventsHandler(UserUpdatedEvent)
6 | export class UserUpdatedHandler
7 | implements IEventHandler {
8 | handle(event: UserUpdatedEvent) {
9 | Logger.log(event, 'UserUpdatedEvent'); // write here
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/events/handlers/user-welcomed.handler.ts:
--------------------------------------------------------------------------------
1 | import { IEventHandler, EventsHandler } from '@nestjs/cqrs';
2 | import { UserWelcomedEvent } from '../impl/user-welcomed.event';
3 | import { Logger } from '@nestjs/common';
4 |
5 | @EventsHandler(UserWelcomedEvent)
6 | export class UserWelcomedHandler
7 | implements IEventHandler {
8 | handle(event: UserWelcomedEvent) {
9 | Logger.log(event, 'UserWelcomedEvent'); // write here
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/events/impl/user-created.event.ts:
--------------------------------------------------------------------------------
1 | import { IEvent } from '@nestjs/cqrs';
2 | import { UserDto } from '../../dtos/users.dto';
3 |
4 | export class UserCreatedEvent implements IEvent {
5 | constructor(
6 | public readonly userDto: UserDto) {}
7 | }
8 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/events/impl/user-deleted.event.ts:
--------------------------------------------------------------------------------
1 | import { IEvent } from '@nestjs/cqrs';
2 |
3 | export class UserDeletedEvent implements IEvent {
4 | constructor(
5 | public readonly userId: string) {}
6 | }
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/events/impl/user-updated.event.ts:
--------------------------------------------------------------------------------
1 | import { IEvent } from '@nestjs/cqrs';
2 | import { UserDto } from '../../dtos/users.dto';
3 |
4 | export class UserUpdatedEvent implements IEvent {
5 | constructor(
6 | public readonly userDto: UserDto) {}
7 | }
8 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/events/impl/user-welcomed.event.ts:
--------------------------------------------------------------------------------
1 | import { IEvent } from '@nestjs/cqrs';
2 |
3 | export class UserWelcomedEvent implements IEvent {
4 | constructor(
5 | public readonly userId: string) {}
6 | }
7 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/models/user.model.ts:
--------------------------------------------------------------------------------
1 | import { AggregateRoot } from '@nestjs/cqrs';
2 | import { UserCreatedEvent } from '../events/impl/user-created.event';
3 | import { UserUpdatedEvent } from '../events/impl/user-updated.event';
4 | import { UserDeletedEvent } from '../events/impl/user-deleted.event';
5 | import { UserWelcomedEvent } from '../events/impl/user-welcomed.event';
6 | import { UserDto } from '../dtos/users.dto';
7 |
8 | export class User extends AggregateRoot {
9 | [x: string]: any;
10 |
11 | constructor(private readonly id: string | undefined) {
12 | super();
13 | }
14 |
15 | setData(data) {
16 | this.data = data;
17 | }
18 |
19 | createUser() {
20 | this.apply(new UserCreatedEvent(this.data));
21 | }
22 |
23 | updateUser() {
24 | this.apply(new UserUpdatedEvent(this.data));
25 | }
26 |
27 | welcomeUser() {
28 | this.apply(new UserWelcomedEvent(this.id));
29 | }
30 |
31 | deleteUser() {
32 | this.apply(new UserDeletedEvent(this.id));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/repository/user.repository.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 | import { User } from '../models/user.model';
3 |
4 | @Injectable()
5 | export class UserRepository {
6 | async createUser(userDto) {
7 | const user = new User(undefined);
8 | user.setData(userDto);
9 | user.createUser();
10 | return user;
11 | }
12 |
13 | async updateUser(userDto) {
14 | const user = new User(userDto.userId);
15 | user.setData(userDto);
16 | user.updateUser();
17 | return user;
18 | }
19 |
20 | async deleteUser(userDto) {
21 | const user = new User(userDto.userId);
22 | user.deleteUser();
23 | return user;
24 | }
25 |
26 | async welcomeUser(userDto) {
27 | const user = new User(userDto.userId);
28 | user.welcomeUser();
29 | return user;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/src/users/sagas/users.sagas.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, Logger } from '@nestjs/common';
2 | import { Observable } from 'rxjs';
3 | import { ICommand, EventObservable } from '@nestjs/cqrs';
4 | import { UserCreatedEvent } from '../events/impl/user-created.event';
5 | import { WelcomeUserCommand } from '../commands/impl/welcome-user.command';
6 | import { delay, map } from 'rxjs/operators';
7 |
8 | @Injectable()
9 | export class UsersSagas {
10 | userCreated = (events$: EventObservable): Observable => {
11 | return events$
12 | .ofType(UserCreatedEvent)
13 | .pipe(
14 | delay(1000),
15 | map(event => {
16 | Logger.log('Inside [UsersSagas] Saga', 'UsersSagas');
17 | const userId = event.userDto[0].userId[0];
18 | return new WelcomeUserCommand(userId);
19 | }),
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/test/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { INestApplication } from '@nestjs/common';
2 | import { Test } from '@nestjs/testing';
3 | import * as request from 'supertest';
4 | import { AppModule } from './../src/app.module';
5 |
6 | describe('AppController (e2e)', () => {
7 | let app: INestApplication;
8 |
9 | beforeAll(async () => {
10 | const moduleFixture = await Test.createTestingModule({
11 | imports: [AppModule],
12 | }).compile();
13 |
14 | app = moduleFixture.createNestApplication();
15 | await app.init();
16 | });
17 |
18 | // it('/ (GET)', () => {
19 | // return request(app.getHttpServer())
20 | // .get('/')
21 | // .expect(200)
22 | // .expect('Hello World!');
23 | // });
24 | });
25 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/test/jest-e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "moduleFileExtensions": ["js", "json", "ts"],
3 | "rootDir": ".",
4 | "testEnvironment": "node",
5 | "testRegex": ".e2e-spec.ts$",
6 | "transform": {
7 | "^.+\\.(t|j)s$": "ts-jest"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "declaration": true,
5 | "noImplicitAny": false,
6 | "removeComments": true,
7 | "noLib": false,
8 | "allowSyntheticDefaultImports": true,
9 | "emitDecoratorMetadata": true,
10 | "experimentalDecorators": true,
11 | "target": "es6",
12 | "sourceMap": true,
13 | "outDir": "./dist",
14 | "baseUrl": "./src",
15 | "resolveJsonModule": true,
16 | "esModuleInterop": true
17 | },
18 | "include": [
19 | "src/**/*",
20 | "pipes/*",
21 | "middlewares/*",
22 | ],
23 | "exclude": [
24 | "node_modules",
25 | "**/*.spec.ts"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/nodejs-cqrs-pattern/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tsconfig.json",
3 | "compilerOptions": {
4 | "types": ["jest", "node"]
5 | },
6 | "include": ["**/*.spec.ts", "**/*.d.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/.editorconfig:
--------------------------------------------------------------------------------
1 | ################################################
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/.eslintignore:
--------------------------------------------------------------------------------
1 | build/*
2 |
3 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 | # dependencies
3 | /node_modules
4 |
5 | # misc
6 | .DS_Store
7 | .env*
8 |
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | .env
13 | build
--------------------------------------------------------------------------------
/nodejs-express-typescript/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "trailingComma": "all",
4 | "singleQuote": true,
5 | "printWidth": 120,
6 | "tabWidth": 2,
7 | "arrowParens": "avoid"
8 | }
9 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/Procfile:
--------------------------------------------------------------------------------
1 | web: node build/app.js
--------------------------------------------------------------------------------
/nodejs-express-typescript/nodemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch": [
3 | "src",
4 | ".env"
5 | ],
6 | "ext": "js,ts,json",
7 | "ignore": [
8 | "src/**/*.spec.ts"
9 | ],
10 | "exec": "ts-node --transpile-only ./src/app.ts"
11 | }
--------------------------------------------------------------------------------
/nodejs-express-typescript/src/api/index.ts:
--------------------------------------------------------------------------------
1 | import { Router } from 'express';
2 | import auth from './routes/auth';
3 | import user from './routes/user';
4 |
5 | // guaranteed to get dependencies
6 | export default () => {
7 | const app = Router();
8 | auth(app);
9 |
10 | return app
11 | }
--------------------------------------------------------------------------------
/nodejs-express-typescript/src/api/middlewares/index.ts:
--------------------------------------------------------------------------------
1 | import isAuth from './isAuth';
2 |
3 | export default {
4 | isAuth,
5 | };
6 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/src/api/middlewares/isAuth.ts:
--------------------------------------------------------------------------------
1 | import jwt from 'express-jwt';
2 | import config from '../../config';
3 |
4 | const getTokenFromHeader = req => {
5 | /**
6 | * @TODO Edge and Internet Explorer do some weird things with the headers
7 | * So I believe that this should handle more 'edge' cases ;)
8 | */
9 | if (
10 | (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Token') ||
11 | (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer')
12 | ) {
13 | return req.headers.authorization.split(' ')[1];
14 | }
15 | return null;
16 | };
17 |
18 | const isAuth = jwt({
19 | secret: config.jwtSecret, // The _secret_ to sign the JWTs
20 | userProperty: 'token', // Use req.token to store the JWT
21 | getToken: getTokenFromHeader, // How to extract the JWT from the request
22 | algorithms: ['RS256']
23 | });
24 |
25 | export default isAuth;
26 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/src/app.ts:
--------------------------------------------------------------------------------
1 | import 'reflect-metadata'; // We need this in order to use @Decorators
2 | import config from './config';
3 | import express from 'express';
4 | import Logger from './loaders/logger';
5 | async function startServer() {
6 | const app = express();
7 | /**
8 | * A little hack here
9 | * Import/Export can only be used in 'top-level code'
10 | * Well, at least in node 10 without babel and at the time of writing
11 | * So we are using good old require.
12 | **/
13 | await require('./loaders').default({ expressApp: app });
14 |
15 | app.listen(config.port, (err) => {
16 | if (err) {
17 | Logger.error(err);
18 | process.exit(1);
19 | }
20 | Logger.info(`
21 | ################################################
22 | 🛡️ Server listening on port: ${config.port} 🛡️
23 | ################################################
24 | `);
25 | });
26 | }
27 |
28 | startServer();
29 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/src/interfaces/IUser.ts:
--------------------------------------------------------------------------------
1 | export interface IUser {
2 | _id: string;
3 | name: string;
4 | email: string;
5 | password: string;
6 | salt: string;
7 | }
8 |
9 | export interface IUserInputDTO {
10 | name: string;
11 | email: string;
12 | password: string;
13 | }
14 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/src/loaders/dependencyInjector.ts:
--------------------------------------------------------------------------------
1 | import { Container } from 'typedi';
2 | import LoggerInstance from './logger';
3 | import config from '../config';
4 |
5 | export default ({ mongoConnection, models }: { mongoConnection; models: { name: string; model: any }[] }) => {
6 | try {
7 | models.forEach(m => {
8 | Container.set(m.name, m.model);
9 | });
10 |
11 | Container.set('logger', LoggerInstance)
12 |
13 | LoggerInstance.info('✌️ Agenda injected into container');
14 | } catch (e) {
15 | LoggerInstance.error('🔥 Error on dependency injector loader: %o', e);
16 | throw e;
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/src/loaders/logger.ts:
--------------------------------------------------------------------------------
1 | import winston from 'winston';
2 | import config from '../config';
3 |
4 | const transports = [];
5 | if(process.env.NODE_ENV !== 'development') {
6 | transports.push(
7 | new winston.transports.Console()
8 | )
9 | } else {
10 | transports.push(
11 | new winston.transports.Console({
12 | format: winston.format.combine(
13 | winston.format.cli(),
14 | winston.format.splat(),
15 | )
16 | })
17 | )
18 | }
19 |
20 | const LoggerInstance = winston.createLogger({
21 | level: config.logs.level,
22 | levels: winston.config.npm.levels,
23 | format: winston.format.combine(
24 | winston.format.timestamp({
25 | format: 'YYYY-MM-DD HH:mm:ss'
26 | }),
27 | winston.format.errors({ stack: true }),
28 | winston.format.splat(),
29 | winston.format.json()
30 | ),
31 | transports
32 | });
33 |
34 | export default LoggerInstance;
--------------------------------------------------------------------------------
/nodejs-express-typescript/src/loaders/mongoose.ts:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | import config from '../config';
3 |
4 | export default async (): Promise => {
5 | const connection = await mongoose.connect(config.databaseURL, { useNewUrlParser: true, useCreateIndex: true });
6 | return connection.connection.db;
7 | };
8 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/src/models/user.ts:
--------------------------------------------------------------------------------
1 | import { IUser } from '../interfaces/IUser';
2 | import mongoose from 'mongoose';
3 |
4 | const User = new mongoose.Schema(
5 | {
6 | name: {
7 | type: String,
8 | required: [true, 'Please enter a full name'],
9 | index: true,
10 | },
11 |
12 | email: {
13 | type: String,
14 | lowercase: true,
15 | unique: true,
16 | index: true,
17 | },
18 |
19 | password: String,
20 |
21 | salt: String,
22 |
23 | role: {
24 | type: String,
25 | default: 'user',
26 | },
27 | },
28 | { timestamps: true },
29 | );
30 |
31 | export default mongoose.model('User', User);
32 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/src/types/express/index.d.ts:
--------------------------------------------------------------------------------
1 | import { Document, Model } from 'mongoose';
2 | import { IUser } from '../../interfaces/IUser';
3 | declare global {
4 | namespace Express {
5 | export interface Request {
6 | currentUser: IUser & Document;
7 | }
8 | }
9 |
10 | namespace Models {
11 | export type UserModel = Model;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/tests/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/nodejs-express-typescript/tests/.gitkeep
--------------------------------------------------------------------------------
/nodejs-express-typescript/tests/sample.test.ts:
--------------------------------------------------------------------------------
1 | describe('Sample Test', () => {
2 | it('can add 2 numbers', () => {
3 | expect(1 + 2).toBe(3);
4 | });
5 | });
6 |
--------------------------------------------------------------------------------
/nodejs-express-typescript/tests/services/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/nodejs-express-typescript/tests/services/.gitkeep
--------------------------------------------------------------------------------
/nodejs-express-typescript/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2017",
4 | "lib": [
5 | "es2017",
6 | "esnext.asynciterable"
7 | ],
8 | "typeRoots": [
9 | "./node_modules/@types",
10 | "./src/types"
11 | ],
12 | "allowSyntheticDefaultImports": true,
13 | "experimentalDecorators": true,
14 | "emitDecoratorMetadata": true,
15 | "forceConsistentCasingInFileNames": true,
16 | "moduleResolution": "node",
17 | "module": "commonjs",
18 | "pretty": true,
19 | "sourceMap": true,
20 | "outDir": "./build",
21 | "allowJs": true,
22 | "noEmit": false,
23 | "esModuleInterop": true
24 | },
25 | "include": [
26 | "./src/**/*"
27 | ],
28 | "exclude": [
29 | "node_modules",
30 | "tests"
31 | ]
32 | }
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkssharma/nodejs-microservices-patterns/2170453c4fafa19f405ddacb332fbafe5d4cfb96/nodejs-microservice-using-docker-Part-1/.DS_Store
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - "6"
5 |
6 | env:
7 | global:
8 | - NODE_ENV=test
9 | - MONGODB_URI=mongodb://localhost/service
10 |
11 | before_script:
12 | - "cd server"
13 | - "npm install"
14 | - "export DISPLAY=:99.0"
15 | - "sh -e /etc/init.d/xvfb start"
16 |
17 | script:
18 | - npm run coveralls
19 |
20 | after_success:
21 | - bash <(curl -s https://codecov.io/bash)
22 |
23 | services: mongodb
24 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/nginx/Dockerfile:
--------------------------------------------------------------------------------
1 | # Set nginx base image
2 | FROM nginx
3 |
4 | # File Author / Maintainer
5 | MAINTAINER Marcin Mrotek
6 |
7 | # Copy custom configuration file from the current directory
8 | COPY nginx.conf /etc/nginx/nginx.conf
9 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/nginx/nginx.conf:
--------------------------------------------------------------------------------
1 | worker_processes 4;
2 |
3 | events { worker_connections 1024; }
4 |
5 | http {
6 |
7 | upstream microservice {
8 | least_conn;
9 | server microservice1:9000 weight=10 max_fails=3 fail_timeout=30s;
10 | server microservice2:9000 weight=10 max_fails=3 fail_timeout=30s;
11 | server microservice3:9000 weight=10 max_fails=3 fail_timeout=30s;
12 | }
13 |
14 | server {
15 | listen 80;
16 |
17 | location / {
18 | proxy_pass http://microservice;
19 | proxy_http_version 1.1;
20 | proxy_set_header Upgrade $http_upgrade;
21 | proxy_set_header Connection 'upgrade';
22 | proxy_set_header Host $host;
23 | proxy_cache_bypass $http_upgrade;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-0"],
3 | "plugins": ["transform-class-properties"]
4 | }
5 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/.env.example:
--------------------------------------------------------------------------------
1 | PORT=
2 | IP=
3 | NODE_ENV=
4 | MONGODB_URI=
5 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | node_modules
3 | dist
4 | coverage
5 | server/config/.env
6 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "expr": true,
3 | "node": true,
4 | "esnext": true,
5 | "bitwise": true,
6 | "eqeqeq": true,
7 | "immed": true,
8 | "latedef": "nofunc",
9 | "newcap": true,
10 | "noarg": true,
11 | "undef": true,
12 | "smarttabs": true,
13 | "asi": true,
14 | "debug": true
15 | }
16 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/.jshintrc-spec:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ".jshintrc",
3 | "globals": {
4 | "describe": true,
5 | "it": true,
6 | "before": true,
7 | "beforeEach": true,
8 | "after": true,
9 | "afterEach": true,
10 | "expect": true,
11 | "assert": true,
12 | "sinon": true
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/Dockerfile:
--------------------------------------------------------------------------------
1 | # Set the base image to Node
2 | FROM node
3 |
4 | # File Author / Maintainer
5 | MAINTAINER Marcin Mrotek
6 |
7 | # Provides cached layer for node_modules
8 | ADD package.json /tmp/package.json
9 | RUN cd /tmp && npm install
10 | RUN mkdir -p /src && cp -a /tmp/node_modules /src/
11 | RUN npm install pm2 -g
12 |
13 | # Define working directory
14 | WORKDIR /src
15 | ADD . /src
16 |
17 | # Expose port
18 | EXPOSE 9000
19 |
20 | # Run app using pm2
21 | CMD ["npm", "run", "pm2"]
22 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/Procfile:
--------------------------------------------------------------------------------
1 | web: node index.js
2 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/api/service/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * @description Express Framework Router
5 | * @param Router
6 | */
7 | import { Router } from 'express';
8 |
9 | /**
10 | * @description Service route Controller
11 | * @param ServiceController
12 | */
13 | import * as ServiceController from './service.controller';
14 |
15 | let router = new Router();
16 |
17 | router.get('/', ServiceController.index);
18 | router.get('/:id', ServiceController.show);
19 | router.post('/', ServiceController.create);
20 | router.put('/:id', ServiceController.update);
21 | router.patch('/:id', ServiceController.update);
22 | router.delete('/:id', ServiceController.destroy);
23 |
24 | /**
25 | * @description Configured router for Service Routes
26 | * @exports router
27 | * @default
28 | */
29 | export default router;
30 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/config/.env:
--------------------------------------------------------------------------------
1 | PORT=9000
2 | IP='0.0.0.0'
3 | NODE_ENV=production
4 | MONGODB_URI=
5 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/config/app.conf.js:
--------------------------------------------------------------------------------
1 | import morgan from 'morgan';
2 | import bodyParser from 'body-parser';
3 | import contentLength from 'express-content-length-validator';
4 | import helmet from 'helmet';
5 | import express from 'express';
6 |
7 | export default class ApplicationConfig {
8 | static init(app) {
9 | let _root = process.cwd();
10 | let _nodeModules = '/node_modules/';
11 |
12 | app.use(express.static(_root + _nodeModules));
13 | app.use(bodyParser.json());
14 | app.use(morgan('dev'));
15 | app.use(contentLength.validateMax({max: 999}));
16 | app.use(helmet());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/config/db.conf.js:
--------------------------------------------------------------------------------
1 | import mongoose from 'mongoose';
2 | import bluebird from 'bluebird';
3 |
4 | mongoose.Promise = bluebird;
5 |
6 | export default class DBConfig {
7 | static init() {
8 | mongoose.connect(process.env.MONGODB_URI);
9 | mongoose.connection.on('error', err => {
10 | console.error(`MongoDB connection error: ${err}`);
11 | process.exit(-1);
12 | });
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/config/routes.conf.js:
--------------------------------------------------------------------------------
1 | import ServiceRoutes from '../api/service'
2 |
3 | export function initRoutes (app) {
4 | const startTime = new Date();
5 |
6 | // Insert routes below
7 | app.use('/api/services', ServiceRoutes);
8 |
9 | app.route('/*')
10 | .get((req, res) => {
11 | const uptime = `${new Date() - startTime}ms`;
12 | res.status(200).json({ startTime, uptime });
13 | }
14 | );
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Set default node environment to development
4 | var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';
5 |
6 | if (env === 'development' || env === 'test') {
7 | // Register the Babel require hook
8 | require('babel-register');
9 | }
10 | // Export the application
11 | exports = module.exports = require('./app');
12 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-1/server/mocha.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Register the Babel require hook
4 | require('babel-core/register');
5 |
6 | var chai = require('chai');
7 |
8 | // Load Chai assertions
9 | global.expect = chai.expect;
10 | global.assert = chai.assert;
11 | chai.should();
12 |
13 | // Load Sinon
14 | global.sinon = require('sinon');
15 |
16 | // Initialize Chai plugins
17 | chai.use(require('sinon-chai'));
18 | chai.use(require('chai-as-promised'));
19 | chai.use(require('chai-things'));
20 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-2/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | node/node_modules
3 | .DS_Store
4 |
5 | node/npm-debug.log
6 | .DS_Store
7 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-2/docker-compose.yml:
--------------------------------------------------------------------------------
1 | nginx:
2 | build: ./nginx
3 | links:
4 | - node1:node1
5 | - node2:node2
6 | - node3:node3
7 | ports:
8 | - "80:80"
9 | node1:
10 | build: ./node
11 | links:
12 | - redis
13 | ports:
14 | - "8080"
15 | node2:
16 | build: ./node
17 | links:
18 | - redis
19 | ports:
20 | - "8080"
21 | node3:
22 | build: ./node
23 | links:
24 | - redis
25 | ports:
26 | - "8080"
27 | redis:
28 | image: redis
29 | ports:
30 | - "6379"
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-2/nginx/Dockerfile:
--------------------------------------------------------------------------------
1 | # Set nginx base image
2 | FROM nginx
3 |
4 | # File Author / Maintainer
5 | MAINTAINER Anand Mani Sankar
6 |
7 | # Copy custom configuration file from the current directory
8 | COPY nginx.conf /etc/nginx/nginx.conf
9 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-2/nginx/Dockerfile_custom:
--------------------------------------------------------------------------------
1 | # Set the base image to Ubuntu
2 | FROM ubuntu
3 |
4 | # File Author / Maintainer
5 | MAINTAINER Anand Mani Sankar
6 |
7 | # Install Nginx
8 |
9 | # Add application repository URL to the default sources
10 | # RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
11 |
12 | # Update the repository
13 | RUN apt-get update
14 |
15 | # Install necessary tools
16 | RUN apt-get install -y nano wget dialog net-tools
17 |
18 | # Download and Install Nginx
19 | RUN apt-get install -y nginx
20 |
21 | # Remove the default Nginx configuration file
22 | RUN rm -v /etc/nginx/nginx.conf
23 |
24 | # Copy a configuration file from the current directory
25 | ADD nginx.conf /etc/nginx/
26 |
27 | # Append "daemon off;" to the configuration file
28 | RUN echo "daemon off;" >> /etc/nginx/nginx.conf
29 |
30 | # Expose ports
31 | EXPOSE 80
32 |
33 | # Set the default command to execute when creating a new container
34 | CMD service nginx start
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-2/nginx/nginx.conf:
--------------------------------------------------------------------------------
1 | worker_processes 4;
2 |
3 | events { worker_connections 1024; }
4 |
5 | http {
6 |
7 | upstream node-app {
8 | least_conn;
9 | server node1:8080 weight=10 max_fails=3 fail_timeout=30s;
10 | server node2:8080 weight=10 max_fails=3 fail_timeout=30s;
11 | server node3:8080 weight=10 max_fails=3 fail_timeout=30s;
12 | }
13 |
14 | server {
15 | listen 80;
16 |
17 | location / {
18 | proxy_pass http://node-app;
19 | proxy_http_version 1.1;
20 | proxy_set_header Upgrade $http_upgrade;
21 | proxy_set_header Connection 'upgrade';
22 | proxy_set_header Host $host;
23 | proxy_cache_bypass $http_upgrade;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-2/node/Dockerfile:
--------------------------------------------------------------------------------
1 | # Set the base image to Ubuntu
2 | FROM ubuntu:trusty
3 |
4 | # File Author / Maintainer
5 | MAINTAINER Anand Mani Sankar
6 |
7 | # Install Node.js and other dependencies
8 | RUN apt-get update && \
9 | apt-get -y install curl && \
10 | curl -sL https://deb.nodesource.com/setup | sudo bash - && \
11 | apt-get -y install python build-essential nodejs
12 |
13 | # Install nodemon
14 | RUN npm install -g nodemon
15 |
16 | # Provides cached layer for node_modules
17 | ADD package.json /tmp/package.json
18 | RUN cd /tmp && npm install
19 | RUN mkdir -p /src && cp -a /tmp/node_modules /src/
20 |
21 | # Define working directory
22 | WORKDIR /src
23 | ADD . /src
24 |
25 | # Expose port
26 | EXPOSE 8080
27 |
28 | # Run app using nodemon
29 | CMD ["nodemon", "/src/index.js"]
30 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-2/node/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express'),
2 | http = require('http'),
3 | redis = require('redis');
4 |
5 | var app = express();
6 |
7 | console.log(process.env.REDIS_PORT_6379_TCP_ADDR + ':' + process.env.REDIS_PORT_6379_TCP_PORT);
8 |
9 | // APPROACH 1: Using environment variables created by Docker
10 | // var client = redis.createClient(
11 | // process.env.REDIS_PORT_6379_TCP_PORT,
12 | // process.env.REDIS_PORT_6379_TCP_ADDR
13 | // );
14 |
15 | // APPROACH 2: Using host entries created by Docker in /etc/hosts (RECOMMENDED)
16 | var client = redis.createClient('6379', 'redis');
17 |
18 |
19 | app.get('/', function(req, res, next) {
20 | client.incr('counter', function(err, counter) {
21 | if(err) return next(err);
22 | res.send('This page has been viewed ' + counter + ' times!');
23 | });
24 | });
25 |
26 | http.createServer(app).listen(process.env.PORT || 8080, function() {
27 | console.log('Listening on port ' + (process.env.PORT || 8080));
28 | });
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-2/node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "author": "Anand Mani Sankar",
7 | "license": "ISC",
8 | "dependencies": {
9 | "express": "^4.12.3",
10 | "hiredis": "^0.2.0",
11 | "mocha": "^2.2.1",
12 | "redis": "^0.12.1"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-2/node/test/dummyTest.js:
--------------------------------------------------------------------------------
1 | var assert = require("assert");
2 |
3 | describe('Dummy Test', function(){
4 | it('should pass', function(){
5 | assert.ok(true, "It is true!");
6 | });
7 | });
--------------------------------------------------------------------------------
/nodejs-microservice-using-docker-Part-2/redis/Dockerfile:
--------------------------------------------------------------------------------
1 | # Set the base image to Ubuntu
2 | FROM ubuntu
3 |
4 | # File Author / Maintainer
5 | MAINTAINER Anand Mani Sankar
6 |
7 | # Update the repository and install Redis Server
8 | RUN apt-get update && apt-get install -y redis-server
9 |
10 | # Expose Redis port 6379
11 | EXPOSE 6379
12 |
13 | # Run Redis Server
14 | ENTRYPOINT ["/usr/bin/redis-server"]
--------------------------------------------------------------------------------