├── .autod.conf.js ├── .eslintignore ├── .eslintrc ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── nodejs.yml │ └── npm-publish.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── README.zh_CN.md ├── app.js ├── appveyor.yml ├── config └── config.default.js ├── index.d.ts ├── lib └── amqplib.js ├── package-lock.json ├── package.json ├── test ├── amqplib.test.js └── fixtures │ └── apps │ └── amqplib-test │ ├── app │ ├── controller │ │ └── home.js │ └── router.js │ ├── config │ └── config.default.js │ └── package.json └── yarn.lock /.autod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | write: true, 5 | prefix: '^', 6 | plugin: 'autod-egg', 7 | test: [ 8 | 'test', 9 | 'benchmark', 10 | ], 11 | devdep: [ 12 | 'egg', 13 | 'egg-ci', 14 | 'egg-bin', 15 | 'autod', 16 | 'autod-egg', 17 | 'eslint', 18 | 'eslint-config-egg', 19 | 'webstorm-disable-index', 20 | ], 21 | exclude: [ 22 | './test/fixtures', 23 | './docs', 24 | './coverage', 25 | ], 26 | }; 27 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-egg", 3 | "rules": { 4 | "comma-dangle": "off" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ##### Checklist 12 | 13 | 14 | - [ ] `npm test` passes 15 | - [ ] tests and/or benchmarks are included 16 | - [ ] documentation is changed or added 17 | - [ ] commit message follows commit guidelines 18 | 19 | ##### Affected core subsystem(s) 20 | 21 | 22 | 23 | ##### Description of change 24 | 25 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | strategy: 17 | matrix: 18 | node-version: [10.x, 12.x, 14.x] 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | - name: Use Node.js ${{ matrix.node-version }} 23 | uses: actions/setup-node@v1 24 | with: 25 | node-version: ${{ matrix.node-version }} 26 | - run: npm ci 27 | - run: npm run build --if-present 28 | - run: npm test 29 | services: 30 | rabbitmq: 31 | image: rabbitmq:3-management 32 | ports: 33 | - 5672:5672 34 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 3 | 4 | name: Node.js Package 5 | 6 | on: 7 | push: 8 | # Sequence of patterns matched against refs/tags 9 | tags: 10 | - v* 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | - uses: actions/setup-node@v1 18 | with: 19 | node-version: 12 20 | - run: npm ci 21 | - run: npm test 22 | services: 23 | rabbitmq: 24 | image: rabbitmq:3-management 25 | ports: 26 | - 5672:5672 27 | 28 | publish-npm: 29 | needs: build 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@v2 33 | - uses: actions/setup-node@v1 34 | with: 35 | node-version: 12 36 | registry-url: https://registry.npmjs.org/ 37 | - run: npm publish 38 | env: 39 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs/ 2 | npm-debug.log 3 | node_modules/ 4 | coverage/ 5 | .idea/ 6 | run/ 7 | .DS_Store 8 | *.swp 9 | 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | addons: 4 | apt: 5 | packages: 6 | - rabbitmq-server 7 | node_js: 8 | - '10' 9 | - '12' 10 | - '14' 11 | before_install: 12 | - npm i npminstall -g 13 | install: 14 | - npminstall 15 | script: 16 | - npm run ci 17 | after_script: 18 | - npminstall codecov && codecov 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 zubin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # egg-amqplib 2 | 3 | [![NPM version][npm-image]][npm-url] 4 | [![build status][travis-image]][travis-url] 5 | [![Test coverage][codecov-image]][codecov-url] 6 | [![David deps][david-image]][david-url] 7 | [![Known Vulnerabilities][snyk-image]][snyk-url] 8 | [![npm download][download-image]][download-url] 9 | 10 | [npm-image]: https://img.shields.io/npm/v/egg-amqplib.svg?style=flat-square 11 | [npm-url]: https://npmjs.org/package/egg-amqplib 12 | [travis-image]: https://img.shields.io/travis/zubincheung/egg-amqplib.svg?style=flat-square 13 | [travis-url]: https://travis-ci.org/zubincheung/egg-amqplib 14 | [codecov-image]: https://img.shields.io/codecov/c/github/zubincheung/egg-amqplib.svg?style=flat-square 15 | [codecov-url]: https://codecov.io/github/zubincheung/egg-amqplib?branch=master 16 | [david-image]: https://img.shields.io/david/zubincheung/egg-amqplib.svg?style=flat-square 17 | [david-url]: https://david-dm.org/zubincheung/egg-amqplib 18 | [snyk-image]: https://snyk.io/test/npm/egg-amqplib/badge.svg?style=flat-square 19 | [snyk-url]: https://snyk.io/test/npm/egg-amqplib 20 | [download-image]: https://img.shields.io/npm/dm/egg-amqplib.svg?style=flat-square 21 | [download-url]: https://npmjs.org/package/egg-amqplib 22 | 23 | 26 | 27 | Amqp plugin for egg with amqplib 28 | 29 | ## Install 30 | 31 | ```bash 32 | $ npm i egg-amqplib --save 33 | ``` 34 | 35 | ## Usage 36 | 37 | ```js 38 | // {app_root}/config/plugin.js 39 | exports.amqplib = { 40 | enable: true, 41 | package: 'egg-amqplib', 42 | }; 43 | ``` 44 | 45 | ## Configuration 46 | 47 | ```js 48 | // {app_root}/config/config.default.js 49 | exports.amqplib = { 50 | client: { 51 | // url: 'amqp://localhost', 52 | connectOptions: { 53 | protocol: 'amqp', 54 | hostname: 'localhost', 55 | port: 5672, 56 | username: 'guest', 57 | password: 'guest', 58 | locale: 'en_US', 59 | frameMax: 0, 60 | heartbeat: 0, 61 | vhost: '/', 62 | }, 63 | // socketOptions: { 64 | // cert: certificateAsBuffer, // client cert 65 | // key: privateKeyAsBuffer, // client key 66 | // passphrase: 'MySecretPassword', // passphrase for key 67 | // ca: [caCertAsBuffer], // array of trusted CA certs 68 | // }, 69 | }, 70 | }; 71 | ``` 72 | 73 | see [config/config.default.js](config/config.default.js) for more detail. 74 | 75 | ## Example 76 | 77 | 78 | 79 | ```js 80 | const queueName = 'test'; 81 | 82 | // Publisher 83 | const msg = 'test'; 84 | const ch = await this.app.amqplib.createChannel(); 85 | await ch.assertQueue(queueName, { durable: false }); 86 | const ok = await ch.sendToQueue(queueName, Buffer.from(msg)); 87 | 88 | // Consumer 89 | await ch.assertQueue(queueName, { durable: false }); 90 | const msg = await new Promise(resolve => ch.consume(queueName, msg => resolve(msg))); 91 | 92 | if (msg !== null) { 93 | ch.ack(msg); 94 | } 95 | 96 | await ch.close(); 97 | ``` 98 | 99 | ## Questions & Suggestions 100 | 101 | Please open an issue [here](https://github.com/zubincheung/egg-amqplib/issues). 102 | 103 | ## License 104 | 105 | [MIT](LICENSE) 106 | -------------------------------------------------------------------------------- /README.zh_CN.md: -------------------------------------------------------------------------------- 1 | # egg-amqplib 2 | 3 | [![NPM version][npm-image]][npm-url] 4 | [![build status][travis-image]][travis-url] 5 | [![Test coverage][codecov-image]][codecov-url] 6 | [![David deps][david-image]][david-url] 7 | [![Known Vulnerabilities][snyk-image]][snyk-url] 8 | [![npm download][download-image]][download-url] 9 | 10 | [npm-image]: https://img.shields.io/npm/v/egg-amqplib.svg?style=flat-square 11 | [npm-url]: https://npmjs.org/package/egg-amqplib 12 | [travis-image]: https://img.shields.io/travis/zubincheung/egg-amqplib.svg?style=flat-square 13 | [travis-url]: https://travis-ci.org/zubincheung/egg-amqplib 14 | [codecov-image]: https://img.shields.io/codecov/c/github/zubincheung/egg-amqplib.svg?style=flat-square 15 | [codecov-url]: https://codecov.io/github/zubincheung/egg-amqplib?branch=master 16 | [david-image]: https://img.shields.io/david/zubincheung/egg-amqplib.svg?style=flat-square 17 | [david-url]: https://david-dm.org/zubincheung/egg-amqplib 18 | [snyk-image]: https://snyk.io/test/npm/egg-amqplib/badge.svg?style=flat-square 19 | [snyk-url]: https://snyk.io/test/npm/egg-amqplib 20 | [download-image]: https://img.shields.io/npm/dm/egg-amqplib.svg?style=flat-square 21 | [download-url]: https://npmjs.org/package/egg-amqplib 22 | 23 | 26 | 27 | 基于 amqplib 的 egg amqp 插件 28 | 29 | ## 依赖说明 30 | 31 | ### 依赖的 egg 版本 32 | 33 | | egg-amqplib 版本 | egg 1.x | 34 | | ---------------- | ------- | 35 | | 1.x | 😁 | 36 | | 0.x | ❌ | 37 | 38 | ### 依赖的插件 39 | 40 | 48 | 49 | ## 开启插件 50 | 51 | ```js 52 | // config/plugin.js 53 | exports.amqplib = { 54 | enable: true, 55 | package: 'egg-amqplib', 56 | }; 57 | ``` 58 | 59 | ## 详细配置 60 | 61 | 请到 [config/config.default.js](config/config.default.js) 查看详细配置项说明。 62 | 63 | ## 示例 64 | 65 | ```js 66 | const queueName = 'test'; 67 | 68 | // Publisher 69 | const msg = 'test'; 70 | const ch = await this.app.amqplib.createChannel(); 71 | await ch.assertQueue(queueName, { durable: false }); 72 | const ok = await ch.sendToQueue(queueName, Buffer.from(msg)); 73 | 74 | // Consumer 75 | await ch.assertQueue(queueName, { durable: false }); 76 | const msg = await new Promise(resolve => ch.consume(queueName, msg => resolve(msg))); 77 | 78 | if (msg !== null) { 79 | ch.ack(msg); 80 | } 81 | 82 | await ch.close(); 83 | ``` 84 | 85 | ## 提问交流 86 | 87 | 请到 [egg issues](https://github.com/zubincheung/egg-amqplib/issues) 移步交流。 88 | 89 | ## License 90 | 91 | [MIT](LICENSE) 92 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const amqp = require('./lib/amqplib'); 4 | 5 | module.exports = app => { 6 | amqp(app); 7 | }; 8 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - nodejs_version: '10' 4 | - nodejs_version: '12' 5 | - nodejs_version: '14' 6 | 7 | install: 8 | - ps: Install-Product node $env:nodejs_version 9 | - npm i npminstall && node_modules\.bin\npminstall 10 | 11 | test_script: 12 | - node --version 13 | - npm --version 14 | - npm run test 15 | build: off 16 | services: 17 | - rabbitmq 18 | -------------------------------------------------------------------------------- /config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * egg-amqplib default config 5 | * @member Config#amqplib 6 | * @property {String} SOME_KEY - some description 7 | */ 8 | exports.amqplib = { 9 | client: { 10 | // url: 'amqp://localhost', 11 | connectOptions: { 12 | protocol: 'amqp', 13 | hostname: 'localhost', 14 | port: 5672, 15 | username: 'guest', 16 | password: 'guest', 17 | locale: 'en_US', 18 | frameMax: 0, 19 | heartbeat: 0, 20 | vhost: '/', 21 | }, 22 | // socketOptions: { 23 | // cert: certificateAsBuffer, // client cert 24 | // key: privateKeyAsBuffer, // client key 25 | // passphrase: 'MySecretPassword', // passphrase for key 26 | // ca: [caCertAsBuffer], // array of trusted CA certs 27 | // }, 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import * as amqp from 'amqplib'; 2 | 3 | interface EggAmqpOptions { 4 | client?: { 5 | [x: string]: any; 6 | url?: string; 7 | connectOptions?: amqp.Options.Connect; 8 | socketOptions?: any; 9 | }; 10 | } 11 | 12 | declare module 'egg' { 13 | // extend app 14 | interface Application { 15 | amqp: amqp.Connection; 16 | amqplib: amqp.Connection; 17 | } 18 | 19 | // extend your config 20 | interface EggAppConfig { 21 | amqplib: EggAmqpOptions; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/amqplib.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | 5 | const amqp = require('amqplib'); 6 | 7 | /** 8 | * mount apqp on app 9 | * @param {Application} app app 10 | */ 11 | module.exports = app => { 12 | app.addSingleton('amqplib', createClient); 13 | }; 14 | 15 | async function createClient(config, app) { 16 | assert( 17 | config.url || config.connectOptions, 18 | "[egg-amqplib] url and connectOptions can't be empty at the same time on config", 19 | ); 20 | 21 | const connectOptions = config.url || parseOptions(config.connectOptions); 22 | app.coreLogger.info(`[egg-amqplib] connection on ${JSON.stringify(connectOptions)}`); 23 | 24 | const client = await amqp.connect( 25 | connectOptions, 26 | config.socketOptions, 27 | ); 28 | 29 | app.coreLogger.info('[egg-amqplib] connection success'); 30 | 31 | return client; 32 | } 33 | 34 | /** 35 | * Parse amqplib connect options 36 | * 37 | * @param {*} connectOptions amqplib connect options 38 | * @return {*} amqplib connect options 39 | */ 40 | function parseOptions(connectOptions) { 41 | return Object.assign( 42 | { 43 | protocol: 'amqp', 44 | hostname: 'localhost', 45 | port: 5672, 46 | username: 'guest', 47 | password: 'guest', 48 | locale: 'en_US', 49 | frameMax: 0, 50 | heartbeat: 0, 51 | vhost: '/', 52 | }, 53 | connectOptions, 54 | ); 55 | } 56 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-amqplib", 3 | "version": "2.0.5", 4 | "description": "Amqp plugin for egg with amqplib", 5 | "eggPlugin": { 6 | "name": "amqplib" 7 | }, 8 | "keywords": [ 9 | "egg", 10 | "eggPlugin", 11 | "egg-plugin", 12 | "amqp", 13 | "amqplib" 14 | ], 15 | "dependencies": { 16 | "@types/amqplib": "^0.5.13", 17 | "amqplib": "^0.7.1", 18 | "bluebird": "^3.7.2" 19 | }, 20 | "devDependencies": { 21 | "autod": "^3.1.0", 22 | "autod-egg": "^1.1.0", 23 | "egg": "^2.27.0", 24 | "egg-bin": "^4.15.0", 25 | "egg-ci": "^1.15.0", 26 | "egg-mock": "^4.0.0", 27 | "eslint": "^7.4.0", 28 | "eslint-config-egg": "^8.0.1", 29 | "webstorm-disable-index": "^1.2.0" 30 | }, 31 | "engines": { 32 | "node": ">=8.0.0" 33 | }, 34 | "scripts": { 35 | "test": "npm run lint -- --fix && egg-bin pkgfiles && npm run test-local", 36 | "test-local": "egg-bin test", 37 | "cov": "egg-bin cov", 38 | "lint": "eslint .", 39 | "ci": "egg-bin pkgfiles --check && npm run lint && npm run cov", 40 | "pkgfiles": "egg-bin pkgfiles", 41 | "autod": "autod" 42 | }, 43 | "files": [ 44 | "config", 45 | "app.js", 46 | "lib", 47 | "index.d.ts" 48 | ], 49 | "ci": { 50 | "version": "8,10,11" 51 | }, 52 | "repository": { 53 | "type": "git", 54 | "url": "git+https://github.com/zubincheung/egg-amqplib" 55 | }, 56 | "bugs": { 57 | "url": "https://github.com/zubincheung/egg-amqplib/issues" 58 | }, 59 | "homepage": "https://github.com/zubincheung/egg-amqplib#readme", 60 | "author": "Zubin", 61 | "license": "MIT" 62 | } 63 | -------------------------------------------------------------------------------- /test/amqplib.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mock = require('egg-mock'); 4 | 5 | describe('test/amqplib.test.js', () => { 6 | let app; 7 | before(() => { 8 | app = mock.app({ 9 | baseDir: 'apps/amqplib-test', 10 | }); 11 | return app.ready(); 12 | }); 13 | 14 | after(() => app.close()); 15 | afterEach(mock.restore); 16 | 17 | it('should publish message', () => { 18 | return app 19 | .httpRequest() 20 | .get('/publish') 21 | .query({ msg: 'hello world' }) 22 | .expect('true') 23 | .expect(200); 24 | }); 25 | 26 | it('should consume message', () => { 27 | return app 28 | .httpRequest() 29 | .get('/consume') 30 | .expect({ msg: 'hello world' }) 31 | .expect(200); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /test/fixtures/apps/amqplib-test/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | const queueName = 'test'; 5 | 6 | class HomeController extends Controller { 7 | async publish() { 8 | const { msg } = this.ctx.query; 9 | 10 | const ch = await this.app.amqplib.createChannel(); 11 | await ch.assertQueue(queueName, { durable: false }); 12 | const ok = await ch.sendToQueue(queueName, Buffer.from(msg)); 13 | await ch.close(); 14 | 15 | this.ctx.body = ok; 16 | this.ctx.status = 200; 17 | } 18 | 19 | async consume() { 20 | const ch = await this.app.amqplib.createChannel(); 21 | await ch.assertQueue(queueName, { durable: false }); 22 | const msg = await new Promise(resolve => ch.consume(queueName, msg => resolve(msg))); 23 | 24 | if (msg !== null) { 25 | ch.ack(msg); 26 | await ch.close(); 27 | 28 | this.ctx.status = 200; 29 | this.ctx.body = { msg: msg.content.toString() }; 30 | } else { 31 | this.ctx.status = 500; 32 | } 33 | } 34 | } 35 | 36 | module.exports = HomeController; 37 | -------------------------------------------------------------------------------- /test/fixtures/apps/amqplib-test/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { router, controller } = app; 5 | 6 | router.get('/publish', controller.home.publish); 7 | router.get('/consume', controller.home.consume); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/amqplib-test/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = '123456'; 4 | 5 | /** 6 | * egg-amqplib default config 7 | * @member Config#amqplib 8 | * @property {String} SOME_KEY - some description 9 | */ 10 | exports.amqplib = { 11 | client: { 12 | // url: 'amqp://localhost', 13 | connectOptions: { 14 | protocol: 'amqp', 15 | hostname: 'localhost', 16 | port: 5672, 17 | username: 'guest', 18 | password: 'guest', 19 | locale: 'en_US', 20 | frameMax: 0, 21 | heartbeat: 0, 22 | vhost: '/', 23 | }, 24 | // socketOptions: { 25 | // cert: certificateAsBuffer, // client cert 26 | // key: privateKeyAsBuffer, // client key 27 | // passphrase: 'MySecretPassword', // passphrase for key 28 | // ca: [caCertAsBuffer], // array of trusted CA certs 29 | // }, 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /test/fixtures/apps/amqplib-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "amqplib-test", 3 | "version": "0.0.1" 4 | } --------------------------------------------------------------------------------