diff --git a/.docs/en/index.md b/.docs/en/index.md index f7edba8..1ada676 100644 --- a/.docs/en/index.md +++ b/.docs/en/index.md @@ -1,6 +1,8 @@ # Quick start -The purpose of this plugin is to provide unified interface for data exchange. Create consumers and publishers proxies, collect registered application consumers and publishers and control them. +The purpose of this library is to provide unified interface for data exchange. Create consumers and publishers proxies, collect registered application consumers and publishers and control them. + +*** ## Installation @@ -20,24 +22,25 @@ extensions: ## Creating custom publisher If some service of your module have to publish messages to data exchange for other modules, you could just -implement `FastyBird\Exchange\Publisher\IPublisher` interface and register your publisher as service +implement `FastyBird\Exchange\Publisher\Publisher` interface and register your publisher as service ```php namespace Your\CoolApp\Publishers; use FastyBird\Exchange\Publisher\Publisher; -use FastyBird\Metadata\Types; +use FastyBird\Metadata\Entities as MetadataEntities; +use FastyBird\Metadata\Types as MetadataTypes; use Nette\Utils; class ModuleDataPublisher implements Publisher { public function publish( - $origin, - Types\RoutingKeyType $routingKey, - ?Utils\ArrayHash $data + MetadataTypes\ModuleSource|MetadataTypes\PluginSource|MetadataTypes\ConnectorSource $source, + MetadataTypes\RoutingKey $routingKey, + MetadataEntities\Entity|null $entity, ) : void { - // Container logic here, eg. publish message to RabbitMQ or Redis etc. + // Service logic here, eg. publish message to RabbitMQ or Redis etc. } } @@ -52,17 +55,16 @@ In your code you could just import one publisher - proxy publisher. ```php namespace Your\CoolApp\Actions; -use FastyBird\Exchange\Publisher\Publisher; -use Nette\Utils; +use FastyBird\Exchange\Publisher\Container; class SomeHandler { - /** @var Publisher */ - private Publisher $publisher; + /** @var Container */ + private Container $publisher; public function __construct( - Publisher $publisher + Container $publisher ) { $this->publisher = $publisher; } @@ -74,9 +76,7 @@ class SomeHandler $this->publisher->publish( $origin, $routingKey, - Utils\ArrayHash::from([ - 'key' => 'value', - ]) + $entity, ); } } @@ -95,18 +95,18 @@ Your consumer could look like this: namespace Your\CoolApp\Publishers; use FastyBird\Exchange\Consumer\Consumer; -use FastyBird\Metadata\Types; -use Nette\Utils; +use FastyBird\Metadata\Entities as MetadataEntities; +use FastyBird\Metadata\Types as MetadataTypes; class DataConsumer implements Consumer { public function consume( - $origin, - Types\RoutingKeyType $routingKey, - ?Utils\ArrayHash $data + MetadataTypes\ModuleSource|MetadataTypes\PluginSource|MetadataTypes\ConnectorSource $source, + MetadataTypes\RoutingKey $routingKey, + MetadataEntities\Entity|null $entity, ) : void { - // Do you data processing logic here + // Do your data processing logic here } } diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1e79fb5..b863b07 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,156 +1,156 @@ -name : "build" +name: "build" -on : - pull_request : - paths-ignore : +on: + pull_request: + paths-ignore: - ".docs/**" - push : - branches : + push: + branches: - "main" - tags : + tags: - v* - schedule : - - cron : "0 8 * * 1" # At 08:00 on Monday - -env : - extensions : "json" - cache-version : "1" - composer-version : "v2" - composer-install : "composer update --no-interaction --no-progress --no-suggest --prefer-dist --prefer-stable" - coverage : "none" - -jobs : - php-qa : - name : "Quality assurance for PHP code" - runs-on : "${{ matrix.operating-system }}" - - strategy : - fail-fast : false - matrix : - php-version : [ "8.1" ] - operating-system : [ "ubuntu-latest" ] - - steps : - - name : "Checkout" - uses : "actions/checkout@v2" - - - name : "Setup PHP cache environment" - id : "extcache" - uses : "shivammathur/cache-extensions@v1" - with : - php-version : "${{ matrix.php-version }}" - extensions : "${{ env.extensions }}" - key : "${{ env.cache-version }}" - - - name : "Cache PHP extensions" - uses : "actions/cache@v2" - with : - path : "${{ steps.extcache.outputs.dir }}" - key : "${{ steps.extcache.outputs.key }}" - restore-keys : "${{ steps.extcache.outputs.key }}" - - - name : "Install PHP" - uses : "shivammathur/setup-php@v2" - with : - php-version : "${{ matrix.php-version }}" - extensions : "${{ env.extensions }}" - tools : "composer:${{ env.composer-version }}, cs2pr" - coverage : "${{ env.coverage }}" - - - name : "Setup problem matchers for PHP" - run : 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - - - name : "Get Composer cache directory" - id : "composercache" - run : 'echo "::set-output name=dir::$(composer config cache-files-dir)"' - - - name : "Cache PHP dependencies" - uses : "actions/cache@v2" - with : - path : "${{ steps.composercache.outputs.dir }}" - key : "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" - restore-keys : "${{ runner.os }}-composer-" - - - name : "Validate Composer" - run : "composer validate" - - - name : "Install dependencies" - run : "${{ env.composer-install }}" - - - name : "Coding Standard" - run : "make php_cs" - - php-static-analysis : - name : "Static analysis for PHP code" - runs-on : "${{ matrix.operating-system }}" - - strategy : - fail-fast : false - matrix : - php-version : [ "8.1" ] - operating-system : [ "ubuntu-latest" ] - - steps : - - name : "Checkout" - uses : "actions/checkout@v2" - - - name : "Setup PHP cache environment" - id : "extcache" - uses : "shivammathur/cache-extensions@v1" - with : - php-version : "${{ matrix.php-version }}" - extensions : "${{ env.extensions }}" - key : "${{ env.cache-version }}" - - - name : "Cache PHP extensions" - uses : "actions/cache@v2" - with : - path : "${{ steps.extcache.outputs.dir }}" - key : "${{ steps.extcache.outputs.key }}" - restore-keys : "${{ steps.extcache.outputs.key }}" - - - name : "Install PHP" - uses : "shivammathur/setup-php@v2" - with : - php-version : "${{ matrix.php-version }}" - extensions : "${{ env.extensions }}" - tools : "composer:${{ env.composer-version }}" - coverage : "${{ env.coverage }}" - - - name : "Setup problem matchers for PHP" - run : 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - - - name : "Get Composer cache directory" - id : "composercache" - run : 'echo "::set-output name=dir::$(composer config cache-files-dir)"' - - - name : "Cache PHP dependencies" - uses : "actions/cache@v2" - with : - path : "${{ steps.composercache.outputs.dir }}" - key : "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" - restore-keys : "${{ runner.os }}-composer-" - - - name : "Install dependencies" - run : "${{ env.composer-install }}" - - - name : "PHPStan" - run : "make phpstan" - - php-tests : - name : "Tests for PHP code" - runs-on : "${{ matrix.operating-system }}" - needs : [ "php-qa", "php-static-analysis" ] - - strategy : - fail-fast : false - matrix : - php-version : [ "8.1" ] - operating-system : [ "ubuntu-latest" ] - - steps : - - name : "Checkout" - uses : "actions/checkout@v2" + schedule: + - cron: "0 8 * * 1" # At 08:00 on Monday + +env: + extensions: "json" + cache-version: "1" + composer-version: "v2" + composer-install: "composer update --no-interaction --no-progress --no-suggest --prefer-dist --prefer-stable" + coverage: "none" + +jobs: + qa: + name: "Code quality assurance" + runs-on: "${{ matrix.operating-system }}" + + strategy: + fail-fast: false + matrix: + php-version: ["8.1"] + operating-system: ["ubuntu-latest"] + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Setup PHP cache environment" + id: "extcache" + uses: "shivammathur/cache-extensions@v1" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.extensions }}" + key: "${{ env.cache-version }}" + + - name: "Cache PHP extensions" + uses: "actions/cache@v2" + with: + path: "${{ steps.extcache.outputs.dir }}" + key: "${{ steps.extcache.outputs.key }}" + restore-keys: "${{ steps.extcache.outputs.key }}" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.extensions }}" + tools: "composer:${{ env.composer-version }}, cs2pr" + coverage: "${{ env.coverage }}" + + - name: "Setup problem matchers for PHP" + run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' + + - name: "Get Composer cache directory" + id: "composercache" + run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' + + - name: "Cache PHP dependencies" + uses: "actions/cache@v2" + with: + path: "${{ steps.composercache.outputs.dir }}" + key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" + restore-keys: "${{ runner.os }}-composer-" + + - name: "Validate Composer" + run: "composer validate" + + - name: "Install dependencies" + run: "${{ env.composer-install }}" + + - name: "Coding Standard" + run: "make cs" + + static-analysis: + name: "Code static analysis" + runs-on: "${{ matrix.operating-system }}" + + strategy: + fail-fast: false + matrix: + php-version: ["8.1"] + operating-system: ["ubuntu-latest"] + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Setup PHP cache environment" + id: "extcache" + uses: "shivammathur/cache-extensions@v1" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.extensions }}" + key: "${{ env.cache-version }}" + + - name: "Cache PHP extensions" + uses: "actions/cache@v2" + with: + path: "${{ steps.extcache.outputs.dir }}" + key: "${{ steps.extcache.outputs.key }}" + restore-keys: "${{ steps.extcache.outputs.key }}" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.extensions }}" + tools: "composer:${{ env.composer-version }}" + coverage: "${{ env.coverage }}" + + - name: "Setup problem matchers for PHP" + run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' + + - name: "Get Composer cache directory" + id: "composercache" + run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' + + - name: "Cache PHP dependencies" + uses: "actions/cache@v2" + with: + path: "${{ steps.composercache.outputs.dir }}" + key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" + restore-keys: "${{ runner.os }}-composer-" + + - name: "Install dependencies" + run: "${{ env.composer-install }}" + + - name: "PHPStan" + run: "make phpstan" + + tests: + name: "Code tests" + runs-on: "${{ matrix.operating-system }}" + needs: ["qa", "static-analysis"] + + strategy: + fail-fast: false + matrix: + php-version: ["8.1"] + operating-system: ["ubuntu-latest"] + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" - name : "Setup MySQL" uses : "mirromutth/mysql-action@v1.1" @@ -159,72 +159,72 @@ jobs : mysql database : "testdb" mysql root password : "root" - - name : "Setup PHP cache environment" - id : "extcache" - uses : "shivammathur/cache-extensions@v1" - with : - php-version : "${{ matrix.php-version }}" - extensions : "${{ env.extensions }}" - key : "${{ env.cache-version }}" - - - name : "Cache PHP extensions" - uses : "actions/cache@v2" - with : - path : "${{ steps.extcache.outputs.dir }}" - key : "${{ steps.extcache.outputs.key }}" - restore-keys : "${{ steps.extcache.outputs.key }}" - - - name : "Install PHP" - uses : "shivammathur/setup-php@v2" - with : - php-version : "${{ matrix.php-version }}" - extensions : "${{ env.extensions }}" - tools : "composer:${{ env.composer-version }}" - coverage : "${{ env.coverage }}" - - - name : "Setup problem matchers for PHP" - run : 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - - - name : "Get Composer cache directory" - id : "composercache" - run : 'echo "::set-output name=dir::$(composer config cache-files-dir)"' - - - name : "Cache PHP dependencies" - uses : "actions/cache@v2" - with : - path : "${{ steps.composercache.outputs.dir }}" - key : "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" - restore-keys : "${{ runner.os }}-composer-" - - - name : "Install dependencies" - run : "${{ env.composer-install }} ${{ matrix.composer-args }}" - - - name : "Tests" - run : "make php_tests" - - - name : "Upload test output" - if : ${{ failure() }} - uses : "actions/upload-artifact@v2" - with : - name : output - path : tests/**/output - - php-tests-code-coverage : - name : "Tests for PHP code with code coverage" - runs-on : "${{ matrix.operating-system }}" - needs : [ "php-tests" ] - - strategy : - matrix : - php-version : [ "8.1" ] - operating-system : [ "ubuntu-latest" ] - fail-fast : false - - if : "github.event_name == 'push'" - - steps : - - name : "Checkout" - uses : "actions/checkout@v2" + - name: "Setup PHP cache environment" + id: "extcache" + uses: "shivammathur/cache-extensions@v1" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.extensions }}" + key: "${{ env.cache-version }}" + + - name: "Cache PHP extensions" + uses: "actions/cache@v2" + with: + path: "${{ steps.extcache.outputs.dir }}" + key: "${{ steps.extcache.outputs.key }}" + restore-keys: "${{ steps.extcache.outputs.key }}" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.extensions }}" + tools: "composer:${{ env.composer-version }}" + coverage: "${{ env.coverage }}" + + - name: "Setup problem matchers for PHP" + run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' + + - name: "Get Composer cache directory" + id: "composercache" + run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' + + - name: "Cache PHP dependencies" + uses: "actions/cache@v2" + with: + path: "${{ steps.composercache.outputs.dir }}" + key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" + restore-keys: "${{ runner.os }}-composer-" + + - name: "Install dependencies" + run: "${{ env.composer-install }} ${{ matrix.composer-args }}" + + - name: "Tests" + run: "make tests" + + - name: "Upload test output" + if: ${{ failure() }} + uses: "actions/upload-artifact@v2" + with: + name: output + path: tests/**/output + + tests-code-coverage: + name: "Code tests with code coverage" + runs-on: "${{ matrix.operating-system }}" + needs: ["tests"] + + strategy: + matrix: + php-version: ["8.1"] + operating-system: ["ubuntu-latest"] + fail-fast: false + + if: "github.event_name == 'push'" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" - name : "Setup MySQL" uses : "mirromutth/mysql-action@v1.1" @@ -233,286 +233,54 @@ jobs : mysql database : "testdb" mysql root password : "root" - - name : "Setup PHP cache environment" - id : "extcache" - uses : "shivammathur/cache-extensions@v1" - with : - php-version : "${{ matrix.php-version }}" - extensions : "${{ env.extensions }}" - key : "${{ env.cache-version }}" - - - name : "Cache PHP extensions" - uses : "actions/cache@v2" - with : - path : "${{ steps.extcache.outputs.dir }}" - key : "${{ steps.extcache.outputs.key }}" - restore-keys : "${{ steps.extcache.outputs.key }}" - - - name : "Install PHP" - uses : "shivammathur/setup-php@v2" - with : - php-version : "${{ matrix.php-version }}" - extensions : "${{ env.extensions }}" - tools : "composer:${{ env.composer-version }}" - coverage : "pcov" - - - name : "Setup problem matchers for PHP" - run : 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' - - - name : "Get Composer cache directory" - id : "composercache" - run : 'echo "::set-output name=dir::$(composer config cache-files-dir)"' - - - name : "Cache PHP dependencies" - uses : "actions/cache@v2" - with : - path : "${{ steps.composercache.outputs.dir }}" - key : "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" - restore-keys : "${{ runner.os }}-composer-" - - - name : "Install dependencies" - run : "${{ env.composer-install }} ${{ matrix.composer-args }}" - - - name : "Tests" - run : "make php_coverage" - - - name : "Coveralls.io" - env : - CI_NAME : github - CI : true - COVERALLS_REPO_TOKEN : "${{ secrets.GITHUB_TOKEN }}" - run : | + - name: "Setup PHP cache environment" + id: "extcache" + uses: "shivammathur/cache-extensions@v1" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.extensions }}" + key: "${{ env.cache-version }}" + + - name: "Cache PHP extensions" + uses: "actions/cache@v2" + with: + path: "${{ steps.extcache.outputs.dir }}" + key: "${{ steps.extcache.outputs.key }}" + restore-keys: "${{ steps.extcache.outputs.key }}" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.extensions }}" + tools: "composer:${{ env.composer-version }}" + coverage: "pcov" + + - name: "Setup problem matchers for PHP" + run: 'echo "::add-matcher::${{ runner.tool_cache }}/php.json"' + + - name: "Get Composer cache directory" + id: "composercache" + run: 'echo "::set-output name=dir::$(composer config cache-files-dir)"' + + - name: "Cache PHP dependencies" + uses: "actions/cache@v2" + with: + path: "${{ steps.composercache.outputs.dir }}" + key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}" + restore-keys: "${{ runner.os }}-composer-" + + - name: "Install dependencies" + run: "${{ env.composer-install }} ${{ matrix.composer-args }}" + + - name: "Tests" + run: "make coverage" + + - name: "Coveralls.io" + env: + CI_NAME: github + CI: true + COVERALLS_REPO_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + run: | wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.1.0/php-coveralls.phar php php-coveralls.phar --verbose --config tests/.coveralls.yml - - build-python : - name : "Build Python distribution" - runs-on : "${{ matrix.operating-system }}" - - strategy : - matrix : - python : [ "3.9" ] - operating-system : [ "ubuntu-latest" ] - - steps : - - name : "Checkout" - uses : "actions/checkout@v2" - - - name : "Set up Python ${{ matrix.python }}" - uses : "actions/setup-python@v1" - with : - python-version : ${{ matrix.python }} - - - name : "Extract version" - uses : "battila7/get-version-action@v2" - id : "get_version" - - - name : "Install dependencies" - run : | - python -m pip install --upgrade pip - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - - name : "Install build dependencies" - run : "python -m pip install wheel --user" - - - name : "Build a binary wheel and a source tarball" - run : "python setup.py sdist bdist_wheel" - - - name : "Upload build result" - uses : "actions/upload-artifact@v1" - with : - name : python-dist - path : dist - - python-qa : - name : "Quality assurance for Python code" - runs-on : "${{ matrix.operating-system }}" - needs : "build-python" - - strategy : - matrix : - python : [ "3.9" ] - operating-system : [ "ubuntu-latest" ] - - steps : - - name : "Checkout" - uses : "actions/checkout@v2" - - - name : "Set up Python ${{ matrix.python }}" - uses : "actions/setup-python@v1" - with : - python-version : ${{ matrix.python }} - - - name : "Install dependencies" - run : | - python -m pip install --upgrade pip - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - - name : "Run code check" - run : "make py_qa" - - python-tests : - name : "Tests for Python code" - runs-on : "${{ matrix.operating-system }}" - needs : [ "python-qa" ] - - strategy : - matrix : - python : [ "3.9" ] - operating-system : [ "ubuntu-latest" ] - - steps : - - name : "Checkout" - uses : "actions/checkout@v2" - - - name : "Setup MySQL" - uses : "mirromutth/mysql-action@v1.1" - with : - mysql version : "5.7" - mysql database : "testdb" - mysql root password : "root" - - - name : "Wait for MySQL" - run : | - while ! mysqladmin ping --host=127.0.0.1 --password=root --silent; do - sleep 1 - done - - - name : "Set up Python ${{ matrix.python }}" - uses : "actions/setup-python@v1" - with : - python-version : ${{ matrix.python }} - - - name : "Install dependencies" - run : | - python -m pip install --upgrade pip - pip install mysqlclient - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - - name : "Run tests" - run : "make py_tests" - - python-tests-code-coverage : - name : "Tests for Python code with code coverage" - runs-on : "${{ matrix.operating-system }}" - needs : [ "python-tests" ] - - strategy : - matrix : - python : [ "3.9" ] - operating-system : [ "ubuntu-latest" ] - - steps : - - name : "Checkout" - uses : "actions/checkout@v2" - - - name : "Setup MySQL" - uses : "mirromutth/mysql-action@v1.1" - with : - mysql version : "5.7" - mysql database : "testdb" - mysql root password : "root" - - - name : "Wait for MySQL" - run : | - while ! mysqladmin ping --host=127.0.0.1 --password=root --silent; do - sleep 1 - done - - - name : "Set up Python ${{ matrix.python }}" - uses : "actions/setup-python@v1" - with : - python-version : ${{ matrix.python }} - - - name : "Install dependencies" - run : | - python -m pip install --upgrade pip - pip install mysqlclient - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - - name : "Install code coverage" - run : "pip install coverage" - - - name : "Run code coverage" - run : "make py_coverage" - - - name : "Report code coverage" - run : "coverage report" - - test-install-python : - name : "Test installation of Python distribution" - runs-on : "${{ matrix.operating-system }}" - needs : "build-python" - - strategy : - matrix : - python : [ "3.7", "3.8", "3.9", "3.10" ] - operating-system : [ "ubuntu-latest" ] - installable : [ "wheel", "sdist" ] - - steps : - - name : "Download build result" - uses : "actions/download-artifact@v1" - with : - name : python-dist - path : dist - - - name : "Set up Python ${{ matrix.python }}" - uses : "actions/setup-python@v1" - with : - python-version : ${{ matrix.python }} - - - name : "Install wheel" - if : matrix.installable == 'wheel' - run : "pip install dist/fastybird_exchange-*-py3-none-any.whl" - - - name : "Install source tarball" - if : matrix.installable == 'sdist' - run : "pip install dist/fastybird-exchange-*.tar.gz" - - publish-on-testpypi : - name : "Publish Python distribution on Test PyPI" - runs-on : "${{ matrix.operating-system }}" - needs : [ "test-install-python", "python-tests" ] - - strategy : - matrix : - operating-system : [ "ubuntu-latest" ] - - if : github.event_name == 'push' && contains(github.ref, 'refs/tags/') - - steps : - - name : "Download build result" - uses : "actions/download-artifact@v1" - with : - name : python-dist - path : dist - - - name : "Publish to index" - uses : "pypa/gh-action-pypi-publish@master" - with : - password : ${{ secrets.testpypi_password }} - repository_url : "https://test.pypi.org/legacy/" - - publish-on-pypi : - name : "Publish Python distribution to PyPI" - runs-on : "${{ matrix.operating-system }}" - needs : "publish-on-testpypi" - - strategy : - matrix : - operating-system : [ "ubuntu-latest" ] - - if : github.event_name == 'push' && contains(github.ref, 'refs/tags/') - - steps : - - name : "Download build result" - uses : "actions/download-artifact@v1" - with : - name : python-dist - path : dist - - - name : "Publish to index" - uses : "pypa/gh-action-pypi-publish@master" - with : - password : ${{ secrets.pypi_password }} \ No newline at end of file diff --git a/.mypy.ini b/.mypy.ini deleted file mode 100644 index 0b79637..0000000 --- a/.mypy.ini +++ /dev/null @@ -1,9 +0,0 @@ -[mypy] -disallow_untyped_defs = True -disallow_any_unimported = True -no_implicit_optional = True -check_untyped_defs = True -warn_return_any = True -show_error_codes = True -warn_unused_ignores = True -mypy_path = tests/stubs diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 3ac153b..0000000 --- a/.pylintrc +++ /dev/null @@ -1,7 +0,0 @@ -[FORMAT] - -# Maximum number of characters on a single line. -max-line-length=120 - -[MESSAGES CONTROL] -disable=duplicate-code diff --git a/LICENSE.md b/LICENSE.md index f2cc4d6..9c8f3ea 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -2,126 +2,180 @@ Version 2.0, January 2004 http://www.apache.org/licenses/ -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 - through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or - are under common control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by - contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) - beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, including but not limited to software source - code, documentation source, and configuration files. - - "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including - but not limited to compiled object code, generated documentation, and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as - indicated by a copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work - and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an - original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or - additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the - Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright - owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including - but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems - that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as " - Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been - received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to - You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, - prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such - Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a - perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise - transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are - necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity ( - including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within - the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this - License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with - or without modifications, and in Source or Object form, provided that You meet the following conditions: - - (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, - trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to - any part of the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You - distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those - notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a - NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided - along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such - third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not - modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be - construed as modifying the License. - - You may add Your own copyright statement to Your modifications and may provide additional or different license terms - and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a - whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in - this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for - inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any - additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any - separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product - names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and - reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and - each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, - MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness - of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this - License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or - otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, - shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or - consequential damages of any character arising as a result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or - any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such - damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose - to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or - rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and - on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and - hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" @@ -132,13 +186,16 @@ APPENDIX: How to apply the Apache License to your work. same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright {yyyy} {name of copyright owner} + Copyright {yyyy} {name of copyright owner} -Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the -License. You may obtain a copy of the License at + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an " -AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific -language governing permissions and limitations under the License. \ No newline at end of file + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/Makefile b/Makefile index 5831a18..8db9214 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: php_qa php_lint php_cs php_csf phpstan php_tests php_coverage py_qa py_tests py_coverage +.PHONY: qa lint cs csf phpstan tests coverage all: @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | xargs @@ -6,54 +6,22 @@ all: vendor: composer.json composer.lock composer install -php_qa: php_lint phpstan php_cs +qa: lint phpstan cs -php_lint: vendor +lint: vendor vendor/bin/parallel-lint --exclude .git --exclude vendor src tests -php_cs: vendor +cs: vendor vendor/bin/phpcs --standard=phpcs.xml src tests -php_csf: vendor +csf: vendor vendor/bin/phpcbf --standard=phpcs.xml src tests phpstan: vendor vendor/bin/phpstan analyse -c phpstan.neon src -php_tests: vendor +tests: vendor vendor/bin/tester -s -p php --colors 1 -C tests/cases -php_coverage: vendor +coverage: vendor vendor/bin/tester -s -p php --colors 1 -C --coverage ./coverage.xml --coverage-src ./src tests/cases - -pylint: - python -m pip install pylint - -mypy: - python -m pip install mypy - -black: - python -m pip install black - -isort: - python -m pip install isort - -py_qa: py_cs py_types py_isort py_black - -py_cs: pylint - pylint **/*.py - -py_types: mypy - mypy **/*.py - -py_isort: isort - isort **/*.py --check - -py_black: black - black **/*.py --check - -py_tests: - python -m unittest - -py_coverage: - coverage run --source=fastybird_exchange -m unittest \ No newline at end of file diff --git a/README.md b/README.md index 99df138..e32a575 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,6 @@ [![Downloads total](https://badgen.net/packagist/dt/FastyBird/exchange?cache=300&style=flast-square)](https://packagist.org/packages/FastyBird/exchange) [![PHPStan](https://img.shields.io/badge/PHPStan-enabled-brightgreen.svg?style=flat-square)](https://github.com/phpstan/phpstan) -![Python](https://badgen.net/pypi/python/fastybird-exchange?cache=300&style=flat-square) -[![Python latest stable](https://badgen.net/pypi/v/fastybird-exchange?cache=300&style=flat-square)](https://pypi.org/project/fastybird-exchange/) -[![Python downloads month](https://img.shields.io/pypi/dm/fastybird-exchange?cache=300&style=flat-square)](https://pypi.org/project/fastybird-exchange/) -[![Black](https://img.shields.io/badge/black-enabled-brightgreen.svg?style=flat-square)](https://github.com/psf/black) -[![MyPy](https://img.shields.io/badge/mypy-enabled-brightgreen.svg?style=flat-square)](http://mypy-lang.org) - *** ## What is FastyBird exchange library? @@ -24,20 +18,10 @@ implementing data exchange services. ## Installation -### PHP based project: - The best way to install **fastybird/exchange** is using [Composer](http://getcomposer.org/): ```sh -$ composer require fastybird/exchange -``` - -### Python based project: - -The best way to install **fastybird-exchange** is using [Pip](https://pip.pypa.io/en/stable/): - -```sh -$ pip install fastybird-exchange +composer require fastybird/exchange ``` ## Documentation diff --git a/composer.json b/composer.json index 3ac82cf..5ac63a3 100644 --- a/composer.json +++ b/composer.json @@ -71,8 +71,7 @@ "autoload-dev" : { "psr-4" : { - "Tests\\Cases\\" : "tests/cases", - "Tests\\Fixtures\\" : "tests/fixtures" + "Tests\\Cases\\Unit\\" : "tests/cases/unit" } }, diff --git a/fastybird_exchange/__init__.py b/fastybird_exchange/__init__.py deleted file mode 100644 index 6ec59cd..0000000 --- a/fastybird_exchange/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/python3 - -# Copyright 2021. FastyBird s.r.o. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Exchange library -""" - -__version__ = "0.60.0" diff --git a/fastybird_exchange/bootstrap.py b/fastybird_exchange/bootstrap.py deleted file mode 100644 index 3934576..0000000 --- a/fastybird_exchange/bootstrap.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/python3 - -# Copyright 2021. FastyBird s.r.o. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Exchange library DI container -""" - -# pylint: disable=no-value-for-parameter - -# Library dependencies -from typing import List, Optional - -# Library dependencies -from kink import di, inject - -# Library libs -from fastybird_exchange.consumer import Consumer, IConsumer -from fastybird_exchange.consumer import IQueue as IConsumerQueue -from fastybird_exchange.publisher import IPublisher -from fastybird_exchange.publisher import IQueue as IPublisherQueue -from fastybird_exchange.publisher import Publisher - - -def register_services() -> None: - """Create exchange services""" - di[Publisher] = Publisher() - di["fb-exchange_publisher"] = di[Publisher] - - di[Consumer] = Consumer() - di["fb-exchange_consumer"] = di[Consumer] - - @inject( - bind={ - "queue": IPublisherQueue, - "publishers": List[IPublisher], - } - ) - def register_publisher_queue( - queue: Optional[IPublisherQueue] = None, - publishers: Optional[List[IPublisher]] = None, - ) -> None: - if queue is not None and publishers is not None: - queue.set_publishers(publishers=publishers) - - register_publisher_queue() - - @inject( - bind={ - "queue": IConsumerQueue, - "consumers": List[IConsumer], - } - ) - def register_consumer_queue( - queue: Optional[IConsumerQueue] = None, - consumers: Optional[List[IConsumer]] = None, - ) -> None: - if queue is not None and consumers is not None: - queue.set_consumers(consumers=consumers) - - register_consumer_queue() diff --git a/fastybird_exchange/client.py b/fastybird_exchange/client.py deleted file mode 100644 index 1825d8f..0000000 --- a/fastybird_exchange/client.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/python3 - -# Copyright 2021. FastyBird s.r.o. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Exchange library messages client -""" - -# Python base dependencies -from abc import ABC, abstractmethod - - -class IClient(ABC): - """ - Data exchange client interface - - @package FastyBird:Exchange! - @module client - - @author Adam Kadlec - """ - - @abstractmethod - def start(self) -> None: - """Client start command""" - - # ----------------------------------------------------------------------------- - - @abstractmethod - def stop(self) -> None: - """Client stop command""" - - # ----------------------------------------------------------------------------- - - @abstractmethod - def handle(self) -> None: - """Handle client actions""" diff --git a/fastybird_exchange/consumer.py b/fastybird_exchange/consumer.py deleted file mode 100644 index fad6fa6..0000000 --- a/fastybird_exchange/consumer.py +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/python3 - -# Copyright 2021. FastyBird s.r.o. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Exchange library messages consumer -""" - -# Python base dependencies -from abc import ABC, abstractmethod -from typing import Dict, List, Optional, Set, Union - -# Library dependencies -from fastybird_metadata.routing import RoutingKey -from fastybird_metadata.types import ConnectorSource, ModuleSource, PluginSource -from kink import inject - - -class IConsumer(ABC): # pylint: disable=too-few-public-methods - """ - Data exchange consumer interface - - @package FastyBird:Exchange! - @module consumer - - @author Adam Kadlec - """ - - @abstractmethod - def consume( - self, - source: Union[ModuleSource, PluginSource, ConnectorSource], - routing_key: RoutingKey, - data: Optional[Dict[str, Union[str, int, float, bool, None]]], - ) -> None: - """Consume data received from exchange bus""" - - -class IQueue(ABC): # pylint: disable=too-few-public-methods - """ - Data exchange consumer queue interface - - @package FastyBird:Exchange! - @module consumer - - @author Adam Kadlec - """ - - @abstractmethod - def set_consumers(self, consumers: List[IConsumer]) -> None: - """Set consumers to queue""" - - # ----------------------------------------------------------------------------- - - @abstractmethod - def append( - self, - source: Union[ModuleSource, PluginSource, ConnectorSource], - routing_key: RoutingKey, - data: Optional[Dict], - ) -> None: - """Append new item to queue""" - - # ----------------------------------------------------------------------------- - - @abstractmethod - def handle(self) -> None: - """Proces one item from queue""" - - # ----------------------------------------------------------------------------- - - @abstractmethod - def has_unfinished_items(self) -> bool: - """Check if queue has some unfinished items""" - - -@inject( - bind={ - "consumers": List[IConsumer], - "queue": IQueue, - } -) -class Consumer: - """ - Data exchange consumer proxy - - @package FastyBird:Exchange! - @module consumer - - @author Adam Kadlec - """ - - __consumers: Set[IConsumer] - __queue: Optional[IQueue] = None - - # ----------------------------------------------------------------------------- - - def __init__( - self, - consumers: Optional[List[IConsumer]] = None, - queue: Optional[IQueue] = None, - ) -> None: - if consumers is None: - self.__consumers = set() - - else: - self.__consumers = set(consumers) - - self.__queue = queue - - # ----------------------------------------------------------------------------- - - def consume( - self, - source: Union[ModuleSource, PluginSource, ConnectorSource], - routing_key: RoutingKey, - data: Optional[Dict], - ) -> None: - """Call all registered consumers and consume data""" - if self.__queue is not None: - self.__queue.append(source=source, routing_key=routing_key, data=data) - - else: - for consumer in self.__consumers: - consumer.consume(source=source, routing_key=routing_key, data=data) - - # ----------------------------------------------------------------------------- - - def register_consumer( - self, - consumer: IConsumer, - ) -> None: - """Register new consumer to proxy""" - self.__consumers.add(consumer) - - if self.__queue is not None: - self.__queue.set_consumers(consumers=list(self.__consumers)) - - # ----------------------------------------------------------------------------- - - def register_queue( - self, - queue: IQueue, - ) -> None: - """Register consumer queue""" - if self.__queue is not None: - raise AttributeError("Queue is already configured in consumer service") - - self.__queue = queue diff --git a/fastybird_exchange/publisher.py b/fastybird_exchange/publisher.py deleted file mode 100644 index 5857c0a..0000000 --- a/fastybird_exchange/publisher.py +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/python3 - -# Copyright 2021. FastyBird s.r.o. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Exchange library publisher -""" - -# Python base dependencies -from abc import ABC, abstractmethod -from typing import Dict, List, Optional, Set, Union - -# Library dependencies -from fastybird_metadata.routing import RoutingKey -from fastybird_metadata.types import ConnectorSource, ModuleSource, PluginSource -from kink import inject - - -class IPublisher(ABC): # pylint: disable=too-few-public-methods - """ - Data exchange publisher interface - - @package FastyBird:Exchange! - @module publisher - - @author Adam Kadlec - """ - - @abstractmethod - def publish( - self, - source: Union[ModuleSource, PluginSource, ConnectorSource], - routing_key: RoutingKey, - data: Optional[Dict], - ) -> None: - """Publish data to exchange bus""" - - -class IQueue(ABC): # pylint: disable=too-few-public-methods - """ - Data exchange publisher queue interface - - @package FastyBird:Exchange! - @module publisher - - @author Adam Kadlec - """ - - @abstractmethod - def set_publishers(self, publishers: List[IPublisher]) -> None: - """Set publishers to queue""" - - # ----------------------------------------------------------------------------- - - @abstractmethod - def append( - self, - source: Union[ModuleSource, PluginSource, ConnectorSource], - routing_key: RoutingKey, - data: Optional[Dict], - ) -> None: - """Append new item to queue""" - - # ----------------------------------------------------------------------------- - - @abstractmethod - def handle(self) -> None: - """Proces one item from queue""" - - # ----------------------------------------------------------------------------- - - @abstractmethod - def has_unfinished_items(self) -> bool: - """Check if queue has some unfinished items""" - - -@inject( - bind={ - "publishers": List[IPublisher], - "queue": IQueue, - } -) -class Publisher: - """ - Data exchange publisher proxy - - @package FastyBird:Exchange! - @module publisher - - @author Adam Kadlec - """ - - __publishers: Set[IPublisher] = set() - __queue: Optional[IQueue] = None - - # ----------------------------------------------------------------------------- - - def __init__( - self, - publishers: Optional[List[IPublisher]] = None, - queue: Optional[IQueue] = None, - ) -> None: - if publishers is None: - self.__publishers = set() - - else: - self.__publishers = set(publishers) - - self.__queue = queue - - # ----------------------------------------------------------------------------- - - def publish( - self, - source: Union[ModuleSource, PluginSource, ConnectorSource], - routing_key: RoutingKey, - data: Optional[Dict], - ) -> None: - """Call all registered publishers and publish data""" - if self.__queue is not None: - self.__queue.append(source=source, routing_key=routing_key, data=data) - - else: - for publisher in self.__publishers: - publisher.publish(source=source, routing_key=routing_key, data=data) - - # ----------------------------------------------------------------------------- - - def register_publisher( - self, - publisher: IPublisher, - ) -> None: - """Register new publisher to proxy""" - self.__publishers.add(publisher) - - if self.__queue is not None: - self.__queue.set_publishers(publishers=list(self.__publishers)) - - # ----------------------------------------------------------------------------- - - def register_queue( - self, - queue: IQueue, - ) -> None: - """Register publisher queue""" - if self.__queue is not None: - raise AttributeError("Queue is already configured in publisher service") - - self.__queue = queue diff --git a/fastybird_exchange/py.typed b/fastybird_exchange/py.typed deleted file mode 100644 index e69de29..0000000 diff --git a/phpcs.xml b/phpcs.xml index faa1eda..80dcc3d 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -16,7 +16,6 @@ - diff --git a/phpstan.neon b/phpstan.neon index a834948..22254bc 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,2 +1,2 @@ parameters: - level: max + level: max diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index c7d708d..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[tool.black] -line-length = 120 - -[tool.isort] -profile = "black" -multi_line_output = 3 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 51fc6d1..0000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -fastybird-metadata>=0.76 -kink>=0.6 -setuptools>=57.4 \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index 514464a..0000000 --- a/setup.py +++ /dev/null @@ -1,92 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2021. FastyBird s.r.o. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Library dependencies -import codecs -import re -from setuptools import setup, find_packages -from os import path - - -this_directory = path.abspath(path.dirname(__file__)) - -with open(path.join(this_directory, "README.md"), encoding="utf-8") as f: - long_description = f.read() - - -def read(*parts): - filename = path.join(path.dirname(__file__), *parts) - - with codecs.open(filename, encoding='utf-8') as fp: - return fp.read() - - -def find_version(*file_paths): - version_file = read(*file_paths) - version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M) - - if version_match: - return version_match.group(1) - - raise RuntimeError("Unable to find version string.") - - -VERSION: str = find_version("fastybird_exchange", "__init__.py") - - -setup( - version=VERSION, - name="fastybird-exchange", - author="FastyBird", - author_email="code@fastybird.com", - license="Apache Software License (Apache Software License 2.0)", - description="FastyBird application exchange services", - url="https://github.com/FastyBird/exchange", - long_description=long_description, - long_description_content_type="text/markdown", - python_requires=">=3.7", - packages=find_packages(), - package_data={"fastybird_exchange": ["py.typed"]}, - install_requires=[ - "fastybird-metadata", - "kink", - "setuptools" - ], - download_url="https://github.com/FastyBird/exchange/archive/%s.tar.gz" % VERSION, - classifiers=[ - "Development Status :: 4 - Beta", - "Environment :: Console", - "Environment :: Plugins", - "Intended Audience :: Developers", - "Intended Audience :: Education", - "Intended Audience :: End Users/Desktop", - "Intended Audience :: Information Technology", - "Intended Audience :: Manufacturing", - "Intended Audience :: System Administrators", - "License :: OSI Approved :: Apache Software License", - "Natural Language :: English", - "Operating System :: OS Independent", - "Programming Language :: PHP", - "Programming Language :: Python", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Topic :: Communications", - "Topic :: Home Automation", - "Topic :: System :: Hardware", - ]) diff --git a/src/Consumer/Container.php b/src/Consumer/Container.php index 80e294d..182c3c1 100644 --- a/src/Consumer/Container.php +++ b/src/Consumer/Container.php @@ -36,7 +36,7 @@ class Container implements Consumer private SplObjectStorage $consumers; public function __construct( - private PsrEventDispatcher\EventDispatcherInterface|null $dispatcher = null, + private readonly PsrEventDispatcher\EventDispatcherInterface|null $dispatcher = null, ) { $this->consumers = new SplObjectStorage(); diff --git a/src/Entities/EntityFactory.php b/src/Entities/EntityFactory.php index 805f3d3..aff63ad 100644 --- a/src/Entities/EntityFactory.php +++ b/src/Entities/EntityFactory.php @@ -32,32 +32,32 @@ final class EntityFactory { public function __construct( - private MetadataEntities\Actions\ActionConnectorControlEntityFactory $actionConnectorControlEntityFactory, - private MetadataEntities\Actions\ActionConnectorPropertyEntityFactory $actionConnectorPropertyEntityFactory, - private MetadataEntities\Actions\ActionDeviceControlEntityFactory $actionDeviceControlEntityFactory, - private MetadataEntities\Actions\ActionDevicePropertyEntityFactory $actionDevicePropertyEntityFactory, - private MetadataEntities\Actions\ActionChannelControlEntityFactory $actionChannelControlEntityFactory, - private MetadataEntities\Actions\ActionChannelPropertyEntityFactory $actionChannelPropertyEntityFactory, - private MetadataEntities\Actions\ActionTriggerControlEntityFactory $actionTriggerControlEntityFactory, - private MetadataEntities\AccountsModule\AccountEntityFactory $accountEntityFactory, - private MetadataEntities\AccountsModule\EmailEntityFactory $emailEntityFactory, - private MetadataEntities\AccountsModule\IdentityEntityFactory $identityEntityFactory, - private MetadataEntities\AccountsModule\RoleEntityFactory $roleEntityFactory, - private MetadataEntities\TriggersModule\ActionEntityFactory $triggerActionEntityFactory, - private MetadataEntities\TriggersModule\ConditionEntityFactory $triggerConditionEntityFactory, - private MetadataEntities\TriggersModule\NotificationEntityFactory $triggerNotificationEntityFactory, - private MetadataEntities\TriggersModule\TriggerControlEntityFactory $triggerControlEntityFactory, - private MetadataEntities\TriggersModule\TriggerEntityFactory $triggerEntityFactory, - private MetadataEntities\DevicesModule\ConnectorEntityFactory $connectorEntityFactory, - private MetadataEntities\DevicesModule\ConnectorControlEntityFactory $connectorControlEntityFactory, - private MetadataEntities\DevicesModule\ConnectorPropertyEntityFactory $connectorPropertyEntityFactory, - private MetadataEntities\DevicesModule\DeviceEntityFactory $deviceEntityFactory, - private MetadataEntities\DevicesModule\DeviceControlEntityFactory $deviceControlEntityFactory, - private MetadataEntities\DevicesModule\DevicePropertyEntityFactory $devicePropertyEntityFactory, - private MetadataEntities\DevicesModule\DeviceAttributeEntityFactory $deviceAttributeEntityFactory, - private MetadataEntities\DevicesModule\ChannelEntityFactory $channelEntityFactory, - private MetadataEntities\DevicesModule\ChannelControlEntityFactory $channelControlEntityFactory, - private MetadataEntities\DevicesModule\ChannelPropertyEntityFactory $channelPropertyEntityFactory, + private readonly MetadataEntities\Actions\ActionConnectorControlEntityFactory $actionConnectorControlEntityFactory, + private readonly MetadataEntities\Actions\ActionConnectorPropertyEntityFactory $actionConnectorPropertyEntityFactory, + private readonly MetadataEntities\Actions\ActionDeviceControlEntityFactory $actionDeviceControlEntityFactory, + private readonly MetadataEntities\Actions\ActionDevicePropertyEntityFactory $actionDevicePropertyEntityFactory, + private readonly MetadataEntities\Actions\ActionChannelControlEntityFactory $actionChannelControlEntityFactory, + private readonly MetadataEntities\Actions\ActionChannelPropertyEntityFactory $actionChannelPropertyEntityFactory, + private readonly MetadataEntities\Actions\ActionTriggerControlEntityFactory $actionTriggerControlEntityFactory, + private readonly MetadataEntities\AccountsModule\AccountEntityFactory $accountEntityFactory, + private readonly MetadataEntities\AccountsModule\EmailEntityFactory $emailEntityFactory, + private readonly MetadataEntities\AccountsModule\IdentityEntityFactory $identityEntityFactory, + private readonly MetadataEntities\AccountsModule\RoleEntityFactory $roleEntityFactory, + private readonly MetadataEntities\TriggersModule\ActionEntityFactory $triggerActionEntityFactory, + private readonly MetadataEntities\TriggersModule\ConditionEntityFactory $triggerConditionEntityFactory, + private readonly MetadataEntities\TriggersModule\NotificationEntityFactory $triggerNotificationEntityFactory, + private readonly MetadataEntities\TriggersModule\TriggerControlEntityFactory $triggerControlEntityFactory, + private readonly MetadataEntities\TriggersModule\TriggerEntityFactory $triggerEntityFactory, + private readonly MetadataEntities\DevicesModule\ConnectorEntityFactory $connectorEntityFactory, + private readonly MetadataEntities\DevicesModule\ConnectorControlEntityFactory $connectorControlEntityFactory, + private readonly MetadataEntities\DevicesModule\ConnectorPropertyEntityFactory $connectorPropertyEntityFactory, + private readonly MetadataEntities\DevicesModule\DeviceEntityFactory $deviceEntityFactory, + private readonly MetadataEntities\DevicesModule\DeviceControlEntityFactory $deviceControlEntityFactory, + private readonly MetadataEntities\DevicesModule\DevicePropertyEntityFactory $devicePropertyEntityFactory, + private readonly MetadataEntities\DevicesModule\DeviceAttributeEntityFactory $deviceAttributeEntityFactory, + private readonly MetadataEntities\DevicesModule\ChannelEntityFactory $channelEntityFactory, + private readonly MetadataEntities\DevicesModule\ChannelControlEntityFactory $channelControlEntityFactory, + private readonly MetadataEntities\DevicesModule\ChannelPropertyEntityFactory $channelPropertyEntityFactory, ) { } diff --git a/src/Events/AfterMessageConsumed.php b/src/Events/AfterMessageConsumed.php index abced5e..dca09cb 100644 --- a/src/Events/AfterMessageConsumed.php +++ b/src/Events/AfterMessageConsumed.php @@ -31,8 +31,8 @@ class AfterMessageConsumed extends EventDispatcher\Event { public function __construct( - private MetadataTypes\RoutingKey $routingKey, - private MetadataEntities\Entity|null $entity, + private readonly MetadataTypes\RoutingKey $routingKey, + private readonly MetadataEntities\Entity|null $entity, ) { } diff --git a/src/Events/AfterMessagePublished.php b/src/Events/AfterMessagePublished.php index 5573ae1..9c95261 100644 --- a/src/Events/AfterMessagePublished.php +++ b/src/Events/AfterMessagePublished.php @@ -31,8 +31,8 @@ class AfterMessagePublished extends EventDispatcher\Event { public function __construct( - private MetadataTypes\RoutingKey $routingKey, - private MetadataEntities\Entity|null $entity, + private readonly MetadataTypes\RoutingKey $routingKey, + private readonly MetadataEntities\Entity|null $entity, ) { } diff --git a/src/Events/BeforeMessageConsumed.php b/src/Events/BeforeMessageConsumed.php index 080e1de..06a172b 100644 --- a/src/Events/BeforeMessageConsumed.php +++ b/src/Events/BeforeMessageConsumed.php @@ -31,8 +31,8 @@ class BeforeMessageConsumed extends EventDispatcher\Event { public function __construct( - private MetadataTypes\RoutingKey $routingKey, - private MetadataEntities\Entity|null $entity, + private readonly MetadataTypes\RoutingKey $routingKey, + private readonly MetadataEntities\Entity|null $entity, ) { } diff --git a/src/Events/BeforeMessagePublished.php b/src/Events/BeforeMessagePublished.php index 1245b14..55586bd 100644 --- a/src/Events/BeforeMessagePublished.php +++ b/src/Events/BeforeMessagePublished.php @@ -31,8 +31,8 @@ class BeforeMessagePublished extends EventDispatcher\Event { public function __construct( - private MetadataTypes\RoutingKey $routingKey, - private MetadataEntities\Entity|null $entity, + private readonly MetadataTypes\RoutingKey $routingKey, + private readonly MetadataEntities\Entity|null $entity, ) { } diff --git a/src/Publisher/Container.php b/src/Publisher/Container.php index 1061851..4b928a6 100644 --- a/src/Publisher/Container.php +++ b/src/Publisher/Container.php @@ -36,7 +36,7 @@ class Container implements Publisher private SplObjectStorage $publishers; public function __construct( - private PsrEventDispatcher\EventDispatcherInterface|null $dispatcher = null, + private readonly PsrEventDispatcher\EventDispatcherInterface|null $dispatcher = null, ) { $this->publishers = new SplObjectStorage(); diff --git a/tests/.coveralls.yml b/tests/.coveralls.yml index 8197af3..245f40e 100644 --- a/tests/.coveralls.yml +++ b/tests/.coveralls.yml @@ -1,4 +1,4 @@ # for php-coveralls -service_name : github-ci -coverage_clover : coverage.xml -json_path : coverage.json \ No newline at end of file +service_name: github-ci +coverage_clover: coverage.xml +json_path: coverage.json \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 87580f2..0000000 --- a/tests/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2021. FastyBird s.r.o. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Exchange plugin tests -""" diff --git a/tests/bootstrap.php b/tests/bootstrap.php index f4ee849..959c2b3 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,7 +1,11 @@ None: ... - - def add_listener(self, event_id: str, listener: Callable[[Event], None], priority: int =0) -> None: ... - - def has_listeners(self, event_id: Optional[str] = None) -> bool: ... - - def remove_listener(self, event_id: str, listener: Callable[[Event], None]) -> None: ...