├── 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 |
7 |
8 |
9 |
10 |
11 |
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 | {props.alt} 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"] --------------------------------------------------------------------------------