commit b744b08829d8031a6751cb6aac4a86e68f8aa19a Author: Sergey Kryuchkov Date: Mon Sep 6 17:46:59 2021 +0300 initial public commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..8f5afde0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,65 @@ +# These are some examples of commonly ignored file patterns. +# You should customize this list as applicable to your project. +# Learn more about .gitignore: +# https://www.atlassian.com/git/tutorials/saving-changes/gitignore + +# Node artifact files +node_modules/ +dist/ + +# Compiled Java class files +*.class + +# Compiled Python bytecode +*.py[cod] + +# Log files +*.log + +# Package files +*.jar + +# Maven +target/ +dist/ +dependency-reduced-pom.xml +pom.xml.versionsBackup + +# JetBrains IDE +.idea/ +*.iml +*.im + +# Unit test reports +TEST*.xml + +# Generated by MacOS +.DS_Store + +# Generated by Windows +Thumbs.db + +# Applications +*.app +*.exe +*.war + +# Large media files +*.mp4 +*.tiff +*.avi +*.flv +*.mov +*.wmv + +# OS or Editor folders +.cache +.project +.settings +.tmproj +*.cache + +# Eclipse project file +*.classpath +.tern-project + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..db1a1254 --- /dev/null +++ b/README.md @@ -0,0 +1,157 @@ +# entaxy-esb + +### Alternative languages + +[Russian](README.ru.md) + +Detailed documentation: [system description](documentation/entaxy_main.adoc).\ +Installation instructions: [installation](documentation/installation/installation-table-of-contents.ru.adoc).\ +Instructions for running tests for the universal +service: [tests](documentation/connectors/uniform-exchange-service/tests/postman.adoc). + +- **extras** - additional esb modules(Developed independently, installed separately.) + - **1c** - module for working with 1C + - **1c-exchange-service** - (Alexey Knyazev, Borodina Valeria) message processing module, service 1C + - **1c-exchange-endpoint** - soap-service 1C + - **1c-exchange-service-endpoint** - service soap-service 1C + - **connector** - stored in and out connectors at 1c-exchange-endpoint and 1c-exchange-service-endpoint + - **support** - support routers for connectors + - **1c-storage** - (Alexey Knyazev) liquibase module creating the necessary tables in the database for 1C + - **nsi** - (Alexey Knyazev, Borodina Valeria) module for nsi + - **nsi-soap** - (Alexey Knyazev) module with soap nsi + - **nsi-storage** - (Alexey Knyazev) liquibase module creating the necessary tables in the database for nsi + - **big-packet** - (Alexey Knyazev) big packet service + - **bridge** - (Mikhail Moiseev) bridge between different esb using brokers + - **db-connector-parent** - (Alexey Knyazev) connector to intermediate database + - **db-connector** - (Alexey Knyazev) connector to intermediate database, converts xml into java objects and + then saves it to the database via jpa, and also back + - **db-hyperjaxb3-naming-extension** - (Alexey Knyazev) - plugin for the hyperjaxb3 plugin that makes more + human-readable names for xsd generated columns and tables + - **file-archive-connector** - (Borodina Valeria) module for working with systems that work through the file + system (collects messages within an hour and collects them into an archive) + - **file-service** - (Alexey Knyazev) service for sending files via esb +- **features** - there should generally be one feature that pulls up features for individual components. Having + installed it, we install entaxy in Karaf +- **platform** - Content of a base entaxy + - **runtime** - Components required for launch and work of the platform + - **base** - starts before the bundles with a low startlevel or even enters the custom build of Karaf + - **branding** - logo creation entaxy + - **connecting** - infrastructure of adapters and connections + - **core** - core entaxy + - **initializer** - Initialization infrastructure on first startup, including checking, creating and running + the required system connections + - **storage-initializer** - (Mikhail Moiseev) everything related to data storage + - **management** - artifact management + - **modules** - additional modules entaxy + - **uniform-service** - uniform service + - **uniform-service-exchange-endpoint** - uniform soap-service + - **connector** - stored in and out connectors + - **support** - support routers for connectors +- **system** - (Andrey Filippov) the product(the module will subsequently be removed) + - **auth** - (Sergey Kryuchkov, Mikhail Moiseev) everything related to authorization, including bundles for specific + authorization schemes, a general interceptor for CXF, etc. + - **common** - common libraries + - **core** - the core of the system + - **dispatcher** - + - **events** - (Mikhail Moiseev) work with topics, our implementation of message delivery + - **permission** - (Mikhail Moiseev) permission + - **template** - (Borodina Valeria) work with templates to create profiles, connectors, etc. + - **error-handler** - (Sergey Kryuchkov) error handling routes and helper classes. + - **deployer** - (Borodina Valeria) everything related to the process of processing data from a gui, converting it + to a blueprint and deploying this blueprint to esb + - **cellar-deployer** - (Borodina Valeria) deploy blueprint to karaf cluster using cellar + - **deployer-api** - (Mikhail Moiseev, Borodina Valeria) interface deployer + - **nexus-deployer** - (Borodina Valeria) deploy generated blueprint to nexus + - **file-system-deployer** - (Mikhail Moiseev) deploy generated blueprints to filesystem + - **registry** - (Mikhail Moiseev) product-defined registries should contain systems, system-groups, services for + specific registry implementations + - **systems** - description of the external system in ours + - **system-groups** - groups of systems, generalized by some attribute + - **profile-commons** - can be connected by a connector to a communication point + - **processes** - + - **service** - this is the point of communication. (something deployed under CXF) + - **connectors** - something that links the profile to the point of communication + - **system-management** - (Borodina Valeria) management of systems, profiles and system connectors + - **transformer** - implementation of data transformations gui -> blueprint + - **test** - tests for postman + + + Use English in the repository! + - in the commit comments + - int the code + +## **Repository rules** + + Commits to the master are undesirable, but if you cannot do otherwise, warn colleagues in the general chat with a description of the reason. + +**short:** + +Feature branching - any development is carried out in separate branches (we branch from master / release) and then we +make a pull request. + +**full:** + +**Branches:** + +- *master* - develop branch, we do new branch from it and we merge into it + +- *release-* - stable release branch from it we do new branch in case of hotfix. + Release branch storage conditions: + + 1. customer pays for support + 2. our support for this release has not expired + 3. the customer did not switch to a new release + +- *feature-branch* - development branches, stored until checked out and merged with the target branch\ + Branch naming: + + * issue number from youtrack + * especially meaningful short name of the functional + +- *hotfix-branch* - branches for hotfixes, stored similarly *feature-branch*\ + Branch naming - prefix "hotfix-" further: + + * issue number from youtrack + * especially meaningful short name of the functional + +**Pull request** + +- **For fixes and minor improvements** we assign to reviewers: lead developer - *Alexey Knyazev* and *responsible + for functionality / interested parties* + responsible and interested can be found in the description of the project above. + +- **For major improvements** to the persons described above, add *Andrey Filippov* and *Sergey Starovoitenkov* + +If no more improvements are planned in the merge-directed branch, when creating a pull request, we mark **Close branch** + +**Camel Headers** + + Headers used for service purposes are named according to the HTTP manifest, i.e. with a capital letter through a dash. + Must start with "Entaxy-" + +**Configuration File Naming Format** + +**Connectors:**\ +_..._\ +examples \ +_project.1c.odata.in_\ +_project.rest1.in_ + +**Project configs (specific functionality):**\ +_._\ +examples\ +_project.audit_\ +_project2.informer_ + +**Extras modules:**\ +_._\ +examples\ +_ru.entaxy.eav_\ +_org.apache.mdm_ + +**Platform:**\ +_.._\ +examples\ +_ru.entaxy.esb.system.management_\ +_ru.entaxy.esb.system.bridge_ + diff --git a/README.ru.md b/README.ru.md new file mode 100644 index 00000000..81e24e87 --- /dev/null +++ b/README.ru.md @@ -0,0 +1,148 @@ +# entaxy-esb + +### Languages +[English](README.md) + +Подробная документация: [описание системы](documentation/entaxy_main.adoc).\ +Инструкция по установке: [установка](documentation/installation/installation-table-of-contents.ru.adoc).\ +Инструкция по запуску тестов для универсального коннектора: [тестирование](documentation/connectors/uniform-exchange-service/tests/postman.adoc). + +- **extras** - дополнительные модули шины, которые не входят в базовую поставку шины.(Разрабатывается независимо, устанавливается отдельно.) + - **1с** - модуль рaботы с 1с + - **1c-exchange-service** - (Алексей Князев, Бородина Валерия) модуль обработки сообщений, сервис 1с + - **1c-exchange-endpoint** - выставленный soap-сервис 1с + - **1c-exchange-service-endpoint** - выставленный служебный soap-сервис 1с + - **connector** - хранятся входящий и исходящий коннектор к 1c-exchange-endpoint и 1c-exchange-service-endpoint + - **support** - маршруты, которые нужны для корректной работы коннектора + - **1с-storage** - (Алексей Князев) модуль liquibase создания необходимых таблиц в бд для 1с + - **nsi** - (Алексей Князев, Бородина Валерия) модуль обработки сообщений nsi + - **nsi-soap** - (Алексей Князев) модуль с выставленным soap nsi + - **nsi-storage** - (Алексей Князев) модуль liquibase создания необходимых таблиц в бд для nsi + - **big-packet** - (Алексей Князев) сервис больших пакетов + - **bridge** - (Моисеев Михаил) мост между шинами с использованием брокеров + - **db-connector-parent** - (Алексей Князев) коннектор к промежуточной базе + - **db-connector** - (Алексей Князев) коннектор к промежуточной базе, преобразует xml в java объекты и потом через jpa сохраняет в бд, и также обратно + - **db-hyperjaxb3-naming-extension** - (Алексей Князев) - плагин для плагина hyperjaxb3 который делает более человекочитаемые имена для генерируемых из xsd столбцов и таблиц + - **file-archive-connector** - (Бородина Валерия) модуль для работы с системами, которые работают через файловую систему(собирает сообщения в течение часа и собирает их в архив) + - **file-service** - (Алексей Князев) сервис отправки файлов через шину +- **features** - там вообще должна быть одна фича, которая подтягивает фичи по отдельным компонентам. Установив ее мы и устанавливаем продукт в караф +- **platform** - Содержимое типовой поставки + - **runtime** - Компоненты необходимые для запуска и работы платформы + - **base** - То, что стартует до остальных бандлов с низким startlevel или вообще входит в кастомную сборку Карафа + - **branding** - создание логотипа entaxy + - **connecting** - инфраструктура адаптеров и коннекций + - **core** - ядро entaxy + - **initializer** - Инфраструктра инициализации при первом запуске, в том числе проверка, создание и запуск необходимых системных коннекций + - **storage-initializer** - (Моисеев Михаил) все, что относится к хранению данных с общей точки зрения + - **management** - управление артефактами + - **modules** - дополнительные модули entaxy + - **uniform-service** - Универсальный сервис + - **uniform-service-exchange-endpoint** - выставленный универсальный soap-сервис + - **uniform-service-exchange-service-endpoint** - выставленный универсальный служебный soap-сервис + - **connector** - хранятся входящий и исходящий коннектор + - **support** - маршруты, которые нужны для корректной работы коннектора +- **system** - (Андрей Филиппов) собственно, продукт(модуль впоследствии будет удален) + - **auth** - (Сергей Крючков, Моисеев Михаил) все, что относится к авторизации, включая бандлы для конкретных схем авторизации, общий интерсептор для CXF и т.д. + - **common** - общие библиотеки + - **core** - ядро системы, что там будет, пока сложно конкретизировать, но что-то наверняка будет + - **dispatcher** - + - **events** - (Моисеев Михаил) работа с топиками, наша реализация доставки сообщений + - **permission** - (Моисеев Михаил) права доступа + - **template** - (Бородина Валерия) работа с шаблонами для создания профилей, коннекторов и т д + - **error-handler** - (Сергей Крючков) маршруты для обработки ошибок и вспомогательные классы. + - **deployer** - (Бородина Валерия) все, что относится к процессу обработки данных из gui, их преобразования в blueprint и деплоя этого blueprint в шину + - **cellar-deployer** - (Бородина Валерия) деплой blueprint в кластер карафа с помощью cellar + - **deployer-api** - (Моисеев Михаил, Бородина Валерия) интерфейс deployer + - **nexus-deployer** - (Бородина Валерия) деплой сгенерированных blueprint в nexus + - **file-system-deployer** - (Моисеев Михаил) деплой сгенерированных blueprint в файловую систему + - **registry** - (Моисеев Михаил) реестры, определенные в продукте, должна содержать systems, system-groups, services для реализаций конкретных реестров + - **systems** - описание внешней системы в нашей. + - **system-groups** - группы систем, обобщённые по какому-либо признаку + - **profile-commons** - может быть связан коннектором с точкой коммуникации. + - **processes** - + - **service** - это точка коммуникации. (что-то, развернутое под CXF) + - **connectors** - нечто, что связывает профиль с точкой коммуникации + - **system-management** - (Бородина Валерия) управление системами, профилями и коннекторами систем + - **transformer** - видимо, друг deploer'а, реализация трансформаций данных gui -> blueprint + - **test** - тесты для postman + + + В репозитории использовать английский! + - в комментариях к коммитам + - в коде + +## **Правила работы с репозиторием** + + Коммиты в мастер глубоко нежелательны, но если нельзя поступить по-другому, предупредите коллег в общем чате с описанием причины. + +**Кратко:** + +Feature branching - любая разработка ведётся в отдельных ветках(бранчуемся от master/release) после чего делаем pull request. + + +**Полно:** + +**Ветки:** + +- *master* - develop ветка от неё бранчуемся, в неё сливаемся + +- *release-* - стабильная релизная ветка от неё бранчуемся в случае hotfix-ов. + Условия хранения релизной ветки: + + 1. заказчик платит за поддержку + 2. не истек срок нашей поддержки этого релиза + 3. заказчик не произвел переход на новый релиз + +- *feature-branch* - ветки разработок, хранится до проверки и слияния с целевой веткой + Именование веток: + + * номером задачи из youtrack + * особо осмысленным кратким названием функционала + +- *hotfix-branch* - ветки для hotfix-ов, хранится аналогично *feature-branch* + Именование веток - префикс "hotfix-" далее: + + * номер задачи из youtrack + * особо осмысленное краткое название исправления + +**Pull request** + +- **Для фиксов и мелких доработок** назначаем в рецензенты: ведущего разработчика - *Алексея Князева* и *ответственных за функционал/заинтересованных лиц* + ответственных и заинтересованных можно посмотреть в описании проекта выше. + +- **Для крупных доработок** к описанным выше лицам добавляем *Андрея Филиппова* и *Сергея Старовойтенкова* + +Если не планируется больше доработок в ветке направленной на мерж, при создании pull request-а помечаем **Close branch** + +**Camel заголовки** + + Заголовки используемые для служебных целей именуются в соответствии с HTTP манифестом, т.е. с большой буквы через тире. + Начинаться должны с "Entaxy-" + +**Формат именования конфигурационных файлов** + +**Коннекторы:**\ +_..._\ +примеры \ +_project.1c.odata.in_\ +_project.rest1.in_ + +**Проектные конфиги(специфическая функциональность):**\ +_._\ +примеры\ +_project.audit_\ +_project2.informer_ + +**Extras модули:**\ +_._\ +примеры\ +_ru.entaxy.eav_\ +_org.apache.mdm_ + +**Платформа:**\ +_.._\ +примеры\ +_ru.entaxy.esb.system.management_\ +_ru.entaxy.esb.system.bridge_ + + diff --git a/documentation/Entaxy.png b/documentation/Entaxy.png new file mode 100644 index 00000000..bc9a4331 Binary files /dev/null and b/documentation/Entaxy.png differ diff --git a/documentation/Management layer.postman_collection.json b/documentation/Management layer.postman_collection.json new file mode 100644 index 00000000..c5dcc632 --- /dev/null +++ b/documentation/Management layer.postman_collection.json @@ -0,0 +1,3606 @@ +{ + "info": { + "_postman_id": "5f1e5b20-f1dd-46d2-a01c-36ed09cee573", + "name": "Management layer", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "Руководство по управлению коннекторами и профилями в шине.", + "item": [ + { + "name": "Создание профиля системы", + "event": [ + { + "listen": "test", + "script": { + "id": "ddae46ff-75a9-443b-8d11-a04edba74dbc", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system_id}}\n {{system_id}}\n \n default system\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Для создания профиля системы нужно вызвать метод createProfile, где вместо “system_uuid” нужно подставить uuid системы, вместо “system_name” - имя системы, “description” описание системы:\n" + }, + "response": [] + }, + { + "name": "Получить профиль системы", + "event": [ + { + "listen": "test", + "script": { + "id": "231fc234-06f3-4758-9b33-61a3f1426d58", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var systemId = pm.environment.get(\"system1_id\");", + "", + "pm.test(\"Body matches \" + systemId, function () {", + " pm.expect(pm.response.text()).to.include(systemId);", + "});", + "", + "var connectorName = pm.globals.get(\"template_name\") + \"-\" + systemId;", + "", + "pm.test(\"Body matches \" + connectorName, function () {", + " pm.expect(pm.response.text()).to.include(connectorName);", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Проверить созданный профиль можно с помощью метода getProfile, где вместо “system_uuid” нужно подставить uuid системы\n" + }, + "response": [] + }, + { + "name": "Получить весь список профилей систем", + "event": [ + { + "listen": "test", + "script": { + "id": "86d87f3a-2067-4d17-becf-b52428bc67e7", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "var systemId = pm.environment.get(\"system1_id\");", + "var esbName = pm.environment.get(\"esb_name\");", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "if (response.hasOwnProperty('fullBridgeProfileType')) {", + " ", + " pm.test(\"Body matches \" + esbName, function () {", + " pm.expect(pm.response.text()).to.include(esbName);", + " });", + " ", + " pm.test(\"Body matches \" + systemId, function () {", + " pm.expect(pm.response.text()).to.include(systemId);", + " });", + "}" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Получить список профилей, зарегистрированных в шине, можно с помощью метода getProfiles" + }, + "response": [] + }, + { + "name": "Остановить работу профиля системы в шине ", + "event": [ + { + "listen": "test", + "script": { + "id": "e9016f40-0fb8-4d44-a58a-7ea98c883aa9", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Остановить профиль и все его зависимости можно с помощью метода stopProfile, где вместо “system_uuid” нужно подставить uuid системы\n" + }, + "response": [] + }, + { + "name": "Запустить работу профиля систем в шине", + "event": [ + { + "listen": "test", + "script": { + "id": "6fccc710-0a84-4843-a1bb-73c643e8c53d", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Запустить профиль и все его зависимости можно с помощью метода startProfile, где вместо “system_uuid” нужно подставить uuid системы\n" + }, + "response": [] + }, + { + "name": "Удалить профиль системы из шины", + "event": [ + { + "listen": "test", + "script": { + "id": "791636da-cb95-40d9-a709-17da9f769ff9", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Удалить профиль и все его зависимости можно с помощью метода removeProfile, где вместо “system_uuid” нужно подставить uuid системы(ВНИМАНИЕ! При удалении профиля также удаляются все связанные с ним коннекторы)" + }, + "response": [] + }, + { + "name": "Получить список шаблонов коннекторов", + "event": [ + { + "listen": "test", + "script": { + "id": "6c1b7bb5-e787-4bfc-9291-73648162dec9", + "exec": [ + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has Messages\", function () {", + " pm.expect(response).to.have.property('listTemplate');", + "});", + "", + "if (response.hasOwnProperty('listTemplate')) {", + " var list_template = response['listTemplate'];", + "", + " pm.test(\"Body matches nsi-in-connector\", function () {", + " pm.expect(pm.response.text()).to.include(\"nsi-in-connector\");", + " });", + " ", + " // if (response.some(item => item.templateName === 'nsi-in-connector')) {", + " pm.globals.set(\"template_name\", \"nsi-in-connector\");", + " // }", + " ", + " pm.test(\"Body matches uniform-service-in-connector\", function () {", + " pm.expect(pm.response.text()).to.include(\"uniform-service-in-connector\");", + " });", + " ", + " pm.test(\"Body matches uniform-service-out-connector\", function () {", + " pm.expect(pm.response.text()).to.include(\"uniform-service-out-connector\");", + " });", + "}" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Для создания коннектора в шине нужно получить список шаблонов(требуются для создания коннекторов) методом getTemplates\n" + }, + "response": [] + }, + { + "name": "Получить информацию о шаблоне коннектора", + "event": [ + { + "listen": "test", + "script": { + "id": "781451d6-5194-40f5-9b34-d9de14fa9b8e", + "exec": [ + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has Messages template\", function () {", + " pm.expect(response).to.have.property('template');", + "});", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{template_name}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Для создания коннектора в шине нужно получить список шаблонов(требуются для создания коннекторов) методом getTemplate, где “template_name” имя шаблона по которому будет сделан коннектор\n" + }, + "response": [] + }, + { + "name": "Создание коннектора", + "event": [ + { + "listen": "test", + "script": { + "id": "7d9c9a60-8a4b-4b3d-b905-f5d7e40f9bd0", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{template_name}}\n {{system_id}}\n \n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Для создания коннектора в шине нужно вызвать метод createConnector, где templateName - это имя шаблона, полученное из метода getTemplates, system_uuid - это uuid профиля, зарегистрированного в системе ранее, также нужно заполнить список параметров необходимый для создания коннектора(ВНИМАНИЕ! если не заполнить список параметров, то установятся значения по умолчанию)\n" + }, + "response": [] + }, + { + "name": "Получить список коннекторов", + "event": [ + { + "listen": "test", + "script": { + "id": "39a21540-e292-418d-9d28-69627de99100", + "exec": [ + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has Messages\", function () {", + " pm.expect(response).to.have.property('listConnector');", + "});", + "", + "if (response.hasOwnProperty('listConnector')) {", + " var list_template = response['listConnector'];", + "", + " pm.test(\"Body matches nsi-in-connector\", function () {", + " pm.expect(pm.response.text()).to.include(\"nsi-in-connector\");", + " });", + "}" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Можно просматривать список подключенных коннекторов в шине методом getConnectors" + }, + "response": [] + }, + { + "name": "Запустить работу коннектора в шине", + "event": [ + { + "listen": "test", + "script": { + "id": "5d1fab2f-51ae-4726-a2ea-c836cf80c8b2", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{template_name}}\n {{system_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Запустить коннектор можно с помощью метода startConnector, где вместо “system_uuid” нужно подставить uuid системы, “template_name” это имя шаблона" + }, + "response": [] + }, + { + "name": "Остановить работу коннектора в шине", + "event": [ + { + "listen": "test", + "script": { + "id": "7dd28510-2b75-439d-9bf9-a277dd1ad5cf", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{template_name}}\n {{system_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Остановить коннектор можно с помощью метода stopConnector, где вместо “system_uuid” нужно подставить uuid системы, “template_name” это имя шаблона" + }, + "response": [] + }, + { + "name": "Удалить коннектор", + "event": [ + { + "listen": "test", + "script": { + "id": "859d5f55-4da4-45a3-9553-fa3b2743044c", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{template_name}}\n {{system_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Удалить коннектор можно с помощью метода removeConnector, где вместо “system_uuid” нужно подставить uuid системы, “template_name” это имя шаблона" + }, + "response": [] + }, + { + "name": "Получить список подключенных шин", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "e676f268-7463-46a7-83f1-852c32cdb570", + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "id": "b03708a1-b1f5-4185-b8d0-8c4e00fe0af9", + "exec": [ + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has Messages listEsb\", function () {", + " pm.expect(response).to.have.property('listEsb');", + "});", + "", + "if (response.hasOwnProperty('listEsb')) {", + " var list_esb = response['listEsb'];", + " var esbName = list_esb[\"esbName\"];", + " ", + " if(Array.isArray(esbName)) {", + " esbName = esbName[0];", + " }", + " ", + " pm.test(\"Body matches \" + esbName, function () {", + " pm.globals.set(\"esb_name\", esbName);", + " });", + "}" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Для получения списка подключенных шин можно с помощью метода getListEsb" + }, + "response": [] + }, + { + "name": "Создание мостового профиля", + "event": [ + { + "listen": "test", + "script": { + "id": "29d4a58d-62c0-468b-9783-4f6e35ca147a", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system_id}}\n {{system_id}}\n {{esb_name}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Создать профиль, ведущий на мост, можно с помощью метода createBridgeProfile, где “system_uuid” uuid системы, “esb_name” имя подключенной шины" + }, + "response": [] + }, + { + "name": "Остановить мостовой профиль", + "event": [ + { + "listen": "test", + "script": { + "id": "7943398a-5511-4a6e-858f-1c4afdb16cc5", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n {{system_id}}\n {{system_id}}\n {{esb_name}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Остановить профиль, ведущий на мост, можно с помощью метода stopBridgeProfile, где “system_uuid” uuid системы, “esb_name” имя подключенной шины\n" + }, + "response": [] + }, + { + "name": "Запустить мостовой профиль", + "event": [ + { + "listen": "test", + "script": { + "id": "a8544cbe-0d41-490f-8507-8841359d00fd", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n {{system_id}}\n {{system_id}}\n {{esb_name}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Запустить профиль, ведущий на мост, можно с помощью метода startBridgeProfile, где “system_uuid” uuid системы, “esb_name” имя подключенной шины\n\n" + }, + "response": [] + }, + { + "name": "Получить мостовой профиль", + "event": [ + { + "listen": "test", + "script": { + "id": "7dadab09-b3c9-477f-a503-d5307f8fa958", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n {{system_id}}\n {{system_id}}\n {{esb_name}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Получить профиль, ведущий на мост, можно с помощью метода getBridgeProfile, где “system_uuid” uuid системы, “esb_name” имя подключенной шины\n\n" + }, + "response": [] + }, + { + "name": "Получить список мостовых профилей", + "event": [ + { + "listen": "test", + "script": { + "id": "954c6f50-e564-476c-b0d3-186af84509e2", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Для получения списка профилей, ведущих на мост, можно использовать метод getBridgeProfiles:(ВНИМАНИЕ! запрос покажет список проброшенных профилей на ТЕКУЩЕЙ шине)\n" + }, + "response": [] + }, + { + "name": "Удалить мостовой профиль", + "event": [ + { + "listen": "test", + "script": { + "id": "bbb77d98-0c2c-4de7-95c7-ae2b79ec887d", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n {{system1_id}}\n {{system1_id}}\n {{esb_name}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Удалить профиль, ведущий на мост, можно с помощью метода removeBridgeProfile, где “system_uuid” uuid системы, “esb_name” имя подключенной шины\n\n\n" + }, + "response": [] + }, + { + "name": "Создать доступ", + "event": [ + { + "listen": "test", + "script": { + "id": "e8022e10-0979-4ae3-98e7-40930fa57727", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system1_id}}\n {{system1_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Создать доступ одной системы к другой, можно с помощью метода createPermission, где “objectUuid” uuid системы, которой нужно дать доступ, “subjectUuid” - uuid системы, к которой нужно дать доступ" + }, + "response": [] + }, + { + "name": "Удалить доступ", + "event": [ + { + "listen": "test", + "script": { + "id": "ab8fdbbf-b4d4-4756-ae75-aba9c117c538", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n {{system_id}}\n {{system_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Удалить доступ одной системы к другой, можно с помощью метода removePermission, где “objectUuid” uuid системы, которой нужно дать доступ, “subjectUuid” - uuid системы, к которой нужно дать доступ" + }, + "response": [] + }, + { + "name": "Получить список систем, доступ к которым от данной системы разрешен", + "event": [ + { + "listen": "test", + "script": { + "id": "f05fc1db-913c-4a91-810a-dd777cefc048", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n {{system_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Получить список систем, доступ к которым от данной системы разрешен, можно с помощью метода getPermissionByObject, где “objectUuid” uuid системы\n" + }, + "response": [] + }, + { + "name": "Получить список систем, доступ которым разрешен к данной системе", + "event": [ + { + "listen": "test", + "script": { + "id": "454c7cde-48bb-49c7-aa11-5e63e298555e", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n {{system_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Получить список систем, доступ которым разрешен к данной системе, можно с помощью метода getPermissionBySubject, где “subjectUuid” uuid системы:\n" + }, + "response": [] + }, + { + "name": "Создать сразу несколько доступов, которым разрешено отправлять сообщения от данной системы", + "event": [ + { + "listen": "test", + "script": { + "id": "9f59cfd2-0abb-4aaa-8e42-273fcb9927c5", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{objectUuid}}\n \n {{subjectUuid1}}\n {{subjectUuid2}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Создать сразу несколько доступов, которым разрешено отправлять сообщения от данной системы, можно с помощью метода сreatePermissionForObjectRequest, где “objectUuid” это uuid системы, от которой буду исходить сообщения, ‘“subjectUuid1”, “subjectUuid2” и т д, это uuid систем, которым будут отправлять сообщения\n" + }, + "response": [] + }, + { + "name": "Создать сразу несколько доступов, которым разрешено отправлять сообщения в данную систему", + "event": [ + { + "listen": "test", + "script": { + "id": "cacd85e7-bced-4116-bccb-ec87620bd0a4", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{objectUuid}}\n \n {{subjectUuid1}}\n {{subjectUuid2}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Создать сразу несколько доступов, которым разрешено отправлять сообщения в данную систему, можно с помощью метода сreatePermissionForSubjectRequest, где “objectUuid1”, “objectUuid2” и т д - это uuid систем, от которых буду исходить сообщения, ‘“subjectUuid” - это uuid системы, которой будут отправлять сообщения\n" + }, + "response": [] + } + ], + "description": "Профиль(profile) - это описание внешней системы в шине.(Например s1).\n\nМостовой профиль(bridge-profile) - это профиль на другой стороне шины, ведущий через мост в профиль.\n(Например s1)\n\nКоннектор(connector) - это связь между интерфейсом, через который может работать система, и профилем.(Например uniform-service, nsi)\n\nДоступ(permission) - это разрешение на взаимодействие двух систем.(Например для того чтобы система s1 смогла отправить сообщение s2)(/permission-management)\n\nУчетная запись(account) - это учетная запись системы для взаимодействия с шиной.\n\nДля каждой системы должна быть учетная запись для возможности отправления сообщений в шину.\n\nТакже есть учетные записи для возможности взаимодействия с управленческим слоем(т. е. для того чтобы управлять коннекторами/профилями/учетными записями/топиками нужна учетная запись с соответствующими правами)(/basic-auth-management)\nКоннекторы делятся на входящие и исходящие(in, out), которые отвечают за отправку сообщения в определенный интерфейс и на получение ответа из определенного интерфейса соответственно.\nНапример, для того чтобы иметь возможность отправить сообщение в soap нужно создать коннектор uniform-service-in-connector, а для того чтобы получить сообщение из soap нужно создать коннектор soap-out-connector.\nПо адресу /system-management-service находится сам сервис управления коннекторами и профилями в шине.\nДля работы внешней системы в шине нужно сначала создать профиль данной системы в шине, потом добавлять к нему необходимые коннекторы и пробрасывать его в необходимые шины.\n", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "94c3de71-9085-4751-8f4f-81aa7068b382", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "6fc701b1-cfdf-464e-b80c-fe7cd100d358", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Rest сервис Topic-management", + "item": [ + { + "name": "Создать топик", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"topicName\": \"boomNews\",\n \"possibleSubscribers\" : [\"systemUuid1\", \"systemUuid2\"],\n \"possiblePublishers\" : [\"systemUuid3\", \"systemUuid4\"]\n}\n", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}:9090/topic-management/create", + "host": [ + "{{host}}" + ], + "port": "9090", + "path": [ + "topic-management", + "create" + ] + }, + "description": "При создании и изменении топика, есть возможность передать списки систем, которым доступна подписка или публикация в данном топике.\n" + }, + "response": [] + }, + { + "name": "Обновить топик", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"topicName\": \"boomNews\",\n \"possibleSubscribers\" : [\"systemUuid1\", \"systemUuid2\"],\n \"possiblePublishers\" : [\"systemUuid3\", \"systemUuid4\"]\n}" + }, + "url": { + "raw": "{{host}}:9090/topic-management/update", + "host": [ + "{{host}}" + ], + "port": "9090", + "path": [ + "topic-management", + "update" + ] + }, + "description": "изменить топик (название не меняется, так как на него завязана сама очередь в брокере)\n" + }, + "response": [] + }, + { + "name": "Удалить топик", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"topicName\": \"boomNews\"\n}" + }, + "url": { + "raw": "{{host}}:9090/topic-management/delete", + "host": [ + "{{host}}" + ], + "port": "9090", + "path": [ + "topic-management", + "delete" + ] + }, + "description": "delete - топик помечается как удалённый\n\n" + }, + "response": [] + }, + { + "name": "Очистка хранилища топиков", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "{{host}}:9090/topic-management/clean", + "host": [ + "{{host}}" + ], + "port": "9090", + "path": [ + "topic-management", + "clean" + ] + }, + "description": "Окончательное удаление топиков, помеченных как удалённые." + }, + "response": [] + }, + { + "name": "Подписаться на топик", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"topicName\": \"boomNews\",\n \"subscriptionType\": \"PUSH\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}:9090/topic-subscription/subscribe", + "host": [ + "{{host}}" + ], + "port": "9090", + "path": [ + "topic-subscription", + "subscribe" + ] + } + }, + "response": [] + }, + { + "name": "Отписаться от топика", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"topicName\": \"boomNews\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}:9090/topic-subscription/unsubscribe", + "host": [ + "{{host}}" + ], + "port": "9090", + "path": [ + "topic-subscription", + "unsubscribe" + ] + } + }, + "response": [] + }, + { + "name": "Массовая обработка при наличии права manage для данного сервиса", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"topicName\": \"boomNews\",\n \"systemUuids\": [\n {\n \"systemUuid\": \"NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN\",\n \"subscriptionType\": \"PUSH\"\n },\n {\n \"systemUuid\": \"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\",\n \"subscriptionType\": \"PULL\"\n },\n {\n \"systemUuid\": \"YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY\",\n \"subscriptionType\": \"PULL\"\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}:9092/topic-subscription/subscribe", + "host": [ + "{{host}}" + ], + "port": "9092", + "path": [ + "topic-subscription", + "subscribe" + ] + } + }, + "response": [] + }, + { + "name": "Массовая обработка при наличии права manage для данного сервиса", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"topicName\": \"boomNews\",\n \"systemUuids\": [\n {\n \"systemUuid\":\"NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN\",\n \"subscriptionType\": \"PUSH\"\n },\n {\n \"systemUuid\": \"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\",\n \"subscriptionType\": \"PULL\"\n },\n {\n \"systemUuid\": \"YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY\",\n \"subscriptionType\": \"PULL\"\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}:9092/topic-subscription/unsubscribe", + "host": [ + "{{host}}" + ], + "port": "9092", + "path": [ + "topic-subscription", + "unsubscribe" + ] + } + }, + "response": [] + }, + { + "name": "Опубликовать событие", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"topicName\": \"boomNews\", \"message\": \"messageText2\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}:9090/topic-subscription/publish", + "host": [ + "{{host}}" + ], + "port": "9090", + "path": [ + "topic-subscription", + "publish" + ] + } + }, + "response": [] + } + ], + "description": "\nСервис состоит из 2-х контекстов:\n\n- _topic-management_ - управление топиками (создание/изменение/удаление)\n- _topic-subscription_ - клиентский сервис подписки и публикации сообщения\n\nПри смене контекста в конфигурационных файлах требуется перераздать права на данный сервис.\n", + "protocolProfileBehavior": {} + }, + { + "name": "Authentication", + "item": [ + { + "name": "Добавление аккаунтов", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n \n system1login\n system1pass\n \n system1uuid\n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + }, + "description": "Метод для добавления учетных записей (addAccount) разработан для добавления новых пользователей в систему.\n" + }, + "response": [] + }, + { + "name": "Обновление аккаунтов", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n \n system1login\n system1pass\n \n system1uuid\n \n \n system2login\n system2pass\n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + }, + "description": "Метод для обновления учетной записи (updateAccount)разработан для обновления следующей информации:\n" + }, + "response": [] + }, + { + "name": "Удаление аккаунтов", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n system1login\n system2login\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + }, + "description": "Метод для удаления аккаунта (removeAccount) служит для удаления аккаунта из системы.\n" + }, + "response": [] + }, + { + "name": "Выдача прав аккаунту", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n \n dog\n topic-management\n service\n \n \n \n \n dog\n system-management\n service\n \n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + }, + "description": "Метод выдачи прав аккаунту (addAccountPermission) служит для создания permission связанных с переданным аккаунтом.\n" + }, + "response": [] + }, + { + "name": " Удаление прав аккаунта", + "request": { + "method": "POST", + "header": [ + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n \n dog\n topic-management\n service\n \n \n \n \n dog\n system-management\n service\n \n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + }, + "description": "Метод удаления прав аккаунта (removeAccountPermission) служит для удаления permission связанных с переданным аккаунтом.\n" + }, + "response": [] + } + ], + "description": "Метод для добавления учетных записей (addAccount) разработан для добавления новых пользователей в систему.\n", + "event": [ + { + "listen": "prerequest", + "script": { + "id": "90b3a65b-d7c1-41ec-b5b3-9008ac46660b", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "9832eddc-fe66-4f0d-a736-86ef1f84aafc", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Сервис загрузки ресурсов", + "item": [ + { + "name": "Загрузка ресурса", + "event": [ + { + "listen": "test", + "script": { + "id": "4ef80c70-993e-45eb-86dd-c203491acabf", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n lama\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для загрузки ресурса в шину нужно использовать метод loadResource.\n- resourceValue - сам ресурс, в формате base64\n\n\n" + }, + "response": [] + }, + { + "name": "Получить ресурс", + "event": [ + { + "listen": "test", + "script": { + "id": "4f63face-528b-4d07-a0fe-ebea026cf416", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n 1\n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для выгрузки заранее загруженного ресурса в шину нужно использовать метод getResource.\n\n\n\n" + }, + "response": [] + }, + { + "name": "Перезагрузить ресурс", + "event": [ + { + "listen": "test", + "script": { + "id": "3eb62411-f82e-427f-899b-a5a4dbd699bb", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n 1\n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для перезагрузки ресурса в шину есть метод reloadResource.\n\n\n\n" + }, + "response": [] + }, + { + "name": "Удалить ресурс", + "event": [ + { + "listen": "test", + "script": { + "id": "9b839a39-a338-4005-80a9-68fb861d8cb2", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n 1\n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для удаления ресурса в шине есть метод removeResource.\n\n\n\n" + }, + "response": [] + }, + { + "name": "Загрузить информацию о ресурсе", + "event": [ + { + "listen": "test", + "script": { + "id": "15ac2ab2-7170-45ec-9eee-0966aa9d834b", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n lama.xsd\n 1\n 1.0\n lama test\n false\n http:lama.xsd\n l\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для загрузки мета информации ресурса в шине есть метод loadResourceInfo.\n\n\n\n" + }, + "response": [] + }, + { + "name": "Получить информацию о ресурсе", + "event": [ + { + "listen": "test", + "script": { + "id": "1987b97e-2f15-4cd7-842e-680acb4a8edd", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n 1\n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для получения мета информации ресурса в шине есть метод getResourceInfo.\n\n\n\n" + }, + "response": [] + }, + { + "name": "Изменить информацию о ресурсе", + "event": [ + { + "listen": "test", + "script": { + "id": "6eb7d443-c65e-4dc0-9f26-417998710ec5", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n 1\n lama.xsd\n 1\n 1.0\n lama test\n false\n http:lama.xsd\n l\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для корректирования мета информации ресурса в шине есть метод еditResourceInfo.\n\n\n\n\n" + }, + "response": [] + }, + { + "name": "Удалить информацию о ресурсе", + "event": [ + { + "listen": "test", + "script": { + "id": "2c30f524-db2e-4a4b-b384-bedfbc3b6841", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n 1\n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для удаления мета информации ресурса в шине есть метод removeResourceInfo.\n\n\n\n\n\n" + }, + "response": [] + }, + { + "name": "Получить список информации о ресурсах", + "event": [ + { + "listen": "test", + "script": { + "id": "cd6ea560-2b66-4e75-8fa2-479c1ee660ae", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для получения списка мета информации ресурсов в шине есть метод getResourceInfoList.\n\n\n\n\n\n" + }, + "response": [] + }, + { + "name": "Получить список информации о ресурсах по имени ресурса", + "event": [ + { + "listen": "test", + "script": { + "id": "b4a24cf7-bfe8-4456-9cfb-395de3961f90", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n .xsd\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для получения списка мета информации ресурсов по имени ресурса в шине есть метод getResourceInfoListByName.\n\n\n\n\n\n" + }, + "response": [] + }, + { + "name": "Получить список информации о ресурсах по namespace ресурса", + "event": [ + { + "listen": "test", + "script": { + "id": "15458871-e3b5-4f5c-a16f-917b3a57ea2e", + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n lama\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/schema", + "host": [ + "{{base_url}}" + ], + "path": [ + "schema" + ] + }, + "description": "Для получения списка мета информации ресурсов по namespace ресурса в шине есть метод getResourceInfoListByNamespace.\n\n\n\n\n\n" + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Работа с файлами", + "item": [ + { + "name": "Загрузка мета информации о файле", + "event": [ + { + "listen": "test", + "script": { + "id": "0348e084-47aa-4b4b-8839-79241f336ca2", + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{messageUUID}}\n 1\n 228377149\n 1\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/bigPackets", + "host": [ + "{{base_url}}" + ], + "path": [ + "bigPackets" + ] + }, + "description": "Для начала загрузки необходимо прислать в шину служебную информацию о файле(количество кусков, id, checksum)" + }, + "response": [] + }, + { + "name": "Загрузка части файла", + "event": [ + { + "listen": "test", + "script": { + "id": "d283f30d-eaa7-4fa4-897c-33380f724e12", + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{messageUUID}}\n 1\n bGFtYQ==\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/bigPackets", + "host": [ + "{{base_url}}" + ], + "path": [ + "bigPackets" + ] + } + }, + "response": [] + }, + { + "name": "Подтверждение загрузки файла", + "event": [ + { + "listen": "test", + "script": { + "id": "ff868b95-e667-4c29-b7d0-c0cac5b51432", + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "content-type": true + } + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "type": "text", + "value": "application/soap+xml;charset=UTF-8;action=\"http://www.entaxy/connector/bigPackets/esb/1.0#Integration:ConfirmTransfer\"" + }, + { + "key": "", + "type": "text", + "value": "", + "disabled": true + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n {{messageUUID}}\n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/bigPackets", + "host": [ + "{{base_url}}" + ], + "path": [ + "bigPackets" + ] + }, + "description": "При загрузки в шину всех кусков файла необходимо послать запрос об окончании загрузки, для проверки целостности файла." + }, + "response": [] + }, + { + "name": "Запрос на скачивание файла", + "event": [ + { + "listen": "test", + "script": { + "id": "c2006b22-00c3-4cef-a432-3eaf66023850", + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "content-type": true + } + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "type": "text", + "value": "Content-Type: application/soap+xml;charset=UTF-8;action=\"http://www.entaxy/connector/bigPackets/esb/1.0#Integration:DownloadRequest\"" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n {{messageUUID}}\n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/bigPackets", + "host": [ + "{{base_url}}" + ], + "path": [ + "bigPackets" + ] + } + }, + "response": [] + }, + { + "name": "Получение куска файла", + "event": [ + { + "listen": "test", + "script": { + "id": "76950610-16ae-4088-a559-36bf8b0d4f33", + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{messageUUID}}\n 1\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/bigPackets", + "host": [ + "{{base_url}}" + ], + "path": [ + "bigPackets" + ] + } + }, + "response": [] + }, + { + "name": "Подтверждение получения файла", + "event": [ + { + "listen": "test", + "script": { + "id": "de8415be-fb49-455f-85e5-6a04e784d710", + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "content-type": true + } + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "Content-Type: application/soap+xml;charset=UTF-8;action=\"http://www.entaxy/connector/bigPackets/esb/1.0#Integration:ConfirmDownload\"", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n {{messageUUID}}\n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/bigPackets", + "host": [ + "{{base_url}}" + ], + "path": [ + "bigPackets" + ] + }, + "description": "Необходим для удаления из шины уже выкачанного файла." + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "8dad468e-a846-4dcb-af3b-22959aa33b7d", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "75322b50-d081-49b3-b833-1d02a88c2136", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "id": "74a38652-a338-49e7-941d-40f6a4c91e24", + "key": "X-ForwardedUser", + "value": "" + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/documentation/connectors/Message.png b/documentation/connectors/Message.png new file mode 100644 index 00000000..b89636dc Binary files /dev/null and b/documentation/connectors/Message.png differ diff --git a/documentation/connectors/create_new_connectors.adoc b/documentation/connectors/create_new_connectors.adoc new file mode 100644 index 00000000..8b76861f --- /dev/null +++ b/documentation/connectors/create_new_connectors.adoc @@ -0,0 +1,203 @@ += План создания коннектора + +Для создания полноценного коннектора необходимо создать bundle с такой структурой: + +. _src/main/resource/template/<название endpoint>-in-connector.ftl_ +. _src/main/resource/template/<название endpoint>-out-connector.ftl_ +. _src/main/resource/OSGI-INF/blueprint/camel-context.xml_ +. _pom.xml_ + +== Создание шаблона входного коннектора(in-connector) + +_Входной коннектор_ - это коннектор, который получает сообщения из вне Entaxy. + +_Шаблон входного коннектора_ - ftl файл, на основе которого шина будет создавать индивидуальные входные коннекторы для каждой системы, с помощью подстановки параметров, полученных от пользователя. + +Пример созданного шаблона, где название endpoint - _example_: +_src/main/resource/template/example-in-connector.ftl_ +[source,xml] +---- + + + + + + + + + + + + + + + + + + + example + + + + + + +---- + +Создание и публикация бина: для связи коннектора с профилем, возможности получить весь список коннекторов определенного типа. +[source, xml] +---- + + + + + + + + + + +---- + +Маршрут коннектора, который полученные сообщения отправляет на выходную точку профиля, к которой прикрепляется сгенерированный пользователем route. +[source, xml] +---- + + + + example + + + +---- + +Начало маршрута входного коннектора может начинаться не с _"direct-vm:example-in-connector-[=systemName]"_, а получать сообщения, например, через определенную папку на диске. + +Для того чтобы отправить сообщение в коннектор необходимо, получить все коннекторы определенного типа (example): +[source,xml] +---- + + + + + +---- + +И отправлять сообщения с помощью: +[source,xml] +---- + +---- + +== Создание шаблона выходного коннектора(out-connector) + +_Выходной коннектор_ - это коннектор, который отправляет сообщения из Entaxy в систему (вне Entaxy). + +_Шаблон выходного коннектора_ - ftl файл, на основе которого шина будет создавать индивидуальные выходные коннекторы для каждой системы, с помощью подстановки параметров, полученных от пользователя. + +Пример созданного шаблона, где название endpoint - _example_: +_src/main/resource/template/example-out-connector.ftl_ +[source,xml] +---- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +---- + +Создание и публикация бина: для связи коннектора с профилем, возможности получить весь список коннекторов определенного типа. +[source, xml] +---- + + + + + + + + + + +---- + +Маршрут выходного коннектора *должен* стартовать с: +[source,xml] +---- + +---- + +== Публикация созданных шаблонов + +Необходимо опубликовать osgi сервис с информацией об созданных шаблонах для того, чтобы механизм создания коннекторов увидел их. + +_src/main/resource/OSGI-INF/blueprint/camel-context.xml_ +[source,xml] +---- + + + + + + + + + + + + + + + + + + + + + + + + + + + +---- + +xref:../core/system-managment/Users-manual-System-management.adoc[Информация о создании коннекторов со стороны пользователя] diff --git a/documentation/connectors/db-connector/deployment_schema.png b/documentation/connectors/db-connector/deployment_schema.png new file mode 100644 index 00000000..33203b0c Binary files /dev/null and b/documentation/connectors/db-connector/deployment_schema.png differ diff --git a/documentation/connectors/naming_service_headers.adoc b/documentation/connectors/naming_service_headers.adoc new file mode 100644 index 00000000..431bf09d --- /dev/null +++ b/documentation/connectors/naming_service_headers.adoc @@ -0,0 +1,86 @@ += Используемые служебные заголовки Entaxy + +ENTAXY_ - глобальный формат заголовков, который используется не только в рамках коннектора. Используется во всём процессе прохождения пакета, так же может быть принят извне. + +NTX_ - внутренний формат заголовков в конкретном коннекторе, носит служебный характер. +Например _NTX_Origin_ - служит для идентификации имени контура шины при прохождении пакета через мост. + +|=== +|Имя заголовка |Описание |Возможные значения |Обязательность + +|X-ForwardedUser +|логин аккаунта, проставляется с помощью _nginx_ +| +|true + +|X-ForwardedUserId +|внутренний id аккаунта, проставляется с помощью _ru.entaxy.esb.system.auth.basic.interceptor.SystemInterceptor_ +| +|true + +|X-SystemName +|имя системы, полученное при авторизации с помощью _ru.entaxy.esb.system.auth.basic.interceptor.SystemInterceptor_ +| +|true + +|X-SystemUuid +|uuid системы, полученное при авторизации с помощью _ru.entaxy.esb.system.auth.basic.interceptor.SystemInterceptor_ +| +|true + +|X-SystemId +|внутренний id системы, полученное при авторизации с помощью _ru.entaxy.esb.system.auth.basic.interceptor.SystemInterceptor_ +| +|true + +|ENTAXY_EndpointName +|Имя коннектора, через который было получено сообщение +|US-SOAP, US-File, US-JMS, .... +|true + +|ENTAXY_ConnectorType +|Тип коннектора, через который было получено сообщение +|uniform-service +|true + +|ENTAXY_ConnectorName +|Имя коннектора, через который было получено сообщение +| +|true + +|ENTAXY_Source +|Имя отправителя +| +|true + +|ENTAXY_SourceType +|Tип отправителя +|system.name, system-group.name, queue.name, topic.name +|false + +|ENTAXY_Destination +|Имя получателя +| +|false + +|ENTAXY_DestinationType +|Tип получателя +|system.name, system-group.name, queue.name, topic.name +|false + +|ENTAXY_Priority +|Приоритет сообщения +|0-9 +|false + +|ENTAXY_ContentType +|Тип сообщения +|application/xml, message/external-body +|false + +|ENTAXY_EmptyContent +|Является ли сообщение пустым +|true; false +|false +|=== + diff --git a/documentation/connectors/uniform-exchange-service/US-active.png b/documentation/connectors/uniform-exchange-service/US-active.png new file mode 100644 index 00000000..ec9c65db Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/US-active.png differ diff --git a/documentation/connectors/uniform-exchange-service/US.png b/documentation/connectors/uniform-exchange-service/US.png new file mode 100644 index 00000000..a3a36d37 Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/US.png differ diff --git a/documentation/connectors/uniform-exchange-service/active-mode.adoc b/documentation/connectors/uniform-exchange-service/active-mode.adoc new file mode 100644 index 00000000..848d95e2 --- /dev/null +++ b/documentation/connectors/uniform-exchange-service/active-mode.adoc @@ -0,0 +1,76 @@ += Активный режим коннектора + +image::US-active.png[] + +== Сервис для отладки активного коннектора + +Поднимается на endpoint _/active_connector_test_consumer_ +при выставленной настройке _active.mode.dev=true_ в файле конфигураций _uniform.service.support.cfg_ + + +== Requests Examples + + POST http://192.168.122.83:8181/cxf/uniform-exchange + +==== SEND MESSAGE: + +[source,xml] +---- + + + + + + + b7e6aab7-8f02-443c-8f67-e2d638dd4da0 + + s1 + + + s2 + + + + + + + + + + + +---- + +==== GET MESSAGE: + + +[source,xml] +---- + + + + + + s2 + system.name + + 1 + 0 + + + +---- + +==== ACK MESSAGE: + +[source,xml] +---- + + + + + {{message_uuid}} + + + +---- diff --git a/documentation/connectors/uniform-exchange-service/ignite.adoc b/documentation/connectors/uniform-exchange-service/ignite.adoc new file mode 100644 index 00000000..361195d0 --- /dev/null +++ b/documentation/connectors/uniform-exchange-service/ignite.adoc @@ -0,0 +1,35 @@ += IGNITE + +IgniteAggregationRepository сделано на основе JdbsAggregationRepository +документация https://help.talend.com/reader/Uc2IlRuFVfGrjaFPdRI7kA/fBdqK2kf6iIkLHQf9nLh6g + +Есть некоторые внутренние баги karaf, которые не позволяют установить некоторые ignite фичи в караф +https://github.com/apache/ignite/blob/fd921a233d35408883695419b6f9979ac674d1b9/modules/osgi-karaf/src/main/resources/features.xml#L87 + +В карафе поднимается ignite, с рабочей директорией, прописанной в ru.entaxy.esb.ignite.cfg, +в параметре ignite.work.directory.path. Это место, где игнайт +создает для себя все, что нужно, и будет хранить данные. + +Ignite настроен с сохранением персисетнтности данных(сохранением их на диск) и +созданием реплицации(бэкапов) на других узлах кластера.(при потере одной ноды, +другие восстановят данные, которе хранились на текущем узле) + +IGNITE_QUIET=false - параметр необходимый для того, чтобы игнайт не писал информацию о себе в лог, +для того что бы параметр применился, необходимо выставить setGridLogger, +смогла установить в караф только JclLogger. + +**AggregationProcessor** + +AggregationProcessor стандартный, не расчитан на работу в кластере из-за чего пришлось вытаскивать исходники +и редактировать сам процессор.(AggregationProcessorWithRestoreTimeout) +Т к теперь AggregationProcessor вызывается как bean, а не как стандартный камеловский процессор, +то процесс старта и остановки происходит в отличном порядке. + +Для работы к кластере: +- добавлен механизм восстановления работы таймаутов на других нодах, +- отредактирован механизм удаления сообщения из репозитория(возникало состояние гонки и появлялись дубликаты), +- исправлен механизм продолжения работы с "застрявшими" сообщениями (recoverTask из таблицы _completed) +- добавлен безопасный механизм забора сообщений из очереди(восстановление сообщения в очереди, если не пришло подтверждение) + + + diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302025.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302025.jpg new file mode 100644 index 00000000..e1e003a6 Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302025.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302028.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302028.jpg new file mode 100644 index 00000000..714838f2 Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302028.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302031.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302031.jpg new file mode 100644 index 00000000..153d8bde Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302031.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302034.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302034.jpg new file mode 100644 index 00000000..0dea892d Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302034.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302035.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302035.jpg new file mode 100644 index 00000000..e569c366 Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302035.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302038.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302038.jpg new file mode 100644 index 00000000..6abd2a8d Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302038.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302039.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302039.jpg new file mode 100644 index 00000000..f67b1f34 Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302039.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302041.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302041.jpg new file mode 100644 index 00000000..3c9ef446 Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302041.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302042.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302042.jpg new file mode 100644 index 00000000..b9f86919 Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302042.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302043.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302043.jpg new file mode 100644 index 00000000..916d6abe Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302043.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302044.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302044.jpg new file mode 100644 index 00000000..d9086a23 Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302044.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302046.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302046.jpg new file mode 100644 index 00000000..4eaf336d Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302046.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302047.jpg b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302047.jpg new file mode 100644 index 00000000..68afa25f Binary files /dev/null and b/documentation/connectors/uniform-exchange-service/tests/img/photo5298499320133302047.jpg differ diff --git a/documentation/connectors/uniform-exchange-service/tests/postman.adoc b/documentation/connectors/uniform-exchange-service/tests/postman.adoc new file mode 100644 index 00000000..d94eb0db --- /dev/null +++ b/documentation/connectors/uniform-exchange-service/tests/postman.adoc @@ -0,0 +1,89 @@ += Инструкция для работы с шиной через универсальный коннектор + +=== Преднастройка окружения + +. Скачать и установить postman(https://www.postman.com/downloads/). +. Импортировать коллекцию запросов и окружение в postman + +Далее показано как импортироваться коллекцию запросов и окружение в postman Version 8.11.1, если стоит другая версия и возникли сложности с инструкцией, то обратитесь к документации postman(https://learning.postman.com/docs/getting-started/importing-and-exporting-data/). + +=== Импорт коллекции запросов и окружения в postman + +* Если вы на домашней странице postman, то нажмите _Import file_, как показано ниже на скрине. + +image::img/photo5298499320133302025.jpg[] + +* Если вы не на домашней странице postman, то нажмите _File_, _Import..._, как показано ниже на скрине. + +image::img/photo5298499320133302031.jpg[] + +* Далее откроется окно с импортом файла, где нужно нажать на _Upload Files_ и импортировать файлы, по одному или сразу оба(xref:postman/uniform-connector.postman_environment.json[Окружение], xref:postman/uniform-connector.postman_collection.json[Коллекция запросов]) + +image::img/photo5298499320133302028.jpg[] + +* Или можно импортировать сразу всю папку с файлами(xref:postman/uniform-connector.postman_environment.json[Окружение], xref:postman/uniform-connector.postman_collection.json[Коллекция запросов]) + +image::img/photo5298499320133302034.jpg[] + +image::img/photo5298499320133302035.jpg[] + +* Далее мы увидим импортированную коллекцию запросов слева и необходимо выбрать импортированное ранее окружение + +image::img/photo5298499320133302038.jpg[] +image::img/photo5298499320133302039.jpg[] + +* Есть возможность настраивать параметры запросов, документация на данную тему(https://learning.postman.com/docs/sending-requests/managing-environments/) + +image::img/photo5298499320133302041.jpg[] + +* Коллекция запросов и окружение были успешно импортированы в postman и готовы к использованию, можно запустить все запросы в автоматическом режиме или запускать их в ручную по очереди + +=== Запуск всех запросов в автоматическом режиме + +* Необходимо нажать на _Run Collection_ в меню коллекции, как показано ниже + +image::img/photo5298499320133302042.jpg[] +image::img/photo5298499320133302043.jpg[] + +* Можно увидеть успешное прохождение коллекции. При успешном прохождении коллекции тестов шина будет очищена. Если не подразумевалось данное поведение, то необходимо снять выделение с запросов(_Remove profile system1_, _Remove profile system2_, _Remove Account system1_, _Remove Account system2_) + +image::img/photo5298499320133302044.jpg[] +image::img/photo5298499320133302046.jpg[] + +=== Запуск запросов в ручную по очереди + +* Для запуска конкретного запроса нужно нажать на него в меню слева, затем откроется меню редактирования запроса, где можно посмотреть все параметры запроса и настроить его как необходимо и нажимая на кнопку _Send_ запрос отправляется на шину + +image::img/photo5298499320133302047.jpg[] + +=== Описание окружения + +... _base_url_ - если запросы будут запускаться с машины находящейся с шиной, то данный параметр не нужно менять(http://localhost:8181/cxf), иначе заменить localhost:8181 на необходимый +... _system1_id_ - имя/идентификатор системы, то как будет представлена система в шине(по умолчанию s1) +... _system1Login_ - логин системы, то как будет аутентифицироваться система в шине(по умолчанию s1) +... _system1Password_ - пароль системы, то как будет аутентифицироваться система в шине(по умолчанию s1) +... _system2_id_ - имя/идентификатор системы, то как будет представлена система в шине(по умолчанию s1) +... _system2Login_ - логин системы, то как будет аутентифицироваться система в шине(по умолчанию s1) +... _system2Password_ - пароль системы, то как будет аутентифицироваться система в шине(по умолчанию s1) +... _adminLogin_ - админская учетная запись, для произведения настроек в шине(по умолчанию admin) +... _adminPassword_ - админская учетная запись, для произведения настроек в шине(по умолчанию admin) + +=== Содержимое тестов +. Коллекция запросов содержит следующие шаги: +.. _Create profile system1_ - создание профиля системы 1, которая будет отправлять сообщения в шину +.. _Create profile system2_ - создание профиля системы 2 +.. _Add Account system1_ - создание учетной записи для системы 1 +.. _Add Account system2_ - создание учетной записи для системы 2 +.. _Create uniform-service-in-connector_ - создание входящего коннектора к универсальному сервису для системы 1 +.. _Create uniform-service-out-connector_ - создание исходящего коннектора к универсальному сервису для системы 1 +.. _Create uniform-service-in-connector_ - создание входящего коннектора к универсальному сервису для системы 2 +.. _Get profile system1_ - запросы для проверки на корректное создания профиля системы1 и коннекторов к нему(uniform-service-in-connector) +.. _Get profile system2_ - запросы для проверки на корректное создания профиля системы1 и коннекторов к нему(uniform-service-in-connector, uniform-service-out-connector) +.. _Create permission_ - создание разрешения для отправки сообщений из системы 1 в систему 2 +.. _SEND_ - отправка тестового сообщения из системы 1 в систему 2 +.. _GET_ - получение тестового сообщения из системы 1 системой 2 +.. _ACK_ - отправка подтверждения получения сообщения системы 2(иначе сообщение будет восстановлено) +.. _Remove profile system1_ - удаление из шины профиля системы 1 и всех связанных с ней коннекторов +.. _Remove profile system2_ - удаление из шины профиля системы 2 и всех связанных с ней коннекторов +.. _Remove Account system1_ - удаление учетной записи системы 1 из шины +.. _Remove Account system2_ - удаление учетной записи системы 2 из шины \ No newline at end of file diff --git a/documentation/connectors/uniform-exchange-service/tests/postman/uniform-connector.postman_collection.json b/documentation/connectors/uniform-exchange-service/tests/postman/uniform-connector.postman_collection.json new file mode 100644 index 00000000..485cada1 --- /dev/null +++ b/documentation/connectors/uniform-exchange-service/tests/postman/uniform-connector.postman_collection.json @@ -0,0 +1,1396 @@ +{ + "info": { + "_postman_id": "0c9cdab7-0764-42b8-a9d1-a11945d7af2a", + "name": "uniform-connector", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "uniform-exchange", + "item": [ + { + "name": "settings esb", + "item": [ + { + "name": "Create profile system1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system1_id}}\n {{system1_id}}\n \n description1\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Create profile system2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system2_id}}\n {{system2_id}}\n \n description2\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Add Account system1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n \n {{system1Login}}\n {{system1Password}}\n \n {{system1_id}}\n \n {{system1_id}}\n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + } + }, + "response": [] + }, + { + "name": "Add Account system2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n \n {{system2Login}}\n {{system2Password}}\n \n {{system2_id}}\n \n {{system2_id}}\n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + } + }, + "response": [] + }, + { + "name": "Create uniform-service-in-connector", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n uniform-service-in-connector\n {{system1_id}}\n \n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Create uniform-service-out-connector", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n uniform-service-out-connector\n {{system2_id}}\n \n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Create uniform-service-in-connector", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n uniform-service-in-connector\n {{system2_id}}\n \n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Get profile system1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var systemId = pm.environment.get(\"system1_id\");", + "", + "pm.test(\"Body matches \" + systemId, function () {", + " pm.expect(pm.response.text()).to.include(systemId);", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system1_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Проверить созданный профиль можно с помощью метода getProfile, где вместо “system_uuid” нужно подставить uuid системы\n" + }, + "response": [] + }, + { + "name": "Get profile system2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var systemId = pm.environment.get(\"system2_id\");", + "", + "pm.test(\"Body matches \" + systemId, function () {", + " pm.expect(pm.response.text()).to.include(systemId);", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system2_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + }, + "description": "Проверить созданный профиль можно с помощью метода getProfile, где вместо “system_uuid” нужно подставить uuid системы\n" + }, + "response": [] + }, + { + "name": "Create permission", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});", + "", + "setTimeout(function(){}, 5000);", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system1_id}}\n {{system2_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "uniform-exchange-connector", + "item": [ + { + "name": "SEND", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is OK\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{system1Password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{system1Login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n \t\n \t\t\n \t{{system2_id}}\n \t\n \t\n \n b7e6aab7-8f02-443c-8f67-e2d638dd4da0\n \n {{system1_id}}\n \n \n RequestNumber\n 111\n \n \n test1\n test1\n val\n \n \n\t \t\t\n\t \t\t\n\t \t\n\t \n \n \n \n \n\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "GET", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has service response\", function () {", + " pm.expect(response).to.have.property('response');", + "});", + "", + "if (response.hasOwnProperty('response')) {", + " var packet = response['response']['packets']['packet'];", + "", + " var header = packet['header'];", + " ", + " var message_id = header['transportUUID'];", + " ", + " console.log(packet['message']['content']);", + " console.log(message_id);", + " ", + " pm.globals.set('message_uuid', message_id);", + " ", + " pm.test(\"Content is OK\", function () {", + " pm.expect(packet['message']['content']).to.be.an('object');", + " });", + " ", + " pm.test(\"message_id is OK\", function () {", + " pm.expect(message_id).to.have.lengthOf(36);", + " });", + "}" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{system2Password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{system2Login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml; charset=UTF-8" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n \r\n {{system2_id}}\r\n system.name\r\n \r\n 1\r\n 0\r\n \r\n \r\n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "ACK", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is 200\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{system2Password}}", + "type": "string" + }, + { + "key": "username", + "value": "{{system2Login}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml; charset=UTF-8" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n {{message_uuid}}\r\n \r\n \r\n\r\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + }, + { + "name": "clean esb", + "item": [ + { + "name": "Remove profile system1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system1_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Remove profile system2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system2_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Remove Account system1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n {{system1_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + } + }, + "response": [] + }, + { + "name": "Remove Account system2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "basic", + "basic": [ + { + "key": "password", + "value": "{{adminPassword}}", + "type": "string" + }, + { + "key": "username", + "value": "{{adminLogin}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n {{system2_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + } + }, + "response": [] + } + ] + } + ], + "description": "для тестирования нужно добавть в environment: system1_id, system2_id", + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + } + ] +} \ No newline at end of file diff --git a/documentation/connectors/uniform-exchange-service/tests/postman/uniform-connector.postman_environment.json b/documentation/connectors/uniform-exchange-service/tests/postman/uniform-connector.postman_environment.json new file mode 100644 index 00000000..eeb0632d --- /dev/null +++ b/documentation/connectors/uniform-exchange-service/tests/postman/uniform-connector.postman_environment.json @@ -0,0 +1,54 @@ +{ + "id": "527e5257-25b4-4246-ac5a-26b88e06eec8", + "name": "uniform-connector", + "values": [ + { + "key": "base_url", + "value": "http://localhost:8181/cxf", + "enabled": true + }, + { + "key": "system1_id", + "value": "s1", + "enabled": true + }, + { + "key": "system2_id", + "value": "s2", + "enabled": true + }, + { + "key": "adminLogin", + "value": "admin", + "enabled": true + }, + { + "key": "adminPassword", + "value": "admin", + "enabled": true + }, + { + "key": "system1Login", + "value": "s1", + "enabled": true + }, + { + "key": "system1Password", + "value": "s1", + "enabled": true + }, + { + "key": "system2Login", + "value": "s2", + "enabled": true + }, + { + "key": "system2Password", + "value": "s2", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2021-08-24T14:43:46.375Z", + "_postman_exported_using": "Postman/7.36.5" +} \ No newline at end of file diff --git a/documentation/connectors/uniform-exchange-service/uniform-exchange-service.adoc b/documentation/connectors/uniform-exchange-service/uniform-exchange-service.adoc new file mode 100644 index 00000000..bb3be05a --- /dev/null +++ b/documentation/connectors/uniform-exchange-service/uniform-exchange-service.adoc @@ -0,0 +1,38 @@ += Универсальный сервис(US) + +Универсальный сервис разработан для корректного и единообразного взаимодействия с _Entaxy_ из _1С интеграции_. + +image::US.png[] + +=== US endpoint + +Универсальный сервис выставлен с помощью soap (может быть заменен на любой другой способ обмена сообщения, например rest, с сохранением схемы), в котором 3 метода _sendPackets_, _getPackets_ и _confirmPackets_. US endpoint включает в себя: выставленный soap сервис, проверку на существование коннектора и отправку в коннектор(что верно и для uniform-service-service-endpoint) + +=== US connector + +Коннектор занимается обработкой полученного пакета. + +- _sendPackets_ - шина анализирует пакет, создавая служебную информацию(такую как имя системы отправителя, имя и тип получателя и т д) и отправляет в выходную точку профиля. + +- _getPackets_ - шина делает проверку служебной информации(такую как имя системы отправителя, имя и тип получателя и т д) и забирает сообщение из очереди, дополнительно отправляя его в агрегатор. Агрегатор необходим для гарантированной доставки пакета, если в течение заданного таймаута (по умолчанию - 10 минут) не придет подтверждение, то пакет будет считаться не доставленным и будет восстановлен в очереди. + +- _confirmPackets_ - шина делает проверку служебной информации(такую как имя системы отправителя, имя и тип получателя и т д), достает пакет из соответствующего источника (если оно есть) и отдает его системе, дополнительно отправляя в агрегатор, который если собирает пару(пакет и подтверждение) считает его доставленным и удаляет из шины. + +_Агрегатор_ может хранить сообщения в ignite и базе данных, для переключения режима работы агрегатора необходимо установить необходимый параметр acknowledge.aggregation.repository (по умолчанию - jdbcAggregationRepository) в uniform.service.support.cfg + +https://help.talend.com/r/Bejd_\~iSyuyc~nF9XIgDIw/fBdqK2kf6iIkLHQf9nLh6g[Информация по jdbcAggregationRepository] + +xref:ignite.adoc[Информация по igniteAggregationRepository] + +=== US support + +Необходим как вспомогательный элемент. Содержит в себе: настройку агрегатора, маршруты работы агрегатора, маршрут связанный с отправкой в систему в активном режиме коннектора. + +== Режимы универсального сервиса: + +- _Пассивный_ выражен в поднятом на стороне шины сервисе, который "пассивно" ждет запроса от системы. + +- _Активный_ выражен в поднятом на стороне системы сервисе, который с некоторой периодичностью (настраивается при создании коннектора, по умолчанию 1m) опрашивает шина на предмет подготовленных сообщений, и, отправляет полученные сообщения в систему как только они пришли. + +xref:active-mode.adoc#_активный_режим_коннектора[Информация по активному режиму работы универсального сервиса] + diff --git a/documentation/core/Common-description-of-the-transport-layer.adoc b/documentation/core/Common-description-of-the-transport-layer.adoc new file mode 100644 index 00000000..2ec470cf --- /dev/null +++ b/documentation/core/Common-description-of-the-transport-layer.adoc @@ -0,0 +1,219 @@ += Общее описание Entaxy + +=== Entaxy обеспечивает следующую функциональность: + +. обеспечение доступа внешних систем к шине через опубликованные сервисы (SOAP, REST, прочее) +. поддержка синхронного и асинхронного способа вызова служб; +. использование защищённой шины, с гарантированной доставкой сообщений, поддерживающего транзакционную модель; +. статическая и алгоритмическая (условная, опирающаяся на значение передаваемых данных) маршрутизация сообщений; +. доступ к данным из сторонних информационных систем с помощью готовых или специально разработанных адаптеров; +. обработка и преобразование сообщений; +. отказоустойчивая конфигурация; +. разнообразные механизмы контроля и управления (аудиты, протоколирование); +. мониторинг данных и бизнес-процессов + +=== Entaxy решает следующие задачи: + +. обмен сообщениями/данными между приложениями и ИС +. организация точек доступа к услугам (сервисам) и данным +. унификация взаимодействия с внешними ИС +. мониторинг данных и бизнес-процессов +. снижение трудоемкости процесса сбора и агрегации информации +. повышение оперативности подготовки отчетов +. обеспечение автоматизированной проверки данных, используемых в процессе деятельности + +=== Entaxy реализована на следующем наборе ПО: + +- ОС: _Astra Linux 1.6 смоленск_ ? +- Программная платформа: _Java 11 (librca)_ +- СУБД (предоставляется заказчиком): _MS SQL Server_ +- СУБД (может использоваться): _PostgreSQL JDBC Driver_ +- Платформа исполнения: _Apache Karaf 4.2.9_ +- Платформа интеграции: _Apache Camel 3.4.4_ +- Каркас реализации веб-сервисов: _Apache CXF 3.4.0_ +- Брокер сообщений: _ActiveMQ Artemis 2.15_ +- Система мониторинга (предоставляется заказчиком): _Zabbix, Grafana_ +- Система управления журналами (предоставляется заказчиком): _стек ELK_ + +=== Схема развертывания + +Ниже представлена схема развертывания основных компонентов шины, содержащая следующие элементы: + +. кластер _NGINX_ - два узла, обеспечивающих отказоустойчивый балансировщик нагрузки, с одним виртуальным IP-адресом +. кластер _Karaf_ - в начальной конфигурации используется 2 узла, в дальнейшем схема масштабируется горизонтально. Наличие кластера обеспечивает отказоустойчивость и производительность, так как нагрузка распределяется между всеми активными узлами +. кластер брокера сообщений _ActiveMQ Artemis_ - отказоустойчивая конфигурация "активный - пассивный", в которой все транзакции активного брокера реплицируются на пассивный. При выходе из строя активного брокера, активным становится пассивный. Все вызовы брокера сообщений осуществляются по схеме failover, которая гарантирует переадресацию запроса в случае недоступности основного узла. +. отказоустойчивый кластер СУБД - предоставляется заказчиком +. _NFS Share_ - подключаемое сетевое файловое хранилище, предоставляется заказчиком +. _ELK_ - узел сбора и обработки логов стеком продуктов ELK (ElasticSearch, Logstash, Kibana) +. узел сбора и обработки метрик с установленными продуктами Zabbix и Grafana + +image::clustering.png[] + +Ниже представлена схема деплоя профилей/коннекторов в шине: + +image::System-management.png[] + +=== Список и характеристики узлов предпродуктивного контура + + +|=== +|Имя сервера |Ресурсы |Назначение |Операционная система |Софт + +| PREPRD_NGINX1 +| 2xCPU, 4Gb RAM, 40 Gb Local +| Балансировщик +| AstraLinux SE 1.6 +| Nginx + +| PREPRD_NGINX2 +| 2xCPU, 4Gb RAM, 40 Gb Local +| Балансировщик +| AstraLinux SE 1.6 +| Nginx + +| PREPRD_KRF1 +| 8xCPU, 12 Gb RAM, 60 Gb Local +| Платформа запуска интеграционных маршрутов +| AstraLinux SE 1.6 +| Apache Karaf, Cellar, java-1.8.0-openjdk + +| PREPRD_KRF2 +| 8xCPU, 12 Gb RAM, 60 Gb Local +| Платформа запуска интеграционных маршрутов +| AstraLinux SE 1.6 +| Apache Karaf, Cellar, java-1.8.0-openjdk + +| PREPRD_NEXUS +| 4xCPU, 12 Gb RAM, 60 Gb Local +| Хранение артефактов +| AstraLinux SE 1.6 +| Nexus + +| PREPRD_AMQ1 +| 4xCPU, 16 Gb RAM, 60 Gb Local +| Брокер сообщений +| AstraLinux SE 1.6 +| Java, ActiveMQ Artemis + +| PREPRD_AMQ2 +| 4xCPU, 16 Gb RAM, 60 Gb Local +| Брокер сообщений +| AstraLinux SE 1.6 +| Java, ActiveMQ Artemis +|=== + +=== Схема прохождения пакета _Система1_ - _Система2_ + +Ниже представлена схема прохождения пакета на примере обмена данными между двумя экземплярами системами. + +Экземпляры систем соединяются с шиной через _Коннектор_, который взаимодействует с сервисом SOAP, Универсальный коннектор, (контекст/cxf/uniform-exchange), предоставляемым шиной. + +Укрупненно маршрут выглядит следующим образом: + +. доставка сообщения до очереди получателя: CXF-сервис -> маршрут Camel send-to-jms -> очередь в Artemis +. получение сообщения: CXF-сервис -> очередь в Artemis +. подтверждение получения: CXF-сервис -> маршрут Camel receive-acknowledge + +image::route_packet.png[] + +=== Средства мониторинга и отладки + +Для мониторинга работы и отладки шины для сценария прохождения пакета могут быть использованы следующие инструменты. + +==== Журнал (лог) Nginx + +Логи Nginx’a располагаются в папке по пути “/var/log/nginx”. + +В папке с логами Nginx’a располагаются 2 типа логов: + +. Access - отображает все процессы, которые проходят через Nginx. +В случае когда запрос отработал успешно, сервер возвращает код 200 в access.log и записывает строку с URL запроса, кодом, размером ответа и временем получения ответа. +. Error - отображает процессы, в которых возникли ошибки +В случае когда запрос отработал с ошибкой, сервер возвращает код 400 (например) в error.log и записывает строку с URL запроса, кодом, кратким описанием ошибки, размером ответа, временем получения ответа и юзер-агентом (HTTP-заголовок, который показывает из какого браузера или иного софта был отправлен запрос). + +==== Трассировка маршрутов Camel + +_Apache Сamel_ - это платформа для запуска интеграционных маршрутов (процессов), которые в самой платформе называются “route”. Основными функциями Apache Camel являются подключения по различным протоколам, маршрутизация запросов и сообщений, а также преобразование данных. + +Работа с маршрутами в Apache Camel и самой платформой осуществляется из hawtio. Hawtio - это графическая консоль управления. Hawtio доступна по следующим ссылкам: + +Karaf-1 - http://<<+host+>>:8181/hawtio/ + +image::screenshots/screenshot_hawtio_1.png[] + +Трассировка маршрутов в hawtio производится на вкладке “Camel”, путем выбора маршрута (папка route) в левой области экрана и перехода на вкладку “Trace”. + +image::screenshots/screenshot_hawtio_2.png[] +image::screenshots/screenshot_hawtio_3.png[] + +После перехода необходимо нажать на кнопку “Start tracing”, платформа запустит трассировку маршрута и выведет на экран схему процесса трассировки. + +image::screenshots/screenshot_hawtio_4.png[] + +В связи с тем что в 3й версии Camel, используемой нами, трассировка по умолчанию отключена потребуется подготовить отлаживаемый контекст. Для этого необходимо включить параметры _backlogTrace_ и _useBreadcrumb_. + +Пример: +[source,xml] +---- + +---- + +Так же для удобства работы можно включить отображение потоков в текстовом формате. +Для этого в Настройках(Preferences) hawtio нужно включить флаг Include trace/debug streams + +image::screenshots/screenshot_hawtio_5.png[] + +В веб-консоли hawtio, помимо работы с маршрутами, есть возможность установки бандлов, плагинов (вкладка OSGI) +Возможность просмотра логов и прочее. + +image::screenshots/screenshot_hawtio_6.png[] +image::screenshots/screenshot_hawtio_7.png[] + +=== Веб-консоль брокера сообщений + +Добавить описание, урлы (для обоих брокеров) и скриншоты на примере любой очереди. Показать, где содержимое, где рейт и прочее. + +Apache ActiveMQ - это брокер сообщений, основной функцией которого является отправка и получение сообщений. + +Работа с брокером сообщений производится через веб-консоль, перейти на которые можно по следующим ссылкам: + +ActiveMQ-1 - http://<<+host+>>:8161/console/ + +image::screenshots/screenshot_artemis_1.png[] + +В веб-консоли можно просматривать очереди сообщений на вкладке “Queues”. + +image::screenshots/screenshot_artemis_2.png[] + +На этой же вкладке можно просмотреть название очереди, адрес очереди. + +image::screenshots/screenshot_artemis_3.png[] + +Посмотреть скорость обмена сообщениями (столбец “Rate”), количество сообщений в очереди. + +image::screenshots/screenshot_artemis_4.png[] + +На вкладке “Producer” можно посмотреть данные об отправленных сообщениях (id сообщений, название адресов, на которые были отправлены сообщения). + +image::screenshots/screenshot_artemis_5.png[] + +На вкладке “Consumers” можно посмотреть данные о полученных сообщениях (id сообщений, из какой очереди пришли сообщения, название адресов, с которых были получены сообщения). + +image::screenshots/screenshot_artemis_6.png[] + +В левой области экрана можно выбрать в списке нужную очередь и посмотреть количество сообщений в ней. + +image::screenshots/screenshot_artemis_7.png[] + +При выборе очереди, автоматически открывается вкладка “Browse”, на которой отображаются все сообщения из выбранной очереди. При нажатии на id сообщения, появится диалоговое окно с сообщением. + +image::screenshots/screenshot_artemis_8.png[] + +При необходимости сообщение можно переместить в другую очередь (кнопка “Move”) или удалить (кнопка “Delete”). + +image::screenshots/screenshot_artemis_9.png[] + +Также в консоли имеется возможность полностью очистить очередь от сообщений или полностью удалить очередь из брокера сообщений, выбрав очередь в левой области экрана и перейдя на вкладку “Delete”. + +image::screenshots/screenshot_artemis_10.png[] + diff --git a/documentation/core/Control Service.png b/documentation/core/Control Service.png new file mode 100644 index 00000000..42ff766b Binary files /dev/null and b/documentation/core/Control Service.png differ diff --git a/documentation/core/System-management.png b/documentation/core/System-management.png new file mode 100644 index 00000000..70ac1e43 Binary files /dev/null and b/documentation/core/System-management.png differ diff --git a/documentation/core/auth/Authentication.png b/documentation/core/auth/Authentication.png new file mode 100644 index 00000000..992eb01b Binary files /dev/null and b/documentation/core/auth/Authentication.png differ diff --git a/documentation/core/auth/Authorization.adoc b/documentation/core/auth/Authorization.adoc new file mode 100644 index 00000000..d693556f --- /dev/null +++ b/documentation/core/auth/Authorization.adoc @@ -0,0 +1,169 @@ += Общие положения + +При передаче сообщения от внешней системы в шину происходит процесс аутентификации внешней системы в шине. Т.е. при передаче сообщения шине с помощью сервера _nginX_ по протоколу _basic_ аутентификации сверяет присвоенные сообщению логин и пароль системы, от которой передается сообщение с ее логином, зарегистрированным в шине. При совпадении логина и пароля сообщение проходит от внешней системы через шину к другой системе. Если же пара логин – пароль не совпадает, то система блокирует сообщение. + +image::Authentication.png[Аутентификация с помощью nginx] + +Обновление учетных записей на _nginx_ по данным от сервиса _basic-auth-management_ проходит каждую минуту. + +Для компактной установки шины без _nginx_ модуль реализует интерцептор для basic аутентификации при обращении к сервисам. Включить встроенную аутентификацию можно в конфигурационном файле ru.entaxy.esb.system.basic_auth.cfg -> свойство internal.authentication.enabled. + +Сервис _basic-auth-management_ служит для работы с учетными записями (аккаунтами) через протокол _SOAP_. + +В сервисе существуют три вида запросов: + +* Добавление аккаунтов; +* Обновление аккаунтов; +* Удаление неактуальных аккаунтов. +* Выдача прав аккаунту +* Удаление прав аккаунта + +=== Добавление аккаунта + +Метод для добавления учетных записей _(addAccount)_ разработан для добавления новых пользователей в систему. + +Запрос на добавление аккаунта выглядит следующим образом: +[source,xml] +---- + + + + + + + system1login + system1pass + + system1uuid + + + + +---- + + +В теле содержится список аккаунтов – это повторение элементов _account_ неограниченное число раз. Также в теле содержатся обязательные поля __ (логин) и __ (пароль). Поле __ (идентефикатор системы) является необязательным. + +Пароль принимается в прямом виде и шифруется непосредственно перед сохранением, чтобы он не хранился в открытом виде. + +=== Обновление аккаунта + +Метод для обновления учетной записи _(updateAccount)_ разработан для обновления следующей информации: + +* новый пароль системы; +* присвоение учетной записи к другой системе. + +Запрос на обновление аккаунта выглядит следующим образом: +[source,xml] +---- + + + + + + + system1login + system1pass + + system1uuid + + + system2login + system2pass + + + + +---- + +В теле содержится список аккаунтов, который содержит информацию аналогичную из п.2. + +=== Удаление аккаунта + +Метод для удаления аккаунта _(removeAccount)_ служит для удаления аккаунта из системы. + +Запрос на удаление аккаунта выглядит следующим образом: +[source,xml] +---- + + + + + + system1login + system2login + + + +---- + +В теле содержится неограниченный список логинов _(loginList)_, которые будут удалены из системы. + +=== Выдача прав аккаунту + +Метод выдачи прав аккаунту _(addAccountPermission)_ служит для создания _permission_ связанных с переданным аккаунтом. + +Запрос на создание права выглядит следующим образом: +[source,xml] +---- + + + + + + + dog + topic-management + service + + + + + dog + system-management + service + + + + + + +---- + + +Если параметр action пустой либо отсутствует в сервисе _permission_ по умолчанию подставляется _default_. + + +=== Удаление прав аккаунта + +Метод удаления прав аккаунта _(removeAccountPermission)_ служит для удаления _permission_ связанных с переданным аккаунтом. + +Запрос на создание права выглядит следующим образом: +[source,xml] +---- + + + + + + + dog + topic-management + service + + + + + dog + system-management + service + + + + + + +---- + + +Если параметр _action_ пустой либо отсутствует в сервисе permission по умолчанию подставляется _default_. diff --git a/documentation/core/bridge/Bridge-Description-and-Configuration.adoc b/documentation/core/bridge/Bridge-Description-and-Configuration.adoc new file mode 100644 index 00000000..089a76da --- /dev/null +++ b/documentation/core/bridge/Bridge-Description-and-Configuration.adoc @@ -0,0 +1,79 @@ +Связь между двумя независимыми брокерами осуществляется с помощью моста. Карафы подключенные к одному брокеру далее будут именоваться шиной. + +image::Route-in-different-esb.png[Прохождение пакета через группу и мост] + +== Установка и настройка + +Установка модуля происходит через фичу: + +* _feature:install bridge_ + +Фича включена в общий установочный скрипт и будет устанавливаться вместе с остальными модулями. Во время установки фичи в караф копируются файлы конфигурации: + +* _ru.entaxy.esb.system.bridge.cfg (основная конфигурация)_ + +=== ru.entaxy.esb.system.bridge.cfg (основная конфигурация) +[source,properties] +---- +# имя локальной шины() +jms.local=test1 +# значение true - мост текущего узла работает в пассивном режиме, +# т.е. сообщения для соответствующего удалённого узла складываются в очередь на локальном брокере, +# из которой уже читает подключаемый узел (локальный брокер должен быть доступен для соединения) +# По умолчанию false - активный режим, запись сообщения идёт сразу в очередь на удалённом брокере, +# подключаемого узла (брокеры по обе стороны моста должны быть доступны) +jms.local.master=false +# имена удаленных шин, задается через запятую(,) +jms.remote.list=test2 + +# адреса брокера, задаются чеерез запятую(jms.url.) +jms.url.test1=192.168.122.81:61616,192.168.122.82:61616 +# логин для подключения к брокеру(jms.username.) +jms.username.test1=input +# пароль для подключения к брокеру(jms.password.) +jms.password.test1=input +# протокол для передачи сообщений внутри шины(jms.protocol.inner.esb.) +# для корректной работы синхронного режима передачи сообщений: необходимо следить +# за одинаковым значением данного параметра в мосту и в самой шине(ru.entaxy.esb.cfg) +# возможные значения tcp, amqp +jms.protocol.inner.esb.test1=tcp +# протокол для передачи сообщений между шинами(jms.protocol.bridge.esb.) +# для корректной работы синхронного режима передачи сообщений: необходимо следить +# за одинаковым значением данного параметра во всех подключенных шинах +# возможные значения tcp, amqp +jms.protocol.bridge.test1=amqp + +# адреса брокера, задаются чеерез запятую(jms.url.) +jms.url.test2=localhost:61616 +# логин для подключения к брокеру(jms.username.) +jms.username.test2=input +# пароль для подключения к брокеру(jms.password.) +jms.password.test2=input +# jms.master. - выставляем в true, когда соответствующий узел настроен в пассивный режим, +# т.е. для него jms.local.master = true (брокер должен быть доступен для соединения) +jms.master.test2=true +# протокол для передачи сообщений внутри шины(jms.protocol.inner.esb.) +# для корректной работы синхронного режима передачи сообщений: необходимо следить +# за одинаковым значением данного параметра в мосту и в самой шине(ru.entaxy.esb.cfg) +# возможные значения tcp, amqp +jms.protocol.inner.esb.test2=tcp +# протокол для передачи сообщений между шинами(jms.protocol.bridge.esb.) +# для корректной работы синхронного режима передачи сообщений: необходимо следить +# за одинаковым значением данного параметра во всех подключенных шинах +# возможные значения tcp, amqp +jms.protocol.bridge.test2=amqp + +# максимальное колчичество попыток отправить сообщение в очередь +# почитать подробнее можно в https://camel.apache.org/components/latest/eips/dead-letter-channel.html#deadLetterChannel-Redelivery +redelivery.maximumRedeliveries=-1 +# время между попытками отправить сообщение в очередь +redelivery.redeliveryDelay=5000 +# экспоненциальный рост времени между попытками отпрвки сообщений в очередь +redelivery.useExponentialBackOff=true + +queue.sender.concurrentConsumers=1 +queue.receiver.concurrentConsumers=1 +---- + + + diff --git a/documentation/core/bridge/Route-in-different-esb.png b/documentation/core/bridge/Route-in-different-esb.png new file mode 100644 index 00000000..e234240f Binary files /dev/null and b/documentation/core/bridge/Route-in-different-esb.png differ diff --git a/documentation/core/clustering.png b/documentation/core/clustering.png new file mode 100644 index 00000000..e5893e3f Binary files /dev/null and b/documentation/core/clustering.png differ diff --git a/documentation/core/deployer/deployer-common.adoc b/documentation/core/deployer/deployer-common.adoc new file mode 100644 index 00000000..3e4ce6cb --- /dev/null +++ b/documentation/core/deployer/deployer-common.adoc @@ -0,0 +1,44 @@ += Файловые репозитории + +*Nexus* + представлен бандлом SYSTEM :: ENTAXY :: NEXUS :: DEPLOYER, реализует взаимодействие с репозиторием Sonatype Nexus. + Конфигурация ru.entaxy.esb.deployer.nexus.cfg +[source] +---- +# все смены адреса расположения nexus и изменение наименования репозитория, необходимо фиксировать в файле +# org.ops4j.pax.url.mvn.cfg параметр: org.ops4j.pax.url.mvn.repositories + +# url расположения nexus +nexus.deployer.url=http://nexusHost +# название репозитория в nexus, необходимого для конфигурирования шины из вне(создание профилей, коннекторов и т д) +nexus.deployer.repository=entaxy +# логин для авторизации в nexus +nexus.deployer.username=deployer +# пароль для авторизации в nexus +nexus.deployer.password=deployer +---- + +*File-system* + представлен бандлом SYSTEM :: ENTAXY :: FILE SYSTEM :: DEPLOYER, реализует взаимодействие с файловой системой, т.е. сохраняет переданные файлы в настроенной папке. + Конфигурация ru.entaxy.esb.deployer.file.system.cfg +[source] +---- +#Корневая папка репозитория +folder.root=/opt/bundle-repository +---- + + +=== Настройка системы + +По умолчанию деплоятся оба бандла и система использует репозиторий File-system. + +Для включения нужного репозитория необходимо оставить включённым бандл того репозитория, который требуется использовать. + +_Пример:_ + По умолчанию включён репозиторий File-system, для включения репозитория Nexus отключаем/удаляем бандл SYSTEM :: ENTAXY :: FILE SYSTEM :: DEPLOYER + + + + + + diff --git a/documentation/core/exception/Centralized-error-handler.adoc b/documentation/core/exception/Centralized-error-handler.adoc new file mode 100644 index 00000000..e4f54a3f --- /dev/null +++ b/documentation/core/exception/Centralized-error-handler.adoc @@ -0,0 +1,144 @@ +Централизованный обработчик ошибок для формирования кодов ошибок, их синхронного возврата клиенту и для асинхронного дублирования более подробного описания ошибки для клиента и для Центральной Базы Интеграции. + +image::Error-handling-Scheme.jpg[] + += Установка и настройка + +Установка модуля происходит через фичу: + +* _feature:install error-handler_ + +Фича включена в общий установочный скрипт и будет устанавливаться вместе с остальными модулями. Во время установки фичи в караф копируются файлы конфигурации: + +* _ru.entaxy.esb.error.cfg (основная конфигурация)_ +* _ru.entaxy.esb.error.code.cfg (справочник исключений с маппингом на коды ошибок)_ +* _ru.entaxy.esb.error.text.cfg (справочник кодов ошибок с маппингом на текстовые сообщения)_ + +Есть возможность настройки маппинга уровней журналирования через файл конфигурации ru.entaxy.esb.error.severity.cfg. + +* _ru.entaxy.esb.error.cfg (основная конфигурация)_ + +[source,properties] +---- +# асинхронный пакет с ошибкой отправляется от имени: +# false - системы, вызвавшей ошибку в шине +# true - шины (система с идентификатором "-1") +ru.entaxy.esb.error.bus.always_at_source=false + +# асинхронный пакет с ошибкой в поле description содержит: +# false - сообщение из маппинга в файле ru.entaxy.esb.error.text.cfg +# true - содержит сообщение, сохранённое в исключении +ru.entaxy.esb.error.description.exception_message=true + +# имя очереди для отправки пакета с ошибкой при недоступности системы, указанной в свойстве ru.entaxy.esb.error.system.name +ru.entaxy.esb.error.queue.name=error + +# имя системы для отправки пакета с ошибкой, подразумевается система ЦБИ +ru.entaxy.esb.error.system.name=error + +# true - включает в пакет с ошибкой весь stacktrace исключения +ru.entaxy.esb.error.stacktrace.show=true + +# свойство автоматического запуска тестового маршрута, который при старте модуля бросает исключение java.lang.IllegalArgumentException: Test exception thrown +ru.entaxy.esb.error.test-route.startup=false +---- + +* _ru.entaxy.esb.error.code.cfg (справочник исключений с маппингом на коды ошибок)_ + +Справочник содержит соответствие имён классов исключений и _http_ кодов ошибок. И будет наполняться по мере использования шины в разных ситуациях. Для исключения, имя которого ещё не указано в этом файле, будет возвращаться _http_ код _520 (Unknown Error)._ + +[source,properties] +---- +DefaultException=520 +com.ctc.wstx.exc.WstxParsingException=400 +java.security.AccessControlException=403 +javax.ws.rs.ForbiddenException=403 +ru.onec.esb.system.common.exception.ConnectorNotFound=424 +ru.onec.esb.system.common.exception.DefaultException=520 +ru.onec.esb.system.common.exception.ProfileNotFound=424 +# и т.д. +---- + +* _ru.entaxy.esb.error.text.cfg (справочник кодов ошибок с маппингом на текстовые сообщения)_ + +Если в основной конфигурации свойство _ru.entaxy.esb.error.description.exception_message_ установлено в _false_, то описание ошибки отправляется из этого файла в соответствие с кодом _http_ ошибки. + +[source,properties] +---- +# 1xx: Informational +# 2xx: Success +200=OK + +# 3xx: Redirection +# 4xx: Client Error +400=Bad Request +403=Forbidden +424=Failed Dependency + +# 5xx: Server Error +520=Unknown Error +# и т.д. +---- + +=== Подключение обработчика ошибок + +Для подключения обработчика ошибок к маршрутам какого-либо модуля необходимо выполнить следующие шаги: + +. Добавить в модуль обработки ошибок в директорию _src/main/resources/xslt/operation_ новый _xslt_ для формирования ответа с ошибкой. Файл должен называться по имени операции, для которой будет формироваться ответ. Например _sendToJMS.xsl_. +. Добавить в _camelContext_ аттрибут _errorHandlerRef="commonErrorHandler"_ и внутри зарегистрировать обработчик и политику повторной доставки: + +[source,xml] +---- + + + + + + +---- + +Для контекстов, содержащих конечные точки _cxf_, необходимо: + +через _pom.xml_ импортировать интерцептор для перехвата ошибок (_SoapFault_) + +[source,xml] +---- + + ru.onec.esb.system.core.common.error.handler.interceptor, + ... + +---- + +добавить интерцептор в _cxfEndpoint_ и _bean_ с указанием в первом аргументе идентификатора _camelContext_ + +[source,xml] +---- + + + + + + + + + + + +---- + +в _camelContext_ добавить маршрут + +[source,xml] +---- + + + + + + +---- + + diff --git a/documentation/core/exception/Error-description.adoc b/documentation/core/exception/Error-description.adoc new file mode 100644 index 00000000..82b3d7fc --- /dev/null +++ b/documentation/core/exception/Error-description.adoc @@ -0,0 +1,31 @@ += Использование обработчика ошибок + +Для централизованной обработки ошибок будем использовать “процессор” зарегистрированный через _ + + + + 1 + system + 2 + system + + default + + + +---- + +Пример ответа: + +[source,xml] +---- + + + false + + +---- + + +=== Get - получает запись Permission + +Принимает параметры + +_permissionId_ (long) - идентификатор объекта _permission_ + +Пример запроса: +[source,xml] +---- + + + + 24 + + +---- + +Пример ответа: +[source,xml] +---- + + + + 24 + 7 + system + 8 + system + connect + + + +---- + + +=== GetByAllParams - получает запись Permission + +Принимает параметры + +- _objectId_ (long) - идентификатор объекта, для которого проверяются права +- _objectType_ (String) - тип объекта +- _subjectId_ (String) - идентификатор предмета применяемого права +- _subjectType_ (String) - тип предмета +- _action_ (String) - тип действия, необязательный по умолчанию проставляется значение _default_ + +Пример запроса: +[source,xml] +---- + + + + + 7 + system + 8 + system + + connect + + + +---- + +Пример ответа: +[source,xml] +---- + + + + 24 + 7 + system + 8 + system + connect + + + +---- + + +=== Create - создаёт запись Permission + +Принимает параметры + +- _objectId_ (long) - идентификатор объекта, для которого проверяются права +- _objectType_ (String) - тип объекта +- _subjectId_ (String) - идентификатор предмета применяемого права +- _subjectType_ (String) - тип предмета +- _action_ (String) - тип действия, необязательный по умолчанию проставляется значение _default_ + +Пример запроса: +[source,xml] +---- + + + + + 7 + account + 1234 + system-group + + send + + + +---- + +Пример ответа: +[source,xml] +---- + + + + 25 + 7 + account + 1234 + system-group + send + + + +---- + +В случае если запись уже создана возвращается ошибка +[source,xml] +---- + + + + soap:Server + org.hibernate.exception.ConstraintViolationException: could not execute statement + + + +---- + +=== Update - изменяет запись Permission + +Принимает параметры + +- _permissionId_ (long) - идентификатор объекта permission +- _objectId_ (long) - идентификатор объекта, для которого проверяются права +- _objectType_ (String) - тип объекта, данный параметр соответствует проектной терминалогии: system, system-group +- _subjectId_ (String) - идентификатор предмета применяемого права +- _subjectType_ (String) - тип предмета +- _action_ (String) - тип действия, необязательный по умолчанию проставляется значение _default_ + +Пример запроса: +[source,xml] +---- + + + + + 23 + 8 + account + 1234 + system-group + + send + + + +---- + + +Пример ответа: +[source,xml] +---- + + + + 23 + 8 + account + 1234 + system-group + send + + + +---- + +В случае если запись не найдена возвращается ошибка +[source,xml] +---- + + + + soap:Server + No entity found for query + + + +---- + + +=== _Delete_ - удаляет запись _Permission_ + +Принимает параметры + +- _objectId_ (long) - идентификатор объекта, для которого проверяются права +- _objectType_ (String) - тип объекта +- _subjectId_ (String) - идентификатор предмета применяемого права +- _subjectType_ (String) - тип предмета +- _action_ (String) - тип действия, необязательный по умолчанию проставляется значение _default_ + +Пример запроса: +[source,xml] +---- + + + + + 7 + account + 1234 + system-group + + send + + + +---- + +Пример ответа: +[source,xml] +---- + + + true + + +---- + +В случае если запись не найдена возвращается ошибка +[source,xml] +---- + + + + soap:Server + No entity found for query + + + +---- + diff --git a/documentation/core/route_packet.png b/documentation/core/route_packet.png new file mode 100644 index 00000000..bd6ad04c Binary files /dev/null and b/documentation/core/route_packet.png differ diff --git a/documentation/core/schema/Schema.adoc b/documentation/core/schema/Schema.adoc new file mode 100644 index 00000000..dd534aec --- /dev/null +++ b/documentation/core/schema/Schema.adoc @@ -0,0 +1,462 @@ += Shema + +Есть три типа ресурсов, которые можно загружать в шину и использовать в маршрутах: + +. Валидационные типы ресурсов (нпрм xsd). Необходимы для валидации сообщения на соответствие той или иной схеме. +. Трансформационные типы ресурсов (нпрм xslt, amd). Необходимы для трасформации сообщений из одной схемы в другую. +. Ресурсы используемые для генерации сервисов (нпрм wsdl). Необходимы для поднятия сервиса на шине. + +Для загрузки трансформационных ресурсов необходимо указывать, является ли данный трансформатор конвертором и схему-источник и схему-результат для неявного преобразования сообщения(конвертор может быть один и только один для пары: схема источник, схема результат) +Схему-источник и схему-результат необходимо указывать только для конверторов, используемых в неявных преобразованиях + +Желательно указывать или определять схему для коннектора, если предполагается использовать функционал неявных преобразований. Неявное преобразование будет работать, если: + +- в заголовке указана схема-источник +- в заголовке указана схема-приемник +- в реестре есть конвертор для этой пары схем + +Указание схемы может попадать в заголовок неявно (из свойств коннектора или из тела сообщения) или явно через медиатор. + +== Схема работы с ресурсами. + +Сначала загружаем сам ресурс в шину, который мы будем использовать в маршрутах. + +Загружаем ресурс и получаем id, с помощью которого можно и _нужно_ добавить служебную информацию! +Также можно перезагрузить данный ресурс и удалять его из шины. + +Также можно загружать служебную информацию, такую как название ресурса, его расширение и т д. +Выгружать весь список ресурсов, и по отдельности выкачивать сам ресурс для анализа. +Также использовать различные сортировки для поиска определенного типа ресурс. + +== Руководство по загрузке ресурсов в шину. + +*LoadResource.* + +Для загрузки ресурса в шину нужно использовать метод loadResource. + +параметры: + +- resourceValue - сам ресурс, в формате base64 + +[source,xml] +---- + + + + + + + +---- + +ответ +[source,xml] +---- + + + 1 + + +---- + +*GetResource.* + +Для выгрузки заранее загруженного ресурса в шину нужно использовать метод getResource. + +параметры: + +- getResourceRequest - id ресурса, который вернулся при вызове метода LoadResource + +[source,xml] +---- + + + + 1 + + +---- + +ответ + +параметры: + +- id - это id ресурса +- createdDate - дата создания ресурса +- createdBy - логин, загрузивший ресурс в шину +- editedDate - дата перезагрузки ресурса +- editedBy - логин, перезагрузивший ресурс в шине +- resourceValue - сам ресурс, в формате base64 + +[source,xml] +---- + + + + 1 + 12/15/20, 1:11 AM + 12/15/20, 1:11 AM + 12/15/20, 1:18 AM + 12/15/20, 1:18 AM + + + + +---- + +*ReloadResource.* + +Для перезагрузки ресурса в шину есть метод reloadResource. + +параметры: + +- id - id ресурса, который вернулся при вызове метода LoadResource +- resourceValue - сам ресурс, в формате base64 + +[source,xml] +---- + + + + 1 + + + + +---- + +ответ +[source,xml] +---- + + + 1 + + +---- + +*RemoveResource.* + +Для удаления ресурса в шине есть метод removeResource. + +параметры: + +- id - id ресурса, который вернулся при вызове метода LoadResource + +[source,xml] +---- + + + + 1 + + +---- + +ответ +[source,xml] +---- + + + 1 + + +---- + +*LoadResourceInfo.* + +Для загрузки мета информации ресурса в шине есть метод loadResourceInfo. + +параметры: + +- idResource - id ресурса, который вернулся при вызове метода LoadResource +- name - имя ресурса вместе с расширением +- version - версия ресурса +- description - описание ресурса +- convertor - является ли ресурс конвертором из одной схемы в другую +- namespace - входное пространство имен +- namespaceOut - выходное пространство имен, используется для трансформаций из одной схемы в другую + +[source,xml] +---- + + + + lama.xsd + 1 + 1.0 + lama test + false + http:lama.xsd + l + + + +---- + +ответ +[source,xml] +---- + + + 1 + + +---- + +*GetResourceInfo.* + +Для получения мета информации ресурса в шине есть метод getResourceInfo. + +параметры: + +- getResourceInfoRequest - id мета информации ресурса, который вернулся при вызове метода LoadResourceInfo + + +[source,xml] +---- + + + + 1 + + +---- + +ответ + +параметры: + +- id - id мета информации ресурса, который вернулся при вызове метода LoadResourceInfo +- idResource - id ресурса, который вернулся при вызове метода LoadResource +- name - имя ресурса вместе с расширением +- version - версия ресурса +- description - описание ресурса +- convertor - является ли ресурс конвертором из одной схемы в другую +- namespace - входное пространство имен +- namespaceOut - выходное пространство имен, используется для трансформаций из одной схемы в другую +- createdDate - дата создания мета информации ресурса +- createdBy - логин, загрузивший мета информацию ресурса в шину +- editedDate - дата перезагрузки мета информации ресурса +- editedBy - логин, перезагрузивший мета информацию ресурса в шине + +[source,xml] +---- + + + + 14 + lama.xsd + 14 + 1.0 + lama test + false + http:lama.xsd + false + ? + 12/15/20, 1:33 AM + ? + 12/15/20, 1:35 AM + + + +---- + +*EditResourceInfo.* + +Для корректирования мета информации ресурса в шине есть метод еditResourceInfo. + +параметры: + +- id - id мета информации ресурса, который вернулся при вызове метода LoadResourceInfo +- idResource - id ресурса, который вернулся при вызове метода LoadResource +- name - имя ресурса вместе с расширением +- version - версия ресурса +- description - описание ресурса +- convertor - является ли ресурс конвертором из одной схемы в другую +- namespace - входное пространство имен +- namespaceOut - выходное пространство имен, используется для трансформаций из одной схемы в другую + +[source,xml] +---- + + + + 1 + lama.xsd + 1 + 1.0 + lama test + false + http:lama.xsd + l + + + +---- + +ответ + +[source,xml] +---- + + + 14 + + +---- + +*RemoveResourceInfo.* + +Для удаления мета информации ресурса в шине есть метод removeResourceInfo. + +параметры: + +- id - id мета информации ресурса, который вернулся при вызове метода LoadResourceInfo + +[source,xml] +---- + + + + 1 + + +---- + +ответ + +[source,xml] +---- + + + 1 + + +---- + +*GetResourceInfoList.* + +Для получения списка мета информации ресурсов в шине есть метод getResourceInfoList. + +[source,xml] +---- + + + + + + +---- + +ответ + +[source,xml] +---- + + + + + 1 + lama.xsd + 1 + 1.0 + lama test + false + http:lama.xsd + l + ? + 12/14/20, 10:00 PM + + + + +---- + +*GetResourceInfoListByName.* + +Для получения списка мета информации ресурсов по имени ресурса в шине есть метод getResourceInfoListByName. + +параметры: + +- name - часть имени мета информации ресурса + +[source,xml] +---- + + + + + .xsd + + + +---- + +ответ + +[source,xml] +---- + + + + + 1 + lama.xsd + 1 + 1.0 + lama test + false + http:lama.xsd + l + ? + 12/14/20, 10:00 PM + + + + +---- + +*GetResourceInfoListByNamespace.* + +Для получения списка мета информации ресурсов по namespace ресурса в шине есть метод getResourceInfoListByNamespace. + +параметры: + +- namespace - часть namespace мета информации ресурса + +[source,xml] +---- + + + + + lama + + + +---- + +ответ + +[source,xml] +---- + + + + + 1 + lama.xsd + 1 + 1.0 + lama test + false + http:lama.xsd + l + ? + 12/14/20, 10:00 PM + + + + +---- \ No newline at end of file diff --git a/documentation/core/screenshots/screenshot_artemis_1.png b/documentation/core/screenshots/screenshot_artemis_1.png new file mode 100644 index 00000000..ecc42604 Binary files /dev/null and b/documentation/core/screenshots/screenshot_artemis_1.png differ diff --git a/documentation/core/screenshots/screenshot_artemis_10.png b/documentation/core/screenshots/screenshot_artemis_10.png new file mode 100644 index 00000000..df0962f0 Binary files /dev/null and b/documentation/core/screenshots/screenshot_artemis_10.png differ diff --git a/documentation/core/screenshots/screenshot_artemis_2.png b/documentation/core/screenshots/screenshot_artemis_2.png new file mode 100644 index 00000000..0c36f8c2 Binary files /dev/null and b/documentation/core/screenshots/screenshot_artemis_2.png differ diff --git a/documentation/core/screenshots/screenshot_artemis_3.png b/documentation/core/screenshots/screenshot_artemis_3.png new file mode 100644 index 00000000..7e20da42 Binary files /dev/null and b/documentation/core/screenshots/screenshot_artemis_3.png differ diff --git a/documentation/core/screenshots/screenshot_artemis_4.png b/documentation/core/screenshots/screenshot_artemis_4.png new file mode 100644 index 00000000..d84f7f88 Binary files /dev/null and b/documentation/core/screenshots/screenshot_artemis_4.png differ diff --git a/documentation/core/screenshots/screenshot_artemis_5.png b/documentation/core/screenshots/screenshot_artemis_5.png new file mode 100644 index 00000000..41f337a4 Binary files /dev/null and b/documentation/core/screenshots/screenshot_artemis_5.png differ diff --git a/documentation/core/screenshots/screenshot_artemis_6.png b/documentation/core/screenshots/screenshot_artemis_6.png new file mode 100644 index 00000000..61631e8b Binary files /dev/null and b/documentation/core/screenshots/screenshot_artemis_6.png differ diff --git a/documentation/core/screenshots/screenshot_artemis_7.png b/documentation/core/screenshots/screenshot_artemis_7.png new file mode 100644 index 00000000..db3c8949 Binary files /dev/null and b/documentation/core/screenshots/screenshot_artemis_7.png differ diff --git a/documentation/core/screenshots/screenshot_artemis_8.png b/documentation/core/screenshots/screenshot_artemis_8.png new file mode 100644 index 00000000..07bbebf8 Binary files /dev/null and b/documentation/core/screenshots/screenshot_artemis_8.png differ diff --git a/documentation/core/screenshots/screenshot_artemis_9.png b/documentation/core/screenshots/screenshot_artemis_9.png new file mode 100644 index 00000000..4d9e1f3f Binary files /dev/null and b/documentation/core/screenshots/screenshot_artemis_9.png differ diff --git a/documentation/core/screenshots/screenshot_hawtio_1.png b/documentation/core/screenshots/screenshot_hawtio_1.png new file mode 100644 index 00000000..b13d15e4 Binary files /dev/null and b/documentation/core/screenshots/screenshot_hawtio_1.png differ diff --git a/documentation/core/screenshots/screenshot_hawtio_2.png b/documentation/core/screenshots/screenshot_hawtio_2.png new file mode 100644 index 00000000..0ec04422 Binary files /dev/null and b/documentation/core/screenshots/screenshot_hawtio_2.png differ diff --git a/documentation/core/screenshots/screenshot_hawtio_3.png b/documentation/core/screenshots/screenshot_hawtio_3.png new file mode 100644 index 00000000..d753892f Binary files /dev/null and b/documentation/core/screenshots/screenshot_hawtio_3.png differ diff --git a/documentation/core/screenshots/screenshot_hawtio_4.png b/documentation/core/screenshots/screenshot_hawtio_4.png new file mode 100644 index 00000000..62905bae Binary files /dev/null and b/documentation/core/screenshots/screenshot_hawtio_4.png differ diff --git a/documentation/core/screenshots/screenshot_hawtio_5.png b/documentation/core/screenshots/screenshot_hawtio_5.png new file mode 100644 index 00000000..62905bae Binary files /dev/null and b/documentation/core/screenshots/screenshot_hawtio_5.png differ diff --git a/documentation/core/screenshots/screenshot_hawtio_6.png b/documentation/core/screenshots/screenshot_hawtio_6.png new file mode 100644 index 00000000..18d9a7c2 Binary files /dev/null and b/documentation/core/screenshots/screenshot_hawtio_6.png differ diff --git a/documentation/core/screenshots/screenshot_hawtio_7.png b/documentation/core/screenshots/screenshot_hawtio_7.png new file mode 100644 index 00000000..dcbad9bb Binary files /dev/null and b/documentation/core/screenshots/screenshot_hawtio_7.png differ diff --git a/documentation/core/system-managment/Users-manual-System-management.adoc b/documentation/core/system-managment/Users-manual-System-management.adoc new file mode 100644 index 00000000..da173ff8 --- /dev/null +++ b/documentation/core/system-managment/Users-manual-System-management.adoc @@ -0,0 +1,836 @@ += Руководство по управлению коннекторами и профилями в шине. + +_Профиль(profile)_ - это описание внешней системы в шине.(Например s1). + +_Мостовой профиль(bridge-profile)_ - это профиль на другой стороне шины, ведущий через мост в профиль. +(Например s1) + +_Коннектор(connector)_ - это связь между интерфейсом, через который может работать система, и профилем.(Например uniform-service, nsi) + +_Доступ(permission)_ - это разрешение на взаимодействие двух систем.(Например для того чтобы система s1 смогла отправить сообщение s2)(/permission-management) + +_Учетная запись(account)_ - это учетная запись системы для взаимодействия с шиной. +Для каждой системы должна быть учетная запись для возможности отправления сообщений в шину. +Также есть учетные записи для возможности взаимодействия с управленческим слоем(т. е. для того чтобы управлять коннекторами/профилями/учетными записями/топиками нужна учетная запись с соответствующими правами)(/basic-auth-management) + +Коннекторы делятся на входящие и исходящие(in, out), которые отвечают за отправку сообщения в определенный интерфейс и на получение ответа из определенного интерфейса соответственно. +Например, для того чтобы иметь возможность отправить сообщение в soap нужно создать коннектор uniform-service-in-connector, а для того чтобы получить сообщение из soap нужно создать коннектор uniform-service-out-connector. + +По адресу _/system-management-service_ находится сам сервис управления коннекторами и профилями в шине. + +Для работы внешней системы в шине нужно сначала создать профиль данной системы в шине, потом добавлять к нему необходимые коннекторы и пробрасывать его в необходимые шины. + +=== Управление профилями + +*СreateProfile.* + +Для создания профиля системы нужно вызвать метод createProfile, где вместо “system_uuid” нужно подставить uuid системы, вместо “system_name” - имя системы, “description” описание системы: + +[source,xml] +---- + + + + + {{system_uuid}} + {{system_uuid}} + + {{description}} + + + + +---- + +Где ответом будет (“true” - если профиль успешно создался, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*GetProfile.* + +Проверить созданный профиль можно с помощью метода getProfile, где вместо “system_uuid” нужно подставить uuid системы: + +[source,xml] +---- + + + + + {{system_uuid}} + + + +---- + +Где ответом будет (профиль со всеми зависимостями, либо ошибка и ее описание): + +[source,xml] +---- + + + + w6 + w6 + description + 2020-01-22+03:00 + System + false + ACTIVE + + + + + +---- + +*GetProfiles* + +Получить список профилей, зарегистрированных в шине, можно с помощью метода getProfiles: + +[source,xml] +---- + + + + + + +---- + +Где ответом будет (список профилей со всеми зависимостями, либо ошибка и ее описание): + +[source,xml] +---- + + + + + w6 + w6 + description + 2020-01-22+03:00 + System + false + ACTIVE + + + + + + +---- + +*StopProfile* + +Остановить профиль и все его зависимости можно с помощью метода stopProfile, где вместо “system_uuid” нужно подставить uuid системы: + +[source,xml] +---- + + + + + {{system_uuid}} + + + +---- + +Где ответом будет (“true” - если профиль и его зависимости успешно остановились, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*StartProfile* + +Запустить профиль и все его зависимости можно с помощью метода startProfile, где вместо “system_uuid” нужно подставить uuid системы: + +[source,xml] +---- + + + + + {{system_uuid}} + + + +---- + +Где ответом будет (“true” - если профиль успешно запустился, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*RemoveProfile* + +Удалить профиль и все его зависимости можно с помощью метода removeProfile, где вместо “system_uuid” нужно подставить uuid системы(ВНИМАНИЕ! +При удалении профиля также удаляются все связанные с ним коннекторы): + +[source,xml] +---- + + + + + {{system_uuid}} + + + +---- + +Где ответом будет (“true” - если профиль и его зависимости успешно удалился, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +=== Управление коннекторами + +*GetTemplates* + +Для создания коннектора в шине нужно получить список шаблонов(требуются для создания коннекторов) методом getTemplates: + +[source,xml] +---- + + + + + + +---- + +Где ответом будет (список шаблонов с параметрами): + +[source,xml] +---- + + + + + + + + + + +---- + +*GetTemplate* + +Для создания коннектора в шине нужно получить список шаблонов(требуются для создания коннекторов) методом getTemplate, где “template_name” имя шаблона по которому будет сделан коннектор: + +[source,xml] +---- + + + + + {{template_name}} + + + +---- + +Где ответом будет (шаблон с параметрами): + +[source,xml] +---- + + + + + +---- + +*СreateConnector* + +Для создания коннектора в шине нужно вызвать метод createConnector, где templateName - это имя шаблона, полученное из метода getTemplates, system_uuid - это uuid профиля, зарегистрированного в системе ранее, также нужно заполнить список параметров необходимый для создания коннектора(ВНИМАНИЕ! если не заполнить список параметров, то установятся значения по умолчанию) : + +[source,xml] +---- + + + + + {{template_name}} + {{system_uuid}} + + + + + + +---- + +Где ответом будет (“true” - если коннектор успешно создался, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*GetConnectors* + +Можно просматривать список подключенных коннекторов в шине методом getConnectors: + +[source,xml] +---- + + + + + + +---- + +Где ответом будет (список коннкторов с параметрами): + +[source,xml] +---- + + + + + nsi-in-connector-w6 + ACTIVE + + + + + +---- + +*StartConnector* + +Запустить коннектор можно с помощью метода startConnector, где вместо “system_uuid” нужно подставить uuid системы, “template_name” это имя шаблона: + +[source,xml] +---- + + + + + {{template_name}} + {{system_uuid}} + + + +---- + +Где ответом будет (“true” - если коннектор успешно запустился, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*StopConnector* + +Остановить коннектор можно с помощью метода stopConnector, где вместо “system_uuid” нужно подставить uuid системы, “template_name” это имя шаблона: + +[source,xml] +---- + + + + + {{template_name}} + {{system_uuid}} + + + +---- + +Где ответом будет (“true” - если коннектор успешно остановилась, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*RemoveConnector* + +Удалить коннектор можно с помощью метода removeConnector, где вместо “system_uuid” нужно подставить uuid системы, “template_name” это имя шаблона: + +[source,xml] +---- + + + + + {{template_name}} + {{system_uuid}} + + + +---- + +Где ответом будет (“true” - если коннектор успешно удалился, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +=== Управление мостовыми профилями + +*GetListEsb* + +Для получения списка подключенных шин можно с помощью метода getListEsb: + +[source,xml] +---- + + + + + + +---- + +Где ответом будет (список подключенных шин, ошибка и ее описание): + +[source,xml] +---- + + + + test1 + + + +---- + +*CreateBridgeProfile* + +Создать профиль, ведущий на мост, можно с помощью метода createBridgeProfile, где “system_uuid” uuid системы, “esb_name” имя подключенной шины: + +[source,xml] +---- + + + + + {{system_uuid}} + {{system_uuid}} + {{esb_name}} + + + +---- + +Где ответом будет (“true” - если профиль, ведущий на мост, успешно создался, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*StopBridgeProfile* + +Остановить профиль, ведущий на мост, можно с помощью метода stopBridgeProfile, где “system_uuid” uuid системы, “esb_name” имя подключенной шины: + +[source,xml] +---- + + + + + {{system_uuid}} + {{system_uuid}} + {{esb_name}} + + + +---- + +Где ответом будет (“true” - если профиль, ведущий на мост, успешно остановился, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*StartBridgeProfile* + +Запустить профиль, ведущий на мост, можно с помощью метода startBridgeProfile, где “system_uuid” uuid системы, “esb_name” имя подключенной шины: + +[source,xml] +---- + + + + + {{system_uuid}} + {{system_uuid}} + {{esb_name}} + + + +---- + +Где ответом будет (“true” - если профиль, ведущий на мост, успешно запустился, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*GetBridgeProfile* + +Получить профиль, ведущий на мост, можно с помощью метода getBridgeProfile, где “system_uuid” uuid системы, “esb_name” имя подключенной шины: + +[source,xml] +---- + + + + + {{system_uuid}} + {{system_uuid}} + {{esb_name}} + + + +---- + +Где ответом будет (профиль, ведущий на мост, пустой ответ): + +[source,xml] +---- + + + + w6 + ACTIVE + test1 + + + +---- + +*RemoveBridgeProfile* + +Удалить профиль, ведущий на мост, можно с помощью метода removeBridgeProfile, где “system_uuid” uuid системы, “esb_name” имя подключенной шины: + +[source,xml] +---- + + + + + {{system_uuid}} + {{system_uuid}} + {{esb_name}} + + + +---- + +Где ответом будет (“true” - если профиль, ведущий на мост, успешно удален, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*GetBridgeProfiles* + +Для получения списка профилей, ведущих на мост, можно использовать метод getBridgeProfiles:(ВНИМАНИЕ! запрос покажет список проброшенных профилей на ТЕКУЩЕЙ шине) + +[source,xml] +---- + + + + + + +---- + +Где ответом будет (список профиль, ведущих на мост, пустой ответ): + +[source,xml] +---- + + + + + w6 + ACTIVE + test1 + + + + +---- + +=== Управление доступами + +*CreatePermission* + +Создать доступ одной системы к другой, можно с помощью метода createPermission, где “objectUuid” uuid системы, которой нужно дать доступ, “subjectUuid” - uuid системы, к которой нужно дать доступ: + +[source,xml] +---- + + + + + {{objectUuid}} + {{subjectUuid}} + + + +---- + +Где ответом будет (“true” - если доступ, успешно создался, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*RemovePermission* + +Удалить доступ одной системы к другой, можно с помощью метода removePermission, где “objectUuid” uuid системы, которой нужно дать доступ, “subjectUuid” - uuid системы, к которой нужно дать доступ: + +[source,xml] +---- + + + + + {{objectUuid}} + {{subjectUuid}} + + + +---- + +Где ответом будет (“true” - если доступ, успешно удалился, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*GetPermissionsByObject* + +Получить список систем, доступ к которым от данной системы разрешен, можно с помощью метода getPermissionByObject, где “objectUuid” uuid системы: + +[source,xml] +---- + + + + + {{objectUuid}} + + + +---- + +Где ответом будет (список систем, которым данная система может отправлять сообщения, ошибка и ее описание): + +[source,xml] +---- + + + + + r2 + + + active + + + + +---- + +*GetPermissionsBySubject* + +Получить список систем, доступ которым разрешен к данной системе, можно с помощью метода getPermissionBySubject, где “subjectUuid” uuid системы: + +[source,xml] +---- + + + + + {{subjectUuid}} + + + +---- + +Где ответом будет (список систем, для которых данная система доступна для отправки сообщений, ошибка и ее описание): + +[source,xml] +---- + + + + + r2 + + + + +---- + +*CreatePermissionForObjectRequest* + +Создать сразу несколько доступов, которым разрешено отправлять сообщения от данной системы, можно с помощью метода сreatePermissionForObjectRequest, где “objectUuid” это uuid системы, от которой буду исходить сообщения, ‘“subjectUuid1”, “subjectUuid2” и т д, это uuid систем, которым будут отправлять сообщения: + +[source,xml] +---- + + + + + {{objectUuid}} + + {{subjectUuid1}} + {{subjectUuid2}} + + + +---- + +Где ответом будет (“true” - если доступа, успешно создались, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- + +*CreatePermissionForSubjectRequest* + +Создать сразу несколько доступов, которым разрешено отправлять сообщения в данную систему, можно с помощью метода сreatePermissionForSubjectRequest, где “objectUuid1”, “objectUuid2” и т д - это uuid систем, от которых буду исходить сообщения, ‘“subjectUuid” - это uuid системы, которой будут отправлять сообщения: + +[source,xml] +---- + + + + + + {{objectUuid1}} + {{objectUuid2}} + {{subjectUuid}} + + + +---- + +Где ответом будет (“true” - если доступа, успешно создались, ошибка и ее описание): + +[source,xml] +---- + + + true + + +---- diff --git a/documentation/core/topic/Scheme_of_work_notifications(events).png b/documentation/core/topic/Scheme_of_work_notifications(events).png new file mode 100644 index 00000000..615c61f3 Binary files /dev/null and b/documentation/core/topic/Scheme_of_work_notifications(events).png differ diff --git a/documentation/core/topic/Topic-management-Rest-service.adoc b/documentation/core/topic/Topic-management-Rest-service.adoc new file mode 100644 index 00000000..8bf75929 --- /dev/null +++ b/documentation/core/topic/Topic-management-Rest-service.adoc @@ -0,0 +1,555 @@ += Rest сервис Topic-management + +=== Rest сервис для работы с топиками. + +Сервис состоит из 2-х контекстов: + +- _topic-management_ - управление топиками (создание/изменение/удаление) +- _topic-subscription_ - клиентский сервис подписки и публикации сообщения + +При смене контекста в конфигурационных файлах требуется перераздать права на данный сервис. + +Схема работы подписок + +image::Topic_publish_diagram.png[] + +Схема работы нотификаций + +image::Scheme_of_work_notifications(events).png[] + +=== Права + +Право доступа в сервис _topic-management_ + +Для доступа к сервису _topic-management_ у аккаунта должно быть право доступа в данный сервис. + +По умолчанию право на доступ к сервису есть у пользователя _admin_. + +Используя данного пользователя в сервисе _permission-management_ можно раздать права на аккаунты систем. + +Параметры для выдачи аккаунту прав на сервис: + +- _objectId_: идентификатор учётной записи +- _objectType_: account +- _subjectId_: topic-management +- _subjectType_: service + +Право manage сервиса _topic-subscription_ + +Для доступа к менеджерским функциям сервиса _topic-subscription_ у аккаунта должно быть право manage - данное право открывает доступ к управлению подписками. + +Функционал управления подписками реализован в методах _subscribe_ и _unsubscribe_, пример использования приведён в подпунктах “Массовая обработка при наличии права manage для данного сервиса”. + +Параметры для выдачи аккаунту права _manage_: + +- _objectId_: идентификатор учётной записи +- _objectType_: account +- _subjectId_: topic-subscription +- _subjectType_: service +- _action_: manage + +=== Конфигурационные файлы + +Конфигурационные файлы по умолчанию хранятся в папке сервера \etc\ + +- _ru.entaxy.esb.system.event.handler.cfg_ + +[source,properties] +---- +# максимальное колчичество попыток отправить сообщение в очередь +# почитать подробнее можно в https://camel.apache.org/components/latest/eips/dead-letter-channel.html#deadLetterChannel-Redelivery +redelivery.maximumRedeliveries=-1 +# время между попытками отправить сообщение в очередь +redelivery.redeliveryDelay=5000 + +#cron - по умолчанию запускается каждые 00:00:00, +#cron выражение использует знак "+" как разделитель для модуля quartz2l +quirtz.job.clean.cron=0+0+0+*+*+?+* +---- + +- _ru.entaxy.esb.system.event.rest.cfg_ + +[source,properties] +---- +service.host=http://0.0.0.0 + +service.port.management=9090 +#Рутовый контекст управляющего сервиса, при изменении требуется перераздать права для данного сервиса +service.root.path.management=/topic-management + +service.port.subscription=9092 +#Рутовый контекст клиентского сервиса, при изменении требуется перераздать права для данного сервиса +service.root.path.subscription=/topic-subscription +---- + +=== Методы topic-management: + +- _create_ - создать топик +При создании и изменении топика, есть возможность передать списки систем, которым доступна подписка или публикация в данном топике. + +Запрос: + +_POST server:9090/topic-management/create_ + +Тело +[source,json] +---- +{ + "topicName": "boomNews", + "possibleSubscribers" : ["systemUuid1", "systemUuid2"], + "possiblePublishers" : ["systemUuid3", "systemUuid4"] +} +---- + +Ответ: + +Статус 201 + +Тело +[source,json] +---- +{ + "title": "Topic created", + "topicName": "", + "subscriberErrors": { + "systemNotFound": [ + "" + ] + }, + "publisherErrors": { + "systemNotFound": [] + } +} +---- + +- update - изменить топик (название не меняется, так как на него завязана сама очередь в брокере) + +Запрос: + +_POST server:9090/topic-management/update_ + +Тело + +[source,json] +---- +{ + "topicName": "boomNews", + "possibleSubscribers" : ["systemUuid1", "systemUuid2"], + "possiblePublishers" : ["systemUuid3", "systemUuid4"] +} +---- + +Ответ: + +Статус 201 + +Тело +[source,json] +---- +{ + "title": "Topic updated", + "topicName": "", + "subscriberErrors": { + "systemNotFound": [ + "" + ] + }, + "publisherErrors": { + "systemNotFound": [] + } +} +---- + +- delete - топик помечается как удалённый + +Запрос: + +_POST server:9090/topic-management/delete_ + +Тело +[source,json] +---- +{ + "topicName": "boomNews" +} +---- + +Ответ: + +Статус 200 + +Тело +[source,json] +---- +{ + "title": "Topic deleted", + "topicName": "" +} +---- + + +- clean - очистка хранилища топиков + +Окончательное удаление топиков, помеченных как удалённые. + +Запрос: + +_POST server:9090/topic-management/clean_ + +Ответ: + +Статус 200 + +Тело +[source,json] +---- +{ + "title": "Cleaned", + "topicDeleted": "" +} +---- + + +=== Методы topic-subscription: + +- _subscribe_ - подписаться на топик + +Запрос: + +_POST server:9090/topic-subscription/subscribe_ + +Тело +[source,json] +---- +{ + "topicName": "boomNews", + "subscriptionType": "PUSH" +} +---- + +Ответ: + +Статус 201 + +Тело +[source,json] +---- +{ + "title": "Subscription created", + "topicName": "", + "systemName": "", + "subscriptionType": "" +} +---- + +=== Массовая обработка при наличии права manage для данного сервиса. + +- _subscribe_ - подписаться на топик + +Запрос: + +_POST server:9092/topic-subscription/subscribe_ + +Тело +[source,json] +---- +{ + "topicName": "boomNews", + "systemUuids": [ + { + "systemUuid": "NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN", + "subscriptionType": "PUSH" + }, + { + "systemUuid": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "subscriptionType": "PULL" + }, + { + "systemUuid": "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY", + "subscriptionType": "PULL" + } + ] +} +---- + +Ответ: + +Статус 200 + +Тело +[source,json] +---- +[ + { + "title": "Internal Server Error", + "detail": "System not found NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN", + "reason": "javax.persistence.NoResultException: No entity found for query" + }, + { + "title": "Subscription created", + "topicName": "ooooo111-ff6e-4219-a878-bff120c495f1", + "systemUUID": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "subscriptionType": "PULL" + }, + { + "title": "Forbidden", + "detail": "No permission to subscribe for system YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY" + } +] +---- + + +- _unsubscribe_ - отписаться от топика + +Запрос: + +_POST server:9090/topic-subscription/unsubscribe_ + +Тело +[source,json] +---- +{ + "topicName": "boomNews" +} +---- + +Ответ: + +Статус 200 + +Тело +[source,json] +---- +{ + "title": "Subscription deleted", + "topicName": "", + "systemName": "" +} +---- + +=== Массовая обработка при наличии права manage для данного сервиса. + +Запрос: + +_POST server:9092/topic-subscription/unsubscribe_ + +Тело +[source,json] +---- +{ + "topicName": "boomNews", + "systemUuids": [ + { + "systemUuid":"NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN", + "subscriptionType": "PUSH" + }, + { + "systemUuid": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "subscriptionType": "PULL" + }, + { + "systemUuid": "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY", + "subscriptionType": "PULL" + } + ] +} +---- + +Ответ: + +Статус 200 + +Тело +[source,json] +---- +[ + { + "title": "Internal Server Error", + "detail": "System not found NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN", + "reason": "javax.persistence.NoResultException: No entity found for query" + }, + { + "title": "Subscription deleted", + "topicName": "ooooo111-ff6e-4219-a878-bff120c495f1", + "systemUUID": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "title": "Subscription not found", + "topicName": "ooooo111-ff6e-4219-a878-bff120c495f1", + "systemUUID": "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY" + } +] +---- + +- _publish_ - опубликовать событие + +Запрос: + +_POST server:9090/topic-subscription/publish_ + +Тело +[source,json] +---- +{ + "topicName": "boomNews", "message": "messageText2" +} +---- + + Ответ: + Статус 200 + Тело + { + "title": "Message published", + "topicName": "" + } + +=== Примеры ответов при ошибке + +- _Передан некорректный JSON или логин не определён_ + +Статус 400 + +Тело +[source,json] +---- +{ + "title": "Incorrect input parameters", + "detail": "Cannot parse incoming JSON or login/system not defined" +} +---- + +- _Подписка не найдена_ + +Статус 404 + +Тело +[source,json] +---- +{ + "title": "Subscription not found", + "topicName": "${exchangeProperty.topicName}", + "systemUUID": "${header.X-SystemUuid}" +} +---- + +- _Топик не зарегистрирован_ + +Статус 400 + +Тело +[source,json] +---- +{ + "title": "Topic not registered", + "topicName": "${exchangeProperty.topicName}" +} +---- + +- _Система не найдена_ + +Статус 500 + +Тело +[source,json] +---- +{ + "title": "Internal Server Error", + "detail": "System not found ${header.X-SystemUuid}", + "reason": "${exception.stacktrace}" +} +---- + +- _Неизвестный тип подписки_ + +Статус 500 + +Тело +[source,json] +---- +{ + "title": "Internal Server Error", + "detail": "Unknown subscription type ${exchangeProperty.subscriptionType}", + "reason": "${exception.stacktrace}" +} +---- + +- _Нет прав на выполнение запрошенной операции_ + +Статус 403 + +Тело +[source,json] +---- +{ + "title": "Forbidden", + "detail": "No permission to subscribe" +} +---- + +- _Неизвестная ошибка_ + +Статус 500 + +Тело +[source,json] +---- +{ + "title": "Internal Server Error", + "detail": "Unknown exception", + "reason": "${exception.stacktrace}" +} +---- + +== Работа модуля топиков в кластере + +=== Подписки + +*PULL подписки не реализованы!* + +Для реализации подписки используются _durable shareable_ подписчики _Apache Artemis_ топиков, а для доставки сообщений из топиков создаются специальные маршруты отправляющие сообщения в подписанную систему(PUSH-подписка). При работе в кластере системой создаются дублирующие маршруты на каждом узле, которые работают в конкурентном режиме, т.е. при падении одного из узлов доставка сообщений будет производиться оставшимися узлами. + +Работа в кластере обеспечивается через компоненты _Apache Felix Event Admin_, реализующий рассылку служебных событий по топикам внутри узла, +и _Apache Karaf Cellar_ с интеграцией с _Event Admin_, реализующий рассылку данного события по всем узлам кластера. При создании/удалении подписки система создаёт соответствующее событие и отправляет в специальный топик _subscription_, далее подписчики на всех узлах, входящих в кластер, получают и обрабатывают данное событие. + +=== Настройки + +Настройки производятся на любом узле либо на мастер узле, в зависимости от настроек кластера. + +Для синхронизации топика _subscription_ в конфигурационном файле _org.apache.karaf.cellar.groups.cfg_, нужно добавить строки: + +[source,properties] +---- + default.event.blacklist.inbound = none + default.event.blacklist.outbound = none + default.event.whitelist.inbound = subscription + default.event.whitelist.outbound = subscription +---- + +Далее если _Apache Karaf Cellar_ настроен правильно, то конфигурационные файлы _org.apache.karaf.cellar.groups.cfg_ должны синхронизироваться и строки, представленные выше, появятся на всех узлах. + +Если синхронизация конфигурационных файлов не проходит, можно проверить статус _cellar_ продюсера командой: + + cluster:producer-status + +если выключен, то можно включить командой: + + cluster:producer-start + +=== Удаление топиков + +Удаление топиков происходит в 2 этапа + +- При вызове метода _delete_ топик помечается в БД, как удалённый + +- По расписанию запускается задача (по умолчанию раз в сутки в 00:00), которая удаляет топик окончательно вместе с подписками, правами и консьюмерами. +Либо очистка запускается вручную вызовом метода _clean_ сервиса _topic-management_ + +Если до очистки системы изменить топик помеченный как удалённый или попытаться создать его заново, то восстановится старый топик + +=== Плановая задача по очистке топиков + +Т.к. удаление топиков происходит в 2 этапа, с помощью планировщика _Quartz2_, работающего в кластере, запускается задача по очистке. Запуск происходит в конкурентном режиме, узел первый запустивший задачу получает приоритет, на остальных узлах задача останавливается до следующего запуска. + +Частота запуска задачи настраивается в конфигурационном файле _ru.entaxy.esb.system.event.handler.cfg_ в свойстве quirtz.job.clean.cron=0+0+0+*+*+?+* +с помощью cron выражения. Особенность cron выражения для quartz в том что “++” используется, как разделитель. + diff --git a/documentation/core/topic/Topic_publish_diagram.png b/documentation/core/topic/Topic_publish_diagram.png new file mode 100644 index 00000000..5b1bc1db Binary files /dev/null and b/documentation/core/topic/Topic_publish_diagram.png differ diff --git a/documentation/entaxy_main.adoc b/documentation/entaxy_main.adoc new file mode 100644 index 00000000..e2ce5fff --- /dev/null +++ b/documentation/entaxy_main.adoc @@ -0,0 +1,177 @@ += Entaxy +:imagesdir: . +:hardbreaks: + +Entaxy - шина, которую можно конфигурировать извне с помощью графического интерфейса или API, состоящая из модулей: + +image::Entaxy.png[] + +== *Управленческий слой(core):* + +=== basic-auth + +модуль, отвечающий за аутентификацию в шине. Tак же занимается хранением, созданием, редактированием и удалением учетных записей. + +xref:core/auth/Authorization.adoc[Более полную информации о basic-auth найдете по этой ссылке] + +_Для разработчиков: +-имеет Api, который занимается Crud операциями, +-хранит учетные записи в базе данных, +-предоставляет файл с актуальной информацией для nginx, +-выставляет interсeptor для аутентификации в других сервисах, +-выставляет interсeptor для определения принадлежности аккаунта определённой системе._ + + +=== permission + +модуль, отвечающий за управление правами доступа. + +xref:core/permission/SOAP-service-Permission-management.adoc[Более полную информации о permission найдете по этой ссылке] + +_Для разработчиков: +-имеет Api, который занимается Crud операциями +- хранит права в базе данных, +-(camel)компонент, который используется в маршрутах, для проверки возможности отправки из системы a в систему b. +-выставляет interсeptor для авторизации в служебных сервисах._ + + +=== system-management-api + +модуль, отвечающий за создание систем и разнообразных коннекторов. (коннекторы бывают разных типов, будет описано далее) + +xref:core/system-managment/Users-manual-System-management.adoc[Более полную информации о system-management найдете по этой ссылке] + +__Для разработчиков: +-имеет Api, который занимается Crud операциями +-хранит параметры в базе данных, +-генерирует профиля и коннекторы на основе переданных через Api параметров и деплоит их через репозиторий nexus или файловую систему и cellar (блок Deployer) в шину. +-также имеет возможность Crud прав доступа над учетными записями систем. +__ + +=== system-registry + +модуль, осуществляющий поддержку динамического управления профилями систем(профиль - это отражение параметров системы в шине) + +__Для разработчиков: +-хранит информацию о системах в базе данных, +-(camel)компонент, который используется в маршрутах для определения нужной системы и коннектора для отправки сообщения в нее. +__ + +=== system-group-registry + +модуль, осуществляющий поддержку динамического управления группами систем, которые определяют логику отправки в необходимую систему в определенной группе. + +__Для разработчиков: +-хранит информацию о группах в базе данных, +-(camel)компонент, который используется в маршрутах для определения нужной системы из группы. +__ + +=== events + +модуль, для работы с топиками(по схеме Publisher (издатель)-Subscriber (подписчик)) для систем. + +xref:core/topic/Topic-management-Rest-service.adoc[Более полную информации о events найдете по этой ссылке] + +__Для разработчиков: +-хранит информацию о топиках в базе данных, +-имеет Api(Rest), который занимается Crud операциями +__ + +=== schema + +модуль, осуществляющий хранение всех схем, через которые делаются преобразования сообщений, валидация, поднятие сервиса в шине. + +xref:core/schema/Schema.adoc[Более полную информации о schema найдете по этой ссылке] + +__Для разработчиков: +-имеет Api, который занимается Crud операциями +-хранит информацию о загруженных схемах в базе данных, +-(camel)компонент, который используется в маршрутах для валидации xml через xsd, которую загрузили в бд. +-service, который подключается к xslt компоненту для подгрузки xsl из бд +-service, который подключается к cxf компоненту для подгрузки xsd и wsdl из бд +__ + +=== bridge + +модуль, осуществляющий передачу сообщений в другую шину. + +xref:core/bridge/Bridge-Description-and-Configuration.adoc[Более полную информации о bridge найдете по этой ссылке] + +__Для разработчиков: +-знает о всех подключенных шинах и их именах в рамках всей системы +-осуществляет передачу сообщений через artemis, также получает сообщения из другой шины. +-в перспективе будет создан компонент который по названию будет определять в какую шину отправить, а не напрямую через очереди, как это сделано сейчас. +__ + +=== Error Handler + +модуль, осуществляющий за обработку ошибок в шине. + +Централизованный обработчик ошибок для формирования кодов ошибок, их синхронного возврата клиенту и для асинхронного дублирования более подробного описания ошибки (для клиента и для Центральной Базы Интеграции). + +xref:core/exception/Centralized-error-handler.adoc[Более полную информации о централизованном обработчике ошибок найдете по этой ссылке] + +xref:core/exception/Error-description.adoc[Более полную информации о классификации ошибок найдете по этой ссылке] + +__Для разработчиков: +-знает о всех подключенных шинах и их именах в рамках всей системы +-осуществляет передачу сообщений через artemis, также получает сообщения из другой шины. +-в перспективе будет создан компонент, который по названию будет определять в какую шину отправить, а не напрямую через очереди, как это сделано сейчас. +__ + +=== Deployer + +набор модулей осуществляющих работу с бандлами + +xref:core/deployer/deployer-common.adoc[Более полную информации о Deployer найдете по этой ссылке] + +__Для разработчиков: +-deployer-api - интерфейс репозитория для хранения артефактов +-file-system-deployer - реализация репозитория в папке +-nexus-deployer - реализация репозитория в Sonartype Nexus +-cellar-deployer - система управления бандлами через Apache Cellar +__ + +== Также как вспомогательные инструменты используется следующие модули: + +_сellar_ - модуль для загрузки сгенерированных blueprint в шину(в несколько карафов). +_ignite_ - модуль для создания распределенного хранилища ключ-значение.(используется для более быстрой работы некоторых компонентов, которым нужно хранилище) +_liquibase_ - модуль для поддержки актуальной схемы бд. + +== Клиентский слой + +_US_ - универсальный коннектор, через который можно отправлять сообщения в другие системы. +_(делится на обычный и служебный)_ +xref:connectors/uniform-exchange-service/uniform-exchange-service.adoc[Универсальный сервис] + +_file-connector_ - коннектор, который сообщения для определенной системы отправляет с помощью файла(получая сообщение, проводит необходимые преобразования, нпрм архивацию, и складывает в определенную папку). + +_db-connector_ - коннектор, который осуществляет обмен сообщениями с системой через бд. (сообщение полученное из другой системы конвертируется в запись в бд, и для отправки сообщения в шину необходимо сделать запись в бд) + +xref:connectors/create_new_connectors.adoc[Информация о создании новых коннекторов] + +image::connectors/db-connector/deployment_schema.png[] + +_nsi_ - soap коннектор, который был поднят с помощью клиентской wsdl и работает по специальной схеме, определенной клиентом с помощью бд. +_big-packets-connector_ - soap коннектор, через который можно отправлять сообщения в другие системы, предназначенный для отправки больших сообщений, которые отправляются по частям. + +=== Необходимые для шины внешние модули + +nginx(опционально) - балансировщик нагрузки, также занимается предварительной аутентификацией. +nexus(опционально) - необходим для хранения и динамической развертки блюпринтов. +db(поддерживается mssql и postgresql) esb_entaxy - необходима для хранения служебных данных(связанных с настройкой маршрутов в шине). +db(поддерживается mssql и postgresql) cache - необходима для хранения временных данных, связанных с определенным сообщением. +artemis - брокер сообщений. +file-storage(nfs) - необходим для работы сервиса больших пакетов, nginx и тд. + +=== Схема прохождения пакета + +Для разработчиков: + +image::connectors/Message.png[] + +_Все сообщения отправляемые в шину будут отправляться из входного коннектора в выходную точку профиля._ + +Общее описание Entaxy: + +xref:core/Common-description-of-the-transport-layer.adoc[Общее описание Entaxy] \ No newline at end of file diff --git a/documentation/installation/img/services.png b/documentation/installation/img/services.png new file mode 100644 index 00000000..13a6ed78 Binary files /dev/null and b/documentation/installation/img/services.png differ diff --git a/documentation/installation/install.adoc b/documentation/installation/install.adoc new file mode 100644 index 00000000..0795c632 --- /dev/null +++ b/documentation/installation/install.adoc @@ -0,0 +1,626 @@ += Руководство по установке Entaxy +:nofooter: +:toc: left +:toc-title: Содержание +:sectnums: +:icons: font +:title-page: +:revnumber: 1.0 + +<<< + +== Цель руководства + +Данное руководство описывает процесс установки системы Entaxy (далее Система) на сервер или рабочую станцию в демонстрационных целях. + +<<< + +== Требования и замечания + +Для установки Системы требуется: + +- Установленная на сервер или рабочую станцию операционная система LTS: AstraLinux 2.12 (Orel), RHEL (CentOS), Ubuntu с настроенными репозиториями для установки программного обеспечения, входящего в состав поставки ОС +- Созданный в системе пользователь с правами sudo. Под этим пользователем будет производиться установка Системы. Далее по инструкции имя пользователя обозначено как ``. Вместо `` нужно подставить имя пользователя, который будет производить установку. +- Опыт работы с Debian/Ubuntu/AstraLinux системами + +<<< + +== Дистрибутивы программных продуктов + +Вместе с инструкцией поставляются все дистрибутивы, необходимые для установки Системы. Их распространение разрешено лицензиями. + +Дистрибутивы доступны в каталоге `distrib`. Перед установкой Системы нужно скопировать этот каталог на сервер или рабочую станцию, куда будет производиться установка в каталог `/home/`. + +Вся дальнейшая установка Системы будет производиться из файлов, скопированных в `/home//distrib` + +<<< + +== Установка PostgresPro 11 Standard Edition + +Система использует СУБД PostgresPro 11 Standard для хранения конфигураций, справочников и т.д. Указанная СУБД входит в Реестр программных продуктов. + +Для установки PostgresPro 11 Standard Edition необходимо перейти в каталог с дистрибутивом PostgresPro 11 Standard Edition, и установить пакеты в следующей последовательности: + +[source,bash] +---- +cd /home//distrib/postgrespro-std-11 +sudo apt install ./postgrespro-std-11-libs_11.12.1-1.orel_amd64.deb +sudo apt install ./postgrespro-std-11-client_11.12.1-1.orel_amd64.deb +sudo apt install ./postgrespro-std-11-server_11.12.1-1.orel_amd64.deb +sudo apt install ./postgrespro-std-11-contrib_11.12.1-1.orel_amd64.deb +sudo apt install ./postgrespro-std-11_11.12.1-1.orel_amd64.deb +---- + +При установке последнего пакета производится автоматическая инициализация кластера СУБД, поэтому никаких действий по начальной инициализации PostgresPro 11 Standard Edition производить не требуется. + +<<< + +== Подготовка СУБД для работы с Entaxy + +Перед установкой Системы нужно подготовить СУБД для работы с ней. + +Подготовка заключается в создании пользователя СУБД и создании баз данных. + +Для работы с СУБД используется инструмент `psql` с правами администратора. Для запуска инструмента выполнить следующие команды: + +[source,bash] +---- +sudo su - postgres +psql +---- + +После запуска иструмента выполняются следующие действия: + +. Создание пользователя: ++ +[source,sql] +---- +CREATE USER entaxy WITH ENCRYPTED PASSWORD 'entaxy'; +---- ++ +. Создание баз данных ++ +[source,sql] +---- +CREATE DATABASE cache; +CREATE DATABASE storage; +---- ++ +. Назначение прав пользователю `entaxy` на только что созданные базы `cache` и `storage`: ++ +[source,sql] +---- +GRANT ALL ON DATABASE cache TO entaxy; +GRANT ALL ON DATABASE storage TO entaxy; +---- + +После создания пользователя и БД выйти из инструмента `psql` с помощью ввода команды `\q` + +После выхода из инструмента для работы с PostgresPro 11 Standard Edition `psql` требуется выйти из консоли пользователя `postgres`. Для этого выполнить команду: + +[source,bash] +---- +exit +---- + +<<< + +== Установка OpenJDK 11 + +Установка OpenJDK 11 производится в каталог `/opt/openjdk` + +Для установки OpenJDK 11 нужно перейти в каталог `/home//distrib/openjdk`, распаковать дистрибутив OpenJDK 11 в каталог установки и назначить на распакованные файлы права пользователя `root`: + +[source,bash] +---- +cd /home//distrib/openjdk +sudo mkdir -p /opt/openjdk +sudo tar xvf bellsoft-jdk11.0.11+9-linux-amd64.tar.gz -C /opt/openjdk +sudo chown -R root:root /opt/openjdk +sudo chmod 755 /opt/openjdk/jdk-11.0.11 +---- + +<<< + +== Установка и настройка nginx + +Для аутентификации пользователей и маршрутизации запросов в Системе используется `nginx`, работающий как реверсивный прокси. +Перед настройкой конфигурации `nginx` необходимо его установить командой: + +[source,bash] +---- +sudo apt install nginx +---- + +Затем удалить конфигурацию nginx по-умолчанию, скопировать предварительно настроенный файл конфигурации `nginx` из каталога `/home//distrib/nginx/sites-available` в `/etc/nginx/sites-available`, создать символьную ссылку на конфигурацию в каталоге разрешённых конфигураций: + +[source,bash] +---- +sudo rm -rf /etc/nginx/sites-enabled/default +sudo cp /home//distrib/nginx/sites-available/entaxy.conf /etc/nginx/sites-available +sudo ln -s /etc/nginx/sites-available/entaxy.conf /etc/nginx/sites-enabled/entaxy.conf +---- + +После установки новой конфигурации и её разрешения, необходимо перезагрузить конфигурацию `nginx` командой: + +[source,bash] +---- +sudo nginx -t <1> +sudo systemctl reload nginx <2> +---- +<1> - валидация конфигурации nginx (если команда вернёт строку `syntax is ok`, то конфигурация валидна) +<2> - перезагрузка конфигурации nginx + +Затем необходимо создать файл паролей Basic аутентификации `htpasswd` в каталоге `/opt/nginx` + +=== Управление сервисом nginx + +Запуск `nginx` выполняется командой: + +[source,bash] +---- +sudo systemctl start nginx +---- + +Остановка `nginx` выполняется командой: + +[source,bash] +---- +sudo systemctl stop nginx +---- + +Перезапуск `nginx` выполняется командой: + +[source,bash] +---- +sudo systemctl restart nginx +---- + +Перезагрузка конфигурации `nginx` выполняется командой: + +[source,bash] +---- +sudo systemctl reload nginx +---- + +<<< + +== Установка Apache Artemis + +Установка Apache Artemis производится в каталог `/opt/artemis` + +Для установки Apache Artemis необходимо выполнить следующие шаги: + +. Создать пользователя `artemis`, под которым будет работать Artemis. При создании пользователя создаётся домашний каталог пользователя `/opt/artemis`, в котором будет установлен сам Artemis: ++ +[source,bash] +---- +sudo useradd -d /opt/artemis -m -r artemis -s /usr/sbin/nologin +---- ++ +. Распаковать дистрибутив Artemis в домашний каталог Artemis и назначить распакованным файлам права пользователя `artemis`: ++ +[source,bash] +---- +cd /home//distrib/artemis +sudo tar xvf apache-artemis-2.17.0-bin.tar.gz -C /opt/artemis +sudo cp -a /opt/artemis/apache-artemis-2.17.0/. /opt/artemis/ +sudo rm -rf /opt/artemis/apache-artemis-2.17.0 +sudo chown -R artemis:artemis /opt/artemis +---- ++ +. Создать каталог для брокера: ++ +[source,bash] +---- +sudo mkdir -p /opt/artemis/brokers +sudo chown artemis:artemis /opt/artemis/brokers +---- ++ +. Создать брокер: ++ +[source,bash] +---- +sudo su -s /bin/sh -c \ + "export JAVACMD=/opt/openjdk/jdk-11.0.11/bin/java; \ + export ARTEMIS_HOME=/opt/artemis; \ + /opt/artemis/bin/artemis create \ + --name entaxy-broker \ + --user artemis \ + --password artemis \ + --require-login \ + /opt/artemis/brokers/entaxy-broker" \ + artemis +---- ++ +После выполнения команды создаётся новый брокер в каталоге `/opt/artemis/brokers/entaxy-broker` с именем `entaxy-broker`. Имя брокера задаётся в параметре `--name`. +Имя пользователя и пароль для входа в Web консоль брокера задаётся в параметрах `--user` и `--password` соответственно. ++ +. Создать файл сервиса `/etc/systemd/system/entaxy@artemis.service`: ++ +.entaxy-broker@artemis.service +[source,bash] +---- +[Unit] +Description=Artemis ActiveMQ Message Broker +After=syslog.target network.target + +[Service] +Type=forking +ExecStart=/opt/artemis/brokers/entaxy-broker/bin/artemis-service start +ExecStop=/opt/artemis/brokers/entaxy-broker/bin/artemis-service stop + +User=artemis +Group=artemis + +[Install] +WantedBy=multi-user.target +---- ++ +. Отредактировать переменную окружения `JAVA_HOME` для сервиса брокера: ++ +[source,bash] +---- +sudo systemctl edit entaxy@artemis.service +---- ++ +При выполнении предыдущей команды откроется текстовый редактор, в который надо добавить следующее содержимое, после чего сохранить файл: ++ +[source,bash] +---- +[Service] +Environment="JAVA_HOME=/opt/openjdk/jdk-11.0.11" +---- + +После создания файла сервиса и определения переменных окружения, выполнить команду +[source,bash] +---- +sudo systemctl daemon-reload +---- + +Выполнение команды перезагрузит конфигурацию `systemd`, и сервис для запуска Artemis станет доступен + +Включить автозапуск сервиса Artemis при старте системы: + +[source,bash] +---- +sudo systemctl enable entaxy@artemis.service +---- + +Запустить брокер Entaxy + +[source,bash] +---- +sudo systemctl start entaxy@artemis.service +---- + +=== Управление сервисом Apache Artemis + +Запуск сервиса брокера `entaxy` выполняется командой: + +[source,bash] +---- +sudo systemctl start entaxy@artemis.service +---- + +Остановка сервиса брокера `entaxy` выполняется командой: + +[source,bash] +---- +sudo systemctl stop entaxy@artemis.service +---- + +<<< + +== Установка Apache Karaf + +Установка Apache Karaf производится в каталог `/opt/karaf` + +Для установки Apache Karaf необходимо выполнить следующие шаги: + +. Создать пользователя `karaf`, под которым будет работать Karaf. При создании пользователя создаётся домашний каталог пользователя `/opt/karaf`, в котором будет установлен сам Karaf: ++ +[source,bash] +---- +sudo useradd -d /opt/karaf -m -r karaf -s /usr/sbin/nologin +---- ++ +. Распаковать дистрибутив Karaf в домашний каталог, и назначить распакованным файлам права пользователя `karaf`: ++ +[source,bash] +---- +cd /home//distrib/karaf +sudo tar xvf apache-karaf-4.2.9.tar.gz -C /opt/karaf +sudo cp -a /opt/karaf/apache-karaf-4.2.9/. /opt/karaf +sudo rm -rf /opt/karaf/apache-karaf-4.2.9 +sudo cp /home//distrib/karaf/jre.properties /opt/karaf/etc/jre.properties +sudo chown -R karaf:karaf /opt/karaf +---- ++ +. Отредактировать переменную окружения `JAVA_HOME` для Karaf: ++ +[source,bash] +---- +sudo sed -i 's/# export JAVA_HOME/export JAVA_HOME=\/opt\/openjdk\/jdk-11.0.11/g' /opt/karaf/bin/setenv +---- ++ +. Создать файл сервиса `/etc/systemd/system/karaf.service` со следующим содержимым: ++ +.karaf.service +[source,bash] +---- +[Unit] +Description=Entaxy Karaf +After=syslog.target network.target + +[Service] +ExecStart=/opt/karaf/bin/karaf start +ExecStop=/opt/karaf/bin/karaf stop + +User=karaf +Group=karaf + +SuccessExitStatus=0 143 +RestartSec=15 +Restart=on-failure + +LimitNOFILE=102642 + +[Install] +WantedBy=multi-user.target +---- ++ +. После создания файла сервиса и определения переменных окружения, выполнить команду: ++ +[source,bash] +---- +sudo systemctl daemon-reload +---- + +Выполнение команды перезагрузит конфигурацию `systemd`, и сервис для запуска Karaf станет доступен + +Включить автозапуск сервиса Karaf при старте системы: + +[source,bash] +---- +sudo systemctl enable karaf.service +---- + +=== Управление сервисом Apache Karaf + +Запуск сервиса `karaf` выполняется командой: + +[source,bash] +---- +sudo systemctl start karaf.service +---- + +Остановка сервиса `karaf` выполняется командой: + +[source,bash] +---- +sudo systemctl stop karaf.service +---- + +<<< + +== Настройка Apache Karaf + +Скопируйте файлы конфигурации Entaxy из `/home//distrib/entaxy/etc` в каталог `/opt/karaf/etc`. Все файлы предварительно настроены для работы всех компонентов на одной машине: + +[source,bash] +---- +sudo cp -a /home//distrib/entaxy/etc/. /opt/karaf/etc +sudo chown -R karaf:karaf /opt/karaf/etc +---- + +Установочные файлы Системы хранятся в локальном репозитории артефактов. Перед установкой Системы необходимо скопировать локальный репозиторий из каталога `/home//distrib/entaxy/.m2` в `/opt/karaf`: + +[source,bash] +---- +sudo cp /home//distrib/entaxy/.m2/. /opt/karaf/.m2 +sudo chown -R karaf:karaf /opt/karaf/.m2 +---- + +После копирования файлов конфигураций и локального репозитория можно запустить сервис `karaf` + +<<< + +== Подготовка ОС для установки Entaxy + +Система в процессе работы использует файловые ресурсы, в которых хранятся передаваемые файлы, пакеты и т.д. Эти ресурсы перед установкой Системы необходимо создать: + +[source,bash] +---- +sudo mkdir -p /opt/karaf/bundle-repository +sudo mkdir -p /mnt/entaxy/file-connector/message-store +sudo mkdir -p /mnt/entaxy/ignite +sudo mkdir -p /mnt/entaxy/filestore +sudo chown -R karaf:karaf /opt/karaf/bundle-repository +sudo chown -R karaf:karaf /mnt/entaxy +---- + +<<< + +== Установка Entaxy + +=== Проверка работоспособности Apache Karaf + +Установка Entaxy осуществляется из консоли управления Apache Karaf. Чтобы войти в консоль управления Apache Karaf, нужно выполнить в терминале команду: + +[source,bash] +---- +ssh -p 8101 karaf@localhost +---- + +При первом входе в консоль управления необходимо на запрос предоставления доступа ввести слово `yes` и нажать `Enter` +После этого Apache Karaf запросит пароль - в качестве пароля ввести `karaf` + +[source,bash] +---- +Warning: Permanently added '[localhost]:8101' (RSA) to the list of known hosts. +Password authentication +Password: + __ __ ____ + / //_/____ __________ _/ __/ + / ,< / __ `/ ___/ __ `/ /_ + / /| |/ /_/ / / / /_/ / __/ + /_/ |_|\__,_/_/ \__,_/_/ + + Apache Karaf (4.2.9) + +Hit '' for a list of available commands +and '[cmd] --help' for help on a specific command. +Hit 'system:shutdown' to shutdown Karaf. +Hit '' or type 'logout' to disconnect shell from current session. +---- + +Для контроля корректности установки ввести команду `list`: + +[source,bash] +---- +karaf@root()> list +START LEVEL 100 , List Threshold: 50 +ID │ State │ Lvl │ Version │ Name +───┼────────┼─────┼─────────┼──────────────────────────────────────────────── +22 │ Active │ 80 │ 4.2.9 │ Apache Karaf :: OSGi Services :: Event +karaf@root()> +---- + +Если статус компонента `Apache Karaf {two-colons} OSGi Services {two-colons} Event` установлен в состояние `Active`, это значит, что Apache Karaf установлен корректно, и можно переходить к установке Entaxy. + +=== Установка Entaxy + +Установка Entaxy выполняется из консоли управления Apache Karaf. Сначала к списку репозиториев Karaf добавляется репозиторий Entaxy: + +[source,bash] +---- +feature:repo-add mvn:ru.entaxy.esb/karaf-features/1.0-SNAPSHOT/xml/features +---- + +Затем запускается команда установки всех компонентов Entaxy +[source,bash] +---- +feature:install entaxy-all +---- + +После завершения установки Entaxy произойдёт выход из консоли управления Apache Karaf. Это связано с перезапуском встроенного в `Karaf` SSH сервера. Это нормальная ситуация, в процессе установки происходит настройка устанавливаемых компонентов. + +=== Проверка работоспособности Entaxy + +Чтобы проверить корректность установки необходимо вновь зайти в консоль управления Karaf: + +[source,bash] +---- +ssh -p 8101 karaf@localhost +---- + +В консоли управления ввести команду: + +[source,bash] +---- +karaf@root()> list +---- + +Отобразится список установленных компонентов Entaxy, и вспомогательных библиотек. Состояние почти всех компонентов должно быть `Active` + +Среди компонентов, которые могут не находиться в состоянии `Active` можно выделить два: + +- `camel-caffeine-lrucache` может находиться в состоянии `Resolved` +- `INTEGRATION {two-colons} ENTAXY {two-colons} DB EXAMPLE CONNECTOR` будет находиться в состоянии `Failure` + +Компонент `INTEGRATION {two-colons} ENTAXY {two-colons} DB EXAMPLE CONNECTOR` необходимо отключить командой: + +[source,bash] +---- +karaf@root()> bundle:stop +---- + +Например, если идентификатор компонента 97, как показано ниже, + +[source,bash] +---- + 97 │ Failure │ 80 │ 1.0.0.SNAPSHOT │ INTEGRATION :: ENTAXY :: DB EXAMPLE CONNECTOR +---- + +то команда будет выглядеть так: + +[source,bash] +---- +karaf@root()> bundle:stop 97 +---- + +После остановки компонент перейдёт в состояние `Resolved` + +=== Отключение компонента установки Nexus + +В процессе своей работы Entaxy генерирует и запускает новые компоненты, например, при создании новой системы, она будет отображаться в Entaxy как отдельный компонент. В момент генерирования и установки нового компонента, производится помещение этого компонента во внешний репозиторий. Это позволяет автоматически переустановить сгенерированные компоненты при добавлении нового узла в кластер Entaxy. +В Entaxy существует два варианта хранения сгенерированных компонентов: + +- Sonatype Nexus +- Файловая система + +По-умолчанию все генерируемые компоненты помещаются в систему управления репозиториями Sonatype Nexus. Это отдельное ПО, целесообразность установки которого оправдана только в кластерных конфигурациях. В нашем случае установка всей системы выполняется на одну машину. + +Чтобы сгенерированные компоненты устанавливались в файловую систему, требуется отключить компонент установки сгенерированных компонентов в Sonatype Nexus. Отключение компонента выполняется следующим образом: + +. Войти в консоль управления Karaf +. Найти идентфикатор компонента `SYSTEM {two-colons} ENTAXY {two-colons} NEXUS {two-colons} DEPLOYER` +. Остановить его командой: ++ +[source,bash] +---- +karaf@root()> bundle:stop +---- + +<<< + +== Настройка обновления файла аутентификации `htpasswd` + +В Entaxy используется Basic аутентификация для всех запросов, приходящих на балансировщик, функции которого выполняет `nginx`. Аутентификация производится средствами самого `nginx`. + +В качестве базы для хранения пользователей `nginx` использует файл в специальном формате htpasswd. + +Для того, чтобы вновь созданные пользователи в Системе могли аутентифицироваться, необходимо передать информацию о них в файл htpasswd. Для этого используется специальный скрипт, который отрабатывает по расписанию. Сам скрипт нужно предварительно скопировать из каталога `/home//distrib/script/htpasswd-checker.sh` в любой каталог, например, в `/opt/htpasswd-checker`: + +[source,bash] +---- +sudo mkdir -p /opt/htpasswd-checker/log +sudo cp /home//distrib/nginx/htpasswd /etc/nginx +sudo cp /home//distrib/script/htpasswd-checker.sh /opt/htpasswd-checker +sudo chown -R root:root /opt/htpasswd-checker +---- + +Так же требуется проверить адреса серверов кластера, публикующих сервис для работы с файлом htpasswd(сервера с karaf) для ключа KARAF_HOST_NAMES: +[source,bash] +---- +KARAF_HOST_NAMES=("http://192.168.122.93:9091" "http://192.168.122.94:9091") +---- + +Затем создать расписание запуска для `cron`: + +[source,bash] +---- +sudo crontab -e +---- + +В открывшемся редакторе добавить запись: + +[source,bash] +---- +* * * * * /opt/htpasswd-checker/htpasswd-checker.sh +---- + +и сохранить файл. Теперь скрипт будет отрабатывать каждую минуту, подключаться к сервису аутентификации в Apache Karaf, проверять изменение пользовательской информации, и обновлять файл `/etc/nginx/htpasswd` если информация обновилась. + +<<< + +== Проверка работоспособности сервисов + +Чтобы проверить, что сервисы Entaxy работают, можно провести быстрый тест. + +Для этого открыть браузер на машине, где установлена Система, и перейти по адресу `http://localhost:8181/cxf`. Браузер запросит имя пользователя и пароль. Ввести `admin` в качестве имени пользователя, и `admin` в качестве пароля. Логин и пароль уже прописаны в файле `/etc/nginx/htpasswd`. При успешной аутентификации отобразится страница следующего вида: + +image::img/services.png[] + +На этом установку Системы можно считать законченной. \ No newline at end of file diff --git a/documentation/installation/installation-table-of-contents.adoc b/documentation/installation/installation-table-of-contents.adoc new file mode 100644 index 00000000..1e720b64 --- /dev/null +++ b/documentation/installation/installation-table-of-contents.adoc @@ -0,0 +1,10 @@ +__Alternative languages:__ + +* xref:installation-table-of-contents.ru.adoc[Russian] + += Installation +Entaxy have different installation ways OOTB: + +* xref:../../temp/entaxy-docker/ReadMe.md[Development docker installation] +* xref:../../features/README.md[Development standalone installation] +* xref:install.adoc[Enterprise environment installation] diff --git a/documentation/installation/installation-table-of-contents.ru.adoc b/documentation/installation/installation-table-of-contents.ru.adoc new file mode 100644 index 00000000..f17ffca6 --- /dev/null +++ b/documentation/installation/installation-table-of-contents.ru.adoc @@ -0,0 +1,10 @@ +__Alternative languages:__ + +* xref:installation-table-of-contents.adoc[English] + += Установка +Entaxy из коробки имеет разные варианты установки: + +* xref:../../temp/entaxy-docker/ReadMe.md[Установка для разработки в докер] +* xref:../../features/README.ru.md[Установка для разработки отдельных серверных приложений] +* xref:install.adoc[Установка на промышленное окружение] diff --git a/documentation/installation/local-installation/image/pgadmin-create-user.jpg b/documentation/installation/local-installation/image/pgadmin-create-user.jpg new file mode 100644 index 00000000..a859f7b1 Binary files /dev/null and b/documentation/installation/local-installation/image/pgadmin-create-user.jpg differ diff --git a/documentation/installation/local-installation/image/pgadmin-start.jpg b/documentation/installation/local-installation/image/pgadmin-start.jpg new file mode 100644 index 00000000..dce6ec63 Binary files /dev/null and b/documentation/installation/local-installation/image/pgadmin-start.jpg differ diff --git a/documentation/installation/local-installation/image/postgresql-installation-1.jpg b/documentation/installation/local-installation/image/postgresql-installation-1.jpg new file mode 100644 index 00000000..2734c56d Binary files /dev/null and b/documentation/installation/local-installation/image/postgresql-installation-1.jpg differ diff --git a/documentation/installation/local-installation/image/source-download.jpg b/documentation/installation/local-installation/image/source-download.jpg new file mode 100644 index 00000000..88e99d88 Binary files /dev/null and b/documentation/installation/local-installation/image/source-download.jpg differ diff --git a/documentation/installation/local-installation/windows-local-installation.adoc b/documentation/installation/local-installation/windows-local-installation.adoc new file mode 100644 index 00000000..d4fde4cf --- /dev/null +++ b/documentation/installation/local-installation/windows-local-installation.adoc @@ -0,0 +1,5 @@ += Entaxy local installation on workstation or server. + +__Alternative languages:__ + +* xref:windows-local-installation.ru.adoc[Russian] diff --git a/documentation/installation/local-installation/windows-local-installation.ru.adoc b/documentation/installation/local-installation/windows-local-installation.ru.adoc new file mode 100644 index 00000000..adb8b77f --- /dev/null +++ b/documentation/installation/local-installation/windows-local-installation.ru.adoc @@ -0,0 +1,116 @@ += Локальная установка Entaxy на рабочую станцию или сервер. + +__Alternative languages:__ + +* xref:windows-local-installation.adoc[English] + +== Введение. + +В этой инструкции мы рассмотрим установку Entaxy, включая брокер и бд, на одной машине с операционной системой Windows. Установка на другие ОС проходит аналогичным образом и отличается выбором соответствующих инсталяторов или использованием пакетных менеджеров. + +== Шаг 1: Установка Java. + +Скачиваем и устанавливаем JAVA. Для работы Entaxy рекомендуется Java 11. Работа платформы протестирована на OpenJDK и LibericaJDK от BellSoft (https://libericajdk.ru/pages/downloads/). + +== Шаг 2: Установка и настройка Maven. + +1. Скачиваем архив с официального сайта (https://maven.apache.org/download.cgi). +2. Распаковываем архив и переходи в директорию bin. +3. Копируем абсолютный путь к директории bin и добавляем его в системную переменную окружения PATH. + +== Шаг 3: Получение исходных кодов и сборка проекта. + +1. Для получения исходных кодов платформы переходим по адресу https://git.emdev.ru/entaxy-public/entaxy-public и нажимаем иконку `скачать`. image:image/source-download.jpg[source-download] +2. Распаковываем архив и переходим в корневую директорию проекта `entaxy-public`. +3. Собираем проект командой `mvn install`. + +== Шаг 4: Установка и настройка БД. + +Entaxy не привязана к какой-либо конкретной СУБД, но в большинстве случаев используется PostgreSQL. + +1. Скачиваем инсталятор с официального сайта (https://www.enterprisedb.com/downloads/postgres-postgresql-downloads). +2. Запускаем установку. image:image/postgresql-installation-1.jpg[postgresql-installation] +3. Оставляем все настройки по умолчанию и устанавливаем пароль `postgres`. +4. Запускаем pgAdmin 4 и устанавливаем мастер пароль для приложения `postgres`. image:image/pgadmin-start.jpg[pgadmin-start] +5. Добавляем подключение к локальному серверу БД. +6. Выбираем доступную базу данных из списка и переходим в Query Tool, в котором выполняем sql запрос: + +[source,sql] +---- +CREATE USER "entaxy" WITH PASSWORD 'entaxy'; +---- +image:image/pgadmin-create-user.jpg[pgadmin-create-user] +[start=7] +. Теперь в том же окне по очереди (по одной строчке) выполняем запросы для создания необходимых для Entaxy баз данных. + +[source,sql] +---- +CREATE DATABASE esb_entaxy; +---- + +[source,sql] +---- +GRANT ALL PRIVILEGES ON DATABASE esb_entaxy TO entaxy; +---- + +[source,sql] +---- +CREATE DATABASE cache; +---- + +[source,sql] +---- +GRANT ALL PRIVILEGES ON DATABASE cache TO entaxy; +---- + +На этом настройка СУБД завершена. + +== Шаг 5: Установка и настройка брокера. + +В этой инструкции мы рассмотрим использование брокера сообщений Artemis. + +1. Скачиваем архив с официального сайта (https://activemq.apache.org/components/artemis/download/). +2. Распаковываем архив и переходим в директорию bin. +3. Запускаем в командной строке создание брокера `artemis create --user entaxy --password entaxy --allow-anonymous $ARTEMIS_HOME/brokers/entaxy-broker`. +4. После создания брокера надо открыть файл `$ARTEMIS_HOME/brokers/entaxy-broker/etc/broker.xml` и проверить, что автоматическое удаление очередей и адресов отключено: + +[source,xml] +---- + + + + false + false + + +---- +5. Запускаем брокер сообщений `$ARTEMIS_HOME/brokers/entaxy-broker/bin/artemis run` + +Установка брокера завершена. + +== Шаг 6: Установка и запуск карафа. + +1. Скачать Karaf Runtime 4.2.9 (Binary Distribution : ZIP) с официального сайта (https://archive.apache.org/dist/karaf/4.2.9/apache-karaf-4.2.9.zip). +2. Распаковываем архив и переходим в директорию `etc`. +3. Копируем в директорию `etc` карафа все файлы исходных кодов из директории `entaxy-public\features\target\cfg` и ещё один файл `entaxy-public\features\target\script\install.karaf`. +4. Переходим в директорию `bin` карафа и запускаем командой `karaf` +После запуска откроется консоль карафа. + +== Шаг 7: Установка Entaxy в караф. + +В командной строке карафа выполнить команду +[source,bash] +---- +shell:source etc/install.karaf +---- +Если времени на установку не хватило, то нужно повторить последнюю команду или выполнить команды установки построчно. Для отображения списка команд достаточно в консоли карафа выполнить команду +[source,bash] +---- +cat etc/install.karaf +---- + +После успешной установки, выполняем команду `list`, чтобы убедиться, что все модули находятся в состоянии `Active`. + +== Шаг 8: Тестирование. + +Для проверки работоспособности платформы переходим к xref:../../connectors/uniform-exchange-service/tests/postman.adoc[инструкции по тестированию]. \ No newline at end of file diff --git a/features/LICENSE.txt b/features/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/features/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/features/README.md b/features/README.md new file mode 100644 index 00000000..f59bfcb8 --- /dev/null +++ b/features/README.md @@ -0,0 +1,152 @@ +# Entaxy features install + +### Alternative languages + +[Russian](README.ru.md) + +### Introduction + +You need several steps for Entaxy features installation. +Use Java 11+. + +### Build +You will need to compile this example first: + + mvn install + +### Run + +To run the example on Apache Karaf 4.x or newer + +#### Step 1: Karaf + +Launch the server + + karaf / karaf.bat + + +#### Step 2: DB Setup + +If use docker: + + docker run --name entaxy_db -p 5432:5432 -e POSTGRES_PASSWORD=entaxy -e POSTGRES_USER=entaxy -e POSTGRES_DB=cache -d postgres + +#### Step 3: Add features + +Add features required + + feature:repo-add mvn:ru.entaxy.esb/karaf-features/LATEST/xml/features + feature:install liquibase-updater + feature:install entaxy-esb-api + +Install nsi + + feature:install nsi + +Install permission + + feature:install permission + +Install system-registry + + feature:install system-registry + +Install system-group-registry + + feature:install system-group-registry + +Install system-group-profile + + install -s blueprint:mvn:ru.entaxy.esb.integration.esb.test.profiles/test-profiles/1.0-SNAPSHOT/xml/g_test + +Install bridge + + feature:install bridge + +Install basic-auth + + feature:install basic-auth + +Install events + + feature:install events + +Useful comand for dev + + bundle:watch mvn:ru.entaxy.esb/nsi-esb/1.0-SNAPSHOT + +#### Step 4: Verify that your service is available using the following url in the browser. + +We assume you're using Karaf's default PAX Web configuration which uses port `8181` for http. If you would like to use another port or https, change the configuration in `${KARAF_HOME}/etc/org.ops4j.pax.web.cfg`. The immediate extension after the hostname and port ("cxf" in the below URL) is configured via the org.apache.cxf.osgi.cfg file (Please see [http://team.ops4j.org/wiki//display/paxweb/Pax+Web](http://team.ops4j.org/wiki//display/paxweb/Pax+Web) for more information on PAX Web). + +[http://localhost:8181/cxf/xdto/NSI?wsdl](http://localhost:8181/cxf/xdto/NSI?wsdl) + +#### Step 5: Start SOAPUI or Postman + +POST request to + + http://localhost:8181/cxf/xdto/NSI + +Send test request: + + + + + + + + +Response contains GUID, copy it and send request for get result: + + + + + + {GUID} + + + + +#### Step 6: Check the file system and DB + Check the folder "target/inbox/" in the Karaf base directory to see that a message has arrived. + +### Forum, Help, etc + +If you hit an problems please let us know on the Camel Forums + + +Please help us make Apache Camel better - we appreciate any feedback you may +have. Enjoy! + + +The Camel riders! + + + +## Reinstall + bin/karaf clean + shell:source install.karaf + + +## Tests + + + +#### Install + + npm install -g newman + +#### Run + + cd test + newman run "Entaxy Integration Tests.postman_collection.json" -e "entaxy dev proxy.postman_environment.json" + +or + + newman run "Entaxy Integration Tests.postman_collection.json" --env-var base_url=http://192.168.122.83:8181/cxf + +#### CXF logging messages + + config:property-set -p org.apache.cxf.features.logging enabled true + +and after restart bundle with cxf service diff --git a/features/README.ru.md b/features/README.ru.md new file mode 100644 index 00000000..0491d6de --- /dev/null +++ b/features/README.ru.md @@ -0,0 +1,181 @@ +# Установка фич (features) + +### Languages + +[English](README.md) + +### Введение + +Для установки фич понадобятся несколько шагов. + +Использовать Java 8 + +### Шаг 1: Сборка проекта + +Необходимо локально собрать корневой проект: + + mvn install + +#### Шаг 2: Настройка брокера, БД и менеджера артефактов. + +При использовании докера запустите Артемис + + sudo docker run --rm -p 8161:8161 -p 61616:61616 -e ARTEMIS_USERNAME=entaxy -e ARTEMIS_PASSWORD=entaxy --name=artemis1 -d vromero/activemq-artemis + +И запустите постгрес + + sudo docker run --name entaxy_db -p 5432:5432 -v /etc/timezone:/etc/timezone:ro -e POSTGRES_PASSWORD=entaxy -e POSTGRES_USER=entaxy -e POSTGRES_DB=cache -d postgres + +или Майкрософт Сиквел + + sudo docker run --name mssql -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=entaxy' -p 1433:1433 -d mcr.microsoft.com/mssql/server:2017-CU8-ubuntu + +`По умолчанию в проекте используется 2 базы данных: cache и esb_entaxy,` +`Названия баз данных прописаны в конфигурациях соединений с бд org.ops4j.datasource-entaxy.esb.*.cfg` + +и осталось поднять nexus(необходимо для работы system-management) + + sudo docker run -d -p 8081:8081 --name nexus sonatype/nexus3 + +Теперь смотрим админский пароль через команду: + + docker exec nexus cat /nexus-data/admin.password +И далее заходим в админку через браузер на http://localhost:8081/. +По умолчанию для работы требуется создать пользователя entaxy/entaxy и maven репозиторий с названием entaxy. + +На Docker Toolbox могут возникнуть ошибки из-за нехватки памяти, решается изменением выделения памяти при запуске` + + docker run -d -p 8081:8081 --name nexus -e INSTALL4J_ADD_VM_PARAMS="-Xms2g -Xmx2g -XX:MaxDirectMemorySize=3g" sonatype/nexus3 + +#### Шаг 3: Подготовка и запуск карафа + +Скопировать в карафовский etc следующие файлы из репозитория entaxy-framework\features\src\main\cfg\ + + jre.properties + org.apache.karaf.cellar.groups.cfg + + + +Так же локальный нексус репозиторий необходимо добавить к стандартным репозиториям в файле org.ops4j.pax.url.mvn.cfg свойство org.ops4j.pax.url.mvn.repositories.` +`Пользователь и название репозитория прописано в конфигурационном файле ru.entaxy.esb.deployer.nexus.cfg.` + + +Запуск Apache Karaf 4.x или новее + + karaf + +Или запуск карафа с очисткой до первоначального состояния + + karaf clean + +## Шаг 4: Установка всех фич за один раз, используя командную строку карафа + + shell:source /entaxy-framework/features/src/main/script/install.karaf + +- После требуется проверить конфигурации соединений с бд в файлах org.ops4j.datasource-entaxy.esb.*.cfg +- Проверить адрес брокера в файле ru.entaxy.esb.cfg свойство ru.entaxy.esb.jms.url +- Проверить адреса брокеров для моста в файле ru.entaxy.esb.system.bridge.cfg свойства jms.url.* +- Заменить файл org.apache.karaf.cellar.groups.cfg + +#### Шаг 4a: Или можно установить фичи вручную + +Добавить необходимые фичи + + feature:repo-add mvn:ru.entaxy.esb/karaf-features/LATEST/xml/features + feature:install liquibase-updater + feature:install entaxy-esb-api + +Установить nsi + + feature:install nsi + +Установить permission + + feature:install permission + +Установить реестр систем + + feature:install system-registry + +Установить тестовый профиль + + install -s blueprint:mvn:ru.entaxy.esb.integration.esb.test.profiles/test-profiles/1.0-SNAPSHOT/xml/s_s1 + +Установить реестр групп систем + + feature:install system-group-registry + +Установить профиль группы систем + + install -s blueprint:mvn:ru.entaxy.esb.integration.esb.test.profiles/test-profiles/1.0-SNAPSHOT/xml/g_fzd + +Установить мост + + feature:install bridge + +Установить сервис управления учётными записями + + feature:install basic-auth + +Установить events + + feature:install events + +Для дев окружения может быть полезна команда watch + + bundle:watch mvn:ru.entaxy.esb/nsi-esb/1.0-SNAPSHOT + +#### Шаг 5: Проверка доступности сервиса через браузер, используя следующий адрес. + +Подразумевается использование настроек по умолчанию для карафовского PAX Web, который для http настроен на порт `8181`. Если Вы желаете использовать другой порт или https, то необходимо поменять настройки в `${KARAF_HOME}/etc/org.ops4j.pax.web.cfg`. Непосредственное продолжение адреса после имени хоста и номера порта (в примере ниже `cxf`) можно настроить в файле `org.apache.cxf.osgi.cfg`. (Для более подробной информации по PAX Web перейдите по ссылке [http://team.ops4j.org/wiki/display/paxweb/Pax+Web](http://team.ops4j.org/wiki/display/paxweb/Pax+Web)) + +#### Шаг 6: Запуск SOAPUI или Postman + +Отправка POST запроса на адрес + + http://localhost:8181/cxf/xdto/NSI + +Тестовый запрос: + + + + + + + + +Ответ сожержит GUID, скопируйте его и отправьте для получения результата: + + + + + + {GUID} + + + + +## Автотесты + + + +#### Установка + + npm install -g newman + +#### Запуск + + cd test + newman run "Entaxy Integration Tests.postman_collection.json" -e "entaxy dev proxy.postman_environment.json" + +#### Запуск нагрузочных тестов через Jmeter + +В тестах прописана система s1, запросы направляются на 83 ноду + +* 1C-EXCHANGE_SEND_GET_ASK.jmx - запись и чтение с подтверждением последовательно +* 1C-EXCHANGE_SEND_GET_ASK_ASYNC.jmx - запись и чтение с подтверждением в параллельных потоках + +Можно запускать с машины 192.168.122.76 + + cd /opt/jenkins/.jenkins/workspace/test_master/test/jmeter + /opt/apache-jmeter-5.2.1/bin/jmeter.sh -n -t ./1C-EXCHANGE_SEND_GET_ASK_ASYNC.jmx diff --git a/features/pom.xml b/features/pom.xml new file mode 100644 index 00000000..065d9e01 --- /dev/null +++ b/features/pom.xml @@ -0,0 +1,196 @@ + + + 4.0.0 + + ru.entaxy.esb + root + 1.8.0 + + + karaf-features + SYSTEM :: ENTAXY :: Features + pom + + + + cfg.dev + + cfg + + + + + src/main/${environmentConfigurationDirectory} + true + ${project.build.directory}/cfg + + + + + + !skipDevConfig + + + + + cfg.local + + cfg.local + + + + + + + + src/main/feature + true + ${project.build.directory}/feature + + + src/main/script + true + ${project.build.directory}/script + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + + resources + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.12 + + + attach-artifacts + package + + attach-artifact + + + + + target/feature/feature.xml + xml + features + + + target/cfg/ru.entaxy.esb.cfg + cfg + ru.entaxy.esb + + + target/cfg/ru.entaxy.esb.connector.1c.service.soap.passive.cfg + cfg + ru.entaxy.esb.connector.1c.service.soap.passive + + + target/cfg/ru.entaxy.esb.connector.1c.soap.passive.cfg + cfg + ru.entaxy.esb.connector.1c.soap.passive + + + target/cfg/ru.entaxy.esb.connector.1c.support.cfg + cfg + ru.entaxy.esb.connector.1c.support + + + target/cfg/ru.entaxy.esb.system.basic_auth.cfg + cfg + ru.entaxy.esb.system.basic_auth + + + target/cfg/ru.entaxy.esb.system.basic_auth.htpasswd.cfg + cfg + ru.entaxy.esb.system.basic_auth.htpasswd + + + target/cfg/ru.entaxy.esb.system.event.rest.cfg + cfg + ru.entaxy.esb.system.event.rest + + + target/cfg/ru.entaxy.esb.system.event.handler.cfg + cfg + ru.entaxy.esb.system.event.handler + + + target/cfg/org.ops4j.datasource-entaxy.esb.cache.cfg + cfg + datasource-cache + + + target/cfg/org.ops4j.datasource-entaxy.esb.storage.cfg + cfg + datasource-storage + + + target/cfg/ru.entaxy.esb.deployer.nexus.cfg + cfg + ru.entaxy.esb.deployer.nexus + + + target/cfg/ru.entaxy.esb.deployer.cellar.cfg + cfg + ru.entaxy.esb.deployer.cellar + + + target/script/install.karaf + script + install + + + target/cfg/ru.entaxy.esb.error.cfg + cfg + ru.entaxy.esb.error + + + target/cfg/ru.entaxy.esb.error.code.cfg + cfg + ru.entaxy.esb.error.code + + + target/cfg/ru.entaxy.esb.error.text.cfg + cfg + ru.entaxy.esb.error.text + + + target/cfg/ru.entaxy.esb.deployer.file.system.cfg + cfg + ru.entaxy.esb.deployer.file.system + + + target/cfg/ru.entaxy.esb.system.schema.cfg + cfg + ru.entaxy.esb.system.schema + + + target/cfg/ru.entaxy.esb.system.management.cfg + cfg + ru.entaxy.esb.system.management + + + target/cfg/jre.properties + properties + jre + + + + + + + + + + diff --git a/features/src/main/cfg/jre.properties b/features/src/main/cfg/jre.properties new file mode 100644 index 00000000..2368ab44 --- /dev/null +++ b/features/src/main/cfg/jre.properties @@ -0,0 +1,726 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# +# Java platform package export properties. +# +# Standard package set. Note that: +# - javax.transaction* is exported with a mandatory attribute +jre-1.6=\ + javax.accessibility, \ + javax.activation;version="1.1", \ + javax.activity, \ + javax.annotation;version="1.0", \ + javax.annotation.processing;version="1.0", \ + javax.crypto, \ + javax.crypto.interfaces, \ + javax.crypto.spec, \ + javax.imageio, \ + javax.imageio.event, \ + javax.imageio.metadata, \ + javax.imageio.plugins.bmp, \ + javax.imageio.plugins.jpeg, \ + javax.imageio.spi, \ + javax.imageio.stream, \ + javax.jws, \ + javax.jws.soap, \ + javax.lang.model, \ + javax.lang.model.element, \ + javax.lang.model.type, \ + javax.lang.model.util, \ + javax.management, \ + javax.management.loading, \ + javax.management.modelmbean, \ + javax.management.monitor, \ + javax.management.openmbean, \ + javax.management.relation, \ + javax.management.remote, \ + javax.management.remote.rmi, \ + javax.management.timer, \ + javax.naming, \ + javax.naming.directory, \ + javax.naming.event, \ + javax.naming.ldap, \ + javax.naming.spi, \ + javax.net, \ + javax.net.ssl, \ + javax.print, \ + javax.print.attribute, \ + javax.print.attribute.standard, \ + javax.print.event, \ + javax.rmi, \ + javax.rmi.CORBA, \ + javax.rmi.ssl, \ + javax.script, \ + javax.security.auth, \ + javax.security.auth.callback, \ + javax.security.auth.kerberos, \ + javax.security.auth.login, \ + javax.security.auth.spi, \ + javax.security.auth.x500, \ + javax.security.cert, \ + javax.security.sasl, \ + javax.sound.midi, \ + javax.sound.midi.spi, \ + javax.sound.sampled, \ + javax.sound.sampled.spi, \ + javax.sql, \ + javax.sql.rowset, \ + javax.sql.rowset.serial, \ + javax.sql.rowset.spi, \ + javax.swing, \ + javax.swing.border, \ + javax.swing.colorchooser, \ + javax.swing.event, \ + javax.swing.filechooser, \ + javax.swing.plaf, \ + javax.swing.plaf.basic, \ + javax.swing.plaf.metal, \ + javax.swing.plaf.multi, \ + javax.swing.plaf.synth, \ + javax.swing.table, \ + javax.swing.text, \ + javax.swing.text.html, \ + javax.swing.text.html.parser, \ + javax.swing.text.rtf, \ + javax.swing.tree, \ + javax.swing.undo, \ + javax.tools, \ + javax.transaction; javax.transaction.xa; partial=true; mandatory:=partial, \ + javax.xml, \ + javax.xml.bind;version="2.2.1", \ + javax.xml.bind.annotation;version="2.2.1", \ + javax.xml.bind.annotation.adapters;version="2.2.1", \ + javax.xml.bind.attachment;version="2.2.1", \ + javax.xml.bind.helpers;version="2.2.1", \ + javax.xml.bind.util;version="2.2.1", \ + javax.xml.crypto, \ + javax.xml.crypto.dom, \ + javax.xml.crypto.dsig, \ + javax.xml.crypto.dsig.dom, \ + javax.xml.crypto.dsig.keyinfo, \ + javax.xml.crypto.dsig.spec, \ + javax.xml.datatype, \ + javax.xml.namespace, \ + javax.xml.parsers, \ + javax.xml.soap;version="1.3", \ + javax.xml.stream;version="1.2", \ + javax.xml.stream.events;version="1.2", \ + javax.xml.stream.util;version="1.2", \ + javax.xml.transform, \ + javax.xml.transform.dom, \ + javax.xml.transform.sax, \ + javax.xml.transform.stax, \ + javax.xml.transform.stream, \ + javax.xml.validation, \ + javax.xml.ws;version="2.2", \ + javax.xml.ws.handler;version="2.2", \ + javax.xml.ws.handler.soap;version="2.2", \ + javax.xml.ws.http;version="2.2", \ + javax.xml.ws.soap;version="2.2", \ + javax.xml.ws.spi;version="2.2", \ + javax.xml.ws.wsaddressing;version="2.2", \ + javax.xml.ws.spi.http;version="2.2", \ + javax.xml.xpath, \ + org.ietf.jgss, \ + org.omg.CORBA, \ + org.omg.CORBA_2_3, \ + org.omg.CORBA_2_3.portable, \ + org.omg.CORBA.DynAnyPackage, \ + org.omg.CORBA.ORBPackage, \ + org.omg.CORBA.portable, \ + org.omg.CORBA.TypeCodePackage, \ + org.omg.CosNaming, \ + org.omg.CosNaming.NamingContextExtPackage, \ + org.omg.CosNaming.NamingContextPackage, \ + org.omg.Dynamic, \ + org.omg.DynamicAny, \ + org.omg.DynamicAny.DynAnyFactoryPackage, \ + org.omg.DynamicAny.DynAnyPackage, \ + org.omg.IOP, \ + org.omg.IOP.CodecFactoryPackage, \ + org.omg.IOP.CodecPackage, \ + org.omg.Messaging, \ + org.omg.PortableInterceptor, \ + org.omg.PortableInterceptor.ORBInitInfoPackage, \ + org.omg.PortableServer, \ + org.omg.PortableServer.CurrentPackage, \ + org.omg.PortableServer.POAManagerPackage, \ + org.omg.PortableServer.POAPackage, \ + org.omg.PortableServer.portable, \ + org.omg.PortableServer.ServantLocatorPackage, \ + org.omg.SendingContext, \ + org.omg.stub.java.rmi, \ + org.omg.stub.javax.management.remote.rmi, \ + org.w3c.dom, \ + org.w3c.dom.bootstrap, \ + org.w3c.dom.css, \ + org.w3c.dom.events, \ + org.w3c.dom.html, \ + org.w3c.dom.ls, \ + org.w3c.dom.ranges, \ + org.w3c.dom.stylesheets, \ + org.w3c.dom.traversal, \ + org.w3c.dom.views, \ + org.w3c.dom.xpath, \ + org.xml.sax, \ + org.xml.sax.ext, \ + org.xml.sax.helpers +# Standard package set. Note that: +# - javax.transaction* is exported with a mandatory attribute +jre-1.7=\ + javax.accessibility, \ + javax.activation;version="1.1", \ + javax.activity, \ + javax.annotation;version="1.0", \ + javax.annotation.processing;version="1.0", \ + javax.crypto, \ + javax.crypto.interfaces, \ + javax.crypto.spec, \ + javax.imageio, \ + javax.imageio.event, \ + javax.imageio.metadata, \ + javax.imageio.plugins.bmp, \ + javax.imageio.plugins.jpeg, \ + javax.imageio.spi, \ + javax.imageio.stream, \ + javax.jws, \ + javax.jws.soap, \ + javax.lang.model, \ + javax.lang.model.element, \ + javax.lang.model.type, \ + javax.lang.model.util, \ + javax.management, \ + javax.management.loading, \ + javax.management.modelmbean, \ + javax.management.monitor, \ + javax.management.openmbean, \ + javax.management.relation, \ + javax.management.remote, \ + javax.management.remote.rmi, \ + javax.management.timer, \ + javax.naming, \ + javax.naming.directory, \ + javax.naming.event, \ + javax.naming.ldap, \ + javax.naming.spi, \ + javax.net, \ + javax.net.ssl, \ + javax.print, \ + javax.print.attribute, \ + javax.print.attribute.standard, \ + javax.print.event, \ + javax.rmi, \ + javax.rmi.CORBA, \ + javax.rmi.ssl, \ + javax.script, \ + javax.security.auth, \ + javax.security.auth.callback, \ + javax.security.auth.kerberos, \ + javax.security.auth.login, \ + javax.security.auth.spi, \ + javax.security.auth.x500, \ + javax.security.cert, \ + javax.security.sasl, \ + javax.sound.midi, \ + javax.sound.midi.spi, \ + javax.sound.sampled, \ + javax.sound.sampled.spi, \ + javax.sql, \ + javax.sql.rowset, \ + javax.sql.rowset.serial, \ + javax.sql.rowset.spi, \ + javax.swing, \ + javax.swing.border, \ + javax.swing.colorchooser, \ + javax.swing.event, \ + javax.swing.filechooser, \ + javax.swing.plaf, \ + javax.swing.plaf.basic, \ + javax.swing.plaf.metal, \ + javax.swing.plaf.multi, \ + javax.swing.plaf.synth, \ + javax.swing.table, \ + javax.swing.text, \ + javax.swing.text.html, \ + javax.swing.text.html.parser, \ + javax.swing.text.rtf, \ + javax.swing.tree, \ + javax.swing.undo, \ + javax.tools, \ + javax.transaction; javax.transaction.xa; partial=true; mandatory:=partial, \ + javax.xml, \ + javax.xml.bind;version="2.2.1", \ + javax.xml.bind.annotation;version="2.2.1", \ + javax.xml.bind.annotation.adapters;version="2.2.1", \ + javax.xml.bind.attachment;version="2.2.1", \ + javax.xml.bind.helpers;version="2.2.1", \ + javax.xml.bind.util;version="2.2.1", \ + javax.xml.crypto, \ + javax.xml.crypto.dom, \ + javax.xml.crypto.dsig, \ + javax.xml.crypto.dsig.dom, \ + javax.xml.crypto.dsig.keyinfo, \ + javax.xml.crypto.dsig.spec, \ + javax.xml.datatype, \ + javax.xml.namespace, \ + javax.xml.parsers, \ + javax.xml.soap;version="1.3", \ + javax.xml.stream;version="1.2", \ + javax.xml.stream.events;version="1.2", \ + javax.xml.stream.util;version="1.2", \ + javax.xml.transform, \ + javax.xml.transform.dom, \ + javax.xml.transform.sax, \ + javax.xml.transform.stax, \ + javax.xml.transform.stream, \ + javax.xml.validation, \ + javax.xml.xpath, \ + org.ietf.jgss, \ + org.omg.CORBA, \ + org.omg.CORBA_2_3, \ + org.omg.CORBA_2_3.portable, \ + org.omg.CORBA.DynAnyPackage, \ + org.omg.CORBA.ORBPackage, \ + org.omg.CORBA.portable, \ + org.omg.CORBA.TypeCodePackage, \ + org.omg.CosNaming, \ + org.omg.CosNaming.NamingContextExtPackage, \ + org.omg.CosNaming.NamingContextPackage, \ + org.omg.Dynamic, \ + org.omg.DynamicAny, \ + org.omg.DynamicAny.DynAnyFactoryPackage, \ + org.omg.DynamicAny.DynAnyPackage, \ + org.omg.IOP, \ + org.omg.IOP.CodecFactoryPackage, \ + org.omg.IOP.CodecPackage, \ + org.omg.Messaging, \ + org.omg.PortableInterceptor, \ + org.omg.PortableInterceptor.ORBInitInfoPackage, \ + org.omg.PortableServer, \ + org.omg.PortableServer.CurrentPackage, \ + org.omg.PortableServer.POAManagerPackage, \ + org.omg.PortableServer.POAPackage, \ + org.omg.PortableServer.portable, \ + org.omg.PortableServer.ServantLocatorPackage, \ + org.omg.SendingContext, \ + org.omg.stub.java.rmi, \ + org.omg.stub.javax.management.remote.rmi, \ + org.w3c.dom, \ + org.w3c.dom.bootstrap, \ + org.w3c.dom.css, \ + org.w3c.dom.events, \ + org.w3c.dom.html, \ + org.w3c.dom.ls, \ + org.w3c.dom.ranges, \ + org.w3c.dom.stylesheets, \ + org.w3c.dom.traversal, \ + org.w3c.dom.views, \ + org.w3c.dom.xpath, \ + org.xml.sax, \ + org.xml.sax.ext, \ + org.xml.sax.helpers, \ + com.sun.nio.sctp +jre-1.8=\ + javax.accessibility, \ + javax.activity, \ + javax.annotation;version="1.0", \ + javax.annotation.processing;version="1.0", \ + javax.crypto, \ + javax.crypto.interfaces, \ + javax.crypto.spec, \ + javax.imageio, \ + javax.imageio.event, \ + javax.imageio.metadata, \ + javax.imageio.plugins.bmp, \ + javax.imageio.plugins.jpeg, \ + javax.imageio.spi, \ + javax.imageio.stream, \ + javax.jws, \ + javax.jws.soap, \ + javax.lang.model, \ + javax.lang.model.element, \ + javax.lang.model.type, \ + javax.lang.model.util, \ + javax.management, \ + javax.management.loading, \ + javax.management.modelmbean, \ + javax.management.monitor, \ + javax.management.openmbean, \ + javax.management.relation, \ + javax.management.remote, \ + javax.management.remote.rmi, \ + javax.management.timer, \ + javax.naming, \ + javax.naming.directory, \ + javax.naming.event, \ + javax.naming.ldap, \ + javax.naming.spi, \ + javax.net, \ + javax.net.ssl, \ + javax.print, \ + javax.print.attribute, \ + javax.print.attribute.standard, \ + javax.print.event, \ + javax.rmi, \ + javax.rmi.CORBA, \ + javax.rmi.ssl, \ + javax.script, \ + javax.security.auth, \ + javax.security.auth.callback, \ + javax.security.auth.kerberos, \ + javax.security.auth.login, \ + javax.security.auth.spi, \ + javax.security.auth.x500, \ + javax.security.cert, \ + javax.security.sasl, \ + javax.sound.midi, \ + javax.sound.midi.spi, \ + javax.sound.sampled, \ + javax.sound.sampled.spi, \ + javax.sql, \ + javax.sql.rowset, \ + javax.sql.rowset.serial, \ + javax.sql.rowset.spi, \ + javax.swing, \ + javax.swing.border, \ + javax.swing.colorchooser, \ + javax.swing.event, \ + javax.swing.filechooser, \ + javax.swing.plaf, \ + javax.swing.plaf.basic, \ + javax.swing.plaf.metal, \ + javax.swing.plaf.multi, \ + javax.swing.plaf.synth, \ + javax.swing.table, \ + javax.swing.text, \ + javax.swing.text.html, \ + javax.swing.text.html.parser, \ + javax.swing.text.rtf, \ + javax.swing.tree, \ + javax.swing.undo, \ + javax.tools, \ + javax.transaction; javax.transaction.xa; partial=true; mandatory:=partial, \ + javax.xml, \ + javax.xml.bind;version="2.2.8", \ + javax.xml.bind.annotation;version="2.2.8", \ + javax.xml.bind.annotation.adapters;version="2.2.8", \ + javax.xml.bind.attachment;version="2.2.8", \ + javax.xml.bind.helpers;version="2.2.8", \ + javax.xml.bind.util;version="2.2.8", \ + javax.xml.crypto, \ + javax.xml.crypto.dom, \ + javax.xml.crypto.dsig, \ + javax.xml.crypto.dsig.dom, \ + javax.xml.crypto.dsig.keyinfo, \ + javax.xml.crypto.dsig.spec, \ + javax.xml.datatype, \ + javax.xml.namespace, \ + javax.xml.parsers, \ + javax.xml.stream;version="1.2", \ + javax.xml.stream.events;version="1.2", \ + javax.xml.stream.util;version="1.2", \ + javax.xml.transform, \ + javax.xml.transform.dom, \ + javax.xml.transform.sax, \ + javax.xml.transform.stax, \ + javax.xml.transform.stream, \ + javax.xml.validation, \ + javax.xml.ws;version="2.2", \ + javax.xml.ws.handler;version="2.2", \ + javax.xml.ws.handler.soap;version="2.2", \ + javax.xml.ws.http;version="2.2", \ + javax.xml.ws.soap;version="2.2", \ + javax.xml.ws.spi;version="2.2", \ + javax.xml.ws.wsaddressing;version="2.2", \ + javax.xml.ws.spi.http;version="2.2", \ + javax.xml.xpath, \ + javafx.animation, \ + javafx.application, \ + javafx.beans, \ + javafx.beans.binding, \ + javafx.beans.property, \ + javafx.beans.property.adapter, \ + javafx.beans.value, \ + javafx.collections, \ + javafx.collections.transform, \ + javafx.concurrent, \ + javafx.css, \ + javafx.embed.swing, \ + javafx.embed.swt, \ + javafx.event, \ + javafx.fxml, \ + javafx.geometry, \ + javafx.print, \ + javafx.scene, \ + javafx.scene.canvas, \ + javafx.scene.chart, \ + javafx.scene.control, \ + javafx.scene.control.cell, \ + javafx.scene.effect, \ + javafx.scene.image, \ + javafx.scene.input, \ + javafx.scene.layout, \ + javafx.scene.media, \ + javafx.scene.paint, \ + javafx.scene.shape, \ + javafx.scene.text, \ + javafx.scene.transform, \ + javafx.scene.web, \ + javafx.stage, \ + javafx.util, \ + javafx.util.converter, \ + netscape.javascript, \ + org.ietf.jgss, \ + org.omg.CORBA, \ + org.omg.CORBA_2_3, \ + org.omg.CORBA_2_3.portable, \ + org.omg.CORBA.DynAnyPackage, \ + org.omg.CORBA.ORBPackage, \ + org.omg.CORBA.portable, \ + org.omg.CORBA.TypeCodePackage, \ + org.omg.CosNaming, \ + org.omg.CosNaming.NamingContextExtPackage, \ + org.omg.CosNaming.NamingContextPackage, \ + org.omg.Dynamic, \ + org.omg.DynamicAny, \ + org.omg.DynamicAny.DynAnyFactoryPackage, \ + org.omg.DynamicAny.DynAnyPackage, \ + org.omg.IOP, \ + org.omg.IOP.CodecFactoryPackage, \ + org.omg.IOP.CodecPackage, \ + org.omg.Messaging, \ + org.omg.PortableInterceptor, \ + org.omg.PortableInterceptor.ORBInitInfoPackage, \ + org.omg.PortableServer, \ + org.omg.PortableServer.CurrentPackage, \ + org.omg.PortableServer.POAManagerPackage, \ + org.omg.PortableServer.POAPackage, \ + org.omg.PortableServer.portable, \ + org.omg.PortableServer.ServantLocatorPackage, \ + org.omg.SendingContext, \ + org.omg.stub.java.rmi, \ + org.omg.stub.javax.management.remote.rmi, \ + org.w3c.dom, \ + org.w3c.dom.bootstrap, \ + org.w3c.dom.css, \ + org.w3c.dom.events, \ + org.w3c.dom.html, \ + org.w3c.dom.ls, \ + org.w3c.dom.ranges, \ + org.w3c.dom.stylesheets, \ + org.w3c.dom.traversal, \ + org.w3c.dom.views, \ + org.w3c.dom.xpath, \ + org.xml.sax, \ + org.xml.sax.ext, \ + org.xml.sax.helpers, \ + com.sun.nio.sctp, \ + sun.nio.ch, \ + com.sun.management +jre-9=\ + javax.accessibility, \ + javax.activation;version="1.2", \ + javax.activity, \ + javax.annotation;version="1.0", \ + javax.annotation.processing;version="1.0", \ + javax.crypto, \ + javax.crypto.interfaces, \ + javax.crypto.spec, \ + javax.imageio, \ + javax.imageio.event, \ + javax.imageio.metadata, \ + javax.imageio.plugins.bmp, \ + javax.imageio.plugins.jpeg, \ + javax.imageio.spi, \ + javax.imageio.stream, \ + javax.lang.model, \ + javax.lang.model.element, \ + javax.lang.model.type, \ + javax.lang.model.util, \ + javax.management, \ + javax.management.loading, \ + javax.management.modelmbean, \ + javax.management.monitor, \ + javax.management.openmbean, \ + javax.management.relation, \ + javax.management.remote, \ + javax.management.remote.rmi, \ + javax.management.timer, \ + javax.naming, \ + javax.naming.directory, \ + javax.naming.event, \ + javax.naming.ldap, \ + javax.naming.spi, \ + javax.net, \ + javax.net.ssl, \ + javax.print, \ + javax.print.attribute, \ + javax.print.attribute.standard, \ + javax.print.event, \ + javax.rmi, \ + javax.rmi.CORBA, \ + javax.rmi.ssl, \ + javax.script, \ + javax.security.auth, \ + javax.security.auth.callback, \ + javax.security.auth.kerberos, \ + javax.security.auth.login, \ + javax.security.auth.spi, \ + javax.security.auth.x500, \ + javax.security.cert, \ + javax.security.sasl, \ + javax.sound.midi, \ + javax.sound.midi.spi, \ + javax.sound.sampled, \ + javax.sound.sampled.spi, \ + javax.sql, \ + javax.sql.rowset, \ + javax.sql.rowset.serial, \ + javax.sql.rowset.spi, \ + javax.swing, \ + javax.swing.border, \ + javax.swing.colorchooser, \ + javax.swing.event, \ + javax.swing.filechooser, \ + javax.swing.plaf, \ + javax.swing.plaf.basic, \ + javax.swing.plaf.metal, \ + javax.swing.plaf.multi, \ + javax.swing.plaf.synth, \ + javax.swing.table, \ + javax.swing.text, \ + javax.swing.text.html, \ + javax.swing.text.html.parser, \ + javax.swing.text.rtf, \ + javax.swing.tree, \ + javax.swing.undo, \ + javax.tools, \ + javax.transaction; javax.transaction.xa; partial=true; mandatory:=partial, \ + javax.xml, \ + javax.xml.bind;version="2.3.0", \ + javax.xml.bind.annotation;version="2.3.0", \ + javax.xml.bind.annotation.adapters;version="2.3.0", \ + javax.xml.bind.attachment;version="2.3.0", \ + javax.xml.bind.helpers;version="2.3.0", \ + javax.xml.bind.util;version="2.3.0", \ + javax.xml.crypto, \ + javax.xml.crypto.dom, \ + javax.xml.crypto.dsig, \ + javax.xml.crypto.dsig.dom, \ + javax.xml.crypto.dsig.keyinfo, \ + javax.xml.crypto.dsig.spec, \ + javax.xml.datatype, \ + javax.xml.namespace, \ + javax.xml.parsers, \ + javax.xml.stream;version="1.2", \ + javax.xml.stream.events;version="1.2", \ + javax.xml.stream.util;version="1.2", \ + javax.xml.transform, \ + javax.xml.transform.dom, \ + javax.xml.transform.sax, \ + javax.xml.transform.stax, \ + javax.xml.transform.stream, \ + javax.xml.validation, \ + javax.xml.xpath, \ + javafx.animation, \ + javafx.application, \ + javafx.beans, \ + javafx.beans.binding, \ + javafx.beans.property, \ + javafx.beans.property.adapter, \ + javafx.beans.value, \ + javafx.collections, \ + javafx.collections.transformation, \ + javafx.concurrent, \ + javafx.css, \ + javafx.embed.swing, \ + javafx.embed.swt, \ + javafx.event, \ + javafx.fxml, \ + javafx.geometry, \ + javafx.print, \ + javafx.scene, \ + javafx.scene.canvas, \ + javafx.scene.chart, \ + javafx.scene.control, \ + javafx.scene.control.cell, \ + javafx.scene.effect, \ + javafx.scene.image, \ + javafx.scene.input, \ + javafx.scene.layout, \ + javafx.scene.media, \ + javafx.scene.paint, \ + javafx.scene.shape, \ + javafx.scene.text, \ + javafx.scene.transform, \ + javafx.scene.web, \ + javafx.stage, \ + javafx.util, \ + javafx.util.converter, \ + netscape.javascript, \ + org.ietf.jgss, \ + org.omg.CORBA, \ + org.omg.CORBA_2_3, \ + org.omg.CORBA_2_3.portable, \ + org.omg.CORBA.DynAnyPackage, \ + org.omg.CORBA.ORBPackage, \ + org.omg.CORBA.portable, \ + org.omg.CORBA.TypeCodePackage, \ + org.omg.CosNaming, \ + org.omg.CosNaming.NamingContextExtPackage, \ + org.omg.CosNaming.NamingContextPackage, \ + org.omg.Dynamic, \ + org.omg.DynamicAny, \ + org.omg.DynamicAny.DynAnyFactoryPackage, \ + org.omg.DynamicAny.DynAnyPackage, \ + org.omg.IOP, \ + org.omg.IOP.CodecFactoryPackage, \ + org.omg.IOP.CodecPackage, \ + org.omg.Messaging, \ + org.omg.PortableInterceptor, \ + org.omg.PortableInterceptor.ORBInitInfoPackage, \ + org.omg.PortableServer, \ + org.omg.PortableServer.CurrentPackage, \ + org.omg.PortableServer.POAManagerPackage, \ + org.omg.PortableServer.POAPackage, \ + org.omg.PortableServer.portable, \ + org.omg.PortableServer.ServantLocatorPackage, \ + org.omg.SendingContext, \ + org.omg.stub.java.rmi, \ + org.omg.stub.javax.management.remote.rmi, \ + org.w3c.dom, \ + org.w3c.dom.bootstrap, \ + org.w3c.dom.css, \ + org.w3c.dom.events, \ + org.w3c.dom.html, \ + org.w3c.dom.ls, \ + org.w3c.dom.ranges, \ + org.w3c.dom.stylesheets, \ + org.w3c.dom.traversal, \ + org.w3c.dom.views, \ + org.w3c.dom.xpath, \ + org.xml.sax, \ + org.xml.sax.ext, \ + org.xml.sax.helpers, \ + com.sun.nio.sctp, \ + sun.nio.ch, \ + com.sun.management +jre-10=${jre-9} +jre-11=${jre-10} diff --git a/features/src/main/cfg/org.apache.karaf.cellar.groups.cfg b/features/src/main/cfg/org.apache.karaf.cellar.groups.cfg new file mode 100644 index 00000000..0d1c33bb --- /dev/null +++ b/features/src/main/cfg/org.apache.karaf.cellar.groups.cfg @@ -0,0 +1,87 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# +# This property stores the cluster groups for which the local node is member +# +groups = default + +# +# Filtering of the bundles in the default cluster group +# +default.bundle.whitelist.inbound=* +default.bundle.whitelist.outbound=* +default.bundle.blacklist.inbound=none +default.bundle.blacklist.outbound=none + +# +# Filtering of the configurations in the default cluster group +# +default.config.whitelist.inbound=* +default.config.whitelist.outbound=* +default.config.blacklist.inbound=org.apache.felix.fileinstall*, \ + org.apache.karaf.management, \ + org.apache.karaf.shell, \ + org.ops4j.pax.web, \ + org.apache.aries.transaction, \ + org.ops4j.pax.logging, \ + org.apache.karaf.cellar.node, \ + org.apache.karaf.cellar.groups.cfg +default.config.blacklist.outbound=org.apache.felix.fileinstall*, \ + org.apache.karaf.management, \ + org.apache.karaf.shell, \ + org.ops4j.pax.web, \ + org.apache.aries.transaction, \ + org.ops4j.pax.logging, \ + org.apache.karaf.cellar.node, \ + org.apache.karaf.cellar.groups.cfg + + +# +# Filtering of the features in the default cluster group +# +default.feature.whitelist.inbound=* +default.feature.whitelist.outbound=* +default.feature.blacklist.inbound=none +default.feature.blacklist.outbound=none + +# +# The following properties define the behavior to use when the node joins the cluster (the usage of the bootstrap +# synchronizer), per cluster group and per resource. +# The following values are accepted: +# disabled: means that the synchronizer doesn't sync cluster group and node states +# cluster: the synchronizer retrieves the state from the cluster group first (pull first), and push the node the state +# to the cluster group after (push after) +# node: the synchronizer push the node state to the cluster group (push first), and pull the state from the cluster group +# after (pull after) +# clusterOnly: the cluster is the "master", the node only retrieves and applies the cluster group state, nothing is +# pushed to the cluster group +# nodeOnly: the node is the "master", the node pushes his state to the cluster group, nothing is pulled from the +# cluster group +# +default.bundle.sync=cluster +default.config.sync=disabled +default.feature.sync=cluster +default.obr.urls.sync=cluster +default.balanced.servlet.sync=cluster + +default.event.blacklist.inbound = none +default.event.blacklist.outbound = none +default.event.whitelist.inbound = subscription +default.event.whitelist.outbound = subscription diff --git a/features/src/main/cfg/org.ops4j.datasource-entaxy.esb.cache.cfg b/features/src/main/cfg/org.ops4j.datasource-entaxy.esb.cache.cfg new file mode 100644 index 00000000..0698d1af --- /dev/null +++ b/features/src/main/cfg/org.ops4j.datasource-entaxy.esb.cache.cfg @@ -0,0 +1,29 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +dataSourceName=entaxy.esb.cache +osgi.jdbc.driver.name=PostgreSQL JDBC Driver +serverName=localhost +portNumber=5432 +databaseName=cache +user=entaxy +password=entaxy +pool=dbcp2 +xa=true +jdbc.pool.maxTotal=100 diff --git a/features/src/main/cfg/org.ops4j.datasource-entaxy.esb.storage.cfg b/features/src/main/cfg/org.ops4j.datasource-entaxy.esb.storage.cfg new file mode 100644 index 00000000..1accbf16 --- /dev/null +++ b/features/src/main/cfg/org.ops4j.datasource-entaxy.esb.storage.cfg @@ -0,0 +1,29 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +dataSourceName=entaxy.esb.storage +osgi.jdbc.driver.name=PostgreSQL JDBC Driver +serverName=localhost +portNumber=5432 +databaseName=esb_entaxy +user=entaxy +password=entaxy +pool=dbcp2 +xa=true +jdbc.pool.maxTotal=100 diff --git a/features/src/main/cfg/ru.entaxy.esb.cfg b/features/src/main/cfg/ru.entaxy.esb.cfg new file mode 100644 index 00000000..37df8416 --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.cfg @@ -0,0 +1,42 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# адреса кластера брокеров сообщений, задаются: +# если tcp в скобках и через запятую: (tcp://192.168.122.81:61616,tcp://192.168.122.82:61616) +# если amqp с failover и в скобках через запятую: failover:(amqp://192.168.122.81:5672,amqp://192.168.122.82:5672) +common.jms.url=tcp://localhost:61616 +# логин для аутентификации в брокере сообщений +common.jms.username=entaxy +# пароль для аутентификации в брокере сообщений +common.jms.password=entaxy +# максимальное количество соединений +# подробнее можно почитать здесь: https://github.com/messaginghub/pooled-jms/blob/master/pooled-jms-docs/Configuration.md +common.jms.maxConnections=20 +# максимальное количество сессий для каждого соединения +# подробнее можно почитать здесь: https://github.com/messaginghub/pooled-jms/blob/master/pooled-jms-docs/Configuration.md +common.jms.maxSessionsPerConnection=100 + +# наименование драйвера для инициализации фабрики планировщика quartz +org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate + +# название очереди, через которую ходят большие пакеты и файлы +common.bridge.file.queue.name=file.queue + +# восстановление профилей, коннекторов и других созданных пользователем блюпринтов с помощью базы данных +is.restore.from.db=true diff --git a/features/src/main/cfg/ru.entaxy.esb.connector.1c.service.soap.passive.cfg b/features/src/main/cfg/ru.entaxy.esb.connector.1c.service.soap.passive.cfg new file mode 100644 index 00000000..57f311d6 --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.connector.1c.service.soap.passive.cfg @@ -0,0 +1,27 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# адрес service-soap, будет формироваться host/cxf + passive.endpoint.address, +# по умолчанию passive.endpoint.address=/service +passive.endpoint.address=/service +# включение кастомной валидации soap сообщений по wsdl +passive.endpoint.validation=true +# название системы, в которую будут отправляться сообщения, если не был выставлен destination +passive.error.system.name=error + diff --git a/features/src/main/cfg/ru.entaxy.esb.connector.1c.soap.passive.cfg b/features/src/main/cfg/ru.entaxy.esb.connector.1c.soap.passive.cfg new file mode 100644 index 00000000..86f5b688 --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.connector.1c.soap.passive.cfg @@ -0,0 +1,24 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# адрес soap-connector, будет формироваться host/cxf + passive.endpoint.address, +# по умолчанию passive.endpoint.address=/exchange +passive.endpoint.address=/exchange +# включение кастомной валидации soap сообщений по wsdl +passive.endpoint.validation=true diff --git a/features/src/main/cfg/ru.entaxy.esb.connector.1c.support.cfg b/features/src/main/cfg/ru.entaxy.esb.connector.1c.support.cfg new file mode 100644 index 00000000..bcf767a7 --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.connector.1c.support.cfg @@ -0,0 +1,47 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# максимальное количество попыток отправить сообщение в очередь из агрегатора +redelivery.maximumRedeliveries=2 +# очередь для отправки сообщений, которые не смог отправить агрегатор в destination +redelivery.deadLetterQueue=revert.message.dead + +# задается в mc, значение по умолчанию 10 минут +acknowledge.completion.timeout=600000 +# настройка способа агрегирования через игнайт или бд +# Важно! следить за тем чтобы данный параметр был одинаковым во всем кластере +# варианты - igniteAggregationRepository, jdbcAggregationRepository (для всех бд кроме postgres), postgresAggregationRepository +# по умолчанию - jdbcAggregationRepository +acknowledge.aggregation.repository=jdbcAggregationRepository + +# Поднимается endpoint /active_connector_test_consumer +# при выставленной настройке mode.dev=true +active.mode.dev=false +active.username=Администратор +active.password= + +# валидация сообщения по wsdl +active.validation=false + +# uuid шины, для отправки в активном режиме в систему от имени шины +bus.id=FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF +get.destination= + +# параметр для тестирования активного коннектора +test.empty.rate=20 diff --git a/features/src/main/cfg/ru.entaxy.esb.deployer.cellar.cfg b/features/src/main/cfg/ru.entaxy.esb.deployer.cellar.cfg new file mode 100644 index 00000000..01ba023e --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.deployer.cellar.cfg @@ -0,0 +1,21 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# название группы cellar, которая прописывается в org.apache.karaf.cellar.groups.cfg, org.apache.karaf.cellar.node.cfg +cellar.group = default diff --git a/features/src/main/cfg/ru.entaxy.esb.deployer.file.system.cfg b/features/src/main/cfg/ru.entaxy.esb.deployer.file.system.cfg new file mode 100644 index 00000000..6e9da9ce --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.deployer.file.system.cfg @@ -0,0 +1,21 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +#Корневая папка репозитория +folder.root=entaxy/bundle-repository diff --git a/features/src/main/cfg/ru.entaxy.esb.deployer.nexus.cfg b/features/src/main/cfg/ru.entaxy.esb.deployer.nexus.cfg new file mode 100644 index 00000000..8b6a5e7b --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.deployer.nexus.cfg @@ -0,0 +1,31 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# все смены адреса расположения nexus и изменение наименования репозитория, необходимо фиксировать в файле +# org.ops4j.pax.url.mvn.cfg параметр: org.ops4j.pax.url.mvn.repositories + + +# url расположения nexus +nexus.deployer.url=http://localhost:8081 +# название репозитория в nexus, необходимого для конфигурирования шины из вне(создание профилей, коннекторов и т д) +nexus.deployer.repository=entaxy +# логин для авторизации в nexus +nexus.deployer.username=entaxy +# пароль для авторизации в nexus +nexus.deployer.password=entaxy diff --git a/features/src/main/cfg/ru.entaxy.esb.error.cfg b/features/src/main/cfg/ru.entaxy.esb.error.cfg new file mode 100644 index 00000000..5bfc235f --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.error.cfg @@ -0,0 +1,40 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# асинхронный пакет с ошибкой отправляется от имени: +# false - системы, вызвавшей ошибку в шине +# true - шины (система с идентификатором "-1") +error.bus.always_at_source=false + +# асинхронный пакет с ошибкой в поле description содержит: +# false - сообщение из маппинга в файле ru.entaxy.esb.error.text.cfg +# true - содержит сообщение, сохранённое в исключении +error.description.exception_message=true + +# имя очереди для отправки пакета с ошибкой при недоступности системы, указанной в свойстве error.system.name +error.queue.name=error + +# имя системы для отправки пакета с ошибкой +error.system.name=error + +# true - включает в пакет с ошибкой весь stacktrace исключения +error.stacktrace.show=true + +# свойство автоматического запуска тестового маршрута, который при старте модуля бросает исключение java.lang.IllegalArgumentException: Test exception thrown +error.test-route.startup=false diff --git a/features/src/main/cfg/ru.entaxy.esb.error.code.cfg b/features/src/main/cfg/ru.entaxy.esb.error.code.cfg new file mode 100644 index 00000000..e673734b --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.error.code.cfg @@ -0,0 +1,41 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# Справочник содержит соответствие имён классов исключений и http кодов ошибок. +# И будет наполняться по мере использования шины в разных ситуациях. +# Для исключения, имя которого ещё не указано в этом файле, +# будет возвращаться http код 520 (Unknown Error). +# согласование кодов ошибок происходит в https://docs.google.com/spreadsheets/d/1rvRyiSN-khuuRSJenwP5g7Q-ilbctOGCFgDfdM-abEk/edit#gid=1202937725 +DefaultException=520 + +com.ctc.wstx.exc.WstxParsingException=400 + +java.lang.NullPointerException=418 +java.security.AccessControlException=403 + +org.apache.cxf.interceptor.security.AuthenticationException=401 +javax.ws.rs.ForbiddenException=403 + +org.apache.camel.language.bean.RuntimeBeanExpressionException=500 + +ConnectorNotFound=424 +ru.entaxy.esb.system.common.exception.DefaultException=520 +ProfileNotFound=424 + +java.io.FileNotFoundException=404 diff --git a/features/src/main/cfg/ru.entaxy.esb.error.text.cfg b/features/src/main/cfg/ru.entaxy.esb.error.text.cfg new file mode 100644 index 00000000..b807a38a --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.error.text.cfg @@ -0,0 +1,33 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# 1xx: Informational +# 2xx: Success +200=OK + +# 3xx: Redirection +# 4xx: Client Error +400=Bad Request +401=Unauthorized +403=Forbidden +418=I’m a teapot +424=Failed Dependency + +# 5xx: Server Error +520=Unknown Error diff --git a/features/src/main/cfg/ru.entaxy.esb.system.basic_auth.cfg b/features/src/main/cfg/ru.entaxy.esb.system.basic_auth.cfg new file mode 100644 index 00000000..617d403d --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.system.basic_auth.cfg @@ -0,0 +1,31 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# адрес basic-auth, будет формироваться host/cxf + basic_auth_endpoint.address, +# по умолчанию basic_auth_endpoint.address=/basic-auth-management +basic_auth_endpoint.address=/basic-auth-management + +#worked and tested on nginX MD5 and SHA-1(recommended) +еncryption.algorithm=SHA-1 +#salt for encryption 1 to 8 characters ([\\.\\/a-zA-Z0-9]{1,8}) +#when salt changed all password need to remake! +еncryption.salt=kDfq0qZJ + +#Встроенная аутентификация +internal.authentication.enabled=true diff --git a/features/src/main/cfg/ru.entaxy.esb.system.basic_auth.htpasswd.cfg b/features/src/main/cfg/ru.entaxy.esb.system.basic_auth.htpasswd.cfg new file mode 100644 index 00000000..3182be71 --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.system.basic_auth.htpasswd.cfg @@ -0,0 +1,30 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +#наименование файла htpasswd на сервере karaf +htpasswd.file.name=htpasswd +#путь сохранения файла htpasswd на сервере karaf, +#при использовании кластера karaf-ов сохранять файл требуется в папку доступную на всех серверах, входящих в кластер +htpasswd.file.directory=entaxy/security +#наименование файла для сохранения контрольной суммы файла htpasswd +htpasswd.file.checksum=MD5.md5 + +htpasswd.service.host=http://0.0.0.0 +htpasswd.service.port=9091 +htpasswd.service.root.path=/htpasswd diff --git a/features/src/main/cfg/ru.entaxy.esb.system.event.handler.cfg b/features/src/main/cfg/ru.entaxy.esb.system.event.handler.cfg new file mode 100644 index 00000000..b57bad6c --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.system.event.handler.cfg @@ -0,0 +1,28 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# максимальное колчичество попыток отправить сообщение в очередь +# почитать подробнее можно в https://camel.apache.org/components/latest/eips/dead-letter-channel.html#deadLetterChannel-Redelivery +redelivery.maximumRedeliveries=-1 +# время между попытками отправить сообщение в очередь +redelivery.redeliveryDelay=5000 + +#cron - every 00:00:00, +#cron expression use "+" separator for quartz in camel +quirtz.job.clean.cron=0+0+0+*+*+?+* diff --git a/features/src/main/cfg/ru.entaxy.esb.system.event.rest.cfg b/features/src/main/cfg/ru.entaxy.esb.system.event.rest.cfg new file mode 100644 index 00000000..f3556bc9 --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.system.event.rest.cfg @@ -0,0 +1,28 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +service.host=http://0.0.0.0 + +service.port.management=9090 +#with changing path you must edit according records in permission table for accounts +service.root.path.management=/topic-management + +service.port.subscription=9092 +#with changing path you must edit according records in permission table for accounts +service.root.path.subscription=/topic-subscription diff --git a/features/src/main/cfg/ru.entaxy.esb.system.management.cfg b/features/src/main/cfg/ru.entaxy.esb.system.management.cfg new file mode 100644 index 00000000..e2398308 --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.system.management.cfg @@ -0,0 +1,25 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# адрес system-management, будет формироваться host/cxf + system-management.endpoint.address, +# по умолчанию system-management.endpoint.address=/exchange +system-management.endpoint.address=/system-management + +# флаг, отвечающий за публикацию сервиса system-management +system-management.endpoint.master=true diff --git a/features/src/main/cfg/ru.entaxy.esb.system.schema.cfg b/features/src/main/cfg/ru.entaxy.esb.system.schema.cfg new file mode 100644 index 00000000..9b4acb2c --- /dev/null +++ b/features/src/main/cfg/ru.entaxy.esb.system.schema.cfg @@ -0,0 +1,22 @@ +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# адрес schema-soap, будет формироваться host/cxf + schema-management.endpoint.address, +# по умолчанию schema-management.endpoint.address=/schema-management +schema-management.endpoint.address=/schema-management diff --git a/features/src/main/feature/feature.xml b/features/src/main/feature/feature.xml new file mode 100644 index 00000000..26f600e9 --- /dev/null +++ b/features/src/main/feature/feature.xml @@ -0,0 +1,502 @@ + + + + + + + mvn:org.apache.camel.karaf/apache-camel/${camel.version}/xml/features + mvn:org.apache.activemq/artemis-features/${activemq.version}/xml/features + mvn:org.hibernate/hibernate-osgi/${hibernate.version}/xml/karaf + mvn:org.apache.karaf.cellar/apache-karaf-cellar/${cellar.version}/xml/features + mvn:org.apache.ignite/ignite-osgi-karaf/${ignite.version}/xml/features + + + aries-blueprint + cxf + camel + camel-blueprint + camel-jaxb + camel-cxf + camel-amqp + camel-core + camel-http + mvn:ru.entaxy.esb.system/component-bean-fix/${project.version} + + osgi.service;objectClass=org.apache.aries.blueprint.NamespaceHandler;osgi.service.blueprint.namespace=http://camel.apache.org/schema/blueprint;effective:=active; + + + + + artemis-jms-client + camel-jms + mvn:org.messaginghub/pooled-jms/1.0.6 + mvn:org.apache.commons/commons-pool2/2.6.2 + + + + hibernate + jdbc + pax-jdbc-pool-dbcp2 + jndi + spring-jdbc + jpa + wrap:mvn:org.postgresql/postgresql/${postgresql.version} + wrap:mvn:com.microsoft.sqlserver/mssql-jdbc/${mssql.version} + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/datasource-cache + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/datasource-storage + + + + + mvn:ru.entaxy.esb.system.core/error-handler/${project.version} + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.error + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.error.code + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.error.text + + + + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/properties/jre + + + karaf-camel-common + system-entaxy-db + system-entaxy-jms + ignite-core + + mvn:org.apache.ignite/ignite-jcl/${ignite.version} + camel-ignite + camel-sql + + entaxy-esb-api + + + + mvn:org.eclipse.aether/aether-transport-http/1.1.0 + mvn:org.eclipse.aether/aether-transport-file/1.1.0 + mvn:org.eclipse.aether/aether-connector-basic/1.1.0 + mvn:org.eclipse.aether/aether-impl/1.1.0 + wrap:mvn:org.apache.maven/maven-aether-provider/3.3.9 + + + + aries-blueprint + karaf-camel-common + system-entaxy-db + system-entaxy-jms + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb + + + + + cellar + bundle-service + system-common + entaxy-common + camel-gson + mvn:ru.entaxy.esb.system.core/template/${project.version} + mvn:ru.entaxy.esb.system.commons/system-commons/${project.version} + mvn:ru.entaxy.esb.system.core.dispatcher/dispatcher/${project.version} + mvn:ru.entaxy.esb.system.registry.profile.commons/profile-commons/${project.version} + + mvn:ru.entaxy.esb.system.registry.connector/connector-impl/${project.version} + mvn:ru.entaxy.esb.system.registry.connector/connector-api/${project.version} + system-api + nexus-deployer + file-system-deployer + cellar-deployer + + blueprint-generator + + + mvn:ru.entaxy.esb.system.management.bundle.manager/bundle-manager/${project.version} + mvn:ru.entaxy.esb.system.management.connector.manager/connector-manager/${project.version} + mvn:ru.entaxy.esb.system.management.bridge.profile.manager/bridge-profile-manager/${project.version} + + mvn:ru.entaxy.esb.system.management.profile.manager/profile-manager/${project.version} + mvn:ru.entaxy.esb.system.management.route.manager/route-manager/${project.version} + system-management + + schema + + + + camel-blueprint + mvn:ru.entaxy.esb.system.deployer/deployer-api/${project.version} + mvn:ru.entaxy.esb.system.deployer/file-system-deployer/${project.version} + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.deployer.file.system + + + + + mvn:org.eclipse.aether/aether-api/${aether.version} + camel-http + camel-cxf + mvn:ru.entaxy.esb.system.deployer/deployer-api/${project.version} + mvn:ru.entaxy.esb.system.deployer/nexus-deployer/${project.version} + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.deployer.nexus + + + + + mvn:ru.entaxy.esb.system.deployer/cellar-deployer/${project.version} + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.deployer.cellar + + + + + mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.freemarker/2.3.29_1 + mvn:ru.entaxy.esb.system.management.blueprint.generator/blueprint-generator/${project.version} + + + + mvn:ru.entaxy.esb.system.management.bundle.jpa/bundle-service/${project.version} + + osgi.service;objectClass=org.hibernate.SessionFactory;effective:=active; + + + + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.system.management + + mvn:ru.entaxy.esb.system.management/system-management-api/${project.version} + + osgi.service;objectClass=org.hibernate.SessionFactory;effective:=active; + + + + + mvn:ru.entaxy.esb.system.core.dispatcher/dispatcher/${project.version} + mvn:ru.entaxy.esb.system.registry.profile.commons/profile-commons/${project.version} + + + + karaf-camel-common + system-entaxy-db + system-entaxy-jms + + mvn:org.liquibase/liquibase-core/${liquibase.version} + + mvn:ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer/liquibase-updater/${project.version} + storage-cache + storage-esb_entaxy + + + + mvn:ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer/storage-cache/${project.version} + + osgi.service;effective:=active;objectClass=javax.sql.DataSource;osgi.jndi.service.name=entaxy.esb.cache; + + + osgi.service;objectClass=javax.sql.DataSource;osgi.jndi.service.name=entaxy.esb.cache-connector; + + + + + mvn:ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer/storage-esb_entaxy/${project.version} + + osgi.service;effective:=active;objectClass=javax.sql.DataSource;osgi.jndi.service.name=entaxy.esb.storage; + + + + + profile-commons + + mvn:ru.entaxy.esb.system.registry.systems.profile/system-profile-api/${project.version} + mvn:ru.entaxy.esb.system.registry.systems.profile/system-profile-collector/${project.version} + mvn:ru.entaxy.esb.system.registry.systems.profile/system-profile-impl-default/${project.version} + + + + + system-entaxy-db + system-entaxy-jms + bundle-service + permission-api + + mvn:ru.entaxy.esb.system.commons/system-commons/${project.version} + mvn:ru.entaxy.esb.system.registry.connector/connector-api/${project.version} + + mvn:ru.entaxy.esb.system.registry.systems/system-api/${project.version} + mvn:ru.entaxy.esb.system.registry.systems/system-impl/${project.version} + + + osgi.service;objectClass=org.hibernate.SessionFactory;effective:=active; + + + + + karaf-camel-common + system-entaxy-jms + + system-common + system-profile + mvn:ru.entaxy.esb.system.registry.systems/system-component/${project.version} + + + osgi.service;objectClass=org.hibernate.SessionFactory;effective:=active; + + + + + mvn:ru.entaxy.esb.system.registry.system-groups.profile/system-group-profile-api/${project.version} + + + mvn:ru.entaxy.esb.system.registry.system-groups.profile/system-group-profile-collector/${project.version} + + + mvn:ru.entaxy.esb.system.registry.system-groups.profile/system-group-profile-impl-default/${project.version} + + + + + karaf-camel-common + system-entaxy-jms + + system-common + system-group-profile + mvn:ru.entaxy.esb.system.registry.system-groups/system-group-component/${project.version} + + + + karaf-camel-common + liquibase-updater + mvn:commons-codec/commons-codec/${commons-codec.version} + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.system.basic_auth + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.system.basic_auth.htpasswd + + + mvn:ru.entaxy.esb.system.auth.basic.api/basic-auth-api/${project.version} + mvn:ru.entaxy.esb.system.auth.basic.impl/basic-auth-impl/${project.version} + mvn:ru.entaxy.esb.system.auth.basic.htpasswd/htpasswd/${project.version} + mvn:ru.entaxy.esb.system.auth.basic/basic-auth-soap/${project.version} + + osgi.service;objectClass=org.hibernate.SessionFactory;effective:=active; + + + + + events-impl + events-rest + events-handler + + + + mvn:ru.entaxy.esb.system.core.events/events-common/${project.version} + + + + cellar + cellar-eventadmin + camel-eventadmin + karaf-camel-common + camel-jsonpath + camel-gson + system-common + error-handler + system-registry + + system-api + + events-api + basic-auth + events-common + + permission-impl + permission-handler + permission-component + + mvn:ru.entaxy.esb.system.commons/system-commons/${project.version} + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.system.event.rest + + + mvn:ru.entaxy.esb.system.core.events/events-rest/${project.version} + + + + system-entaxy-db + + events-common + + mvn:ru.entaxy.esb.system.core.events/events-api/${project.version} + + + + system-common + events-api + + events-common + + mvn:ru.entaxy.esb.system.core.events/events-impl/${project.version} + + osgi.service;objectClass=org.hibernate.SessionFactory;effective:=active; + + + + + camel-ognl + camel-gson + camel-quartz + system-common + events-api + + events-common + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.system.event.handler + + + mvn:ru.entaxy.esb.system.core.events/events-handler/${project.version} + + + osgi.service;effective:=active;objectClass=javax.sql.DataSource;osgi.jndi.service.name=entaxy.esb.cache; + + + + + permission-impl + permission-handler + permission-component + permission-soap + permission-manager + + + + mvn:ru.entaxy.esb.system.core.permission/permission-common/${project.version} + + + + system-entaxy-db + + mvn:ru.entaxy.esb.system.core.permission/permission-api/${project.version} + + + + liquibase-updater + system-entaxy-db + system-common + permission-api + + permission-common + + mvn:ru.entaxy.esb.system.core.permission/permission-impl/${project.version} + + osgi.service;objectClass=org.hibernate.SessionFactory;effective:=active; + + + + + camel-ognl + system-entaxy-jms + system-common + permission-impl + + permission-common + + + + mvn:ru.entaxy.esb.system.core.permission/permission-handler/${project.version} + + + + permission-component + + mvn:ru.entaxy.esb.system.management.permission.manager/permission-manager/${project.version} + + + + system-common + camel-gson + permission-common + permission-impl + system-api + mvn:ru.entaxy.esb.system.commons/system-commons/${project.version} + + mvn:ru.entaxy.esb.system.core.permission/permission-component/${project.version} + + + + basic-auth + karaf-camel-common + + mvn:ru.entaxy.esb.system.core.permission/permission-soap/${project.version} + + + + system-entaxy-db + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/cfg/ru.entaxy.esb.system.schema + + + mvn:ru.entaxy.esb.system.registry.schema/schema-api/${project.version} + mvn:ru.entaxy.esb.system.registry.schema/schema-impl/${project.version} + mvn:ru.entaxy.esb.system.registry.schema/schema-soap/${project.version} + mvn:ru.entaxy.esb.system.registry.schema/schema-component/${project.version} + + osgi.service;objectClass=org.hibernate.SessionFactory;effective:=active; + + + + + basic-auth + permission + entaxy-esb-api + system-registry + system-group-registry + events + + + + + mvn:ru.entaxy.esb.platform.runtime.base/branding/${project.version}/properties/branding + + + entaxy-service + + + diff --git a/features/src/main/script/README.md b/features/src/main/script/README.md new file mode 100644 index 00000000..e3947383 --- /dev/null +++ b/features/src/main/script/README.md @@ -0,0 +1,9 @@ + + +## Репозиторий с релизами + +http://192.168.122.76:8081/service/rest/repository/browse/karaf_patch/ + +## Install patch + + tar -zxf karaf_update_1.0.10-SNAPSHOT.tgz install.sh; ./install.sh 1.0.10-SNAPSHOT diff --git a/features/src/main/script/change_ips.sh b/features/src/main/script/change_ips.sh new file mode 100644 index 00000000..e92f8407 --- /dev/null +++ b/features/src/main/script/change_ips.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### + +sed -i s/192.168.122.81/artemis1/g ru.entaxy.esb.* +sed -i s/192.168.122.82/artemis2/g ru.entaxy.esb.* +sed -i s/192.168.122.84/database/g org.ops4j.datasource-entaxy.esb.* diff --git a/features/src/main/script/create_full_karaf_assembly.sh b/features/src/main/script/create_full_karaf_assembly.sh new file mode 100644 index 00000000..4b5ce190 --- /dev/null +++ b/features/src/main/script/create_full_karaf_assembly.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### + +DIRNAME="$( cd "$(dirname "$0")" ; pwd -P )" + +INSTALL_DIR=$DIRNAME/karaf-full-$(date +%d%m%Y-%H%M) + +mkdir -p $INSTALL_DIR/bin +mkdir -p $INSTALL_DIR/etc +mkdir -p $INSTALL_DIR/lib +mkdir -p $INSTALL_DIR/system +mkdir -p $INSTALL_DIR/data +mkdir -p $INSTALL_DIR/systemd/system + +sudo systemctl stop karaf +echo "Stopped karaf" + +cp -R /opt/karaf/bin/* $INSTALL_DIR/bin +cp -R /opt/karaf/etc/* $INSTALL_DIR/etc +cp -R /opt/karaf/lib/* $INSTALL_DIR/lib +cp -R /opt/karaf/system/* $INSTALL_DIR/system +cp -R /opt/karaf/data/* $INSTALL_DIR/data +cp /etc/systemd/system/karaf $INSTALL_DIR/systemd/system +cp /etc/systemd/system/karaf.service $INSTALL_DIR/systemd/system + +sudo systemctl start karaf +echo "Started karaf" + +rm -rf $INSTALL_DIR/data/tmp/* +rm -rf $INSTALL_DIR/data/log/* +rm -rf $INSTALL_DIR/data/txlog/* + +#pushd ./$INSTALL_DIR/etc +#$DIRNAME/change_ips.sh +#popd + +if test -f "$DIRNAME/version"; then + ESB_ENTAXY_VERSION=`cat $DIRNAME/version` +else + ESB_ENTAXY_VERSION=1.0-SNAPSHOT +fi +echo "Installing $ESB_ENTAXY_VERSION" + +pushd $INSTALL_DIR +tar czvf $DIRNAME/karaf_full_$ESB_ENTAXY_VERSION.tgz * +popd + +rm -rf $INSTALL_DIR diff --git a/features/src/main/script/create_update_patch.sh b/features/src/main/script/create_update_patch.sh new file mode 100644 index 00000000..7232b001 --- /dev/null +++ b/features/src/main/script/create_update_patch.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### + +# создает архив с обновлением + +DIRNAME="$( cd "$(dirname "$0")" ; pwd -P )" + +if test -f "$DIRNAME/version"; then + ESB_ENTAXY_VERSION=`cat $DIRNAME/version` +else + ESB_ENTAXY_VERSION=1.0-SNAPSHOT +fi +echo "Create patch version $ESB_ENTAXY_VERSION" + +RELEASE_DIR=$DIRNAME/karaf-$(date +%d%m%Y-%H%M) +mkdir -p $RELEASE_DIR + +mkdir -p $RELEASE_DIR/etc +mkdir -p $RELEASE_DIR/data + +sudo systemctl stop karaf +echo "Stopped karaf" + +cp -R /opt/karaf/etc/* $RELEASE_DIR/etc +cp -R /opt/karaf/data/* $RELEASE_DIR/data +cp $DIRNAME/change_ips.sh $RELEASE_DIR/etc +cp $DIRNAME/install_patch.sh $RELEASE_DIR/install.sh + +sudo systemctl start karaf +echo "Started karaf" + +rm -rf $RELEASE_DIR/data/tmp/* +rm -rf $RELEASE_DIR/data/log/* +rm -rf $RELEASE_DIR/data/txlog/* + +pushd $RELEASE_DIR +tar czvf $DIRNAME/karaf_update_$ESB_ENTAXY_VERSION.tgz * +popd + + +rm -rf $RELEASE_DIR + +curl -v --user 'deployer:deployer' --upload-file $DIRNAME/README.md http://192.168.122.76:8081/repository/karaf_patch/README.md +curl -v --user 'deployer:deployer' --upload-file $DIRNAME/karaf_update_$ESB_ENTAXY_VERSION.tgz http://192.168.122.76:8081/repository/karaf_patch/karaf_update_$ESB_ENTAXY_VERSION.tgz +echo "Upload path to nexus http://192.168.122.76:8081/service/rest/repository/browse/karaf_patch/" diff --git a/features/src/main/script/install.karaf b/features/src/main/script/install.karaf new file mode 100644 index 00000000..68561b8c --- /dev/null +++ b/features/src/main/script/install.karaf @@ -0,0 +1,16 @@ +ESB_ENTAXY_VERSION=${project.version} +echo "Entaxy version=$ESB_ENTAXY_VERSION" + + +feature:repo-add mvn:ru.entaxy.esb/karaf-features/$ESB_ENTAXY_VERSION/xml/features +echo "feature:install entaxy-all" +feature:install entaxy-all +feature:repo-add mvn:ru.entaxy.esb.platform.runtime/base/$ESB_ENTAXY_VERSION/xml/features +echo "feature:install base" +feature:install base +feature:repo-add mvn:ru.entaxy.esb.platform.runtime/core/$ESB_ENTAXY_VERSION/xml/features +echo "feature:install core" +feature:install core +feature:repo-add mvn:ru.entaxy.esb.platform.runtime.modules/uniform-service/$ESB_ENTAXY_VERSION/xml/features +echo "feature:install entaxy-uniform-service" +feature:install entaxy-uniform-service \ No newline at end of file diff --git a/features/src/main/script/install_patch.sh b/features/src/main/script/install_patch.sh new file mode 100644 index 00000000..e0b99dd5 --- /dev/null +++ b/features/src/main/script/install_patch.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### + +# первый параметр номер версии +# если задан второй параметр чистит конфиги + +DIRNAME="$( cd "$(dirname "$0")" ; pwd -P )" +ESB_ENTAXY_VERSION=$1 +PATCH_FILE=$DIRNAME/karaf_update_$ESB_ENTAXY_VERSION.tgz + +if test -f "$PATCH_FILE"; then + echo "Installing $ESB_ENTAXY_VERSION, use patch file: $PATCH_FILE" +else + echo "Error: patch file $PATCH_FILE not found" +fi + +sudo systemctl stop karaf +echo "Stopped karaf" + +BKPDIR=$DIRNAME/backup-karaf-$(date +%d%m%Y-%H%M) +mkdir -p $BKPDIR +echo "Created dir $BKPDIR" + +# create backup +sudo cp -r /opt/karaf/etc $BKPDIR +sudo cp -r /opt/karaf/data $BKPDIR + +# clean backed dirs +sudo su - -c "rm -rf /opt/karaf/data/*" karaf + +if [ -n "$2" ] +then + # clean configs + sudo su - -c "rm -rf /opt/karaf/etc/ru.entaxy.esb.*" karaf + sudo su - -c "rm -rf /opt/karaf/etc/org.ops4j.datasource-entaxy.esb.*" karaf + echo "Karaf data and configs cleaned up" +else + echo "Karaf data cleaned up" +fi + +sudo tar -zxk -f $PATCH_FILE -C /opt/karaf/ + +if [ -n "$2" ] +then + sudo /opt/karaf/etc/change_ips.sh + echo "Run change_ips.sh" +fi + +# restore file owner +sudo chown -R karaf. /opt/karaf/{etc,data} + +sudo systemctl start karaf +echo "Started karaf" + +sleep 30 +sudo su - -c "/opt/karaf/bin/client 'list --no-format | grep -v Active'" karaf diff --git a/features/src/main/script/update_karaf_clean.sh b/features/src/main/script/update_karaf_clean.sh new file mode 100644 index 00000000..f5574f2b --- /dev/null +++ b/features/src/main/script/update_karaf_clean.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +### +# ~~~~~~licensing~~~~~~ +# karaf-features +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### + +# берет номер версии из файла version, если его нет то используется 1.0-SNAPSHOT +# если задан первый параметр чистит конфиги + +DIRNAME="$( cd "$(dirname "$0")" ; pwd -P )" + +if test -f "$DIRNAME/version"; then + ESB_ENTAXY_VERSION=`cat $DIRNAME/version` +else + ESB_ENTAXY_VERSION=1.0-SNAPSHOT +fi +echo "Installing $ESB_ENTAXY_VERSION" + +sudo systemctl stop karaf + +echo "Stopped karaf" + +BKPDIR=$DIRNAME/backup-karaf-$(date +%d%m%Y-%H%M) +mkdir -p $BKPDIR + +echo "Created dir $BKPDIR" + +# create backup +cp -r /opt/karaf/etc $BKPDIR +cp -r /opt/karaf/data $BKPDIR + +# clean backed dirs +sudo rm -rf /opt/karaf/data/* + +if [ -n "$1" ] +then + # clean configs + sudo rm -rf /opt/karaf/etc/ru.entaxy.esb.* + sudo rm -rf /opt/karaf/etc/org.ops4j.datasource-entaxy.esb.* + echo "Karaf data and configs cleaned up" +else + echo "Karaf data cleaned up" +fi + +# restore file owner +sudo chown -R karaf. /opt/karaf/{etc,data} + +sudo systemctl start karaf + +echo "Started karaf" + +sleep 15 + +sudo cp -r $DIRNAME/install.karaf /opt/karaf/ + +sudo su - -c "/opt/karaf/bin/client 'esb_entaxy_VERSION=$ESB_ENTAXY_VERSION; shell:source /opt/karaf/install.karaf;'" karaf + +echo "== Update database" +sudo su - -c "/opt/karaf/bin/client 'feature:install liquibase-updater'" karaf +sleep 60 +echo "== Install all features" +sudo su - -c "/opt/karaf/bin/client 'feature:install entaxy-all'" karaf +sleep 60 +echo "== Install system-group profile" +sudo su - -c "/opt/karaf/bin/client 'bundle:install -s blueprint:mvn:ru.entaxy.esb.integration.esb.test.profiles/test-profiles/$ESB_ENTAXY_VERSION/xml/g_test'" karaf + +echo "Install process finished" diff --git a/platform/LICENSE.txt b/platform/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/aggregate.marker b/platform/aggregate.marker new file mode 100644 index 00000000..e69de29b diff --git a/platform/pom.xml b/platform/pom.xml new file mode 100644 index 00000000..24ca8f22 --- /dev/null +++ b/platform/pom.xml @@ -0,0 +1,20 @@ + + + + root + ru.entaxy.esb + 1.8.0 + + 4.0.0 + + platform + ENTAXY :: PLATFORM + Entaxy Platform + pom + + + runtime + + \ No newline at end of file diff --git a/platform/runtime/LICENSE.txt b/platform/runtime/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/LICENSE.txt b/platform/runtime/base/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/branding/LICENSE.txt b/platform/runtime/base/branding/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/branding/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/branding/pom.xml b/platform/runtime/base/branding/pom.xml new file mode 100644 index 00000000..07df7b06 --- /dev/null +++ b/platform/runtime/base/branding/pom.xml @@ -0,0 +1,66 @@ + + + + ru.entaxy.esb.platform.runtime + base + 1.8.0 + + 4.0.0 + + ru.entaxy.esb.platform.runtime.base + branding + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: BRANDING + Entaxy Branding + pom + + + + + src/main/cfg + true + ${project.build.directory}/cfg + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + + resources + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.12 + + + attach-artifacts + package + + attach-artifact + + + + + target/cfg/branding.properties + properties + branding + + + + + + + + + + + \ No newline at end of file diff --git a/platform/runtime/base/branding/src/main/cfg/branding.properties b/platform/runtime/base/branding/src/main/cfg/branding.properties new file mode 100644 index 00000000..12a1cf82 --- /dev/null +++ b/platform/runtime/base/branding/src/main/cfg/branding.properties @@ -0,0 +1,36 @@ +### +# ~~~~~~licensing~~~~~~ +# branding +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +welcome = \ +\u001B[36m :::::::::: :::: ::: ::::::::::: ::: ::: ::: ::: ::: \u001B[0m\r\n\ +\u001B[36m :+: :+:+: :+: :+: :+: :+: :+: :+: :+: :+: \u001B[0m\r\n\ +\u001B[36m +:+ :+:+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ \u001B[0m\r\n\ +\u001B[36m +#++:++# +#+ +:+ +#+ +#+ +#++:++#++: +#++:+ +#++: \u001B[0m\r\n\ +\u001B[36m +#+ +#+ +#+#+# +#+ +#+ +#+ +#+ +#+ +#+ \u001B[0m\r\n\ +\u001B[36m #+# #+# #+#+# #+# #+# #+# #+# #+# #+# \u001B[0m\r\n\ +\u001B[36m ########## ### #### ### ### ### ### ### ### \u001B[0m\r\n\ +\r\n\ +\u001B[1m Entaxy \u001B[0m (${project.version})\r\n\ +\u001B[1m Karaf version: \u001B[0m (${karaf.version})\r\n\ +\u001B[1m Camel version: \u001B[0m (${camel.version})\r\n\ +\u001B[1m CXF version: \u001B[0m (${cxf.version})\r\n\ +\r\n\ +Hit '\u001B[1m\u001B[0m' for a list of available commands\r\n\ + and '\u001B[1m[cmd] --help\u001B[0m' for help on a specific command.\r\n\ +Hit '\u001B[1m\u001B[0m' or '\u001B[1mosgi:shutdown\u001B[0m' to shutdown Entaxy.\r\n diff --git a/platform/runtime/base/connecting/LICENSE.txt b/platform/runtime/base/connecting/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/adapter/LICENSE.txt b/platform/runtime/base/connecting/adapter/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/adapter/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/adapter/adapters-core/LICENSE.txt b/platform/runtime/base/connecting/adapter/adapters-core/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/adapter/adapters-core/pom.xml b/platform/runtime/base/connecting/adapter/adapters-core/pom.xml new file mode 100644 index 00000000..ab362bd8 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/pom.xml @@ -0,0 +1,68 @@ + + + + + ru.entaxy.esb.platform.runtime.base.connecting + adapter + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting.adapter + adapters-core + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER :: ADAPTER CORE + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER :: ADAPTER CORE + + + + ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.api, + ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.impl, + ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.metadata, + ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.tracker, + ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.util + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.tracker.AdapterTrackerActivator + + + + + + + + + org.osgi + osgi.core + ${osgi.version} + provided + + + com.google.code.gson + gson + ${gson.version} + + + ru.entaxy.esb.system.management.blueprint.generator + blueprint-generator + ${project.version} + + + ru.entaxy.esb.platform.runtime.base.connecting.generator + generator-factory + ${project.version} + + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/api/Adapter.java b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/api/Adapter.java new file mode 100644 index 00000000..4f6bb2d5 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/api/Adapter.java @@ -0,0 +1,51 @@ +/*- + * ~~~~~~licensing~~~~~~ + * adapters-core + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.api; + +import ru.entaxy.esb.system.management.blueprint.generator.Blueprint; + +import java.util.HashMap; +import java.util.Map; + +public interface Adapter { + public static final String ADAPTER_CLASS_HEADER_NAME = "Entaxy-Adapter-Class"; + public static final String ADAPTER_HEADER_NAME = "Entaxy-Adapter"; + public default boolean isInited() { + return false; + } + public default String getId() { + return "none"; + } + public default String getName() { + return "Undefined"; + } + public default String getDescription() { + return "Undefined"; + } + public default Map getOptions() { + return new HashMap<>(); + } + public default Map getProperties() { + return new HashMap<>(); + } + public default Blueprint generate(String type, Map map) throws Exception { + return null; + } +} diff --git a/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/impl/DefaultAdapter.java b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/impl/DefaultAdapter.java new file mode 100644 index 00000000..726745d0 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/impl/DefaultAdapter.java @@ -0,0 +1,164 @@ +/*- + * ~~~~~~licensing~~~~~~ + * adapters-core + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.impl; + +import com.google.gson.*; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.api.Adapter; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.metadata.AdapterFieldElement; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.metadata.AdapterGeneratorElement; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.metadata.AdapterMetadataElement; +import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generator; +import ru.entaxy.esb.platform.runtime.base.connecting.generator.factory.GeneratorFactory; +import ru.entaxy.esb.platform.runtime.base.connecting.generator.ftl.FTLGenerator; +import ru.entaxy.esb.system.management.blueprint.generator.Blueprint; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.stream.Collectors; + +public class DefaultAdapter implements Adapter { + + protected static final Logger log = LoggerFactory.getLogger(DefaultAdapter.class); + + protected BundleContext bundleContext; + + protected boolean isInited = false; + protected String defaultId = "none"; + protected String defaultName = "Undefined"; + protected String defaultDescription = "Undefined"; + protected AdapterMetadataElement adapterMetadata; + protected Map generatorList = new HashMap<>(); + + public DefaultAdapter(BundleContext bundleContext) throws IOException { + this.bundleContext = bundleContext; + log.debug("Constructor of adapter {}", DefaultAdapter.class.getName()); + this.isInited = this.init(); + } + + protected boolean init() throws IOException { + URL metadataUrl = this.bundleContext.getBundle().getEntry("/ru/entaxy/adapter/metadata.json"); + log.debug("Json URL is {}", metadataUrl.toString()); + + String metadata = new BufferedReader ( + new InputStreamReader( + metadataUrl.openStream(), StandardCharsets.UTF_8)) + .lines() + .collect(Collectors.joining("\n")); + + log.debug("Adapter json description: \n" + metadata); + + GsonBuilder builder = new GsonBuilder(); + Gson gson = builder.create(); + + JsonElement je = (new JsonParser()).parse(metadata); + JsonObject root = je.getAsJsonObject(); + + JsonElement adapterElement = root.get("adapter"); + + this.adapterMetadata = gson.fromJson(adapterElement, AdapterMetadataElement.class); + + initGenerators(adapterMetadata.getGenerators()); + + return this.adapterMetadata != null && !generatorList.isEmpty(); + } + + private void initGenerators(List generators) { + for (AdapterGeneratorElement generator: generators) { + String usageType = generator.getType(); + String generatorType = generator.getGenerator(); + generatorList.put(usageType, + GeneratorFactory.createGenerator(generatorType, usageType, bundleContext)); + } + log.debug("generatorList: " + generatorList); + //TODO checkGeneratorList(); + } + + /* Interface */ + + @Override + public boolean isInited() { + return isInited; + } + + @Override + public String getId() { + return this.isInited?this.adapterMetadata.getId():this.defaultId; + } + + public void setId(String id) { + this.adapterMetadata.setId(id); + } + + @Override + public String getName() { + return this.isInited?this.adapterMetadata.getName():this.defaultName; + } + + public void setName(String name) { + this.adapterMetadata.setName(name); + } + + @Override + public String getDescription() { + return this.isInited?this.adapterMetadata.getDescription():this.defaultDescription; + } + + public void setDescription(String description) { + this.adapterMetadata.setDescription(description); + } + + @Override + public Map getProperties(){ + return this.adapterMetadata.getFields() + .stream() + .filter(field -> field.isProperty()) + .collect(Collectors.toMap(AdapterFieldElement::getName, AdapterFieldElement::getType)); + } + + @Override + public Map getOptions(){ + return this.adapterMetadata.getFields() + .stream() + .filter(field -> field.isOption()) + .collect(Collectors.toMap(AdapterFieldElement::getName, AdapterFieldElement::getType)); + } + + @Override + public Blueprint generate(String type, Map map) throws Exception { + FTLGenerator generator = (FTLGenerator) generatorList.get(type); + if (null == generator) { + throw new NoSuchElementException(type + " generator missed in generator list."); + } + // TODO: 09.07.2021 Artifact wrapper needed instead of Blueprint (not only blueprint can be return from generator) + Blueprint result = generator.generate(map); + + return result; + } +} diff --git a/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/metadata/AdapterFieldElement.java b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/metadata/AdapterFieldElement.java new file mode 100644 index 00000000..8ed583b2 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/metadata/AdapterFieldElement.java @@ -0,0 +1,71 @@ +/*- + * ~~~~~~licensing~~~~~~ + * adapters-core + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.metadata; + +public class AdapterFieldElement { + + protected String name; + protected String type = "String"; + protected boolean property = false; + protected boolean option = false; + protected String defaultValue = ""; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public boolean isProperty() { + return property; + } + + public void setProperty(boolean isProperty) { + this.property = isProperty; + } + + public boolean isOption() { + return option; + } + + public void setOption(boolean isOption) { + this.option = isOption; + } + + public String getDefault() { + return defaultValue; + } + + public void setDefault(String defaultValue) { + this.defaultValue = defaultValue; + } + + +} diff --git a/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/metadata/AdapterGeneratorElement.java b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/metadata/AdapterGeneratorElement.java new file mode 100644 index 00000000..63173b8f --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/metadata/AdapterGeneratorElement.java @@ -0,0 +1,47 @@ +/*- + * ~~~~~~licensing~~~~~~ + * adapters-core + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.metadata; + +public class AdapterGeneratorElement { + protected String type; + protected String generator = "FTLGenerator"; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getGenerator() { + return generator; + } + + public void setGenerator(String generator) { + this.generator = generator; + } + + public String toString() { + return "AdapterGeneratorElement: " + + "{'type': '" + type + "', " + + "'generator': '" + generator + "'}"; + } +} diff --git a/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/metadata/AdapterMetadataElement.java b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/metadata/AdapterMetadataElement.java new file mode 100644 index 00000000..3c4803f0 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/metadata/AdapterMetadataElement.java @@ -0,0 +1,79 @@ +/*- + * ~~~~~~licensing~~~~~~ + * adapters-core + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.metadata; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +public class AdapterMetadataElement { + + protected static final Logger log = LoggerFactory.getLogger(AdapterMetadataElement.class); + + protected String id; + protected String name; + protected String description; + + protected List fields = new ArrayList<>(); + + public List getGenerators() { + return generators; + } + + public void setGenerators(List generators) { + this.generators = generators; + } + + protected List generators = new ArrayList(); + + public void addField(AdapterFieldElement field) { + this.fields.add(field); + } + + public int getFieldsCount() { + return this.fields.size(); + } + + public List getFields() { + return fields; + } + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/tracker/AdapterHelper.java b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/tracker/AdapterHelper.java new file mode 100644 index 00000000..3eb4b078 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/tracker/AdapterHelper.java @@ -0,0 +1,91 @@ +/*- + * ~~~~~~licensing~~~~~~ + * adapters-core + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.tracker; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.osgi.framework.wiring.BundleWiring; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.api.Adapter; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +public class AdapterHelper { + + protected static final Logger log = LoggerFactory.getLogger(AdapterHelper.class); + + protected BundleContext bundleContext; + + protected List objects = new ArrayList<>(); + protected List registrations = new ArrayList<>(); + + public AdapterHelper(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + public void create(Bundle targetBundle, String className) { + log.info("Creating adapter in " + targetBundle.getSymbolicName() + + " of class " + targetBundle.getClass().getName() + + " having context of " + targetBundle.getBundleContext().getClass().getName()); + BundleWiring wiring = targetBundle.adapt(BundleWiring.class); + ClassLoader cl = wiring.getClassLoader(); + try { + Class clazz = cl.loadClass(className); + Constructor constructor = clazz.getConstructor(BundleContext.class); + Object obj = constructor.newInstance(targetBundle.getBundleContext()); + log.debug("Created object of class {}", obj.getClass().getName()); + + Adapter adapter = (Adapter)obj; + if (!adapter.isInited()) { + log.warn("Adapter initialization failed."); + return; + } + + Hashtable properties = new Hashtable<>(); + properties.put("adapter.id", adapter.getId()); + properties.put("adapter.name", adapter.getName()); + properties.put("adapter.description", adapter.getDescription()); + + ServiceRegistration sr = targetBundle.getBundleContext().registerService(new String[] {Adapter.class.getName()}, obj, properties); + +// // print out adapter info +// String props = "\n"; +// for (Map.Entry entry: adapter.getProperties().entrySet()) +// props += entry.getKey() + ": " + entry.getValue() + "\n"; +// String opts = "\n"; +// for (Map.Entry entry: adapter.getOptions().entrySet()) +// opts += entry.getKey() + ": " + entry.getValue() + "\n"; +// +// log.info("\n\n\tFINAL ADAPTER INFO: \nID: {}\nDescription: {}\nProperties:{}Options:{}" +// , adapter.getId() +// , adapter.getDescription() +// , props +// , opts); + + } catch (Exception e) { + log.error("Can't create adapter:\n", e); + } + } +} diff --git a/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/tracker/AdapterTracker.java b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/tracker/AdapterTracker.java new file mode 100644 index 00000000..23c8bd0b --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/tracker/AdapterTracker.java @@ -0,0 +1,56 @@ +/*- + * ~~~~~~licensing~~~~~~ + * adapters-core + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.tracker; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; +import org.osgi.util.tracker.BundleTracker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.api.Adapter; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.impl.DefaultAdapter; + +import java.util.Optional; + +public class AdapterTracker extends BundleTracker { + + protected static final Logger log = LoggerFactory.getLogger(AdapterTracker.class); + + protected AdapterHelper helper; + + @SuppressWarnings("unchecked") + public AdapterTracker(BundleContext bundleContext) { + super(bundleContext, Bundle.ACTIVE, null); + this.helper = new AdapterHelper(bundleContext); + } + + @Override + public Object addingBundle(Bundle bundle, BundleEvent event) { + String isAdapter = bundle.getHeaders().get(Adapter.ADAPTER_HEADER_NAME); + if (Boolean.valueOf(isAdapter)) { + String className = Optional.ofNullable(bundle.getHeaders(). + get(Adapter.ADAPTER_CLASS_HEADER_NAME)).orElse(DefaultAdapter.class.getName()); + log.debug("Adapter class " + className + " FOUND IN BUNDLE " + bundle.getSymbolicName()); + helper.create(bundle, className); + } + return bundle; + } +} diff --git a/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/tracker/AdapterTrackerActivator.java b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/tracker/AdapterTrackerActivator.java new file mode 100644 index 00000000..7ff5c832 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/tracker/AdapterTrackerActivator.java @@ -0,0 +1,44 @@ +/*- + * ~~~~~~licensing~~~~~~ + * adapters-core + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.tracker; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AdapterTrackerActivator implements BundleActivator { + + protected static final Logger log = LoggerFactory.getLogger(AdapterTrackerActivator.class); + + protected AdapterTracker tracker; + + @Override + public void start(BundleContext context) throws Exception { + tracker = new AdapterTracker(context); + tracker.open(); + } + + @Override + public void stop(BundleContext context) throws Exception { + tracker.close(); + } + +} diff --git a/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/util/AdapterUtil.java b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/util/AdapterUtil.java new file mode 100644 index 00000000..c74dcecc --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/util/AdapterUtil.java @@ -0,0 +1,43 @@ +/*- + * ~~~~~~licensing~~~~~~ + * adapters-core + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.util; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.api.Adapter; + +import java.util.Collection; + +public class AdapterUtil { + private static final Logger log = LoggerFactory.getLogger(AdapterUtil.class); + public static Adapter getAdapter(String adapterName) throws InvalidSyntaxException { + String filter = "(adapter.name=" + adapterName + ")"; + log.debug("Get adapter service filtered by: " + filter); + BundleContext bundleContext = FrameworkUtil.getBundle(Adapter.class).getBundleContext(); + Collection> referenceList = bundleContext.getServiceReferences(Adapter.class, filter); + Adapter adapter = bundleContext.getService(referenceList.iterator().next()); + + return adapter; + } +} diff --git a/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/util/ConnectionUsageType.java b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/util/ConnectionUsageType.java new file mode 100644 index 00000000..c42a6b81 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/adapters-core/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/adapter/core/util/ConnectionUsageType.java @@ -0,0 +1,27 @@ +/*- + * ~~~~~~licensing~~~~~~ + * adapters-core + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.util; + +public class ConnectionUsageType { // TODO: 09.07.2021 maybe enum usage instead of class planning + public static final String INIT = "init"; + public static final String REF = "ref"; + public static final String FROM = "from"; + public static final String TO = "to"; +} diff --git a/platform/runtime/base/connecting/adapter/artemis-adapter/LICENSE.txt b/platform/runtime/base/connecting/adapter/artemis-adapter/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/adapter/artemis-adapter/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/adapter/artemis-adapter/pom.xml b/platform/runtime/base/connecting/adapter/artemis-adapter/pom.xml new file mode 100644 index 00000000..f87393f4 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/artemis-adapter/pom.xml @@ -0,0 +1,39 @@ + + + + + ru.entaxy.esb.platform.runtime.base.connecting + adapter + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting.adapter + artemis-adapter + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER :: ARTEMIS ADAPTER + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER :: ARTEMIS ADAPTER + + + + * + + + + + + org.apache.felix + maven-bundle-plugin + true + + + true + + + + + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/ru/entaxy/adapter/metadata.json b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/ru/entaxy/adapter/metadata.json new file mode 100644 index 00000000..b16665df --- /dev/null +++ b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/ru/entaxy/adapter/metadata.json @@ -0,0 +1,689 @@ +{ + "adapter": { + "id": "artemis.adapter.1", + "name": "artemisAdapter", + "description": "Artemis adapter to interact with queues and topics.", + "fields": [ + { + "name": "destinationType", + "type": "String", + "default": "queue", + "property": false, + "option": false + }, + { + "name": "destinationName", + "type": "String", + "property": false, + "option": false + }, + + { + "name": "clientId", + "property": true, + "option": true + }, + { + "name": "connectionFactory", + "type": "ConnectionFactory", + "property": true, + "option": true + }, + { + "name": "disableReplyTo", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "durableSubscriptionName", + "property": true, + "option": true + }, + { + "name": "jmsMessageType", + "type": "JmsMessageType", + "property": true, + "option": true + }, + { + "name": "replyTo", + "property": true, + "option": true + }, + { + "name": "testConnectionOnStartup", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "acknowledgementModeName", + "default": "AUTO_ACKNOWLEDGE", + "property": true, + "option": true + }, + { + "name": "artemisConsumerPriority", + "type": "int", + "property": true, + "option": true + }, + { + "name": "asyncConsumer", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "autoStartup", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "cacheLevel", + "type": "int", + "property": true, + "option": true + }, + { + "name": "cacheLevelName", + "default": "CACHE_AUTO", + "property": true, + "option": true + }, + { + "name": "concurrentConsumers", + "type": "int", + "default": "1", + "property": true, + "option": true + }, + { + "name": "maxConcurrentConsumers", + "type": "int", + "property": true, + "option": true + }, + { + "name": "replyToDeliveryPersistent", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "selector", + "property": true, + "option": true + }, + { + "name": "subscriptionDurable", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "subscriptionName", + "property": true, + "option": true + }, + { + "name": "subscriptionShared", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "acceptMessagesWhileStopping", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "allowReplyManagerQuickStop", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "consumerType", + "type": "ConsumerType", + "default": "Default", + "property": true, + "option": true + }, + { + "name": "defaultTaskExecutorType", + "type": "DefaultTaskExecutorType", + "property": true, + "option": true + }, + { + "name": "eagerLoadingOfProperties", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "eagerPoisonBody", + "default": "Poison JMS message due to ${exception.message}", + "property": true, + "option": true + }, + { + "name": "exceptionHandler", + "type": "ExceptionHandler", + "option": true + }, + { + "name": "exchangePattern", + "type": "ExchangePattern", + "option": true + }, + { + "name": "exposeListenerSession", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "replyToSameDestinationAllowed", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "taskExecutor", + "type": "TaskExecutor", + "property": true, + "option": true + }, + { + "name": "deliveryDelay", + "type": "long", + "default": "-1", + "property": true, + "option": true + }, + { + "name": "deliveryMode", + "type": "Integer", + "property": true, + "option": true + }, + { + "name": "deliveryPersistent", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "explicitQosEnabled", + "type": "Boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "formatDateHeadersToIso8601", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "lazyStartProducer", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "preserveMessageQos", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "priority", + "type": "int", + "default": "4", + "property": true, + "option": true + }, + { + "name": "replyToConcurrentConsumers", + "type": "int", + "default": "1", + "property": true, + "option": true + }, + { + "name": "replyToMaxConcurrentConsumers", + "type": "int", + "property": true, + "option": true + }, + { + "name": "replyToOnTimeoutMaxConcurrentConsumers", + "type": "int", + "default": "1", + "property": true, + "option": true + }, + { + "name": "replyToOverride", + "property": true, + "option": true + }, + { + "name": "replyToType", + "type": "ReplyToType", + "property": true, + "option": true + }, + { + "name": "requestTimeout", + "type": "long", + "default": "20000", + "property": true, + "option": true + }, + { + "name": "timeToLive", + "type": "long", + "default": "-1", + "property": true, + "option": true + }, + { + "name": "allowAdditionalHeaders", + "property": true, + "option": true + }, + { + "name": "allowNullBody", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "alwaysCopyMessage", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "correlationProperty", + "property": true, + "option": true + }, + { + "name": "disableTimeToLive", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "forceSendOriginalMessage", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "includeSentJMSMessageID", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "replyToCacheLevelName", + "property": true, + "option": true + }, + { + "name": "replyToDestinationSelectorName", + "property": true, + "option": true + }, + { + "name": "streamMessageTypeEnabled", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "allowAutoWiredConnectionFactory", + "type": "boolean", + "default": "true", + "property": true + }, + { + "name": "allowAutoWiredDestinationResolver", + "type": "boolean", + "default": "true", + "property": true + }, + { + "name": "allowSerializedHeaders", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "artemisStreamingEnabled", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "asyncStartListener", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "asyncStopListener", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "autowiredEnabled", + "type": "boolean", + "default": "true", + "property": true + }, + { + "name": "configuration", + "type": "JmsConfiguration", + "property": true + }, + { + "name": "destinationResolver", + "type": "DestinationResolver", + "property": true, + "option": true + }, + { + "name": "errorHandler", + "type": "ErrorHandler", + "property": true, + "option": true + }, + { + "name": "exceptionListener", + "type": "ExceptionListener", + "property": true, + "option": true + }, + { + "name": "headerFilterStrategy", + "type": "HeaderFilterStrategy", + "property": true, + "option": true + }, + { + "name": "idleConsumerLimit", + "type": "int", + "default": "1", + "property": true, + "option": true + }, + { + "name": "idleTaskExecutionLimit", + "type": "int", + "default": "1", + "property": true, + "option": true + }, + { + "name": "includeAllJMSXProperties", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "jmsKeyFormatStrategy", + "type": "JmsKeyFormatStrategy", + "property": true, + "option": true + }, + { + "name": "mapJmsMessage", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "maxMessagesPerTask", + "type": "int", + "default": "-1", + "property": true, + "option": true + }, + { + "name": "messageConverter", + "type": "MessageConverter", + "property": true, + "option": true + }, + { + "name": "messageCreatedStrategy", + "type": "MessageCreatedStrategy", + "property": true, + "option": true + }, + { + "name": "messageIdEnabled", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "messageListenerContainerFactory", + "type": "MessageListenerContainerFactory", + "property": true, + "option": true + }, + { + "name": "messageTimestampEnabled", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "pubSubNoLocal", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "queueBrowseStrategy", + "type": "QueueBrowseStrategy", + "property": true + }, + { + "name": "receiveTimeout", + "type": "long", + "default": "1000", + "property": true, + "option": true + }, + { + "name": "recoveryInterval", + "type": "long", + "default": "5000", + "property": true, + "option": true + }, + { + "name": "requestTimeoutCheckerInterval", + "type": "long", + "default": "1000", + "property": true, + "option": true + }, + { + "name": "synchronous", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "transferException", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "transferExchange", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "useMessageIDAsCorrelationID", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "waitForProvisionCorrelationToBeUpdatedCounter", + "type": "int", + "default": "50", + "property": true, + "option": true + }, + { + "name": "waitForProvisionCorrelationToBeUpdatedThreadSleepingTime", + "type": "long", + "default": "100", + "property": true, + "option": true + }, + { + "name": "errorHandlerLoggingLevel", + "type": "LoggingLevel", + "default": "WARN", + "property": true, + "option": true + }, + { + "name": "errorHandlerLogStackTrace", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "password", + "property": true, + "option": true + }, + { + "name": "username", + "property": true, + "option": true + }, + { + "name": "transacted", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "transactedInOut", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "lazyCreateTransactionManager", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "transactionManager", + "type": "PlatformTransactionManager", + "property": true, + "option": true + }, + { + "name": "transactionName", + "property": true, + "option": true + }, + { + "name": "transactionTimeout", + "type": "int", + "default": "-1", + "property": true, + "option": true + } + ], + "generators":[ + { + "type": "pathParameter", + "generator": "", + "config": { + "expession": "${destinationType}:${destinationName}" + } + }, + { + "type": "init", + "generator": "" + }, + { + "type": "ref", + "generator": "" + }, + { + "type": "from", + "generator": "" + }, + { + "type": "to", + "generator": "" + } + ] + } +} \ No newline at end of file diff --git a/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/from.ftl b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/from.ftl new file mode 100644 index 00000000..e2224970 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/from.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + artemis-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#include 'queryParameters.ftl'> + diff --git a/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/init.ftl b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/init.ftl new file mode 100644 index 00000000..4aef063a --- /dev/null +++ b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/init.ftl @@ -0,0 +1,73 @@ +<#-- + ~~~~~~licensing~~~~~~ + artemis-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#assign factoryProperties = ["url", "username", "password", "maxConnections", "maxSessionsPerConnection"]> +<#function exceptFactoryProperties(propertyName)> + <#return !factoryProperties?seq_contains(propertyName)> + + + + + + <#if connection.properties??> + + <#list connection.properties as key, value> + + + + + + + + + + + + + + <#-- //TODO change template for property reference usage instead of text value --> + + <#if connection.properties??> + <#list connection.properties?keys?filter(exceptFactoryProperties) as key> + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/queryParameters.ftl b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/queryParameters.ftl new file mode 100644 index 00000000..b8c74103 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/queryParameters.ftl @@ -0,0 +1,26 @@ +<#-- + ~~~~~~licensing~~~~~~ + artemis-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#assign queryParameters> + <#if connection.options??> + <@compress single_line=true> + ?<#list connection.options as key, value>[=key]=[=value]<#sep>& + + + diff --git a/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/ref.ftl b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/ref.ftl new file mode 100644 index 00000000..805a4c73 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/ref.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + artemis-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> + diff --git a/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/to.ftl b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/to.ftl new file mode 100644 index 00000000..5784e5aa --- /dev/null +++ b/platform/runtime/base/connecting/adapter/artemis-adapter/src/main/resources/template/to.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + artemis-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#include 'queryParameters.ftl'> + diff --git a/platform/runtime/base/connecting/adapter/file-adapter/LICENSE.txt b/platform/runtime/base/connecting/adapter/file-adapter/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/adapter/file-adapter/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/adapter/file-adapter/pom.xml b/platform/runtime/base/connecting/adapter/file-adapter/pom.xml new file mode 100644 index 00000000..51a9de5a --- /dev/null +++ b/platform/runtime/base/connecting/adapter/file-adapter/pom.xml @@ -0,0 +1,40 @@ + + + + + ru.entaxy.esb.platform.runtime.base.connecting + adapter + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting.adapter + file-adapter + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER :: FILE ADAPTER + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER :: FILE ADAPTER + + + + * + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + true + + + + + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/ru/entaxy/adapter/metadata.json b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/ru/entaxy/adapter/metadata.json new file mode 100644 index 00000000..f145fa4f --- /dev/null +++ b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/ru/entaxy/adapter/metadata.json @@ -0,0 +1,540 @@ +{ + "adapter": { + "id": "file.adapter.1", + "name": "fileAdapter", + "description": "File adapter to interact with FS.", + "fields": [ + { + "name": "directoryName", + "type": "File", + "default": "./default-directory/", + "property": false, + "option": false + }, + + { + "name": "bridgeErrorHandler", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "lazyStartProducer", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "autowiredEnabled", + "type": "boolean", + "default": "true", + "property": true, + "option": false + }, + + { + "name": "charset", + "option": true + }, + { + "name": "doneFileName", + "option": true + }, + { + "name": "fileName", + "option": true + }, + { + "name": "delete", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "moveFailed", + "option": true + }, + { + "name": "noop", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "preMove", + "option": true + }, + { + "name": "preSort", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "recursive", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "sendEmptyMessageWhenIdle", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "directoryMustExist", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "exceptionHandler", + "type": "ExceptionHandler", + "option": true + }, + { + "name": "exchangePattern", + "type": "ExchangePattern", + "option": true + }, + { + "name": "extendedAttributes", + "option": true + }, + { + "name": "inProgressRepository", + "type": "IdempotentRepository", + "option": true + }, + { + "name": "IdempotentRepository", + "option": true + }, + { + "name": "onCompletionExceptionHandler", + "type": "ExceptionHandler", + "option": true + }, + { + "name": "pollStrategy", + "type": "PollingConsumerPollStrategy", + "option": true + }, + { + "name": "probeContentType", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "processStrategy", + "type": "GenericFileProcessStrategy", + "option": true + }, + { + "name": "startingDirectoryMustExist", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "startingDirectoryMustHaveAccess", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "appendChars", + "option": true + }, + { + "name": "fileExist", + "type": "GenericFileExist", + "default": "Override", + "option": true + }, + { + "name": "flatten", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "jailStartingDirectory", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "moveExisting", + "option": true + }, + { + "name": "tempFileName", + "option": true + }, + { + "name": "tempPrefix", + "option": true + }, + { + "name": "allowNullBody", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "chmod", + "option": true + }, + { + "name": "chmodDirectory", + "option": true + }, + { + "name": "eagerDeleteTargetFile", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "forceWrites", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "keepLastModified", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "moveExistingFileStrategy", + "type": "FileMoveExistingStrategy", + "option": true + }, + { + "name": "autoCreate", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "bufferSize", + "type": "int", + "default": "131072", + "option": true + }, + { + "name": "copyAndDeleteOnRenameFail", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "renameUsingCopy", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "synchronous", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "antExclude", + "option": true + }, + { + "name": "antFilterCaseSensitive", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "antInclude", + "option": true + }, + { + "name": "eagerMaxMessagesPerPoll", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "exclude", + "option": true + }, + { + "name": "excludeExt", + "option": true + }, + { + "name": "filter", + "type": "GenericFileFilter", + "option": true + }, + { + "name": "filterDirectory", + "option": true + }, + { + "name": "filterFile", + "option": true + }, + { + "name": "idempotent", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "idempotentKey", + "option": true + }, + { + "name": "idempotentRepository", + "type": "IdempotentRepository", + "option": true + }, + { + "name": "include", + "option": true + }, + { + "name": "includeExt", + "option": true + }, + { + "name": "maxDepth", + "type": "int", + "default": "2147483647", + "option": true + }, + { + "name": "maxMessagesPerPoll", + "type": "int", + "option": true + }, + { + "name": "minDepth", + "type": "int", + "option": true + }, + { + "name": "move", + "option": true + }, + { + "name": "exclusiveReadLockStrategy", + "type": "GenericFileExclusiveReadLockStrategy", + "option": true + }, + { + "name": "readLock", + "default": "none", + "option": true + }, + { + "name": "readLockCheckInterval", + "type": "long", + "default": "1000", + "option": true + }, + { + "name": "readLockDeleteOrphanLockFiles", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "readLockIdempotentReleaseAsync", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "readLockIdempotentReleaseAsyncPoolSize", + "type": "int", + "option": true + }, + { + "name": "readLockIdempotentReleaseDelay", + "type": "int", + "option": true + }, + { + "name": "readLockIdempotentReleaseExecutorService", + "type": "ScheduledExecutorService", + "option": true + }, + { + "name": "readLockLoggingLevel", + "type": "LoggingLevel", + "default": "DEBUG", + "option": true + }, + { + "name": "readLockMarkerFile", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "readLockMinAge", + "type": "long", + "default": "0", + "option": true + }, + { + "name": "readLockMinLength", + "type": "long", + "default": "1", + "option": true + }, + { + "name": "readLockRemoveOnCommit", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "readLockRemoveOnRollback", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "readLockTimeout", + "type": "long", + "default": "10000", + "option": true + }, + { + "name": "backoffErrorThreshold", + "type": "int", + "option": true + }, + { + "name": "backoffIdleThreshold", + "type": "int", + "option": true + }, + { + "name": "backoffMultiplier", + "type": "int", + "option": true + }, + { + "name": "delay", + "type": "long", + "default": "500", + "option": true + }, + { + "name": "greedy", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "initialDelay", + "type": "long", + "default": "1000", + "option": true + }, + { + "name": "repeatCount", + "type": "long", + "default": "0", + "option": true + }, + { + "name": "runLoggingLevel", + "type": "LoggingLevel", + "default": "TRACE", + "option": true + }, + { + "name": "scheduledExecutorService", + "type": "ScheduledExecutorService", + "option": true + }, + { + "name": "scheduler", + "type": "Object", + "default": "none", + "option": true + }, + { + "name": "schedulerProperties", + "type": "Map", + "option": true + }, + { + "name": "startScheduler", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "timeUnit", + "type": "TimeUnit", + "default": "MILLISECONDS", + "option": true + }, + { + "name": "useFixedDelay", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "shuffle", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "sortBy", + "option": true + }, + { + "name": "sorter", + "type": "Comparator", + "option": true + } + ], + "generators":[ + { + "type": "pathParameter", + "generator": "", + "config": { + "expession": "${directoryName}" + } + }, + { + "type": "init", + "generator": "" + }, + { + "type": "ref", + "generator": "" + }, + { + "type": "from", + "generator": "" + }, + { + "type": "to", + "generator": "" + } + ] + } +} \ No newline at end of file diff --git a/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/from.ftl b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/from.ftl new file mode 100644 index 00000000..f477e33a --- /dev/null +++ b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/from.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + file-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#include 'queryParameters.ftl'> + diff --git a/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/init.ftl b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/init.ftl new file mode 100644 index 00000000..89322de7 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/init.ftl @@ -0,0 +1,53 @@ +<#-- + ~~~~~~licensing~~~~~~ + file-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> + + + + + <#if connection.properties??> + + <#list connection.properties as key, value> + + + + + + + + + + + + + + <#if connection.properties??> + <#list connection.properties as key, value> + + + + + + diff --git a/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/queryParameters.ftl b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/queryParameters.ftl new file mode 100644 index 00000000..6c462f2c --- /dev/null +++ b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/queryParameters.ftl @@ -0,0 +1,26 @@ +<#-- + ~~~~~~licensing~~~~~~ + file-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#assign queryParameters> + <#if connection.options??> + <@compress single_line=true> + ?<#list connection.options as key, value>[=key]=[=value]<#sep>& + + + diff --git a/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/ref.ftl b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/ref.ftl new file mode 100644 index 00000000..39040861 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/ref.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + file-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> + diff --git a/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/to.ftl b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/to.ftl new file mode 100644 index 00000000..0ecfe249 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/file-adapter/src/main/resources/template/to.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + file-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#include 'queryParameters.ftl'> + diff --git a/platform/runtime/base/connecting/adapter/jms-adapter/LICENSE.txt b/platform/runtime/base/connecting/adapter/jms-adapter/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/adapter/jms-adapter/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/adapter/jms-adapter/pom.xml b/platform/runtime/base/connecting/adapter/jms-adapter/pom.xml new file mode 100644 index 00000000..ec5681fe --- /dev/null +++ b/platform/runtime/base/connecting/adapter/jms-adapter/pom.xml @@ -0,0 +1,39 @@ + + + + + ru.entaxy.esb.platform.runtime.base.connecting + adapter + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting.adapter + jms-adapter + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER :: JMS ADAPTER + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER :: JMS ADAPTER + + + + * + + + + + + org.apache.felix + maven-bundle-plugin + true + + + true + + + + + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/ru/entaxy/adapter/metadata.json b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/ru/entaxy/adapter/metadata.json new file mode 100644 index 00000000..d7a9c40a --- /dev/null +++ b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/ru/entaxy/adapter/metadata.json @@ -0,0 +1,689 @@ +{ + "adapter": { + "id": "jms.adapter.1", + "name": "jmsAdapter", + "description": "JMS adapter to interact with queues and topics.", + "fields": [ + { + "name": "destinationType", + "type": "String", + "default": "queue", + "property": false, + "option": false + }, + { + "name": "destinationName", + "type": "String", + "property": false, + "option": false + }, + + { + "name": "clientId", + "property": true, + "option": true + }, + { + "name": "connectionFactory", + "type": "ConnectionFactory", + "property": true, + "option": true + }, + { + "name": "disableReplyTo", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "durableSubscriptionName", + "property": true, + "option": true + }, + { + "name": "jmsMessageType", + "type": "JmsMessageType", + "property": true, + "option": true + }, + { + "name": "replyTo", + "property": true, + "option": true + }, + { + "name": "testConnectionOnStartup", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "acknowledgementModeName", + "default": "AUTO_ACKNOWLEDGE", + "property": true, + "option": true + }, + { + "name": "artemisConsumerPriority", + "type": "int", + "property": true, + "option": true + }, + { + "name": "asyncConsumer", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "autoStartup", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "cacheLevel", + "type": "int", + "property": true, + "option": true + }, + { + "name": "cacheLevelName", + "default": "CACHE_AUTO", + "property": true, + "option": true + }, + { + "name": "concurrentConsumers", + "type": "int", + "default": "1", + "property": true, + "option": true + }, + { + "name": "maxConcurrentConsumers", + "type": "int", + "property": true, + "option": true + }, + { + "name": "replyToDeliveryPersistent", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "selector", + "property": true, + "option": true + }, + { + "name": "subscriptionDurable", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "subscriptionName", + "property": true, + "option": true + }, + { + "name": "subscriptionShared", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "acceptMessagesWhileStopping", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "allowReplyManagerQuickStop", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "consumerType", + "type": "ConsumerType", + "default": "Default", + "property": true, + "option": true + }, + { + "name": "defaultTaskExecutorType", + "type": "DefaultTaskExecutorType", + "property": true, + "option": true + }, + { + "name": "eagerLoadingOfProperties", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "eagerPoisonBody", + "default": "Poison JMS message due to ${exception.message}", + "property": true, + "option": true + }, + { + "name": "exceptionHandler", + "type": "ExceptionHandler", + "option": true + }, + { + "name": "exchangePattern", + "type": "ExchangePattern", + "option": true + }, + { + "name": "exposeListenerSession", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "replyToSameDestinationAllowed", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "taskExecutor", + "type": "TaskExecutor", + "property": true, + "option": true + }, + { + "name": "deliveryDelay", + "type": "long", + "default": "-1", + "property": true, + "option": true + }, + { + "name": "deliveryMode", + "type": "Integer", + "property": true, + "option": true + }, + { + "name": "deliveryPersistent", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "explicitQosEnabled", + "type": "Boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "formatDateHeadersToIso8601", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "lazyStartProducer", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "preserveMessageQos", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "priority", + "type": "int", + "default": "4", + "property": true, + "option": true + }, + { + "name": "replyToConcurrentConsumers", + "type": "int", + "default": "1", + "property": true, + "option": true + }, + { + "name": "replyToMaxConcurrentConsumers", + "type": "int", + "property": true, + "option": true + }, + { + "name": "replyToOnTimeoutMaxConcurrentConsumers", + "type": "int", + "default": "1", + "property": true, + "option": true + }, + { + "name": "replyToOverride", + "property": true, + "option": true + }, + { + "name": "replyToType", + "type": "ReplyToType", + "property": true, + "option": true + }, + { + "name": "requestTimeout", + "type": "long", + "default": "20000", + "property": true, + "option": true + }, + { + "name": "timeToLive", + "type": "long", + "default": "-1", + "property": true, + "option": true + }, + { + "name": "allowAdditionalHeaders", + "property": true, + "option": true + }, + { + "name": "allowNullBody", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "alwaysCopyMessage", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "correlationProperty", + "property": true, + "option": true + }, + { + "name": "disableTimeToLive", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "forceSendOriginalMessage", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "includeSentJMSMessageID", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "replyToCacheLevelName", + "property": true, + "option": true + }, + { + "name": "replyToDestinationSelectorName", + "property": true, + "option": true + }, + { + "name": "streamMessageTypeEnabled", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "allowAutoWiredConnectionFactory", + "type": "boolean", + "default": "true", + "property": true + }, + { + "name": "allowAutoWiredDestinationResolver", + "type": "boolean", + "default": "true", + "property": true + }, + { + "name": "allowSerializedHeaders", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "artemisStreamingEnabled", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "asyncStartListener", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "asyncStopListener", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "autowiredEnabled", + "type": "boolean", + "default": "true", + "property": true + }, + { + "name": "configuration", + "type": "JmsConfiguration", + "property": true + }, + { + "name": "destinationResolver", + "type": "DestinationResolver", + "property": true, + "option": true + }, + { + "name": "errorHandler", + "type": "ErrorHandler", + "property": true, + "option": true + }, + { + "name": "exceptionListener", + "type": "ExceptionListener", + "property": true, + "option": true + }, + { + "name": "headerFilterStrategy", + "type": "HeaderFilterStrategy", + "property": true, + "option": true + }, + { + "name": "idleConsumerLimit", + "type": "int", + "default": "1", + "property": true, + "option": true + }, + { + "name": "idleTaskExecutionLimit", + "type": "int", + "default": "1", + "property": true, + "option": true + }, + { + "name": "includeAllJMSXProperties", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "jmsKeyFormatStrategy", + "type": "JmsKeyFormatStrategy", + "property": true, + "option": true + }, + { + "name": "mapJmsMessage", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "maxMessagesPerTask", + "type": "int", + "default": "-1", + "property": true, + "option": true + }, + { + "name": "messageConverter", + "type": "MessageConverter", + "property": true, + "option": true + }, + { + "name": "messageCreatedStrategy", + "type": "MessageCreatedStrategy", + "property": true, + "option": true + }, + { + "name": "messageIdEnabled", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "messageListenerContainerFactory", + "type": "MessageListenerContainerFactory", + "property": true, + "option": true + }, + { + "name": "messageTimestampEnabled", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "pubSubNoLocal", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "queueBrowseStrategy", + "type": "QueueBrowseStrategy", + "property": true + }, + { + "name": "receiveTimeout", + "type": "long", + "default": "1000", + "property": true, + "option": true + }, + { + "name": "recoveryInterval", + "type": "long", + "default": "5000", + "property": true, + "option": true + }, + { + "name": "requestTimeoutCheckerInterval", + "type": "long", + "default": "1000", + "property": true, + "option": true + }, + { + "name": "synchronous", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "transferException", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "transferExchange", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "useMessageIDAsCorrelationID", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "waitForProvisionCorrelationToBeUpdatedCounter", + "type": "int", + "default": "50", + "property": true, + "option": true + }, + { + "name": "waitForProvisionCorrelationToBeUpdatedThreadSleepingTime", + "type": "long", + "default": "100", + "property": true, + "option": true + }, + { + "name": "errorHandlerLoggingLevel", + "type": "LoggingLevel", + "default": "WARN", + "property": true, + "option": true + }, + { + "name": "errorHandlerLogStackTrace", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "password", + "property": true, + "option": true + }, + { + "name": "username", + "property": true, + "option": true + }, + { + "name": "transacted", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "transactedInOut", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "lazyCreateTransactionManager", + "type": "boolean", + "default": "true", + "property": true, + "option": true + }, + { + "name": "transactionManager", + "type": "PlatformTransactionManager", + "property": true, + "option": true + }, + { + "name": "transactionName", + "property": true, + "option": true + }, + { + "name": "transactionTimeout", + "type": "int", + "default": "-1", + "property": true, + "option": true + } + ], + "generators":[ + { + "type": "pathParameter", + "generator": "", + "config": { + "expession": "${destinationType}:${destinationName}" + } + }, + { + "type": "init", + "generator": "" + }, + { + "type": "ref", + "generator": "" + }, + { + "type": "from", + "generator": "" + }, + { + "type": "to", + "generator": "" + } + ] + } +} \ No newline at end of file diff --git a/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/from.ftl b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/from.ftl new file mode 100644 index 00000000..50f279af --- /dev/null +++ b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/from.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + jms-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#include 'queryParameters.ftl'> + diff --git a/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/init.ftl b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/init.ftl new file mode 100644 index 00000000..4d23e3a1 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/init.ftl @@ -0,0 +1,57 @@ +<#-- + ~~~~~~licensing~~~~~~ + jms-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> + + + + + <#if connection.properties??> + + <#list connection.properties as key, value> + + + + + + + + + + + + + + <#-- //TODO change template for property reference usage instead of text value --> + + <#if connection.properties??> + <#list connection.properties as key, value> + + + + + + + + diff --git a/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/queryParameters.ftl b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/queryParameters.ftl new file mode 100644 index 00000000..f5cef24f --- /dev/null +++ b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/queryParameters.ftl @@ -0,0 +1,26 @@ +<#-- + ~~~~~~licensing~~~~~~ + jms-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#assign queryParameters> + <#if connection.options??> + <@compress single_line=true> + ?<#list connection.options as key, value>[=key]=[=value]<#sep>& + + + diff --git a/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/ref.ftl b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/ref.ftl new file mode 100644 index 00000000..1e7f4020 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/ref.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + jms-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> + diff --git a/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/to.ftl b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/to.ftl new file mode 100644 index 00000000..af8b51c5 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/jms-adapter/src/main/resources/template/to.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + jms-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#include 'queryParameters.ftl'> + diff --git a/platform/runtime/base/connecting/adapter/pom.xml b/platform/runtime/base/connecting/adapter/pom.xml new file mode 100644 index 00000000..16335b88 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/pom.xml @@ -0,0 +1,26 @@ + + + + + ru.entaxy.esb.platform.runtime.base + connecting + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting + adapter + pom + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER + + + adapters-core + file-adapter + jms-adapter + artemis-adapter + postgresql-adapter + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/adapter/postgresql-adapter/LICENSE.txt b/platform/runtime/base/connecting/adapter/postgresql-adapter/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/adapter/postgresql-adapter/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/adapter/postgresql-adapter/pom.xml b/platform/runtime/base/connecting/adapter/postgresql-adapter/pom.xml new file mode 100644 index 00000000..15a411f0 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/postgresql-adapter/pom.xml @@ -0,0 +1,47 @@ + + + + + ru.entaxy.esb.platform.runtime.base.connecting + adapter + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting.adapter + postgresql-adapter + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER :: POSTGRESQL ADAPTER + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: ADAPTER :: POSTGRESQL ADAPTER + + + + * + + + + + + org.apache.felix + maven-bundle-plugin + true + + + true + + + + + + + + + + org.apache.camel + camel-jdbc + ${camel.version} + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/ru/entaxy/adapter/metadata.json b/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/ru/entaxy/adapter/metadata.json new file mode 100644 index 00000000..48a13f3a --- /dev/null +++ b/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/ru/entaxy/adapter/metadata.json @@ -0,0 +1,134 @@ +{ + "adapter": { + "id": "postgresql.adapter.${postgresql.version}", + "name": "postgresqlAdapter", + "description": "Postgresql adapter to interact with databases.", + "fields": [ + { + "name": "dataSourceName", + "type": "String", + "default": "dataSource", + "property": false, + "option": false + }, + + { + "name": "dataSource", + "type": "DataSource", + "property": true + }, + { + "name": "lazyStartProducer", + "type": "boolean", + "default": "false", + "property": true, + "option": true + }, + { + "name": "autowiredEnabled", + "type": "boolean", + "default": "true", + "property": true + }, + { + "name": "connectionStrategy", + "type": "ConnectionStrategy", + "property": true, + "option": true + }, + + { + "name": "allowNamedParameters", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "outputClass", + "property": true, + "option": true + }, + { + "name": "outputType", + "type": "JdbcOutputType", + "default": "SelectList", + "option": true + }, + { + "name": "parameters", + "default": "Map", + "option": true + }, + { + "name": "readSize", + "type": "int", + "option": true + }, + { + "name": "resetAutoCommit", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "transacted", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "useGetBytesForBlob", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "useHeadersAsParameters", + "type": "boolean", + "default": "false", + "option": true + }, + { + "name": "useJDBC4ColumnNameAndLabelSemantics", + "type": "boolean", + "default": "true", + "option": true + }, + { + "name": "beanRowMapper", + "type": "BeanRowMapper", + "option": true + }, + { + "name": "prepareStatementStrategy", + "type": "JdbcPrepareStatementStrategy", + "option": true + } + ], + "generators":[ + { + "type": "pathParameter", + "generator": "", + "config": { + "expession": "${dataSourceName}" + } + }, + { + "type": "init", + "generator": "" + }, + { + "type": "ref", + "generator": "" + }, + { + "type": "from", + "generator": "" + }, + { + "type": "to", + "generator": "" + } + ] + } +} \ No newline at end of file diff --git a/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/init.ftl b/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/init.ftl new file mode 100644 index 00000000..db484034 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/init.ftl @@ -0,0 +1,58 @@ +<#-- + ~~~~~~licensing~~~~~~ + postgresql-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> + + + + + <#if connection.properties??> + + <#list connection.properties as key, value> + + + + + + + + + + + + + + <#-- //TODO change template for property reference usage instead of text value --> + + <#if connection.properties??> + <#list connection.properties as key, value> + + + + + + + + diff --git a/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/queryParameters.ftl b/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/queryParameters.ftl new file mode 100644 index 00000000..d34d40f2 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/queryParameters.ftl @@ -0,0 +1,26 @@ +<#-- + ~~~~~~licensing~~~~~~ + postgresql-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#assign queryParameters> + <#if connection.options??> + <@compress single_line=true> + ?<#list connection.options as key, value>[=key]=[=value]<#sep>& + + + diff --git a/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/ref.ftl b/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/ref.ftl new file mode 100644 index 00000000..c264362c --- /dev/null +++ b/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/ref.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + postgresql-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> + diff --git a/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/to.ftl b/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/to.ftl new file mode 100644 index 00000000..7fb81863 --- /dev/null +++ b/platform/runtime/base/connecting/adapter/postgresql-adapter/src/main/resources/template/to.ftl @@ -0,0 +1,21 @@ +<#-- + ~~~~~~licensing~~~~~~ + postgresql-adapter + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> +<#include 'queryParameters.ftl'> + diff --git a/platform/runtime/base/connecting/connection/LICENSE.txt b/platform/runtime/base/connecting/connection/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/connection/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/connection/pom.xml b/platform/runtime/base/connecting/connection/pom.xml new file mode 100644 index 00000000..1b29c7d9 --- /dev/null +++ b/platform/runtime/base/connecting/connection/pom.xml @@ -0,0 +1,38 @@ + + + + + ru.entaxy.esb.platform.runtime.base + connecting + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting + connection + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: CONNECTION + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: CONNECTION + + + + ru.entaxy.esb.platform.runtime.base.connecting.connection, + ru.entaxy.esb.platform.runtime.base.connecting.connection.util + + + + + + ru.entaxy.esb.platform.runtime.base.connecting.adapter + adapters-core + ${project.version} + + + ru.entaxy.esb.system.management.blueprint.generator + blueprint-generator + ${project.version} + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/connection/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/connection/Connection.java b/platform/runtime/base/connecting/connection/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/connection/Connection.java new file mode 100644 index 00000000..89912b79 --- /dev/null +++ b/platform/runtime/base/connecting/connection/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/connection/Connection.java @@ -0,0 +1,35 @@ +/*- + * ~~~~~~licensing~~~~~~ + * connection + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.connection; + +import java.util.Properties; + +public interface Connection { + public static final String PID_PREFIX = "ru.entaxy.esb.connection."; + public String getUuid(); + public String getName(); + public boolean isPlatform(); + public String getAdapterName(); + public String getPathParameter(); + public Properties getProperties(); + public Properties getOptions(); + public String getConfigurationPid(); + public String getScope(); +} diff --git a/platform/runtime/base/connecting/connection/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/connection/ConnectionImpl.java b/platform/runtime/base/connecting/connection/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/connection/ConnectionImpl.java new file mode 100644 index 00000000..10b2e3dd --- /dev/null +++ b/platform/runtime/base/connecting/connection/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/connection/ConnectionImpl.java @@ -0,0 +1,110 @@ +/*- + * ~~~~~~licensing~~~~~~ + * connection + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.connection; + +import java.util.Properties; + +public class ConnectionImpl implements Connection { + private String uuid; + private String name; + private boolean platform; + private String adapterName; + private String pathParameter; + private Properties properties; + private Properties options; + private String scope; + + @Override + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean isPlatform() { + return platform; + } + + public void setPlatform(boolean platform) { + this.platform = platform; + } + + @Override + public String getAdapterName() { + return adapterName; + } + + public void setAdapterName(String adapterName) { + this.adapterName = adapterName; + } + + @Override + public String getPathParameter() { + return pathParameter; + } + + public void setPathParameter(String pathParameter) { + this.pathParameter = pathParameter; + } + + @Override + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + @Override + public Properties getOptions() { + return options; + } + + public void setOptions(Properties options) { + this.options = options; + } + + @Override + public String getConfigurationPid() { + return PID_PREFIX + name.replace('-', '.'); + } + + @Override + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } +} diff --git a/platform/runtime/base/connecting/connection/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/connection/util/ConnectionUtil.java b/platform/runtime/base/connecting/connection/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/connection/util/ConnectionUtil.java new file mode 100644 index 00000000..94d22eca --- /dev/null +++ b/platform/runtime/base/connecting/connection/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/connection/util/ConnectionUtil.java @@ -0,0 +1,56 @@ +/*- + * ~~~~~~licensing~~~~~~ + * connection + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.connection.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.api.Adapter; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.util.AdapterUtil; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.util.ConnectionUsageType; +import ru.entaxy.esb.platform.runtime.base.connecting.connection.Connection; +import ru.entaxy.esb.system.management.blueprint.generator.Blueprint; + +import java.util.HashMap; +import java.util.Map; + +public class ConnectionUtil { + private static final Logger log = LoggerFactory.getLogger(ConnectionUtil.class); + + // TODO: 09.07.2021 Artifact wrapper needed instead of Blueprint (not only blueprint can be return from generator) + public static Blueprint get(Connection connection, String usageType) throws Exception { + Adapter adapter = AdapterUtil.getAdapter(connection.getAdapterName()); + Map map = new HashMap<>(); + map.put("connectionName", connection.getName()); + map.put("connection", connection); + return adapter.generate(usageType, map); + } + public static Blueprint getInit(Connection connection) throws Exception { + return get(connection, ConnectionUsageType.INIT); + } + public static Blueprint getRef(Connection connection) throws Exception { + return get(connection, ConnectionUsageType.REF); + } + public static Blueprint getFrom(Connection connection) throws Exception { + return get(connection, ConnectionUsageType.FROM); + } + public static Blueprint getTo(Connection connection) throws Exception { + return get(connection, ConnectionUsageType.TO); + } +} diff --git a/platform/runtime/base/connecting/generator/LICENSE.txt b/platform/runtime/base/connecting/generator/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/generator/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/generator/ftl-generator/LICENSE.txt b/platform/runtime/base/connecting/generator/ftl-generator/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/generator/ftl-generator/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/generator/ftl-generator/pom.xml b/platform/runtime/base/connecting/generator/ftl-generator/pom.xml new file mode 100644 index 00000000..47432f92 --- /dev/null +++ b/platform/runtime/base/connecting/generator/ftl-generator/pom.xml @@ -0,0 +1,42 @@ + + + + + ru.entaxy.esb.platform.runtime.base.connecting + generator + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting.generator + ftl-generator + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: GENERATOR :: FTL GENERATOR + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: GENERATOR :: FTL GENERATOR + + + + ru.entaxy.esb.platform.runtime.base.connecting.generator.ftl + + + + + + ru.entaxy.esb.platform.runtime.base.connecting.generator + generator-api + ${project.version} + + + ru.entaxy.esb.system.core + template + ${project.version} + + + ru.entaxy.esb.system.management.blueprint.generator + blueprint-generator + ${project.version} + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/generator/ftl-generator/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/generator/ftl/FTLGenerator.java b/platform/runtime/base/connecting/generator/ftl-generator/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/generator/ftl/FTLGenerator.java new file mode 100644 index 00000000..d43b8ed3 --- /dev/null +++ b/platform/runtime/base/connecting/generator/ftl-generator/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/generator/ftl/FTLGenerator.java @@ -0,0 +1,66 @@ +/*- + * ~~~~~~licensing~~~~~~ + * ftl-generator + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.generator.ftl; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generator; +import ru.entaxy.esb.system.core.template.Template; +import ru.entaxy.esb.system.management.blueprint.generator.Blueprint; +import ru.entaxy.esb.system.management.blueprint.generator.BlueprintGenerator; + +import java.util.Map; + +public class FTLGenerator implements Generator { + + private static final Logger log = LoggerFactory.getLogger(FTLGenerator.class); + + private BlueprintGenerator blueprintGenerator; + private Template template; + + @Override + public Blueprint generate(Map properties) throws Exception { + Map params = (Map)properties; + log.debug("\nTemplateLocation: {}\nTemplateName: {}\nConnectionName: {}", + template.getTemplateLocation(), template.getTemplateName(), params.get("connectionName")); + Blueprint blueprint = getBlueprintGenerator().createBlueprint(template.getTemplateLocation(), + template.getTemplateName(), params.get("connectionName"), params); + // TODO: 09.07.2021 Artifact wrapper needed instead of Blueprint (not only blueprint can be return from generator) + return blueprint; + } + + public void setTemplate(Template template) { + this.template = template; + } + + public BlueprintGenerator getBlueprintGenerator() { + if (blueprintGenerator == null) { + BundleContext bundleContext = FrameworkUtil.getBundle(BlueprintGenerator.class).getBundleContext(); + ServiceReference blueprintGeneratorServiceReference = + bundleContext.getServiceReference(BlueprintGenerator.class); + blueprintGenerator = bundleContext.getService(blueprintGeneratorServiceReference); + } + return blueprintGenerator; + } + +} diff --git a/platform/runtime/base/connecting/generator/generator-api/LICENSE.txt b/platform/runtime/base/connecting/generator/generator-api/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/generator/generator-api/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/generator/generator-api/pom.xml b/platform/runtime/base/connecting/generator/generator-api/pom.xml new file mode 100644 index 00000000..9f5924bb --- /dev/null +++ b/platform/runtime/base/connecting/generator/generator-api/pom.xml @@ -0,0 +1,32 @@ + + + + + ru.entaxy.esb.platform.runtime.base.connecting + generator + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting.generator + generator-api + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: GENERATOR :: GENERATOR API + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: GENERATOR :: GENERATOR API + + + + ru.entaxy.esb.platform.runtime.base.connecting.generator + + + + + + ru.entaxy.esb.system.management.blueprint.generator + blueprint-generator + ${project.version} + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/generator/generator-api/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/generator/Generator.java b/platform/runtime/base/connecting/generator/generator-api/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/generator/Generator.java new file mode 100644 index 00000000..46e61632 --- /dev/null +++ b/platform/runtime/base/connecting/generator/generator-api/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/generator/Generator.java @@ -0,0 +1,29 @@ +/*- + * ~~~~~~licensing~~~~~~ + * generator-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.generator; + +import ru.entaxy.esb.system.management.blueprint.generator.Blueprint; + +import java.util.Map; + +public interface Generator { + // TODO: 09.07.2021 Artifact wrapper needed instead of Blueprint (not only blueprint can be return from generator) + public Blueprint generate(Map properties) throws Exception; +} diff --git a/platform/runtime/base/connecting/generator/generator-factory/LICENSE.txt b/platform/runtime/base/connecting/generator/generator-factory/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/generator/generator-factory/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/generator/generator-factory/pom.xml b/platform/runtime/base/connecting/generator/generator-factory/pom.xml new file mode 100644 index 00000000..c64a81ef --- /dev/null +++ b/platform/runtime/base/connecting/generator/generator-factory/pom.xml @@ -0,0 +1,32 @@ + + + + + ru.entaxy.esb.platform.runtime.base.connecting + generator + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting.generator + generator-factory + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: GENERATOR :: GENERATOR FACTORY + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: GENERATOR :: GENERATOR FACTORY + + + + ru.entaxy.esb.platform.runtime.base.connecting.generator.factory + + + + + + ru.entaxy.esb.platform.runtime.base.connecting.generator + ftl-generator + ${project.version} + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/generator/generator-factory/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/generator/factory/GeneratorFactory.java b/platform/runtime/base/connecting/generator/generator-factory/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/generator/factory/GeneratorFactory.java new file mode 100644 index 00000000..1ac11a30 --- /dev/null +++ b/platform/runtime/base/connecting/generator/generator-factory/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/generator/factory/GeneratorFactory.java @@ -0,0 +1,54 @@ +/*- + * ~~~~~~licensing~~~~~~ + * generator-factory + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.generator.factory; + +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generator; +import ru.entaxy.esb.platform.runtime.base.connecting.generator.ftl.FTLGenerator; +import ru.entaxy.esb.system.core.template.TemplateImpl; + +public class GeneratorFactory { + private final static Logger log = LoggerFactory.getLogger(GeneratorFactory.class); + public static final String DEFAULT_GENERATOR = "FTLGenerator"; + + public static Generator createGenerator(String usageType, BundleContext bundleContext) { + return createGenerator(DEFAULT_GENERATOR, usageType, bundleContext); + } + + public static Generator createGenerator(String generatorType, String usageType, BundleContext bundleContext) { + + log.debug("Creating {} template for {}", usageType, generatorType); + Generator generator; + TemplateImpl template = new TemplateImpl(); + template.setTemplateName(usageType); + template.setBundleContext(bundleContext); + + switch (generatorType) { + case DEFAULT_GENERATOR: + default: + FTLGenerator ftlGenerator = new FTLGenerator(); + ftlGenerator.setTemplate(template); + generator = ftlGenerator; + } + return generator; + } +} diff --git a/platform/runtime/base/connecting/generator/pom.xml b/platform/runtime/base/connecting/generator/pom.xml new file mode 100644 index 00000000..f6d49cce --- /dev/null +++ b/platform/runtime/base/connecting/generator/pom.xml @@ -0,0 +1,24 @@ + + + + + ru.entaxy.esb.platform.runtime.base + connecting + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting + generator + pom + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: GENERATOR + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: GENERATOR + + + generator-api + ftl-generator + generator-factory + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/pom.xml b/platform/runtime/base/connecting/pom.xml new file mode 100644 index 00000000..312c7290 --- /dev/null +++ b/platform/runtime/base/connecting/pom.xml @@ -0,0 +1,25 @@ + + + + + ru.entaxy.esb.platform.runtime + base + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base + connecting + pom + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING + + + connection + generator + adapter + producer + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/producer/LICENSE.txt b/platform/runtime/base/connecting/producer/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/producer/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/producer/connection-producer/LICENSE.txt b/platform/runtime/base/connecting/producer/connection-producer/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/producer/connection-producer/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/producer/connection-producer/pom.xml b/platform/runtime/base/connecting/producer/connection-producer/pom.xml new file mode 100644 index 00000000..48238ec7 --- /dev/null +++ b/platform/runtime/base/connecting/producer/connection-producer/pom.xml @@ -0,0 +1,43 @@ + + + + + ru.entaxy.esb.platform.runtime.base.connecting + producer + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting.producer + connection-producer + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: PRODUCER :: CONNECTION PRODUCER + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: PRODUCER :: CONNECTION PRODUCER + + + + ru.entaxy.esb.platform.runtime.base.connecting.producer.connection.util + + + + + + org.osgi + osgi.core + ${osgi.version} + provided + + + ru.entaxy.esb.platform.runtime.base.connecting.producer + producer-api + ${project.version} + + + com.google.code.gson + gson + ${gson.version} + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/producer/connection-producer/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/producer/connection/ConnectionProducer.java b/platform/runtime/base/connecting/producer/connection-producer/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/producer/connection/ConnectionProducer.java new file mode 100644 index 00000000..4b9d2c72 --- /dev/null +++ b/platform/runtime/base/connecting/producer/connection-producer/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/producer/connection/ConnectionProducer.java @@ -0,0 +1,49 @@ +/*- + * ~~~~~~licensing~~~~~~ + * connection-producer + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.producer.connection; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.base.connecting.adapter.core.api.Adapter; +import ru.entaxy.esb.platform.runtime.base.connecting.connection.Connection; +import ru.entaxy.esb.platform.runtime.base.connecting.connection.ConnectionImpl; +import ru.entaxy.esb.platform.runtime.base.connecting.producer.Producer; + +import java.util.HashMap; +import java.util.Map; + +public class ConnectionProducer implements Producer { + + private static final Logger log = LoggerFactory.getLogger(ConnectionProducer.class); + private static final Map adapterMap = new HashMap<>(); + + @Override + public Connection createConnection(JsonObject jsonConnection) { + return new Gson().fromJson(jsonConnection, ConnectionImpl.class); + } + + @Override + public Connection useConnection(JsonObject jsonConnection) { + return null; + } + +} diff --git a/platform/runtime/base/connecting/producer/connection-producer/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/producer/connection/util/ConnectionProducerUtil.java b/platform/runtime/base/connecting/producer/connection-producer/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/producer/connection/util/ConnectionProducerUtil.java new file mode 100644 index 00000000..16b582dc --- /dev/null +++ b/platform/runtime/base/connecting/producer/connection-producer/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/producer/connection/util/ConnectionProducerUtil.java @@ -0,0 +1,44 @@ +/*- + * ~~~~~~licensing~~~~~~ + * connection-producer + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.producer.connection.util; + +import com.google.gson.JsonObject; +import ru.entaxy.esb.platform.runtime.base.connecting.connection.Connection; +import ru.entaxy.esb.platform.runtime.base.connecting.producer.connection.ConnectionProducer; + +public class ConnectionProducerUtil { + private static ConnectionProducer instance; + + public static Connection createConnection(JsonObject jsonConnection) { + return getConnectionProducer().createConnection(jsonConnection); + } + + public static Connection useConnection(JsonObject jsonConnection) { + return getConnectionProducer().useConnection(jsonConnection); + } + + private static ConnectionProducer getConnectionProducer() { + if (instance == null) { + instance = new ConnectionProducer(); + } + return instance; + } + +} diff --git a/platform/runtime/base/connecting/producer/pom.xml b/platform/runtime/base/connecting/producer/pom.xml new file mode 100644 index 00000000..a08e21b1 --- /dev/null +++ b/platform/runtime/base/connecting/producer/pom.xml @@ -0,0 +1,23 @@ + + + + + ru.entaxy.esb.platform.runtime.base + connecting + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting + producer + pom + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: PRODUCER + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: PRODUCER + + + producer-api + connection-producer + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/producer/producer-api/LICENSE.txt b/platform/runtime/base/connecting/producer/producer-api/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/base/connecting/producer/producer-api/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/base/connecting/producer/producer-api/pom.xml b/platform/runtime/base/connecting/producer/producer-api/pom.xml new file mode 100644 index 00000000..df257c76 --- /dev/null +++ b/platform/runtime/base/connecting/producer/producer-api/pom.xml @@ -0,0 +1,42 @@ + + + + + ru.entaxy.esb.platform.runtime.base.connecting + producer + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.base.connecting.producer + producer-api + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: PRODUCER :: PRODUCER API + ENTAXY :: PLATFORM :: RUNTIME :: BASE :: CONNECTING :: PRODUCER :: PRODUCER API + + + + ru.entaxy.esb.platform.runtime.base.connecting.producer + + + + + + ru.entaxy.esb.platform.runtime.base.connecting + connection + ${project.version} + + + ru.entaxy.esb.platform.runtime.base.connecting.adapter + adapters-core + ${project.version} + + + com.google.code.gson + gson + ${gson.version} + + + \ No newline at end of file diff --git a/platform/runtime/base/connecting/producer/producer-api/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/producer/Producer.java b/platform/runtime/base/connecting/producer/producer-api/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/producer/Producer.java new file mode 100644 index 00000000..10aad370 --- /dev/null +++ b/platform/runtime/base/connecting/producer/producer-api/src/main/java/ru/entaxy/esb/platform/runtime/base/connecting/producer/Producer.java @@ -0,0 +1,28 @@ +/*- + * ~~~~~~licensing~~~~~~ + * producer-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.base.connecting.producer; + +import com.google.gson.JsonObject; +import ru.entaxy.esb.platform.runtime.base.connecting.connection.Connection; + +public interface Producer { + public Connection createConnection(JsonObject jsonConnection) throws Exception; + public Connection useConnection(JsonObject jsonConnection); +} diff --git a/platform/runtime/base/pom.xml b/platform/runtime/base/pom.xml new file mode 100644 index 00000000..7a31369d --- /dev/null +++ b/platform/runtime/base/pom.xml @@ -0,0 +1,23 @@ + + + + ru.entaxy.esb.platform + runtime + 1.8.0 + + 4.0.0 + + ru.entaxy.esb.platform.runtime + base + + ENTAXY :: PLATFORM :: RUNTIME :: BASE + Entaxy Platform runtime base + pom + + + branding + connecting + + \ No newline at end of file diff --git a/platform/runtime/base/src/main/features/features.xml b/platform/runtime/base/src/main/features/features.xml new file mode 100644 index 00000000..f36ba415 --- /dev/null +++ b/platform/runtime/base/src/main/features/features.xml @@ -0,0 +1,80 @@ + + + + + + + mvn:org.apache.camel.karaf/apache-camel/${camel.version}/xml/features + + + connecting + + + + generator + mvn:ru.entaxy.esb.platform.runtime.base.connecting/connection/${project.version} + producer + adapter + + + + mvn:ru.entaxy.esb.platform.runtime.base.connecting.generator/generator-api/${project.version} + mvn:ru.entaxy.esb.platform.runtime.base.connecting.generator/ftl-generator/${project.version} + mvn:ru.entaxy.esb.platform.runtime.base.connecting.generator/generator-factory/${project.version} + + + + camel-gson + mvn:ru.entaxy.esb.platform.runtime.base.connecting.producer/producer-api/${project.version} + mvn:ru.entaxy.esb.platform.runtime.base.connecting.producer/connection-producer/${project.version} + + + + adapters-core + file-adapter + artemis-adapter + postgresql-adapter + + + + mvn:ru.entaxy.esb.platform.runtime.base.connecting.adapter/adapters-core/${project.version} + + + + mvn:org.apache.camel/camel-file/${camel.version} + mvn:ru.entaxy.esb.platform.runtime.base.connecting.adapter/file-adapter/${project.version} + + + + mvn:org.apache.camel/camel-jms/${camel.version} + mvn:ru.entaxy.esb.platform.runtime.base.connecting.adapter/artemis-adapter/${project.version} + + + + wrap:mvn:org.postgresql/postgresql/${postgresql.version} + mvn:org.apache.camel/camel-jdbc/${camel.version} + mvn:ru.entaxy.esb.platform.runtime.base.connecting.adapter/postgresql-adapter/${project.version} + + + diff --git a/platform/runtime/core/LICENSE.txt b/platform/runtime/core/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/initializer/LICENSE.txt b/platform/runtime/core/initializer/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/initializer/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/initializer/connection-initializer/LICENSE.txt b/platform/runtime/core/initializer/connection-initializer/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/initializer/connection-initializer/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/initializer/connection-initializer/pom.xml b/platform/runtime/core/initializer/connection-initializer/pom.xml new file mode 100644 index 00000000..5bcc55b4 --- /dev/null +++ b/platform/runtime/core/initializer/connection-initializer/pom.xml @@ -0,0 +1,56 @@ + + + + + ru.entaxy.esb.platform.runtime.core + initializer + 1.8.0 + + + 4.0.0 + ru.entaxy.esb.platform.runtime.core.initializer + connection-initializer + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: CONNECTION INITIALIZER + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: CONNECTION INITIALIZER + + + + + org.apache.felix + maven-bundle-plugin + true + + + ru.entaxy.esb.platform.runtime.core.initializer.connection.ConnectionInitializer?id=connections&repeat=false&depends-on=core,datasources + + + + + + + + + org.osgi + osgi.core + + + ru.entaxy.esb.platform.runtime.core.management + connection-manager + ${project.version} + + + com.google.code.gson + gson + ${gson.version} + + + ru.entaxy.esb.platform.runtime.core.initializer + init-manager + ${project.version} + compile + + + \ No newline at end of file diff --git a/platform/runtime/core/initializer/connection-initializer/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/connection/ConnectionInitializer.java b/platform/runtime/core/initializer/connection-initializer/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/connection/ConnectionInitializer.java new file mode 100644 index 00000000..2c76f668 --- /dev/null +++ b/platform/runtime/core/initializer/connection-initializer/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/connection/ConnectionInitializer.java @@ -0,0 +1,89 @@ +/*- + * ~~~~~~licensing~~~~~~ + * connection-initializer + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.initializer.connection; + +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ru.entaxy.esb.platform.runtime.core.initializer.api.AbstractInitializer; +import ru.entaxy.esb.platform.runtime.core.initializer.api.InitializerException; +import ru.entaxy.esb.platform.runtime.core.management.connection.util.ConnectionManagerUtil; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.Charset; + +public class ConnectionInitializer extends AbstractInitializer { + + private static final Logger log = LoggerFactory.getLogger(ConnectionInitializer.class); + + private static final String JSON_FILE_NAME = "entaxy-platform-connections.json"; + + private static final String jsonBundlePath = "/connection/" + JSON_FILE_NAME; + + private static final String JSON_FILE_PATH = System.getProperty("karaf.etc") + + File.separator + + "init" + + File.separator + + JSON_FILE_NAME; + + @Override + public void init() throws InitializerException { + log.info("ConnectionInitializer started"); + log.info("-->> " + JSON_FILE_PATH); + + try { + initPlatformConnections(bundleContext); + } catch (Exception e) { + throw new InitializerException(this, "Can't create platform connections", "", e); + } + } + + @Override + public void reinit() throws InitializerException { + // TODO Auto-generated method stub + } + + private void initPlatformConnections(BundleContext bundleContext) throws Exception { + String json = getJsonAsString(bundleContext); + ConnectionManagerUtil.getService().createAndInstallConnections(json); + } + + private String getJsonAsString(BundleContext context) throws IOException { + URL jsonUrl; + File f = new File(JSON_FILE_PATH); + if (f.exists() && f.canRead()) { + jsonUrl = f.toURI().toURL(); + log.info("Path to json file: " + jsonUrl.toString()); + } else { + jsonUrl = context.getBundle().getEntry(jsonBundlePath); + log.debug("Path to json file: " + jsonUrl.toString()); + } + InputStream inputStream = jsonUrl.openStream(); + byte[] bytes = inputStream.readAllBytes(); + String result = new String(bytes, Charset.defaultCharset()); + inputStream.close(); + return result; + } + +} diff --git a/platform/runtime/core/initializer/connection-initializer/src/main/resources/connection/entaxy-platform-connections.json b/platform/runtime/core/initializer/connection-initializer/src/main/resources/connection/entaxy-platform-connections.json new file mode 100644 index 00000000..f6e93ac6 --- /dev/null +++ b/platform/runtime/core/initializer/connection-initializer/src/main/resources/connection/entaxy-platform-connections.json @@ -0,0 +1,54 @@ +{ + "connections": [ + { + "nodeType": "connection", + "uuid": "connection-uuid-1", + "name": "entaxy-file", + "adapterName": "fileAdapter", + "platform": true, + "pathParameter": "data/shared", + "properties": {}, + "options": { + "noop": true, + "fileName": "default.txt", + "allowNullBody": "true" + } + }, + { + "nodeType": "connection", + "uuid": "connection-uuid-2", + "name": "entaxy-broker", + "adapterName": "artemisAdapter", + "platform": true, + "pathParameter": "queue:entaxy.default", + "properties": { + "url": "(tcp://localhost:61616)", + "username": "entaxy", + "password": "entaxy", + "maxConnections": "20", + "maxSessionsPerConnection": "100" + }, + "options": {} + }, + { + "nodeType": "connection", + "uuid": "connection-uuid-3", + "name": "entaxy-db-storage", + "adapterName": "postgresqlAdapter", + "platform": true, + "pathParameter": "entaxy.esb.storage", + "properties": {}, + "options": {} + }, + { + "nodeType": "connection", + "uuid": "connection-uuid-4", + "name": "entaxy-db-cache", + "adapterName": "postgresqlAdapter", + "platform": true, + "pathParameter": "entaxy.esb.cache", + "properties": {}, + "options": {} + } + ] +} diff --git a/platform/runtime/core/initializer/core-initializer/LICENSE.txt b/platform/runtime/core/initializer/core-initializer/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/initializer/core-initializer/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/initializer/core-initializer/pom.xml b/platform/runtime/core/initializer/core-initializer/pom.xml new file mode 100644 index 00000000..334d4f72 --- /dev/null +++ b/platform/runtime/core/initializer/core-initializer/pom.xml @@ -0,0 +1,40 @@ + + 4.0.0 + + ru.entaxy.esb.platform.runtime.core + initializer + 1.8.0 + + ru.entaxy.esb.platform.runtime.core.initializer + core-initializer + bundle + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: core-initializer + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: core-initializer + + + ru.entaxy.esb.platform.runtime.core.initializer.core + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ru.entaxy.esb.platform.runtime.core.initializer.core.CoreInitializer?id=core&repeat=true&depends-on=datasources + + + + + + + + + ru.entaxy.esb.platform.runtime.core.initializer + init-manager + ${project.version} + + + \ No newline at end of file diff --git a/platform/runtime/core/initializer/core-initializer/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/core/CoreInitializer.java b/platform/runtime/core/initializer/core-initializer/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/core/CoreInitializer.java new file mode 100644 index 00000000..520ddbba --- /dev/null +++ b/platform/runtime/core/initializer/core-initializer/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/core/CoreInitializer.java @@ -0,0 +1,49 @@ +/*- + * ~~~~~~licensing~~~~~~ + * core-initializer + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.initializer.core; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.core.initializer.api.AbstractInitializer; +import ru.entaxy.esb.platform.runtime.core.initializer.api.InitializerException; + +/** + * + * NOOP-class for now, just to check everything works + * Can be filled with the functionality in the future + * + * @author sstarovoytenkov + * + */ +public class CoreInitializer extends AbstractInitializer { + + protected static final Logger log = LoggerFactory.getLogger(CoreInitializer.class); + + @Override + public void init() throws InitializerException { + log.info("Init in CoreInitializer is called"); + } + + @Override + public void reinit() throws InitializerException { + log.info("ReInit in CoreInitializer is called"); + } + +} diff --git a/platform/runtime/core/initializer/datasources-initializer/LICENSE.txt b/platform/runtime/core/initializer/datasources-initializer/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/initializer/datasources-initializer/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/initializer/datasources-initializer/pom.xml b/platform/runtime/core/initializer/datasources-initializer/pom.xml new file mode 100644 index 00000000..d68230d1 --- /dev/null +++ b/platform/runtime/core/initializer/datasources-initializer/pom.xml @@ -0,0 +1,49 @@ + + 4.0.0 + + ru.entaxy.esb.platform.runtime.core + initializer + 1.8.0 + + ru.entaxy.esb.platform.runtime.core.initializer + datasources-initializer + bundle + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: datasources-initializer + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: datasources-initializer + + + + + * + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ru.entaxy.esb.platform.runtime.core.initializer.datasources.DataSourcesInitializer?id=datasources&repeat=false + + + + + + + + + + ru.entaxy.esb.platform.runtime.core.initializer + init-manager + ${project.version} + + + org.osgi + osgi.core + + + + \ No newline at end of file diff --git a/platform/runtime/core/initializer/datasources-initializer/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/datasources/DataSourcesInitializer.java b/platform/runtime/core/initializer/datasources-initializer/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/datasources/DataSourcesInitializer.java new file mode 100644 index 00000000..0c1281e9 --- /dev/null +++ b/platform/runtime/core/initializer/datasources-initializer/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/datasources/DataSourcesInitializer.java @@ -0,0 +1,59 @@ +/*- + * ~~~~~~licensing~~~~~~ + * datasources-initializer + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.initializer.datasources; + +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.core.initializer.api.AbstractInitializer; +import ru.entaxy.esb.platform.runtime.core.initializer.api.InitializerException; + +import javax.sql.DataSource; +import java.util.Collection; + +public class DataSourcesInitializer extends AbstractInitializer { + + protected static final Logger log = LoggerFactory.getLogger(DataSourcesInitializer.class); + + @Override + public void init() throws InitializerException { + log.info("Init in DataSourcesInitializer is called"); + try { + Collection> dataSources = + this.bundleContext.getServiceReferences( + javax.sql.DataSource.class, + "(|(osgi.jndi.service.name=entaxy.esb.storage)(osgi.jndi.service.name=entaxy.esb.cache))"); + if (dataSources.size()!=2) + throw new InitializerException(this, "Datasources initialization error", "Datasources count = " + dataSources.size(), null); + } catch (InvalidSyntaxException e) { + e.printStackTrace(); + log.error("Initializer error: " + e.getMessage()); + throw new InitializerException(this, "Initializer exception", "Initializer exception", e); + } + } + + @Override + public void reinit() throws InitializerException { + log.info("ReInit in CoreInitializer is called"); + } + + +} diff --git a/platform/runtime/core/initializer/init-manager/LICENSE.txt b/platform/runtime/core/initializer/init-manager/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/initializer/init-manager/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/initializer/init-manager/pom.xml b/platform/runtime/core/initializer/init-manager/pom.xml new file mode 100644 index 00000000..507cff08 --- /dev/null +++ b/platform/runtime/core/initializer/init-manager/pom.xml @@ -0,0 +1,50 @@ + + 4.0.0 + + ru.entaxy.esb.platform.runtime.core + initializer + 1.8.0 + + ru.entaxy.esb.platform.runtime.core.initializer + init-manager + bundle + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: init-manager + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: init-manager + + + ru.entaxy.esb.platform.runtime.core.initializer.api + + + + + + org.apache.felix + maven-bundle-plugin + ${maven-bundle-plugin.version} + true + + + ru.entaxy.esb.platform.runtime.core.initializer.Activator + + + + + + + + + org.osgi + osgi.core + + + org.apache.karaf.config + org.apache.karaf.config.core + ${karaf.version} + + + org.apache.camel + camel-tooling-model + + + + \ No newline at end of file diff --git a/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/Activator.java b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/Activator.java new file mode 100644 index 00000000..9e6ff4d4 --- /dev/null +++ b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/Activator.java @@ -0,0 +1,43 @@ +/*- + * ~~~~~~licensing~~~~~~ + * init-manager + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.initializer; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + protected InitializerTracker tracker; + protected InitManager initManager; + + @Override + public void start(BundleContext context) throws Exception { + this.initManager = new InitManager(context); + tracker = new InitializerTracker(context, this.initManager); + tracker.open(); + + } + + @Override + public void stop(BundleContext context) throws Exception { + tracker.close(); + } + +} diff --git a/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/InitManager.java b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/InitManager.java new file mode 100644 index 00000000..20b94177 --- /dev/null +++ b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/InitManager.java @@ -0,0 +1,324 @@ +/*- + * ~~~~~~licensing~~~~~~ + * init-manager + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.initializer; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.camel.tooling.model.Strings; +import org.apache.felix.utils.properties.TypedProperties; +import org.apache.karaf.config.core.ConfigRepository; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.wiring.BundleWiring; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ru.entaxy.esb.platform.runtime.core.initializer.api.Initializer; +import ru.entaxy.esb.platform.runtime.core.initializer.api.InitializerException; + +/** + * + * Manager for initializers + * + * TODO (if needed): + * 1. keep map "initializerClassName -> bundleId" + * 2. publish as a service + * 3. provide interface with method "reinit(String className)" + * + * + * @author sstarovoytenkov + * + */ +public class InitManager { + + protected static final Logger log = LoggerFactory.getLogger(InitManager.class); + + /** + * pid of config to store initialization status (true/false) + * will be created on first start of InitManager + */ + protected final String pid = "ru.entaxy.esb.initializer"; + + protected ConfigRepository configRepository; + protected BundleContext bundleContext; + + protected Map> initersToDeps = new HashMap<>(); + protected Map> depsToIniters = new HashMap<>(); + + protected Map initializers = new HashMap<>(); + + protected List waiting = new ArrayList<>(); + + protected class InitializerMeta { + + String id; + String className; + boolean repeat; + + Bundle bundle; + + List dependsOn = new ArrayList<>(); + List dependedBy = new ArrayList<>(); + + boolean executed = false; + boolean toBeExecuted = true; + + public void load(String initializerData) { + String[] data = initializerData.split("\\?"); + + this.className = data[0]; + String queryString = data.length>1?data[1]:""; + + String[] queryStringData = queryString.split("&"); + Map params = new HashMap<>(); + for (int i=0; i1?paramData[1]:""); + } + + this.id = params.containsKey(Initializer.INITIALIZER_QUERY_STRING_PARAM_ID) + ?(Strings.isNullOrEmpty(params.get(Initializer.INITIALIZER_QUERY_STRING_PARAM_ID)) + ?className + :params.get(Initializer.INITIALIZER_QUERY_STRING_PARAM_ID)) + :className; + + String dependsOn = params.get(Initializer.INITIALIZER_QUERY_STRING_PARAM_DEPENDS_ON); + if (!Strings.isNullOrEmpty(dependsOn)) { + String[] dependencies = dependsOn.split(","); + for (int i=0; iInitializer + */ + BundleWiring wiring = bundle.adapt(BundleWiring.class); + ClassLoader cl = wiring.getClassLoader(); + Class clazz; + try { + clazz = cl.loadClass(className); + log.info("Loaded class {}", clazz.getName()); + Constructor constructor = clazz.getConstructor(); + Initializer initializer = (Initializer) constructor.newInstance(); + initializer.setBundleContext(bundle.getBundleContext()); + initializer.setInitializerId(id); + initializer.init(); + InitManager.this.updateById(id, true); + this.executed = true; + this.notifyDependent(); + return true; + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InitializerException e) { + log.error("Initializer error: class=" + className + + ", id=" + id + " -> [" + e.getMessage() + "] :: " + + (e instanceof InitializerException?((InitializerException)e).getDescription():""), e); + return false; + } + + } + + public void dependencyReady(InitializerMeta meta) { + synchronized (this.dependsOn) { + this.dependsOn.remove(meta); + if (!this.executed && this.canExecute()) + this.execute(); + } + } + + }; + + + protected InitializerMeta getMetaById(String id) { + synchronized (initializers) { + if (!initializers.containsKey(id)) { + InitializerMeta meta = new InitializerMeta(); + meta.id = id; + initializers.put(id, meta); + } + return initializers.get(id); + } + } + + public InitManager(BundleContext context) { + this.bundleContext = context; + + ServiceReference ref1 = this.bundleContext.getServiceReference(ConfigRepository.class); + this.configRepository = this.bundleContext.getService(ref1); + + if (!getValueById(this.getClass().getName())){ + updateById(this.getClass().getName(), true); + } + } + + protected InitializerMeta createMeta(String initializerMeta, Bundle bundle) { + InitializerMeta meta = new InitializerMeta(); + meta.load(initializerMeta); + meta.bundle = bundle; + + synchronized (this.initializers) { + if (this.initializers.containsKey(meta.id)) { + this.initializers.get(meta.id).load(meta); + } else { + this.initializers.put(meta.id, meta); + } + } + + return this.initializers.get(meta.id); + + } + + /** + * + * @param initializerClass class name read by tracker from Entaxy-Initializer-Class manifest header + * @param bundle + */ + public void init(String initializerClass, Bundle bundle) { + log.info("Found initializer of class {} in bundle [{}] {}", initializerClass, + bundle.getBundleId(), bundle.getSymbolicName()); + + InitializerMeta meta = createMeta(initializerClass, bundle); + + /** + * check the initialization status + */ + if (meta.isExecutedBefore()) { + log.info("Initializer with id {} in bundle [{}] {} is already inited", meta.id, + meta.bundle.getBundleId(), meta.bundle.getSymbolicName()); + + if (meta.repeat) + log.info("Initializer with id {} is set to be repeated", meta.id); + else { + meta.toBeExecuted = false; + meta.notifyDependent(); + return; + } + } + + if (!meta.canExecute()) { + String dependsOn = meta.dependsOn.stream().map((m)->m.id).collect(Collectors.joining(",")); + log.info("Initializer with id {} is waiting for dependencies: {}", meta.id, dependsOn); + + /* + * synchronized (this.waiting) { this.waiting.add(meta.id); } + */ + return; + } + + meta.execute(); + } + +/* protected void execute(InitializerMeta meta) { + if (meta.execute()) + synchronized (this.waiting) { + this.waiting.remove(meta.id); + } + for (String id: this.waiting) { + InitializerMeta waits = getMetaById(id); + synchronized (waits) { + if (waits.canExecute()) + } + } + } +*/ + /** + * + * @param initializerId class name to check + * @return true if the initializer is already completed, false otherwise + */ + protected boolean getValueById(String initializerId) { + try { + TypedProperties tp = this.configRepository.getConfig(pid); + if (!tp.containsKey(initializerId)) + return false; + return "true".equals(tp.get(initializerId).toString()); + } catch (IOException | InvalidSyntaxException e) { + log.warn("Can't get property " + initializerId, e); + } + return false; + } + + protected void updateById(String initializerId, boolean value) { + log.info("Updating by id {}", initializerId); + try { + TypedProperties tp = this.configRepository.getConfig(pid); + tp.put(initializerId, value?"true":"false"); + this.configRepository.update(pid, tp); + } catch (IOException | InvalidSyntaxException e) { + log.warn("Can't update property " + initializerId, e); + } + } + +} diff --git a/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/InitializerTracker.java b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/InitializerTracker.java new file mode 100644 index 00000000..e1d8abda --- /dev/null +++ b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/InitializerTracker.java @@ -0,0 +1,47 @@ +/*- + * ~~~~~~licensing~~~~~~ + * init-manager + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.initializer; + +import org.apache.camel.tooling.model.Strings; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; +import org.osgi.util.tracker.BundleTracker; +import ru.entaxy.esb.platform.runtime.core.initializer.api.Initializer; + +public class InitializerTracker extends BundleTracker { + + protected InitManager initManager; + + public InitializerTracker(BundleContext context, InitManager initManager) { + super(context, Bundle.ACTIVE, null); + this.initManager = initManager; + } + + @Override + public Object addingBundle(Bundle bundle, BundleEvent event) { + String initializerClass = bundle.getHeaders().get(Initializer.INITIALIZER_CLASS_HEADER); + if (!Strings.isNullOrEmpty(initializerClass)) { + this.initManager.init(initializerClass, bundle); + } + return null; + } + +} diff --git a/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/api/AbstractInitializer.java b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/api/AbstractInitializer.java new file mode 100644 index 00000000..ea38d101 --- /dev/null +++ b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/api/AbstractInitializer.java @@ -0,0 +1,55 @@ +/*- + * ~~~~~~licensing~~~~~~ + * init-manager + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.initializer.api; + +import org.osgi.framework.BundleContext; + +public abstract class AbstractInitializer implements Initializer { + + protected String initializerId = this.getClass().getName(); + + protected BundleContext bundleContext; + + @Override + public void setBundleContext(BundleContext context) { + this.bundleContext = context; + } + + @Override + public long getBundleId() { + return this.bundleContext.getBundle().getBundleId(); + } + + @Override + public String getBundleName() { + return this.bundleContext.getBundle().getSymbolicName(); + } + + @Override + public void setInitializerId(String id) { + this.initializerId = id; + } + + @Override + public String getInitializerId() { + return this.initializerId; + } + +} diff --git a/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/api/Initializer.java b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/api/Initializer.java new file mode 100644 index 00000000..b3f7f30d --- /dev/null +++ b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/api/Initializer.java @@ -0,0 +1,57 @@ +/*- + * ~~~~~~licensing~~~~~~ + * init-manager + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.initializer.api; + +import org.osgi.framework.BundleContext; + +public interface Initializer { + + public static final String INITIALIZER_CLASS_HEADER = "Entaxy-Initializer-Class"; + + + /* + * Query string params for bundle manifest header Entaxy-Initializer-Class + * - id - initializer ID (className by default) + * - depends-on - list of comma-separated ids on initializers that must be executed first + * - repeat - repeat initialization on every start (e.g. liquibase updater) (false by default) + * + * The header will look like + * Entaxy-Initializer-Class: ru.entaxy.initializer.Init1?id=init_1&depends-on=connection&repeat=true + */ + public static final String INITIALIZER_QUERY_STRING_PARAM_ID = "id"; + public static final String INITIALIZER_QUERY_STRING_PARAM_DEPENDS_ON = "depends-on"; + public static final String INITIALIZER_QUERY_STRING_PARAM_REPEAT = "repeat"; + + public void init() throws InitializerException; + + /* + * Initializer must do cleanup and init again + * + * for future use + */ + public void reinit() throws InitializerException; + + public void setBundleContext(BundleContext context); + public long getBundleId(); + public String getBundleName(); + + public void setInitializerId(String id); + public String getInitializerId(); +} diff --git a/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/api/InitializerException.java b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/api/InitializerException.java new file mode 100644 index 00000000..26d857a6 --- /dev/null +++ b/platform/runtime/core/initializer/init-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/api/InitializerException.java @@ -0,0 +1,58 @@ +/*- + * ~~~~~~licensing~~~~~~ + * init-manager + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.initializer.api; + +public class InitializerException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -7112390630151310687L; + + protected long bundleId; + protected String bundleName; + protected String initializerId; + protected String description; + + public InitializerException(Initializer initializer, String message, String description, Throwable cause) { + super(message, cause); + this.bundleId = initializer.getBundleId(); + this.bundleName = initializer.getBundleName(); + this.initializerId = initializer.getInitializerId(); + this.description = description; + } + + public long getBundleId() { + return bundleId; + } + + public String getBundleName() { + return bundleName; + } + + public String getInitializerId() { + return initializerId; + } + + public String getDescription() { + return description; + } + +} diff --git a/platform/runtime/core/initializer/pom.xml b/platform/runtime/core/initializer/pom.xml new file mode 100644 index 00000000..c456a1bf --- /dev/null +++ b/platform/runtime/core/initializer/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + + ru.entaxy.esb.platform.runtime + core + 1.8.0 + + ru.entaxy.esb.platform.runtime.core + initializer + pom + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER + + init-manager + core-initializer + connection-initializer + storage-initializer + datasources-initializer + + \ No newline at end of file diff --git a/platform/runtime/core/initializer/storage-initializer/LICENSE.txt b/platform/runtime/core/initializer/storage-initializer/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/initializer/storage-initializer/cache/LICENSE.txt b/platform/runtime/core/initializer/storage-initializer/cache/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/cache/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/initializer/storage-initializer/cache/README.md b/platform/runtime/core/initializer/storage-initializer/cache/README.md new file mode 100644 index 00000000..d35a8000 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/cache/README.md @@ -0,0 +1,7 @@ +# ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: STORAGE INITIALIZER :: cache + +## База данных + +Обновления проходят автоматически при переустановке/рестарте модуля liquibase-updater. + +Если сделать обновление вручную через maven, то автоматическое обновление будет падать с ошибкой. \ No newline at end of file diff --git a/platform/runtime/core/initializer/storage-initializer/cache/pom.xml b/platform/runtime/core/initializer/storage-initializer/cache/pom.xml new file mode 100644 index 00000000..14a6ae7e --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/cache/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + + storage-initializer + ru.entaxy.esb.platform.runtime.core.initializer + 1.8.0 + + + ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer + storage-cache + + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: STORAGE INITIALIZER :: cache + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: STORAGE INITIALIZER :: cache + bundle + + + + ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer + liquibase-updater + ${project.version} + provided + + + diff --git a/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/OSGI-INF/blueprint/camel-contex.xml b/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/OSGI-INF/blueprint/camel-contex.xml new file mode 100644 index 00000000..92e8d05f --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/OSGI-INF/blueprint/camel-contex.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/db/changelog.xml b/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/db/changelog.xml new file mode 100644 index 00000000..7c6d5581 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/db/changelog.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/db/changeset/001-aggregation-table-create.xml b/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/db/changeset/001-aggregation-table-create.xml new file mode 100644 index 00000000..87f56979 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/db/changeset/001-aggregation-table-create.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/db/changeset/002-quartz.xml b/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/db/changeset/002-quartz.xml new file mode 100644 index 00000000..be4e526a --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/cache/src/main/resources/db/changeset/002-quartz.xml @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/LICENSE.txt b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/README.md b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/README.md new file mode 100644 index 00000000..82805dbb --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/README.md @@ -0,0 +1,7 @@ +# ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: STORAGE INITIALIZER :: esb_entaxy + +## База данных + +Обновления проходят автоматически при переустановке/рестарте модуля liquibase-updater. + +Если сделать обновление вручную через maven, то автоматическое обновление будет падать с ошибкой. \ No newline at end of file diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/pom.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/pom.xml new file mode 100644 index 00000000..7d2ea1dd --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + + storage-initializer + ru.entaxy.esb.platform.runtime.core.initializer + 1.8.0 + + + ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer + storage-esb_entaxy + + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: STORAGE INITIALIZER :: esb_entaxy + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: STORAGE INITIALIZER :: esb_entaxy + bundle + + + + ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer + liquibase-updater + ${project.version} + provided + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/OSGI-INF/blueprint/camel-contex.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/OSGI-INF/blueprint/camel-contex.xml new file mode 100644 index 00000000..6f2dbe13 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/OSGI-INF/blueprint/camel-contex.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changelog.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changelog.xml new file mode 100644 index 00000000..e8f6f8ab --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changelog.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/001-storage-table-create.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/001-storage-table-create.xml new file mode 100644 index 00000000..9f7da183 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/001-storage-table-create.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/002-service_registry-table-create.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/002-service_registry-table-create.xml new file mode 100644 index 00000000..c8e5a64b --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/002-service_registry-table-create.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/003-bundle-table-create.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/003-bundle-table-create.xml new file mode 100644 index 00000000..f4c5b174 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/003-bundle-table-create.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/004-system-table-create.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/004-system-table-create.xml new file mode 100644 index 00000000..e0015ac4 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/004-system-table-create.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/005-basic_auth_accounts-table-create.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/005-basic_auth_accounts-table-create.xml new file mode 100644 index 00000000..05d23be3 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/005-basic_auth_accounts-table-create.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/006-event_topic-table-create.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/006-event_topic-table-create.xml new file mode 100644 index 00000000..c97a6c2c --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/006-event_topic-table-create.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/007-system_subscription_registry-table-create.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/007-system_subscription_registry-table-create.xml new file mode 100644 index 00000000..b9d6c018 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/007-system_subscription_registry-table-create.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/008-connector-table-create.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/008-connector-table-create.xml new file mode 100644 index 00000000..b76e2588 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/008-connector-table-create.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/009-export-allowed-create-table.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/009-export-allowed-create-table.xml new file mode 100644 index 00000000..4e9776dd --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/009-export-allowed-create-table.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/010-permission-table-create.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/010-permission-table-create.xml new file mode 100644 index 00000000..bd070b19 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/010-permission-table-create.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/011-admin-account.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/011-admin-account.xml new file mode 100644 index 00000000..86f75a1d --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/011-admin-account.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/012-alter-version-on-string.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/012-alter-version-on-string.xml new file mode 100644 index 00000000..f0be1228 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/012-alter-version-on-string.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/013-admin-topic-permission.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/013-admin-topic-permission.xml new file mode 100644 index 00000000..7ad7f351 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/013-admin-topic-permission.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/014-alter-tables-topic-subscription.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/014-alter-tables-topic-subscription.xml new file mode 100644 index 00000000..55a8da46 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/014-alter-tables-topic-subscription.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/015-schema-table-create.xml b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/015-schema-table-create.xml new file mode 100644 index 00000000..76d37dc2 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/esb_entaxy/src/main/resources/db/changeset/015-schema-table-create.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/core/initializer/storage-initializer/liquibase-updater/LICENSE.txt b/platform/runtime/core/initializer/storage-initializer/liquibase-updater/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/liquibase-updater/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/initializer/storage-initializer/liquibase-updater/pom.xml b/platform/runtime/core/initializer/storage-initializer/liquibase-updater/pom.xml new file mode 100644 index 00000000..609204c6 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/liquibase-updater/pom.xml @@ -0,0 +1,47 @@ + + + + storage-initializer + ru.entaxy.esb.platform.runtime.core.initializer + 1.8.0 + + 4.0.0 + + ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer + liquibase-updater + + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: STORAGE INITIALIZER :: LIQUIBASE UPDATER + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: STORAGE INITIALIZER :: LIQUIBASE UPDATER + bundle + + + + * + + + ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer.liquibase.updater.* + + + + + + com.microsoft.sqlserver + mssql-jdbc + + + org.postgresql + postgresql + + + org.liquibase + liquibase-core + + + org.osgi + osgi.core + + + + \ No newline at end of file diff --git a/platform/runtime/core/initializer/storage-initializer/liquibase-updater/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/storage/initializer/liquibase/updater/LiquibaseUpdater.java b/platform/runtime/core/initializer/storage-initializer/liquibase-updater/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/storage/initializer/liquibase/updater/LiquibaseUpdater.java new file mode 100644 index 00000000..87b10e1d --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/liquibase-updater/src/main/java/ru/entaxy/esb/platform/runtime/core/initializer/storage/initializer/liquibase/updater/LiquibaseUpdater.java @@ -0,0 +1,51 @@ +/*- + * ~~~~~~licensing~~~~~~ + * liquibase-updater + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer.liquibase.updater; + +import liquibase.Contexts; +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.database.jvm.JdbcConnection; +import liquibase.osgi.OSGiResourceAccessor; +import org.osgi.framework.BundleContext; + +import javax.sql.DataSource; + +public class LiquibaseUpdater { + + private static final String CHANGELOG_PATH = "db/changelog.xml"; + + public LiquibaseUpdater(DataSource dataSource, BundleContext bundleContext) { + try { + java.sql.Connection connection = dataSource.getConnection(); + + Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection)); + String config = bundleContext.getBundle().getEntry(CHANGELOG_PATH).getPath(); + + Liquibase liquibase = new liquibase.Liquibase(config, + new OSGiResourceAccessor(bundleContext.getBundle()), database); + + liquibase.update(new Contexts()); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/platform/runtime/core/initializer/storage-initializer/pom.xml b/platform/runtime/core/initializer/storage-initializer/pom.xml new file mode 100644 index 00000000..61cc9612 --- /dev/null +++ b/platform/runtime/core/initializer/storage-initializer/pom.xml @@ -0,0 +1,23 @@ + + + + ru.entaxy.esb.platform.runtime.core + initializer + 1.8.0 + + 4.0.0 + + ru.entaxy.esb.platform.runtime.core.initializer + storage-initializer + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: STORAGE INITIALIZER + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INITIALIZER :: STORAGE INITIALIZER + pom + + + liquibase-updater + esb_entaxy + cache + + \ No newline at end of file diff --git a/platform/runtime/core/management/LICENSE.txt b/platform/runtime/core/management/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/management/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/management/connection-manager/LICENSE.txt b/platform/runtime/core/management/connection-manager/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/core/management/connection-manager/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/core/management/connection-manager/pom.xml b/platform/runtime/core/management/connection-manager/pom.xml new file mode 100644 index 00000000..79550407 --- /dev/null +++ b/platform/runtime/core/management/connection-manager/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + + + ru.entaxy.esb.platform.runtime.core + management + 1.8.0 + + + ru.entaxy.esb.platform.runtime.core.management + connection-manager + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: MANAGEMENT :: CONNECTION MANAGER + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: MANAGEMENT :: CONNECTION MANAGER + + + + ru.entaxy.esb.platform.runtime.core.management.connection.api, + ru.entaxy.esb.platform.runtime.core.management.connection.util + + + + + + ru.entaxy.esb.platform.runtime.base.connecting.producer + connection-producer + ${project.version} + + + + \ No newline at end of file diff --git a/platform/runtime/core/management/connection-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/management/connection/api/ConnectionManager.java b/platform/runtime/core/management/connection-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/management/connection/api/ConnectionManager.java new file mode 100644 index 00000000..e410cf68 --- /dev/null +++ b/platform/runtime/core/management/connection-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/management/connection/api/ConnectionManager.java @@ -0,0 +1,28 @@ +/*- + * ~~~~~~licensing~~~~~~ + * connection-manager + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.management.connection.api; + +import ru.entaxy.esb.platform.runtime.base.connecting.connection.Connection; + +import java.util.List; + +public interface ConnectionManager { + public List createAndInstallConnections(String json) throws Exception; +} diff --git a/platform/runtime/core/management/connection-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/management/connection/impl/ConnectionManagerImpl.java b/platform/runtime/core/management/connection-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/management/connection/impl/ConnectionManagerImpl.java new file mode 100644 index 00000000..ca1364cd --- /dev/null +++ b/platform/runtime/core/management/connection-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/management/connection/impl/ConnectionManagerImpl.java @@ -0,0 +1,166 @@ +/*- + * ~~~~~~licensing~~~~~~ + * connection-manager + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.management.connection.impl; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.platform.runtime.base.connecting.connection.Connection; +import ru.entaxy.esb.platform.runtime.base.connecting.connection.util.ConnectionUtil; +import ru.entaxy.esb.platform.runtime.base.connecting.producer.connection.util.ConnectionProducerUtil; +import ru.entaxy.esb.platform.runtime.core.management.connection.api.ConnectionManager; +import ru.entaxy.esb.system.management.blueprint.generator.Blueprint; + +import java.io.File; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; + +public class ConnectionManagerImpl implements ConnectionManager { + + private static final String CONNECTION = "connection"; + private static final String GROUP_ID = "ru.entaxy.esb."; + private static final String XML_EXTENSION = "xml"; + private static final String LOCAL_FILE_REPOSITORY = "data" + File.separator + "local-repository"; + private static final Logger log = LoggerFactory.getLogger(ConnectionManagerImpl.class); + + public List createAndInstallConnections(String json) throws Exception { + return createConnections(json, false, true); + } + + private List createConnections(String json) throws Exception { + return createConnections(json, false, false); + } + + private List createConnections(String json, boolean register, boolean install) throws Exception { + List connectionList = new ArrayList<>(); + JsonElement jsonElement = getJsonElement(json); + List jsonConnectionList = getJsonConnectionList(jsonElement); + for (JsonObject jsonConnection : jsonConnectionList) { + connectionList.add(createConnection(jsonConnection, register, install)); + } + return connectionList; + } + + private JsonElement getJsonElement(String json) { + return new Gson().fromJson(json, JsonElement.class); + } + + private List getJsonConnectionList(JsonElement element) { + List jsonConnectionList = new ArrayList<>(); + + if (element.isJsonObject()) { + JsonObject object = element.getAsJsonObject(); + if (object.has("nodeType") && + "connection".equals(object.get("nodeType").getAsString())) { + jsonConnectionList.add(object); + } else { + for (Map.Entry entry : object.entrySet()) { + jsonConnectionList.addAll(getJsonConnectionList(entry.getValue())); + } + } + } else if (element.isJsonArray()) { + for (JsonElement jsonElement : element.getAsJsonArray()) { + jsonConnectionList.addAll(getJsonConnectionList(jsonElement)); + } + } + + return jsonConnectionList; + } + + private Connection createConnection(JsonObject jsonConnection, boolean register, boolean install) { + Connection connection = ConnectionProducerUtil.createConnection(jsonConnection); + if (register) { + // TODO: 09.07.2021 registration method + } + if (install) { + try { + installConnection(connection); + } catch (Exception e) { + log.error("Can't install connection: {}", e.getMessage()); + } + } + return connection; + } + + public Bundle installConnection(Connection connection) throws Exception { + String name = connection.getName(); + String type = CONNECTION; + String version = String.valueOf(1.0); + Blueprint blueprint = ConnectionUtil.getInit(connection); + log.debug(new String(blueprint.getBody(), Charset.defaultCharset())); + + +// return bundleManager.installAndStartBundle(name, type, version, blueprint); + // Local bundle install needed instead of cellar install to cluster + String bundleUrl = deployBlueprint(GROUP_ID + type, type + "-" + name, + version, XML_EXTENSION, blueprint.getBody()); + Bundle bundle = installAndStartBundle(bundleUrl); + return bundle; + // TODO: 09.07.2021 callback for webeditor needed + } + + // ru.entaxy.esb.system.deployer.file.FileSystemRepositoryImpl.deployBlueprint method copy + public String deployBlueprint(String groupId, String name, String version, + String extension, byte[] data) throws Exception { + Path path = preparePath(groupId, name, version, extension); + if (!Files.exists(path.getParent())) { + Files.createDirectories(path.getParent()); + } + Files.write(path, data); + return "blueprint:file:" + path.normalize(); + } + + private Path preparePath(String groupId, String name, String version, String extension) { + String gpoupIdPath = groupId.replaceAll("\\.", Matcher.quoteReplacement(File.separator)); + String fileName = name + "-" + version + "." + extension; + Path path = Paths.get(LOCAL_FILE_REPOSITORY, gpoupIdPath, fileName); + return path; + } + + private Bundle installAndStartBundle(String bundleUrl) { + BundleContext bundleContext = FrameworkUtil.getBundle(ConnectionManagerImpl.class).getBundleContext(); + Bundle bundle = null; + try { + bundle = bundleContext.installBundle(bundleUrl, null); + try { + bundle.start(); + } catch (BundleException e) { + log.error("Unable to start bundle " + bundle.getLocation() + ": " + e, e); + } + } catch (BundleException e) { + log.error("Unable to install bundle " + bundle.getLocation() + ": " + e, e); + } + return bundle; + } + + +} diff --git a/platform/runtime/core/management/connection-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/management/connection/util/ConnectionManagerUtil.java b/platform/runtime/core/management/connection-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/management/connection/util/ConnectionManagerUtil.java new file mode 100644 index 00000000..fccacf3a --- /dev/null +++ b/platform/runtime/core/management/connection-manager/src/main/java/ru/entaxy/esb/platform/runtime/core/management/connection/util/ConnectionManagerUtil.java @@ -0,0 +1,56 @@ +/*- + * ~~~~~~licensing~~~~~~ + * connection-manager + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.platform.runtime.core.management.connection.util; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; + +import ru.entaxy.esb.platform.runtime.core.management.connection.api.ConnectionManager; + +public class ConnectionManagerUtil { + + private static ServiceTracker tracker = null; + + public static ConnectionManager getService() { + + // get our own bundleContext + BundleContext bundleContext = FrameworkUtil.getBundle(ConnectionManagerUtil.class).getBundleContext(); + + // found an issue: service is not returned 'cause the initializers start earlier than + // Karaf publishes service + // So we should use tracker here to be sure the service is active + if (tracker == null) { + tracker = new ServiceTracker(bundleContext, ConnectionManager.class, null); + tracker.open(); + } + try { + tracker.waitForService(2000); + } catch (Exception e) { + // TODO: handle exception + } + + ServiceReference connectionManagerServiceReference = + tracker.getServiceReference(); + // bundleContext.getServiceReference(ConnectionManager.class); + return bundleContext.getService(connectionManagerServiceReference); + } +} diff --git a/platform/runtime/core/management/connection-manager/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/platform/runtime/core/management/connection-manager/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 00000000..58162bb4 --- /dev/null +++ b/platform/runtime/core/management/connection-manager/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/platform/runtime/core/management/pom.xml b/platform/runtime/core/management/pom.xml new file mode 100644 index 00000000..58377881 --- /dev/null +++ b/platform/runtime/core/management/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + ru.entaxy.esb.platform.runtime + core + 1.8.0 + + + ru.entaxy.esb.platform.runtime.core + management + pom + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: MANAGEMENT + ENTAXY :: PLATFORM :: RUNTIME :: CORE :: MANAGEMENT + + + connection-manager + + + \ No newline at end of file diff --git a/platform/runtime/core/pom.xml b/platform/runtime/core/pom.xml new file mode 100644 index 00000000..44be999d --- /dev/null +++ b/platform/runtime/core/pom.xml @@ -0,0 +1,17 @@ + + 4.0.0 + + ru.entaxy.esb.platform + runtime + 1.8.0 + + ru.entaxy.esb.platform.runtime + core + pom + ENTAXY :: PLATFORM :: RUNTIME :: CORE + ENTAXY :: PLATFORM :: RUNTIME :: CORE + + initializer + management + + \ No newline at end of file diff --git a/platform/runtime/core/src/main/features/features.xml b/platform/runtime/core/src/main/features/features.xml new file mode 100644 index 00000000..88fb99c1 --- /dev/null +++ b/platform/runtime/core/src/main/features/features.xml @@ -0,0 +1,49 @@ + + + + + + + + management + initializer + + + + mvn:ru.entaxy.esb.platform.runtime.core.management/connection-manager/${project.version} + + + + storage-initializer + mvn:ru.entaxy.esb.platform.runtime.core.initializer/init-manager/${project.version} + mvn:ru.entaxy.esb.platform.runtime.core.initializer/core-initializer/${project.version} + mvn:ru.entaxy.esb.platform.runtime.core.initializer/datasources-initializer/${project.version} + mvn:ru.entaxy.esb.platform.runtime.core.initializer/connection-initializer/${project.version} + + + + mvn:ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer/liquibase-updater/${project.version} + mvn:ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer/storage-esb_entaxy/${project.version} + mvn:ru.entaxy.esb.platform.runtime.core.initializer.storage.initializer/storage-cache/${project.version} + + + diff --git a/platform/runtime/modules/LICENSE.txt b/platform/runtime/modules/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/modules/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/modules/pom.xml b/platform/runtime/modules/pom.xml new file mode 100644 index 00000000..c2ae6154 --- /dev/null +++ b/platform/runtime/modules/pom.xml @@ -0,0 +1,16 @@ + + 4.0.0 + + ru.entaxy.esb.platform + runtime + 1.8.0 + + ru.entaxy.esb.platform.runtime + modules + pom + ENTAXY :: PLATFORM :: RUNTIME :: MODULES + ENTAXY :: PLATFORM :: RUNTIME :: MODULES + + uniform-service + + \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/LICENSE.txt b/platform/runtime/modules/uniform-service/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/modules/uniform-service/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/modules/uniform-service/cfg/uniform.exchange.passive.cfg b/platform/runtime/modules/uniform-service/cfg/uniform.exchange.passive.cfg new file mode 100644 index 00000000..09f7764f --- /dev/null +++ b/platform/runtime/modules/uniform-service/cfg/uniform.exchange.passive.cfg @@ -0,0 +1,5 @@ +# адрес soap-connector, будет формироваться host/cxf + passive.endpoint.address, +# по умолчанию passive.endpoint.address=/exchange +passive.endpoint.address=/uniform-exchange +# включение кастомной валидации soap сообщений по wsdl +passive.endpoint.validation=true \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/cfg/uniform.service.ignite.cfg b/platform/runtime/modules/uniform-service/cfg/uniform.service.ignite.cfg new file mode 100644 index 00000000..0b927ffe --- /dev/null +++ b/platform/runtime/modules/uniform-service/cfg/uniform.service.ignite.cfg @@ -0,0 +1,11 @@ +# путь до рабочей директории для ignite, на каждой ноде своя +ignite.work.directory.path=entaxy/uniform/ignite + +# количество узлов, которые будут хранить данные(бэкапы) с этого узла, +# нужен для корректной работы кластера,если данный узел упал +# по умолчанию backups = 2 +ignite.backups=2 +# спектр адресов, которые занимает игнайт для образовния кластера +# https://apacheignite.readme.io/docs/tcpip-discovery +ignite.addresses=127.0.0.1:47500,127.0.0.1:47501 + diff --git a/platform/runtime/modules/uniform-service/cfg/uniform.service.support.cfg b/platform/runtime/modules/uniform-service/cfg/uniform.service.support.cfg new file mode 100644 index 00000000..177fb65d --- /dev/null +++ b/platform/runtime/modules/uniform-service/cfg/uniform.service.support.cfg @@ -0,0 +1,28 @@ +# максимальное количество попыток отправить сообщение в очередь из агрегатора +redelivery.maximumRedeliveries=2 +# очередь для отправки сообщений, которые не смог отправить агрегатор в destination +redelivery.deadLetterQueue=revert.message.dead + +# задается в mc, значение по умолчанию 10 минут +acknowledge.completion.timeout=600000 +# настройка способа агрегирования через игнайт или бд +# Важно! следить за тем чтобы данный параметр был одинаковым во всем кластере +# варианты - igniteAggregationRepository, jdbcAggregationRepository (для всех бд кроме postgres), postgresAggregationRepository +# по умолчанию - jdbcAggregationRepository +acknowledge.aggregation.repository=jdbcAggregationRepository + +# Поднимается endpoint /active_connector_test_consumer +# при выставленной настройке mode.dev=true +active.mode.dev=false +active.username=Администратор +active.password= + +# валидация сообщения по wsdl +active.validation=false + +# uuid шины, для отправки в активном режиме в систему от имени шины +bus.id=FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF +get.destination= + +# параметр для тестирования активного коннектора +test.empty.rate=20 \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/connector/LICENSE.txt b/platform/runtime/modules/uniform-service/connector/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/modules/uniform-service/connector/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/modules/uniform-service/connector/pom.xml b/platform/runtime/modules/uniform-service/connector/pom.xml new file mode 100644 index 00000000..88902c56 --- /dev/null +++ b/platform/runtime/modules/uniform-service/connector/pom.xml @@ -0,0 +1,85 @@ + + + + ru.entaxy.esb.platform.runtime.modules + uniform-service + 1.8.0 + + 4.0.0 + + ru.entaxy.esb.platform.runtime.modules.uniform.service + connector + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: MODULES :: UNIFORM :: SERVICE :: CONNECTOR + ENTAXY :: PLATFORM :: RUNTIME :: MODULES :: UNIFORM :: SERVICE :: CONNECTOR + + + + template + + + javax.xml.soap*;version="[1.3,2)", + javax.jws.*;version="[2.0.0,3.0.0)", + javax.jws.soap.*;version="[2.0.0,3.0.0)", + javax.xml.ws.*;version="[2.2.0,3.0.0)", + !com.sun.xml.*, + ru.entaxy.esb.system.common.aggregation, + ru.entaxy.esb.system.core.common.error.handler.interceptor, + ru.entaxy.esb.system.core.template, + ru.entaxy.esb.system.profile.commons, + ru.entaxy.esb.system.profile.commons.connectors.in, + ru.entaxy.esb.system.profile.commons.connectors.out, + javax.xml.bind;version="[2,3)", + javax.xml.bind.annotation;version="[2,3)", + javassist.util.proxy, + org.apache.commons.lang3, + * + + + + + + xerces + xercesImpl + ${xerces.version} + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + ru.entaxy.esb.system.registry.systems.profile + system-profile-api + ${project.version} + + + ru.entaxy.esb.system.registry.systems.profile + system-profile-collector + ${project.version} + + + org.osgi + osgi.core + ${osgi.version} + provided + + + org.apache.cxf + cxf-rt-transports-http + + + org.apache.cxf + cxf-rt-transports-http-jetty + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/connector/src/main/resources/OSGI-INF/blueprint/camel-context.xml b/platform/runtime/modules/uniform-service/connector/src/main/resources/OSGI-INF/blueprint/camel-context.xml new file mode 100644 index 00000000..a9b54033 --- /dev/null +++ b/platform/runtime/modules/uniform-service/connector/src/main/resources/OSGI-INF/blueprint/camel-context.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/connector/src/main/resources/template/uniform-service-in-connector.ftl b/platform/runtime/modules/uniform-service/connector/src/main/resources/template/uniform-service-in-connector.ftl new file mode 100644 index 00000000..16e759c8 --- /dev/null +++ b/platform/runtime/modules/uniform-service/connector/src/main/resources/template/uniform-service-in-connector.ftl @@ -0,0 +1,577 @@ +<#-- + ~~~~~~licensing~~~~~~ + connector + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <#if isActive == "true"> + + + + [=systemName] + + + [=endpointUrl] + + + + + + + + + ${headers.ENTAXY_SystemEndpoint} == null || ${headers.ENTAXY_SystemId} == null + + + + + true + + + + http://www.entaxy.ru/connector/universal/system/1.0 + + + ${headers.ENTAXY_SystemEndpoint} + + + + + + + + + + ${headers.SystemHasMessages} == 'true' + + + {{bus.id}} + + + {{get.destination}} + + + + + + + GetPackets + + + + + + //soap-type:response/soap-type:packets + + + + + //soap-type:packets/soap-type:packet[1]/soap-type:message/soap-type:content/node() + + + //soap-type:packets/soap-type:packet[1] + + + + + + ${headers.ENTAXY_MessageUUID} + + + + ConfirmGettingPackets + + + + + + + not(//soap-type:status/text() = '200') + + + + + true + + + + + false + + + + + + + + + + //soap-type:packet/soap-type:message/soap-type:messageUUID/text() + + + + //soap-type:packet/soap-type:header/soap-type:destination/soap-type:id/text() + + + + + //soap-type:packet/soap-type:header/soap-type:destination/soap-type:type/text() + + + + //soap-type:packet/soap-type:message/soap-type:source/soap-type:id/text() + + + + //soap-type:packet/soap-type:message/soap-type:source/soap-type:type/text() + + + + + + ${headers.ENTAXY_Source} == '' + + ${headers.X-SystemName} + + + + ${headers.NTX_SystemId} != ${headers.ENTAXY_Source} + + + + + //soap-type:packet/soap-type:message/soap-type:messageType/text() + + + //soap-type:packet/soap-type:message/soap-type:priority/text() + + + ${headers.ENTAXY_Priority} == null || ${headers.ENTAXY_Priority} == "" + + 4 + + + + + //soap-type:packet/soap-type:message/soap-type:customHeader + + + + + ${body} == null + + + + + + + + <#else> + + + + + uniform-service + + + uniform-service-in-connector-[=systemName] + + + + + ${headers.operationName} == 'PutPackets' + + + + ${headers.operationName} == 'ConfirmGettingPackets' + + + + ${headers.operationName} == 'GetPackets' + + + + + + + + + + + + + count(/soap-type:packets/soap-type:packet) + + + ${headers.NTX_1C_EXCHANGE_PacketCount} > 1 + + + + + /soap-type:packets/soap-type:packet[1] + + + + /soap-type:packet/soap-type:message/soap-type:messageUUID/text() + + + + ${headers.ENTAXY_MessageUUID} == "00000000-0000-0000-0000-000000000000" +<#-- health check --> + + + ]]> + + + + + + + /soap-type:packet/soap-type:header/soap-type:destination/soap-type:id/text() + + + + + /soap-type:packet/soap-type:header/soap-type:destination/soap-type:type/text() + + + + + + + /soap-type:packet/soap-type:message/soap-type:source/soap-type:id/text() + + + + + /soap-type:packet/soap-type:message/soap-type:source/soap-type:type/text() + + + + ${headers.X-SystemName} != ${headers.ENTAXY_Source} + + + ${headers.ENTAXY_Source} == '' + + ${headers.X-SystemName} + + + + + /soap-type:packet/soap-type:message/soap-type:messageType/text() + + + + /soap-type:packet/soap-type:message/soap-type:priority/text() + + + + /soap-type:packet/soap-type:message/soap-type:customHeader + + + + + + + + ${body} == null + + + + + + + + + ]]> + + + + + + + + + + + + /soap-type:packet/soap-type:message/soap-type:contentType/text() + + + + + count(/soap-type:packet/soap-type:message/soap-type:content) = 1 + + + /soap-type:packet/soap-type:message/soap-type:content/@xsi:type + + + + + boolean(normalize-space(/soap-type:packet/soap-type:message/soap-type:content/text())) + + + + + count(/soap-type:packet/soap-type:message/soap-type:content/child::*) + + + + + ${headers.NTX_ContentChildNodesCount} == 1 + + + /soap-type:packet/soap-type:message/soap-type:content/* + + + + Document + + + + ${headers.NTX_ContentChildNodesCount} > 1 + + + /soap-type:packet/soap-type:message/soap-type:content/* + + + + NodeList + + + + ${headers.NTX_ContentChildNodesCount} == 0 + + + ${headers.NTX_ContentHasNotEmptyText} + + + /soap-type:packet/soap-type:message/soap-type:content/text() + + + + String + + + + + + ]]> + + + + + + + + + + + + + + + + ]]> + + + + + + + + + /soap-type:getPacketsRequest/soap-type:destination/soap-type:id/text() + + + + ${headers.NTX_SystemId} == '' + + ${headers.X-SystemName} + + + + ${headers.NTX_SystemId} != ${headers.X-SystemName} + + + + + + + entaxy.uniform.service.exchange.[=systemName] + + + /soap-type:getPacketsRequest/soap-type:limitCount/text() + + + /soap-type:getPacketsRequest/soap-type:limitSize/text() + + + ${headers.NTX_LimitCount} > 1 || ${headers.NTX_LimitSize} > 0 + + + + + + + ${null} + + + + entaxy-broker:queue:${headers.NTX_OutQueue} + + + + + ${body} == null + + + 204 + + + + + + + + + + + ${headers.JMSDestination.name} + + + ${bean:uuidGenerator.toString} + + + + + ${headers.CamelJms_IntMessageType} == 'String' + + + + ${body}]]> + + + + + + + + + + + + + + + count(/soap-type:uuids/soap-type:uuid) + + + ${headers.NTX_UuidCount} > 1 + + + + /soap-type:uuids/soap-type:uuid[1] + + + + /soap-type:uuid/text() + + + + ${headers.ENTAXY_AcknowledgeMsgID} + + + + + + + diff --git a/platform/runtime/modules/uniform-service/connector/src/main/resources/template/uniform-service-out-connector.ftl b/platform/runtime/modules/uniform-service/connector/src/main/resources/template/uniform-service-out-connector.ftl new file mode 100644 index 00000000..b8387831 --- /dev/null +++ b/platform/runtime/modules/uniform-service/connector/src/main/resources/template/uniform-service-out-connector.ftl @@ -0,0 +1,163 @@ +<#-- + ~~~~~~licensing~~~~~~ + connector + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <#if isActive == "true"> + + + + + [=systemName] + + + [=endpointUrl] + + + + + ${headers.ENTAXY_SystemEndpoint} == null || ${headers.NTX_SystemId} == null + + + + + + + ${headers.JMSDestination.name} + + + ${bean:uuidGenerator.toString} + + + + + + ${body} + ]]> + + + + + http://www.entaxy.ru/connector/universal/system/1.0 + + + PutPackets + + + ${headers.ENTAXY_SystemEndpoint} + + + + + + not(//soap-type:status/text() = '200') + + + + + true + + + + + + + + + + + + ${headers.ENTAXY_Priority} == null || ${headers.ENTAXY_Priority} == "" + + 4 + + + + entaxy.uniform.service.exchange.[=systemName] + + + + + + + diff --git a/platform/runtime/modules/uniform-service/feature/features.xml b/platform/runtime/modules/uniform-service/feature/features.xml new file mode 100644 index 00000000..bf13a4c5 --- /dev/null +++ b/platform/runtime/modules/uniform-service/feature/features.xml @@ -0,0 +1,36 @@ + + + + + + mvn:ru.entaxy.esb/karaf-features/${project.version}/xml/features + + + + mvn:ru.entaxy.esb.platform.runtime.modules/uniform-service/${project.version}/cfg/uniform.service.support + + + mvn:ru.entaxy.esb.platform.runtime.modules/uniform-service/${project.version}/cfg/uniform.service.ignite + + + entaxy-common + + mvn:ru.entaxy.esb.platform.runtime.modules.uniform.service/support/${project.version} + mvn:ru.entaxy.esb.platform.runtime.modules.uniform.service/connector/${project.version} + + osgi.service;effective:=active;objectClass=org.apache.camel.Component;connection.name=entaxy-broker + + + + + common-soap + + mvn:ru.entaxy.esb.platform.runtime.modules/uniform-service/${project.version}/cfg/uniform.exchange.passive + + mvn:ru.entaxy.esb.platform.runtime.modules.uniform.service/uniform-service-endpoint/${project.version} + + + diff --git a/platform/runtime/modules/uniform-service/pom.xml b/platform/runtime/modules/uniform-service/pom.xml new file mode 100644 index 00000000..3ac2ceab --- /dev/null +++ b/platform/runtime/modules/uniform-service/pom.xml @@ -0,0 +1,86 @@ + + 4.0.0 + + ru.entaxy.esb.platform.runtime + modules + 1.8.0 + + ru.entaxy.esb.platform.runtime.modules + uniform-service + pom + ENTAXY :: PLATFORM :: RUNTIME :: MODULES :: UNIFORM :: SERVICE + ENTAXY :: PLATFORM :: RUNTIME :: MODULES :: UNIFORM :: SERVICE + + connector + support + uniform-service-endpoint + + + + + + features + + + + ./ + true + + **/features.xml + + ${project.build.directory} + + + cfg + ${project.build.directory}/cfg + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.12 + + + attach-artifacts + package + + attach-artifact + + + + + target/feature/features.xml + xml + features + + + target/cfg/uniform.service.ignite.cfg + cfg + uniform.service.ignite + + + target/cfg/uniform.exchange.passive.cfg + cfg + uniform.exchange.passive + + + target/cfg/uniform.service.support.cfg + cfg + uniform.service.support + + + + + + + + + + + feature/features.xml + + + + + \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/support/LICENSE.txt b/platform/runtime/modules/uniform-service/support/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/modules/uniform-service/support/README.md b/platform/runtime/modules/uniform-service/support/README.md new file mode 100644 index 00000000..9b43ec10 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/README.md @@ -0,0 +1,32 @@ +**IGNITE** + +IgniteAggregationRepository сделано на основе JdbsAggregationRepository +документация https://help.talend.com/reader/Uc2IlRuFVfGrjaFPdRI7kA/fBdqK2kf6iIkLHQf9nLh6g + +Есть некоторые внутренние баги karaf, которые не позволяют установить некоторые ignite фичи в караф +https://github.com/apache/ignite/blob/fd921a233d35408883695419b6f9979ac674d1b9/modules/osgi-karaf/src/main/resources/features.xml#L87 + +В карафе поднимается ignite, с рабочей директорией, прописанной в ru.entaxy.esb.ignite.cfg, +в параметре ignite.work.directory.path. Это место, где игнайт +создает для себя все, что нужно, и будет хранить данные. + +Ignite настроен с сохранением персисетнтности данных(сохранением их на диск) и +созданием реплицации(бэкапов) на других узлах кластера.(при потере одной ноды, +другие восстановят данные, которе хранились на текущем узле) + +IGNITE_QUIET=false - параметр необходимый для того, чтобы игнайт не писал информацию о себе в лог, +для того что бы параметр применился, необходимо выставить setGridLogger, +смогла установить в караф только JclLogger. + +**AggregationProcessor** + +AggregationProcessor стандартный, не расчитан на работу в кластере из-за чего пришлось вытаскивать исходники +и редактировать сам процессор.(AggregationProcessorWithRestoreTimeout) +Т к теперь AggregationProcessor вызывается как bean, а не как стандартный камеловский процессор, +то процесс старта и остановки происходит в отличном порядке. + +Для работы к кластере: +- добавлен механизм восстановления работы таймаутов на других нодах, +- отредактирован механизм удаления сообщения из репозитория(возникало состояние гонки и появлялись дубликаты), +- исправлен механизм продолжения работы с "застрявшими" сообщениями (recoverTask из таблицы _completed) +- добавлен безопасный механизм забора сообщений из очереди(восстановление сообщения в очереди, если не пришло подтверждение) \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/support/pom.xml b/platform/runtime/modules/uniform-service/support/pom.xml new file mode 100644 index 00000000..cea16345 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/pom.xml @@ -0,0 +1,122 @@ + + + + ru.entaxy.esb.platform.runtime.modules + uniform-service + 1.8.0 + + 4.0.0 + + ru.entaxy.esb.platform.runtime.modules.uniform.service + support + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: MODULES :: UNIFORM :: SERVICE :: SUPPORT + ENTAXY :: PLATFORM :: RUNTIME :: MODULES :: UNIFORM :: SERVICE :: SUPPORT + + + + ru.entaxy.esb.platform.runtime.modules.uniform-service.wsdl.*, + ru.entaxy.esb.platform.runtime.modules.uniform-service.xslt.*, + ru.entaxy.esb.platform.runtime.modules.uniform-service.xslt.type.*, + + + javax.xml.soap*;version="[1.3,2)", + javax.jws.*;version="[2.0.0,3.0.0)", + javax.jws.soap.*;version="[2.0.0,3.0.0)", + javax.xml.ws.*;version="[2.2.0,3.0.0)", + !com.sun.xml.*, + ru.entaxy.esb.system.common.osgi, + ru.entaxy.esb.system.common.osgi.impl, + ru.entaxy.esb.system.common.exception, + ru.entaxy.esb.system.common.aggregation.*, + ru.entaxy.esb.system.common.interceptor, + ru.entaxy.esb.system.common.util, + ru.entaxy.esb.system.common.validator, + * + + + + + + xerces + xercesImpl + ${xerces.version} + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + ru.entaxy.esb.system.registry.systems.profile + system-profile-api + ${project.version} + + + ru.entaxy.esb.system.registry.systems.profile + system-profile-collector + ${project.version} + + + org.osgi + osgi.core + ${osgi.version} + provided + + + org.eclipse.persistence + javax.persistence + ${jpa.version} + + + org.hibernate + hibernate-core + ${hibernate.version} + + + javax.transaction + javax.transaction-api + ${javax.transaction.version} + + + javax.interceptor + javax.interceptor-api + ${javax.interceptor.version} + + + org.apache.cxf + cxf-rt-transports-http + + + org.apache.cxf + cxf-rt-transports-http-jetty + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.apache.ignite + ignite-core + ${ignite.version} + + + + org.apache.ignite + ignite-jcl + ${ignite.version} + + + + com.hazelcast + hazelcast + ${hazelcast.version} + + + + \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/OSGI-INF/blueprint/camel-context.xml b/platform/runtime/modules/uniform-service/support/src/main/resources/OSGI-INF/blueprint/camel-context.xml new file mode 100644 index 00000000..ba117a08 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/OSGI-INF/blueprint/camel-context.xml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${body.replace('content xsi:type=', 'content xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type=')} + + + + + + + + ${headers.NTX_HeadersXML} + + + + + + + + + + + + + + + + ${headers.NTX_Acknowledge} == true + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + uniform-service + + + + + + + + + + + ${headers.operationName} == 'GetPackets' + + ${date:now:s} + + + ${headers.currSeconds} > {{test.empty.rate}} + + + + s1 + + + ${headers.NTX_SystemId} + + + 00000000-0000-0000-0000-000000000000 + + + + 00000000-0000-0000-0000-000000000000 + + + + + ${headers.operationName} == 'ConfirmGettingPackets' + + + ]]> + + + 200 + + + 00000000-0000-0000-0000-000000000000 + + + + + ${headers.operationName} == 'PutPackets' + + + ]]> + + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/bigPackets.wsdl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/bigPackets.wsdl new file mode 100644 index 00000000..55aa4134 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/bigPackets.wsdl @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/exchangeTypes_1_0.xsd b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/exchangeTypes_1_0.xsd new file mode 100644 index 00000000..e0758ec1 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/exchangeTypes_1_0.xsd @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/soap-active.wsdl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/soap-active.wsdl new file mode 100644 index 00000000..b310fb07 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/soap-active.wsdl @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/soap-passive.wsdl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/soap-passive.wsdl new file mode 100644 index 00000000..127564ea --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/wsdl/soap-passive.wsdl @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/ConfirmGettingPacketRequest.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/ConfirmGettingPacketRequest.xsl new file mode 100644 index 00000000..ca69d740 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/ConfirmGettingPacketRequest.xsl @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/ConfirmGettingPacketResponse.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/ConfirmGettingPacketResponse.xsl new file mode 100644 index 00000000..5a723866 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/ConfirmGettingPacketResponse.xsl @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/GetPacketRequest.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/GetPacketRequest.xsl new file mode 100644 index 00000000..d51d4b02 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/GetPacketRequest.xsl @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/GetPacketResponse.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/GetPacketResponse.xsl new file mode 100644 index 00000000..5a723866 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/GetPacketResponse.xsl @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/GetPacketResponseTest.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/GetPacketResponseTest.xsl new file mode 100644 index 00000000..9fca63a1 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/GetPacketResponseTest.xsl @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + 200 + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + RequestNumber + 111 + + + test1 + val + + + + + + + +
+
+
+
+
diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/PutPacketRequest.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/PutPacketRequest.xsl new file mode 100644 index 00000000..8f21b1cc --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/PutPacketRequest.xsl @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/PutPacketResponse.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/PutPacketResponse.xsl new file mode 100644 index 00000000..5a723866 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/PutPacketResponse.xsl @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/address.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/address.xsl new file mode 100644 index 00000000..4271a9ef --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/address.xsl @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + system.name + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/bigPacketInfos.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/bigPacketInfos.xsl new file mode 100644 index 00000000..836f94ce --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/bigPacketInfos.xsl @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/bigPacketPart.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/bigPacketPart.xsl new file mode 100644 index 00000000..7594d813 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/bigPacketPart.xsl @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/packet.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/packet.xsl new file mode 100644 index 00000000..db9a5cd4 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/packet.xsl @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/packets.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/packets.xsl new file mode 100644 index 00000000..7e5bfcbb --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/packets.xsl @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/request.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/request.xsl new file mode 100644 index 00000000..5039339a --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/request.xsl @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/response.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/response.xsl new file mode 100644 index 00000000..c3a25390 --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/response.xsl @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/uuids.xsl b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/uuids.xsl new file mode 100644 index 00000000..09c83dbb --- /dev/null +++ b/platform/runtime/modules/uniform-service/support/src/main/resources/ru/entaxy/esb/platform/runtime/modules/uniform-service/xslt/type/uuids.xsl @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + diff --git a/platform/runtime/modules/uniform-service/tests/uniform-exchange/uniform-exchange-connector env.postman_environment.json b/platform/runtime/modules/uniform-service/tests/uniform-exchange/uniform-exchange-connector env.postman_environment.json new file mode 100644 index 00000000..6415a093 --- /dev/null +++ b/platform/runtime/modules/uniform-service/tests/uniform-exchange/uniform-exchange-connector env.postman_environment.json @@ -0,0 +1,39 @@ +{ + "id": "0c775f13-bd86-4f7a-a66b-70d8e8dd03df", + "name": "uniform-service-connector env", + "values": [ + { + "key": "base_url", + "value": "http://localhost:8181/cxf", + "enabled": true + }, + { + "key": "system1_id", + "value": "s1", + "enabled": true + }, + { + "key": "system2_id", + "value": "s2", + "enabled": true + }, + { + "key": "adminLogin", + "value": "admin", + "enabled": true + }, + { + "key": "adminPassword", + "value": "admin", + "enabled": true + }, + { + "key": "system_active", + "value": "sa", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2020-04-22T10:27:24.630Z", + "_postman_exported_using": "Postman/7.22.1" +} \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/tests/uniform-exchange/uniform-exchange-connector test.postman_collection.json b/platform/runtime/modules/uniform-service/tests/uniform-exchange/uniform-exchange-connector test.postman_collection.json new file mode 100644 index 00000000..ec760f43 --- /dev/null +++ b/platform/runtime/modules/uniform-service/tests/uniform-exchange/uniform-exchange-connector test.postman_collection.json @@ -0,0 +1,2172 @@ +{ + "info": { + "_postman_id": "29562910-e6d9-40a2-ac59-960344ce0b74", + "name": "uniform-exchange-connector test", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "uniform-exchange-passive test", + "item": [ + { + "name": "settings esb", + "item": [ + { + "name": "Create profile system1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system1_id}}\n {{system1_id}}\n \n description1\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Create profile system2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system2_id}}\n {{system2_id}}\n \n description2\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Add Account system1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n \n {{system1_id}}\n {{system1_id}}\n \n {{system1_id}}\n \n {{system1_id}}\n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + } + }, + "response": [] + }, + { + "name": "Add Account system2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n \n {{system2_id}}\n {{system2_id}}\n \n {{system2_id}}\n \n {{system2_id}}\n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + } + }, + "response": [] + }, + { + "name": "Create uniform-service-in-connector", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n uniform-service-in-connector\n {{system1_id}}\n \n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Create uniform-service-out-connector", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n uniform-service-out-connector\n {{system2_id}}\n \n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Create uniform-service-in-connector", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{adminLogin}}" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n uniform-service-in-connector\n {{system2_id}}\n \n \n \n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Create permission", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});", + "", + "setTimeout(function(){}, 5000);", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system1_id}}\n {{system2_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "uniform-exchange-connector", + "item": [ + { + "name": "uniform-exchange-connector SEND", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is OK\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system1_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n \t\n \t\t\n \t{{system2_id}}\n \t\n \t\n \n b7e6aab7-8f02-443c-8f67-e2d638dd4da0\n \n {{system1_id}}\n \n \n RequestNumber\n 111\n \n \n test1\n test1\n val\n \n \n\t \t\t\n\t \t\t\n\t \t\n\t \n \n \n \n \n\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector GET", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has service response\", function () {", + " pm.expect(response).to.have.property('response');", + "});", + "", + "if (response.hasOwnProperty('response')) {", + " var packet = response['response']['packets']['packet'];", + "", + " var header = packet['header'];", + " ", + " var message_id = header['transportUUID'];", + " ", + " console.log(packet['message']['content']);", + " console.log(message_id);", + " ", + " pm.globals.set('message_uuid', message_id);", + " ", + " pm.test(\"Content is OK\", function () {", + " pm.expect(packet['message']['content']).to.be.an('object');", + " });", + " ", + " pm.test(\"message_id is OK\", function () {", + " pm.expect(message_id).to.have.lengthOf(36);", + " });", + "}" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml; charset=UTF-8" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{system2_id}}" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n \r\n {{system2_id}}\r\n system.name\r\n \r\n 1\r\n 0\r\n \r\n \r\n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector ACK", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is 200\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/xml; charset=UTF-8" + }, + { + "key": "X-ForwardedUser", + "type": "text", + "value": "{{system2_id}}" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n {{message_uuid}}\r\n \r\n \r\n\r\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + }, + { + "name": "uniform-exchange-connector empty content", + "item": [ + { + "name": "uniform-exchange-connector SEND", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is OK\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system1_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n
\n 10000000-0000-0000-0000-000000000000\n \n {{system2_id}}\n \n
\n \n 10000000-0000-0000-0000-000000000000\n ВыгрузкаДанных\n \n \n
\n
\n
\n
\n\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector GET", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has service response\", function () {", + " pm.expect(response).to.have.property('response');", + "});", + "", + "if (response.hasOwnProperty('response')) {", + " var packet = response['response']['packets']['packet'];", + "", + " var header = packet['header'];", + " ", + " var message_id = header['transportUUID'];", + " ", + " console.log(packet['message']['content']);", + " console.log(message_id);", + " ", + " pm.globals.set('message_uuid', message_id);", + " ", + " pm.test(\"message_id is OK\", function () {", + " pm.expect(message_id).to.have.lengthOf(36);", + " });", + "}" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system2_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n \r\n {{system2_id}}\r\n system.name\r\n \r\n 1\r\n 0\r\n \r\n \r\n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector ACK", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is 200\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system2_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n {{message_uuid}}\r\n \r\n \r\n\r\n\r\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "uniform-exchange-connector escape", + "item": [ + { + "name": "uniform-exchange-connector SEND", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is OK\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system1_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n
\n 2b5df363-410e-4917-8209-d2fd580a44e1\n \n {{system2_id}}\n \n
\n \n 2b5df363-410e-4917-8209-d2fd580a44e1\n ВыгрузкаДанных\n \n object_id\n 3a4623e2-8b12-11ea-a250-000c297cfa2a\n \n \n object_date\n 63724982760122\n \n \n\t\t\t\t\t\t<Data xmlns:cc="http://v8.entaxy.ru/8.1/data/enterprise/current-config"\n\t\t\t\t\t\txmlns:dmp="http://www.entaxy.ru/entaxyFresh/Data/Dump/1.0.2.1"\n\t\t\t\t\t\txmlns:ns="http://v8.entaxy.ru/8.1/data/enterprise"\n\t\t\t\t\t\txmlns:v8="http://v8.entaxy.ru/8.1/data/core"\n\t\t\t\t\t\txmlns:xs="http://www.w3.org/2001/XMLSchema"\n\t\t\t\t\t\txmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\n\t\t\t\t\t\t<cc:CatalogObject.кшдПериодическиеВыгрузки xsi:type="cc:CatalogObject.кшдПериодическиеВыгрузки">\n\t\t\t\t\t\t<cc:IsFolder>false</cc:IsFolder>\n\t\t\t\t\t\t<cc:Ref>3a4623e2-8b12-11ea-a250-000c297cfa2a</cc:Ref>\n\t\t\t\t\t\t<cc:DeletionMark>false</cc:DeletionMark>\n\t\t\t\t\t\t<cc:Owner xsi:type="cc:CatalogRef.кшдИнтеграционныеШины">5205e857-c7ba-11e9-a23f-000c297cfa2a</cc:Owner>\n\t\t\t\t\t\t<cc:Parent>00000000-0000-0000-0000-000000000000</cc:Parent>\n\t\t\t\t\t\t<cc:Description>Тест</cc:Description>\n\t\t\t\t\t\t<cc:НаименованиеПКО>ПерВыг_ПКО_Отправка</cc:НаименованиеПКО>\n\t\t\t\t\t\t<cc:ТипЗадания>f75b1344-4081-46b0-bc1e-79f9dd3c0f22</cc:ТипЗадания>\n\t\t\t\t\t\t<cc:Приоритет>0</cc:Приоритет>\n\t\t\t\t\t\t<cc:Комментарий/>\n\t\t\t\t\t\t<cc:РегламентноеЗадание>dff80fe7-2e66-4b9c-bdcc-f8e8d29c8ea5</cc:РегламентноеЗадание>\n\t\t\t\t\t\t<cc:Получатели>\n\t\t\t\t\t\t<cc:Получатель>5ce4815e-7f4b-11ea-a24e-000c297cfa2a</cc:Получатель>\n\t\t\t\t\t\t</cc:Получатели>\n\t\t\t\t\t\t</cc:CatalogObject.кшдПериодическиеВыгрузки>\n\t\t\t\t\t\t</Data>\n \n \n
\n
\n
\n
" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector GET", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has service response\", function () {", + " pm.expect(response).to.have.property('response');", + "});", + "", + "if (response.hasOwnProperty('response')) {", + " var packet = response['response']['packets']['packet'];", + "", + " var header = packet['header'];", + " ", + " var message_id = header['transportUUID'];", + " ", + " console.log(packet['message']['content']);", + " console.log(message_id);", + " ", + " pm.globals.set('message_uuid', message_id);", + " ", + " pm.test(\"Content is OK\", function () {", + " pm.expect(packet['message']['content']).to.be.an('object');", + " });", + " ", + " pm.test(\"message_id is OK\", function () {", + " pm.expect(message_id).to.have.lengthOf(36);", + " });", + "}" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system2_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n \r\n {{system2_id}}\r\n system.name\r\n \r\n 1\r\n 0\r\n \r\n \r\n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector ACK", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is 200\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system2_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n {{message_uuid}}\r\n \r\n \r\n\r\n\r\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "uniform-exchange-connector hello", + "item": [ + { + "name": "uniform-exchange-connector SEND", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is OK\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system1_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n
\n 2b5df363-410e-4917-8209-d2fd580a44e1\n \n {{system2_id}}\n \n
\n \n 2b5df363-410e-4917-8209-d2fd580a44e1\n ВыгрузкаДанных\n \n object_id\n 3a4623e2-8b12-11ea-a250-000c297cfa2a\n \n \n object_date\n 63724982760122\n \n \n\t\t\t\t\t\tпривет!\n \n \n
\n
\n
\n
\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector GET", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has service response\", function () {", + " pm.expect(response).to.have.property('response');", + "});", + "", + "if (response.hasOwnProperty('response')) {", + " var packet = response['response']['packets']['packet'];", + "", + " var header = packet['header'];", + " ", + " var message_id = header['transportUUID'];", + " ", + " console.log(packet['message']['content']);", + " console.log(message_id);", + " ", + " pm.globals.set('message_uuid', message_id);", + " ", + " pm.test(\"Content is OK\", function () {", + " pm.expect(packet['message']['content']).to.be.an('string');", + " });", + " ", + " pm.test(\"message_id is OK\", function () {", + " pm.expect(message_id).to.have.lengthOf(36);", + " });", + "}" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system2_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n \r\n {{system2_id}}\r\n system.name\r\n \r\n 1\r\n 0\r\n \r\n \r\n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector ACK", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is 200\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system2_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n {{message_uuid}}\r\n \r\n \r\n\r\n\r\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "uniform-exchange-connector file", + "item": [ + { + "name": "uniform-exchange-connector SEND", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is OK\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system1_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n
\n 2b5df363-410e-4917-8209-d2fd580a44e1\n \n {{system2_id}}\n \n
\n \n 2b5df363-410e-4917-8209-d2fd580a44e1\n ВыгрузкаДанных\n \n object_id\n 3a4623e2-8b12-11ea-a250-000c297cfa2a\n \n \n object_date\n 63724982760122\n \n \n\t\t\t\t\t\tUEsDBBQAAggIANyzr1BGZDbMGcYSAECPNgAoAAAANmM2NDIzNmUtOTMxNS00ZmQ5\n\t\t\t\t\tLTlmOWItMDRlZTkwZTJmN2Y2Lm1zZ+S9W48bW5Ym9uwB+j8M+vXgVEYESaWy0FMA\n\t\t\t\t\tk0FSQXFvipnBZEa8NKSkREYEI3VGyUyS8dQXY2xjDIxhDGBjYLs9vjwaKDRcmHL3\n\t\t\t\t\t9Mxf0Pkl/gtel73jxuA166hS5QJOScokd1z22uv6rW/9v//4n//Cfr94/89X8fz+\n\t\t\t\t\t4dd3d//iz2eLxU+/Pjt7ev0r8+5XXx7P4M+zCXzk7OP94uOXn74EDx/P7h6/fIF/\n\t\t\t\t\t/nj3+f5TMP1z9e1J/FP69eVyqb5v3nW+fHyYneFlzuzH+Kcz81fGr6xfmfpr9w8H\n\t\t\t\t\tXVR//On1jo/fff6SfnD1ULibZe1Xn79MzyzDMM9uRf/6bvYxfp99Ntj/4R+D+4fF\n\t\t\t\t\t+/u7j3/+mz/7Z//FX9zd/boF15x/ng4+hB/vFr/6y6//9uvvvv7Hr//p6/8M//1H\n\t\t\t\t\t+Ps/ff2Hr//49bc//83Pf/vzX3397de/g////c9/Db/93df/++vv4ff4mX/6+V/D\n\t\t\t\t\tn/8H/P7/+fqPP//rfw438+vF+qeP/+LPf6lL0APQE1x9/PSbD7X3d58+vH//42vj\n\t\t\t\t\t46sfTfPj+x/fW/WPPxqGcWddnN99em+9/4sz9WH9Rfvj/OMi+Hwv3n+JfvPp/fzh\n\t\t\t\t\tI32k8OPssw93X4Kf8Oe/AZG5hyf5/OUvFx8fFn8ZzCP1vewj+mtf/7uvf//z33z9\n\t\t\t\t\tTz//VeUrgbv51de/gwf9x5//26//Af78e3wN8Jj/+PX3f/6bj+cfrdefGvBQk/OP\n\t\t\t\t\t8FCTjz++Nz+8h4dqGI1Xd/Bsxmu6cnaV7ML/Pb5SeH241u9+/lf6xX397W8+mB8n\n\t\t\t\t\td1b91Y8f31s1Xvb1q1odljUnrwxjcvF+YvGy29dIL/Nv6YZ/+/V/gpuHvfr5v4T9\n\t\t\t\t\t+gf42b+CP3//9X+Hffs9PNTvfv4r2M/f0mP+E/z23/zGMsyLH03jR8N0jcav669+\n\t\t\t\t\tbaprnrrgxh39e1jgP8ASv8Wv0BUtuFz9R/PctWq/Nuq/btSLVyx/IV3xf4AP/Nd4\n\t\t\t\t\tKyCXtEVf/yknLpW/Tr/7P8KSLOO///qPJ8iAof73Y8X/6f/xbRSulL+Bf6Id/Ad4\n\t\t\t\t\tX/8OVv4rWPv3dOR+/5ta+tXtn0kX+l++/mc6lfR6vv7uLPvN39FWZb/9v77+Xf79\n\t\t\t\t\tVP06+y6c+b+BB/936cn+29zK/yv8jJ4KJPv1q4tavW7ymvlf5D/981/TVvyVeg+/\n\t\t\t\t\t+w3oxvQbG7/MffN3tPH/gA8Oj/+3sPDf/KK7VXnF7Ib+PUokKcS/po39ezqB/xXf\n\t\t\t\t\t+c//5uv/xruFn/pN+QN8gWNWSC+b/fD/JE1MsgQf/2/gZTWHneDD5esm/W/ww/lT\n\t\t\t\t\t7SEYrZ0HJ54ZkzfNV/31RW1Su3ucJOLxQ61330+cpbDbT+O2KUaW/Pxnf/bP/LE5\n\t\t\t\t\t64/nj3e1q9mHWM4d2boy+uHwYdI6xz+fFt2W0b8dPi5aS+Ptm6sp/tmvDRcS/vTs\n\t\t\t\t\tK1gCfnRheE9Xs0nrk9E/h191L+GrV9MJf/VJtkbqzx8cW84Gtoxk4tX77qjuu3cL\n\t\t\t\t\tWEJ2ZSTWZiC6YtV32ys/bK6ke4P/TsT1ZeyNV4mf/tmEh1D/tQz6E5bou/SjRf7H\n\t\t\t\t\tuf+mRu/N8FG2Vkb/Cf/8wfD6w8Wk9cro28PPcKewBP71adIy4M+rqcSbr10FF92O\n\t\t\t\t\t0TuD9wA/93AJeDj+6muj5/Kf/TotD0vsusIhy9MS266g/34Oy9BnYBnchQ98OdgV\n\t\t\t\t\tWB7fheG9nhr9L7gq7IyLv04M713u4913TssJtr0TehfwyrzN/U43+xoe5gKv6sJG\n\t\t\t\t\tt+rqs6bRXwZOsJzSXdi4Gj4viE+3izIRrpvrfiimIqgn/XD0KF1nKtyoTjt2Df/d\n\t\t\t\t\tDGG3PtN/sIRowau7aJ3hUg+ytYYbvQov8CoJPpwJrw4fqo4PAP+2SMzwbvqjqT8e\n\t\t\t\t\tNXAJS868RIBc+PHg2gQRElZ/PFoLGwXVD7zES6QtLOHerZyuP/vwBg6B/rMtZ7DE\n\t\t\t\t\tpNt5+GBNrv2x92j0dr3WVv0kAd8U6LI044OUBfrtJ5ZGfPbAHv50QbswfIRdgVN8\n\t\t\t\t\tz0cQT3GdPqtFq+rj5eeG5f2483BnjQp/whL4V5GMlgO3ufZcZyGTO2NwbaylPar1\n\t\t\t\t\tx1czf4yv+s6Q45Eh4ZX6YdTILw9L6Dd76mulw85v9tTXql9nlZ4gJddt4jFDpQev\n\t\t\t\t\tcqaO2g94ph5amb4AqYSbfkVnZe/XNrUYLLHx5tMdiFbSvopBMht9txN6obcQXSfx\n\t\t\t\t\tW8Zq4E7C/vhmDltQIwHvRF4yrHtB+QqXtncLWr17cT+Kb+L+ovVe6Y42afiLro1P\n\t\t\t\t\tAEs8SDqdw8dWM/HcaeLbd9agZZiDLmyqexX6tlh44WUIJ3Qlxt5SuCOT/p20p0r9\n\t\t\t\t\tqte32CrEuf8cMgikS9K/sx2p/NXG37dIq5LOsuB6lgy9JLLgwRZ+12mIwAAZmUR9\n\t\t\t\t\tVwYD21v4sZzJ7k3ku72QDGLbqtIDh0orG4FKPXCotJLiq9YDFVbtanqBh/x2+LCg\n\t\t\t\t\tg38Fd0N3QXqyT4c9msBew8EHdbxW1qrya9l3LmNYoiyw26V1WJM26FHrKoSHNQc2\n\t\t\t\t\tvOqwieoXBLbmxTfzvhvVZDJdy7i99Fw5l9eHSSssURbYY6UVX2dJYI+U1rk67GCC\n\t\t\t\t\tLujKpDvv8XXeonGEO3qTmh60vW9vWR7gdyAM6EihgAcTtFifyEob3if8+gUbRVDH\n\t\t\t\t\tE9QdtrJeaI67PbRiRj/7PCxx7FfKn8+8nNxXbofzC/yYfTWj/a+xg3DcMfNjf+Yp\n\t\t\t\t\tQffGHbS1c9+dmn13Hgh7tBjYV/OB7Vhw5GhHxl79Ozpmb9+pd/YFheDcAIULYtmn\n\t\t\t\t\t13k/jCV6Obj/6NWFVzOpP4r/Pr+ashvDskMOFbgxkhwpepBJywM/ijcLXDB4++30\n\t\t\t\t\to/Bv8MGbIIWhEidyKB8vuoIdyBYeM4eu+MdewuiF6CiiCKGmrquNe6U0N/iXm36F\n\t\t\t\t\tyBnGTZVj+uENbPBdTV4bDRF6y/7YD0XoLLz4ai5AxETSC714VBdJswY+B/qd5SsM\n\t\t\t\t\trY4Byz35Zm/uB+fDeEHOstolEKkLOkdXM7zj/nRKNrVdFxYotXC6kO5sLtfgnVvD\n\t\t\t\t\tpD92ll7SXgi3E0MgZUr6t1g5OXlBWWKDWKVeci6Jnd7JNI0O4E+QiXvlxvff6Lf+\n\t\t\t\t\tPuf1sxoC3wLe+gS/BrEavVqjh6oI3XkWORStiivAcsWvpZFC6u5fTcFolO4iO435\n\t\t\t\t\tj216NeVTXfByRg0vFEsZTsAgXM58uw12YlrzAjPy3Kug705rwhV18MsjGV4GQi2P\n\t\t\t\t\tm7rdTnyEO7wKKPb4gj5Y37FvYjlu18E3BfUTrWVIHp8fi7UIzMDvjlYQASQilgFo\n\t\t\t\t\tqATcVdM/zQfHTYzw8FOoA7sDMRqciXdGj87LZT6Cgne3ptf5lGnlC4yYbeUkUmgT\n\t\t\t\t\tstam6BC/0kCDAZt6ptz5Op/UIcVdeNS89hRPLV7VoQjpHDc7kxOQG7Dw53nzRHdx\n\t\t\t\t\thtqJ3VX6KtrW4pVhuRrJjI4UWkXXNRckZIfYHs4l6wt0lB/hvwfyijH8L9oUHQnI\n\t\t\t\t\t1lQlGNaobhZ0NeegIAMDq3ycYYulCCeRb1+CKEVL3x0tvMQHTWvU/XC0Bkc6kOGw\n\t\t\t\t\tJsKbEPXGoErlHC9eeBcgYc8Rr5wpKorX5ad82B9T/EbZAjJBCwrA+2RnyEVJMpVC\n\t\t\t\t\tUvdFx+u4xAcyTfjzntp81Orok3Acs2bRSnM1A9ABu65oeMuc7iBxo8wBrdrtsytC\n\t\t\t\t\tPkaXIqR+9VXz/gXKUbojOVVSjATqJOicXXiNAl3W+HgXb22VfEFLhoIcorYKMRoY\n\t\t\t\t\tuP5s0AKVE0YgE6DFreFCWE5dBmbsWW3DH1+h1oINnHuuN/W77TX4loYHm+zFMgJJ\n\t\t\t\t\tNKQdmWCKZvDzhRx78BUPHMzmUsa9sErxbXg2cCon3bcs+PgqH6YSlwAFKBNwllzH\n\t\t\t\t\tEi2T3kXirPvjHoQnoCtdsfasHvhRoEOTm3nZ7FTZnLLWasFr7ZzhKdVZFPA9ElQ9\n\t\t\t\t\tldEhOtukL0J8jdd84yiNt7yJb99AcIF28w17xah++Kyw9lIpQ1qiIou0LWXYsrM7\n\t\t\t\t\tDD9P8fIYCUhScq+23ShHBfD3gERrhV9nXQuiCIpSWbPqJB0owms7Zyg3E3Vw6TNa\n\t\t\t\t\tovqGP08oHYY6FBQeZdla7FQl6H+j9qYHYje+oWzDms/GzvRHY7DGbBUZieECPqcT\n\t\t\t\t\tdH2d/iKX7DWfka5gzV0Rl/BDrzAEJHftDd70J3G9LPwq/XmQs+p5be8W0kGoodjT\n\t\t\t\t\txTuawn99Nk303GUHAd6TZPkAs1SnB/nEr8oWprCjpYjbcCrB47OjhQiHplzDSR3f\n\t\t\t\t\tQGAJHp59M0cjANFDA7T3fOCOVuSugQMYGMnAvYSP3a0G4xH4FXcJqmORzAI4Tg2I\n\t\t\t\t\tQVYyHk6rvENWOamDeI+i431huUA/a73fD8W7KLmixwaayqbeXmQqGBxqFJszZaYF\n\t\t\t\t\thXYkM7zREGgqM04pVk5i37JMsHhRHPJYPk47lqVEDIpQt6NcE21HSGPr7DS79dOc\n\t\t\t\t\tB5Cp65JzcIp80IOwiKTy0ZWgvUVDxu06OAG4qeCHj2p+y0i8cGrhjoATOQf7C0ry\n\t\t\t\t\tBv0LGTQN2QWVb3trbw3xKJji/hiiQLe5kCH4Fy2jNrBngYzBp7DlHJyEqnxnOYA4\n\t\t\t\t\tRj5QtLaEKofKR06Db8oHefy5w67kgvPiSzbVrU9Ka0EM+lrt+Zs0DeCdDyP2clCD\n\t\t\t\t\tL1luwIX1btmVo7ICh7reKFeFqL/SgcQiyx6g53cVttBpZKl8YJN9plWO945vHLxd\n\t\t\t\t\t+jgnGwZo0R36efkuRuTesitboywKauKSz3CMw6DqI2U9cIzDgKJV4TNoh2HgCkPY\n\t\t\t\t\tQ/CXwGGwvBqKniSv0FkLUE1i3CN9AZZc2lcgtL14fypk02Eg73fTZzjGYTgoTqUU\n\t\t\t\t\tWC7geANOJm5uiJvMKuecjZtn84mFjzyUIiMy26Q/sJqjoiNWVRwVkUZanrqxbFNf\n\t\t\t\t\tH76xzUS6TTAKvRkYDnh/wwaVFRwMJhZ+tzP31ga8sqHpu2CCkk48cKMpbHpdgikS\n\t\t\t\t\tXQ9e7d3Kg68KGzNPl3N41XjYB90bEJPpWriXkew61rEbS9JZ7QweurFbiqGVG1v0\n\t\t\t\t\tBD9SOkSm7tojqZSQDjEdbHr75+z14Em+YPftnjwf7Wt9oRPMkYBKrmzojfRKlZdp\n\t\t\t\t\tsbdDS5AesI3+awogMJn9VHG1/KXyJinvg59okij5UPRajjVJuISySjK4nMGmrkAv\n\t\t\t\t\toPkxBt02fAwCSneKKdIIvgq6w7FkMjVE4hkybFdlXU8xSSgXe7Jn+0zSZgqkwiSd\n\t\t\t\t\to0+eZaY9fFeZy0J+p6uyI7hpoA+4AP4p528rJ9rejAR6VBPYdQWHsrE5KV1zqZrN\n\t\t\t\t\tEF9CxyPpVbZ4ujvyGngXW1Ibu/Ia+XIUycXuihSXo0ZrEXdCOe7EYAsNmTjg3o4a\n\t\t\t\t\tYm2QKbJHSX8MJsgVibRGDTkeNvz95ZU0r8G+1tbM2SF5jVI9dV86vZzXAOlNiiUW\n\t\t\t\t\tdA7qWaIhwbf/Q6YMzob3mIh466YaHSsXrC/wjWPMNYzpjX/AJV+X8xp4xarLcTFU\n\t\t\t\t\tpTaKUqq9GBWjpVfNLslRFNfZu6eKFcoUu/EnixXKFO7IPrGy20svbq8g6MJnXfs2\n\t\t\t\t\t5jfapt8yw4E9ojr7uDMHo1cDqxZ4lmMcUGMupMs4mDhZrI6s0myKFfoYNcoc0Osi\n\t\t\t\t\tJ/kdqBBU9klWCPukswdUJyupG/RLLpQD/bBgTxc/Rjnx/ru0KLi4yIFrKtwYsiOn\n\t\t\t\t\t57TQjWEvp+yixsIWNT9u1wao6G1/DhseSvI9wd8EN8Z3we64VwFscI30BZiU0FtB\n\t\t\t\t\tgJ1AdLQYjOHv1+ZMxn4ApiiSIdZPJQTXfiTsCbiuQ+sgCMdhOS10Y0i0Ts9plaKi\n\t\t\t\t\tCk8mZKPA5ZSc+zJB+fjMx44Vn9rnt+9YB3BZJW9L1FeqTzJJ5/G57/xJ5irNzsO8\n\t\t\t\t\t7ySTlwNWPIR4JMRaO/ifXQc2tjfzQCb8bhuO3TSBeGQtu7hEez24rvByTiut6JPM\n\t\t\t\t\tXs5JpZXNULeitHKm6iTacUxQm3OB44JSJVTdSlMgmB4EScSvEgAPE9jvMHu2ohLb\n\t\t\t\t\thUrWSY5bFgvOZxg9PmaUVIFlrnUom/NqKNNGNZKEDEI/VJXf7LJU1cUrE4oOA24b\n\t\t\t\t\tU4JwPvpsRzCFSEVjfBiLkzRFEctVMk8VMU7on1xewdoK6ou0vNI0/Hi0GnS9GohT\n\t\t\t\t\t3bfBDbEvA4iUwGVtWhA91b1kaoFD2YBwt+G3vrvq3Rlaep0bfpUVhUMs8ZMR8Fyl\n\t\t\t\t\t+JM040yJ27Ra94YTMiBiEaXWa2nqDPPlqj6yuN6Ijs9QOjXqlmvuCvrGCV4sV/+g\n\t\t\t\t\tQt2nTdgn/BlNMXvCV3+AvzslycS7vKW7KUVFuUB7DVHxQVESLLEvt7svsYuitTW3\n\t\t\t\t\tC5JpQZQ0xogJJHMMIjeWgQCFiF8FOzKHwJuWSDogB5HpqUDp2CgJRetIjEE5Strm\n\t\t\t\t\topSiJFQtqV7Bwkduw9kIpHuulFmbwhiV2GdJxMIHK73HCSK1MfvW7WO9GZaILxTY\n\t\t\t\t\tMIWo4L/vUfmZlLRt7Ra70l2UJe8QsSP160wVIDcPElE1ZZX2gYfZJoKkcv7w6eMj\n\t\t\t\t\tywuYy7luJsId1ny3Ew2uzUi4zUbfxXB/tICwPpJrwxL2tDGwO3M/nEWILnvx6eOS\n\t\t\t\t\tFM50Ek5n4DClzN7yeVrdQrnY0FhZ/i5N3mV4gx8yPHhUgA7nygTHJmQKduQ4VaM3\n\t\t\t\t\tmVNj5TJS7OErS9oWqBqwXM4KMYy+PVqAp2z51wYIQNTwwV8V9pxyOVvKSIduMgr4\n\t\t\t\t\tiapmW8PDblVTsclnKioyOIPWHRTQghethcKpvMpAzLVUn2jnCZfQ4BAqDifcyID+\n\t\t\t\t\tBv787RuVYekrpHrpzq653FSROlatBWgIQZOdF4GJ4MPm7w6X2NBIqqUC/uQrT5VB\n\t\t\t\t\tLN6hlmJeYv2cLHTW8HByFpqs2bCxLws9sKcWBOWmCEFCE5AVLC/E5LpF5IN7IPME\n\t\t\t\t\trmp4yWXkxZ5xTBaajMDu8G1f7KZUzsFZ6FJ54bN2lHIyIVtxirDkvI2GTDY24FAe\n\t\t\t\t\tix0ZgZzkgeVS2EYKIHJ4x8a2Dc87SifE62kvze7Kw74NJ4DRDbxlrz7oImJO1MET\n\t\t\t\t\tBnPUroODvMJ4Hb5igdIDndIJ5Fg0qiKBZ8TruOEoWs+I1wtpwoo9L3b55FVRDpei\n\t\t\t\t\tTyohTNkhuh1WmCZbISOoAPpY0B1qR7IVN5fbn7SDJU4J9fNBGAm4c3wvje3HfnfY\n\t\t\t\t\tQEgDZVE8c+COFgLTO4GRSBtdlDZYMWwKmc2lG9X81vakHSxxSqifD8JILo4P9fNB\n\t\t\t\t\tGCwRkQt6zplUhQxTruxHqhdm9eRX+AojRJh5qufGe0K5mJGhO2fkD6PzGXGN8rFt\n\t\t\t\t\t+ZatWhzPlGixyCzogGOmQJURbIUAQl1SdYliju8Z0MiiyqmM3QduG2ENhkjAu4Go\n\t\t\t\t\tCNyWpRfKiDbeojIkNr/BjiTe+CqU9iwAxwj+jqcWT10n9LsobvMZiFt94PoxypEY\n\t\t\t\t\tO+B3zELY8HUhr3Va7E4uynG53iPatCh258Ba9R+epa93TsACUgA64GZ78QlDGJML\n\t\t\t\t\tP1lfRHGZ1wpvQNgtwr+Sl6M8loW2G1VLbdcbKabxtBTho4YOZzJwTLsF9VrY0xqF\n\t\t\t\t\tus0l7D2ol2EiY7AbXQ/0gxkNbDnvU77Xn0l7EskE1E9Fsh8f5BkpQhQA0lqnpwgz\n\t\t\t\t\tO1IpAzFhnW3GQFe1YuDr515dTtx/YV0A1vqnVpUsfMnwKJNiRwO3rFFkjJv5MFHV\n\t\t\t\t\tbELgOlNecrctUbXl59gSTFYeqBc2lUK0hu/UqSZwNeu74CMl04W0OjOIesAF6cDP\n\t\t\t\t\thiuZ9OYQIZnS9mpiS10RawLPkAkUCEbcBs+xJapjOFpwqivQ7VqTnb4G+BgY/pA2\n\t\t\t\t\tT5RzcH/BCJdHikM+lPVFcflrWir1PyjrWnZBEMp0fkUdYP13DGPYeokiBvpEW6Kr\n\t\t\t\t\tNHtsyS7/g+xIVTtv2/BjcF+tdg3UTeyBaIluGzYTdsRFPQKb3e1FXujPqfV5WJPB\n\t\t\t\t\t6baEoqLj64abGOjFHltyQahb/RonRdnRfieIz32m+A3eOHZNPldBoHLL6qrupFps\n\t\t\t\t\tHJmDVWNcotLGsEyKriLMgV79m9WWyzJCqbF9bupoPehexSAX4I9OVwOsLbuihmZK\n\t\t\t\t\tdL2EjMCw7oewadRQ3La89cuuLeNmYleDaobggEK3XXAy6lOa7uBExK1qx6AkRFOl\n\t\t\t\t\txnRXqKmw9Ofck6mSbWEBdMmISypJKrAu6wiF0CVJXVzko2VKwGF54XHHlTeRlrqv\n\t\t\t\t\tyFBFccXxcJyIYebghEgoX/FExXdg0dPp3syx/VciggpcFx/TaImgxC1soByjVztc\n\t\t\t\t\tDuxeIEJs1RPLwYEuLaJMT4iE8iJWKE+fJmKMUULrxAiYCy56kohRBVO1b5Gb2ld5\n\t\t\t\t\trVBlXbnBNAVnomhNN0XJO8v1C9js0mKos86qntxou/UK+eWrsOClSuapvQJa8Z2I\n\t\t\t\t\tBZfczy7joemFArPshogdZFaIMJnvu81ErI21N3ZqHmgwYQ9XwnKq+oqek8zHJC/K\n\t\t\t\t\txTOS+bksCud53/Eh7uueq3v0bmp0xNBVoR5/pRhAZqjDBX6vjMDj+jQbotKER9kQ\n\t\t\t\t\ttwdBxhTsyHQBr74Gp3tNcuEkfffOhGPDYYx7ByELvFrXq8EmRxI30ho2+nj8xsPF\n\t\t\t\t\tYDwEQwHHLkQoXC+m5IMfQjQUC9uzvKBZE5QavasRONcawfJT07Pg7buTGbxW0CnO\n\t\t\t\t\tCtyXGNzaAMwTS+cIvjIDrwXEKJw2PLBugzFxGdTQunmutxboXLsgH2NvjV3ncMe1\n\t\t\t\t\tQRc9IG9NbVroBFEwBXs/R597NeiOLAiqwVDCV68vQ9Ablowdy782wf9u1rEVwcd0\n\t\t\t\t\tuH23pEjAaHihA2YWfhzeJfC6ptIe1lG1CLsNH4tIwGHZBJ8dRUomU5DW0RLeF9pU\n\t\t\t\t\tL/RMx8YI4K4uQqRDEHXsYYYHrMFDmeimgVI0fNBo8IBzkMuVHzTX4MrBAxOQBF+b\n\t\t\t\t\tNxbwxkcNtNqg1JZg7Ve+PYXgYQpWHSICuz2Fo2fK+CYc2NFi4EpMwFlwRzUO++Hm\n\t\t\t\t\th3Ai4a2MwVFMLkMPduTQLLSWzmdkoXPq94gs9Chn/RTYaqT6cikJVXTVNQJEKYG+\n\t\t\t\t\trptlyUsqkttFi94f5ft1f9i+LAJLGOs6qW7j3aZuy7o2bRY7rjUrq6kNGTW2ye+x\n\t\t\t\t\tg9wDGWvq0h1aoASX8M2Ak5VrHyw5HJsl4tLkWEYibhsDF+mYnL01NVjilNasvK7l\n\t\t\t\t\tjuHjOUBI1+Zep711z0OFiX9YpAmHi3LvrnIaF4QKIkepT+02GywcCCgh5/Jjqfzw\n\t\t\t\t\tg27Mn3A/binHfbZ5B4RTKnR9ce8d2gOSB9XhuNk4iPW07C6GyiuyVWpMV/cf+MpG\n\t\t\t\t\t/iYPuUPtovBNLso3ecgd0hLRVDlHnTyu84kKPWyxHi50V1yR7yE9ZrlaCN5cwI2k\n\t\t\t\t\tsWxdHVIQ1G78kfWhfHEIQ5qg2RAuaOhwmKDaBcsF3u1lILDfCI4ZtbG5ESg6OfPh\n\t\t\t\t\t9Qy6cG7sKRzJK2pLIcXXXsNGgGOMjAodMLtgmsJmHczMCsG8PgReu1Qxhf3H14fy\n\t\t\t\t\tqhh98BPqQ3lVnHud3B/A1GUcdFPwTapXEeupvgFb5f9COo66BUW19xJKkErSirxi\n\t\t\t\t\tssExdaZamUjPLrQDTaLzgyM1qwL3sJNDlLta+VKqtpxmGr9tzF7OBVI35J50YLcT\n\t\t\t\t\tQAwGItcLsM3AQ8/HGq4gZp+JUMZk2UUDXDCQgRn8KFod02bwx4nZ09cpSS3T5qrX\n\t\t\t\t\tuWBEHKZ4rgkmjBEPQkQvuMRUCLjY/n5StSPdt0xIF7TmUrFkplAn1SXbuRkN18VN\n\t\t\t\t\tJWiDonq84FQPp3wiMs8QnyWUgSY3nnt3F+U7UelDlaw8ND7DrPTNzZVdis2ObaAs\n\t\t\t\t\tazPdBl6NcDhIm1GOL1NocuwYoMyouAGuKhbFwWXtzJG3EdMDwuqE0p2Cizubg6Bb\n\t\t\t\t\tVfnOE6rd9C6Oa6Dcjsup8C1vFSvHU/Z+ZJ5OIyGnQrUmlfwK/NPDwkW0aI0VPcAF\n\t\t\t\t\to+uQhcFWCpEZCdJemowSgbDxfA7OMz1hF7rJ8yZbwxYyVwSzRnAHbQWk+aD67Wpq\n\t\t\t\t\tSWRY2HMXL7rHyvaWEHQtfWymcjtzEYPyS24icW0kTCC37mP+ciznvn0ZgUcbyhfe\n\t\t\t\t\tY2Vz05TulHyrqR4zQhdMFS4ytyyP18opPQ/t7z1rsR9UzwSuyH6VnXPXNmol+bbg\n\t\t\t\t\tEs2MWhVkoWVM3wb1lbdurCfuw1RcNxdO6/OjGItH/3Z0nmkrB2XFuLu/+cUYBpBU\n\t\t\t\t\tE0QH4nJ4vZYfRrAzoGoCCCLCJpYBYi8WlkiGsP1tIt+8vpzLGOONeSjXRl12xRpz\n\t\t\t\t\t4l6MIKxJ6CHwMB6uYcOXsOwKAu3vASJKlFNJtql9BvO+LfEfI8xcfVabotzHGV1s\n\t\t\t\t\tczjL5bbX5Mavv2UvzbEAG+6lqYHFqvsICx6LOtGJ2GitDAt7u/uuA3ZjtJR2BOYK\n\t\t\t\t\tbMj6O+ilyTlCIR9w6pLFCCmXVThD0Zuo2Iw5H26VI+SmDBOz4u6gq7JWDhWpm3yo\n\t\t\t\t\tx4f9hwwarIoa1HPH0SLTRqADkTXKwN2tdFSJNrXF7RNpzSNjJakrZ8lk/zsLLvPE\n\t\t\t\t\tJlkwYSqb+vpYjCc/yPoEjGfqAXHd7KCQTiQzUDmjhgQfZOB62JM58yyxYu7jBgj0\n\t\t\t\t\tQiSoiZprcIzAbjjGi8+u3VImWjnZKWyB2vIqcVvwJ7GSaKDNw2aC7old08LK6bJc\n\t\t\t\t\tN/2BxG7CPKeaG5x/xlwg/ONlqfg1pKW/Ydh/ODWZphmRscSMdR1xPOSiREs/MOoi\n\t\t\t\t\tHtZAQyFlGSbpMB9u+d2hBVK4fvFh/60mqFWAq2CStm6WN/kV/vkTKYL71O4gMl2x\n\t\t\t\t\tv5Gn44WqAKoVXH2aEipy3b1XJM3iSyimGr6KoJbvB0zGcVfLOmsF336ZQvveaU0P\n\t\t\t\t\tG9yEx7NQUE2gqh7WNAb2PJDh1BDIOBF6DdqRsbMA9YN0ypYEDwjCfybrBW/Xbp/c\n\t\t\t\t\t9EBycXp/Va59b3eC9pMiwyrn+jjQUiHNgyLejWm/NY1IZgA36+/ZssQ8sblytuzD\n\t\t\t\t\tVPkeOShHmvM0NJpwks1QiCmTmjAbN5VjmYiAawVRjuJNkTr3P08zKODWq+QvsaBu\n\t\t\t\t\tsNep0tPVO1Z6a8adnCvi3if0tSrYfDZdtrSj53SXLTVFp7c/a8Z2uzNH707GQ7Ct\n\t\t\t\t\tMpIW9rU7S7Cbc9nthOBfNQbgzg3cGXy1Fw4qWYdPdtmIbeH03tRyP7ty2fbSSktu\n\t\t\t\t\tMN3bGXqP+OclptKxsr9rWZ2NbxFT08W+dlfCSKsexBL7W85eJjLgsO3QrFIeMHAg\n\t\t\t\t\te1O5h4J7aQptFD6yALpOXYDF8hKv7hNdwhTrz3Vu6WvXwDczBcqS69WqxjMcmVVC\n\t\t\t\t\txXcCLdd2xVe2l57KQp6nM3rYWAbqji5Vg1Rw0YooW6Rw8A8Lpm77XIrPETkUq3Qi\n\t\t\t\t\tu/GZXCAnimbLZAXYd6jdPbcs0zMti92BtxqJ/RzaNkVc/BzaNnSmiHet2p+CjyWC\n\t\t\t\t\txEiA7hCGXJuB52LYL0yR4K5NAt+ekcpxPWMwbpunygfDnE6mbavAxm+VD9De3ExH\n\t\t\t\t\t+eBaHgrG0B4Tib0fVPmE/ah3ytc+119VxpE2PyW/x9CQSrL4XJo6WmeM6LmbGc24\n\t\t\t\t\tyiD0+gifVDSpadNxFXJyO/Owig4Y40b2hkss56ryolz5fTdPUQBK8RvdV6SB26om\n\t\t\t\t\tWPUAuwxmuWXthXNKtU0RTuEzIxA7sRIk9J1IrA3FEVPrj5GGzFl5sVPD8qLfeun5\n\t\t\t\t\tzrLMcJBZyLBHpFL6yoqdM4WI9+4qXOCrTTcb/THqZ027ZHe1tO4maeXMwZK8+4Uy\n\t\t\t\t\tywuiEMEU+kClUbMrrxWBce6c0Oucpp2N+at/KxQIBBmotY4C3TWJXwr5syXlOO6Y\n\t\t\t\t\tgw47UsDcWu0EVaywh8hQFHghuG9h9OJRILzZab6zgpS3pzgPPJ1Gryn9GmZAvElr\n\t\t\t\t\tlpH1ahupwUaboS4ykFR0tugkdqm5Jd/ZstMIsHOAfIuKMiJPVrJUPL9rPeFjw6oz\n\t\t\t\t\tT+N5OnFOpY1L1cvHA1py+IysVOjCNfTgRaOPbfA/E6yxU5PM0kPfM5zjpiJ6UFoC\n\t\t\t\t\t9Cf6kyNDJl4Ni+b+i0cf50Ni2tQzJdBpsjaLklVOmDNqSWGcHDHh9XRrkopRsQFG\n\t\t\t\t\tUXum6eSsp2ZRWA4dTR5upwZmoL78ZtSwm84jZV13J+MgeFjJWNT8EDQboi1Bsw26\n\t\t\t\t\tI3jtlxGoJXLXQm/txZ1YjG/mvu2sXzg17Ba9wUhsHWcM+Vd5iiG7lMO43wgyuHv6\n\t\t\t\t\tPBMjrGZjGuQT9+f2vnBtGa+OJ7WnytbeOc2libVc7BpLsV8FM6lJqULZzIMza5tq\n\t\t\t\t\tGI1ndneKWJDnrtiKRsOZHpP305b9RJOM9piA7Yfj4IU9qsMrW2L469sjjJzXHNKA\n\t\t\t\t\tTPRCeW2GAuW/ezUDrVUX3cPITkg6TzfJanbTc0yy7laoNMlKDpip5AeVLqtsydkC\n\t\t\t\t\tBdw/CSW7BAdWW6+icBa5zJLuGM3GxmWz3ijSWVQNaMPg23vHBjOX89HsT5zjU3wo\n\t\t\t\t\tGA0dj8PAd3Eiv4G2q4SNP5zK0MHWCxc0l+XPccCK7mcPL+fYoYGZaBDYxsCOlj5C\n\t\t\t\t\tHkNsfd5vVxkue/Ucu6p6+0+zqyw7rC8qxCcpN5Wmk1EqxzOkVczGPu+OXLvS0kiV\n\t\t\t\t\tkE7v3fiKist382D84fvZj6W8BOUXUHYNDGHcAxdMLBGV7oXChF0AlYJ5PXA1cTKl\n\t\t\t\t\tO1wLnPKw/g762XerGZATZY6eqIdZ81gS/8X2jTxEe73jFldmV366yHgqN/VpTvxe\n\t\t\t\t\t/uwmUZPWVYyjwKQLpubaWKIuQcp1AcZyYOMoMG856DprLxzWXv7spn0HnnwyYiEw\n\t\t\t\t\tlQbfYoL26w0VRZIp4lJBodhFpukwW6JZOJ5hSyj5cKSOsKeGb4sEHO6473Zi8sEj\n\t\t\t\t\t2InREmn2pT2BHztwYgUs04kETgXfY0vwsD+DKwcVBG3q6Vw5e73fRA3k+qSmrL3R\n\t\t\t\t\tnaLY8GAykQVDe3phCdoz3ZvL4iCdduVC5y+ua7pZtHAFddjJiea5X5++McftofJC\n\t\t\t\t\t3q8WGdhIy1mCSwqb1pkhBn7gioYX0KiGGmxu3R/7gQc/E91e+F1w3O6zKep1Y46n\n\t\t\t\t\tjL/g9ovqvM62ZUsc+vz3B50e0rgLhXqoWvpb8l/skhGCLVSpFQRejVbMFCkSrB3K\n\t\t\t\t\tRCwFNli6qGogALNlhLMCmYqpJtcvnf9in4xkjGckJpsyshWPkNoZzuVUmpqFXjpN\n\t\t\t\t\tBZ0ptha1wSoxlUZFx3dB6uQ3o0BODrYx0iaP76BgO4TXW8PBwWJthoMxNuS2G17Y\n\t\t\t\t\t5updZy6x0ZhafL0ELFXdcw9nFtXDAE4MtouYg5OC7ayJsBRsI2igTFiRa0nhcaTY\n\t\t\t\t\tUZuN7SCxqqwbKi62Q5LYDEAtEnTk2nLwEqZqulWjO1jkVOmNAYh2NkN5sX3G3Ysp\n\t\t\t\t\tsRheOFp5LuoYoy7tHjXaupcRuD04WzkhdvZxLxbdq0hYHsjG8E+hxKLtyjtMWl9n\n\t\t\t\t\tAcUZRtIzBTt/pcCZEEzfZm7I3SFejupj7dpqMno5bKF8DXo6UlNu697U7DIFYPvp\n\t\t\t\t\tvMcFjNLpg6iouFHQTpF0cWqQh6Kz9GOcYwbLxB5ESp0YgqwYJ4KI7ohQESBmhwxX\n\t\t\t\t\t3yc3nAdfPmcQVd6a7dFO2+RG4TvvJ+yWMnjALnjDh6ucpa7aPhWWaxZB7uuXjqAD\n\t\t\t\t\tb8YLkVQQh4WMaoiSEnEngk1LBmNE0N3AXToNv3sVeuObSHwfCLq9nm/BYHC0vGEz\n\t\t\t\t\tKhMS2MkAXs/nSdr8YGZLvDskwN5mrrKuemWxWAaKm5xaLhT4wh3otosXDbYC7yfA\n\t\t\t\t\tAZiiiy04c5zRnoiuH/Rd0GPh3QJH+g7ciEdteisZ3kQvHGxVHqpd2vxsglQ2i4jZ\n\t\t\t\t\t2V9l2uoLT2FEHyQdjko2hcgKNM9BcZTiXjHTaQBkBMt88FeKYWTbKKyt+d+XM/LI\n\t\t\t\t\tRl7KuzryUmJrnsRZ7O60IQMjwVl4fXdqifFoJcCUiqS9FMF30Ka1T2Pd5zZT72SB\n\t\t\t\t\ts7LUDp4OGb/NMOETpNS20zathU7Q2QeXFJ623UVdA9Z/UJu7Tqelo4yoZtMMgKdm\n\t\t\t\t\tlfDdGbqXRmZzI47tn0j5wU8L7dB5YtDu3tBOhqMGajUwkEiIA0pvCvpjiqkAgyc8\n\t\t\t\t\tWAMsZNnTlSCW9uP6J3RUdGJol4nWyaEdvp90dJ72n3QvFbVn7YeI8mGfV1YvDxAz\n\t\t\t\t\t1RGmgKoH4Tr73FyofbECFdPpbGdPJZt6YlaJYrNtBS3PwjY+ZGjpu3dr8LvB/5Iz\n\t\t\t\t\tD8cfEat7B/yuTsBmORBhD+71tKwSxWansW9smz9yQlZJkSDlWDZa+zKLWVqRHOvX\n\t\t\t\t\tOgN9ZJz+R9EX4FjP5sKSWMZOpNXGka1rD09xSHNpBPKnYcXSgqgL6VDD6f9v9UXV\n\t\t\t\t\tW1ctW7OsdznLAR6QlEoxF2kH6O4kFb3OJ8ReKHNUvpuHqUbkslVzN4jgv80wgH2O\n\t\t\t\t\tE+mLcgLbWQositp3S2QDBDlYCBBqH4eAdntBfywwLbDEhhlkCCRM40sfBnCA47TM\n\t\t\t\t\t6maveTReOn/8nZpBvflVDgVTc8Ujj3Y5Rsttl9jeIHV0sXxvg9T+YjllGosxmU9k\n\t\t\t\t\t794avZiBPVrj6CvQE7BLN3PkkZIQk/lILha2TT8emt9Hg9TuYjk10KWgGjValKf4\n\t\t\t\t\tDgQOFOm9QbhfhzvhkPRkPyySPZcLVHLcNWwssoFUrgIkfsD38U2pmA4DUFA6KCcT\n\t\t\t\t\ttmh4sUgGOGci8WoSwTWWh+AanIcH1qsTSlsYaPV8dxZ/D1RM+2TikzYKuhtSK7W0\n\t\t\t\t\tw4lxrYy9IdPz6lC5yIzfD8VmOlI5CmavzBJptM8vvZMcxCqGKCiZgF43I2FhP1G7\n\t\t\t\t\tLsD0eO5l5K2Nle/e1XwGT/j2qAZOz4vvJN/b0ZONI9YIY4QFp7Oq9JCyJGu0LcJI\n\t\t\t\t\tt0IBlxtdPjkeHd0o8iqtZGoYfU2zYzIxAWeS0lln2NKXchRmYdCqxKN0Sl5HH/Yt\n\t\t\t\t\t7gmRDFoQxiA/su3jnBq4hLCQyk3QKEA/IKSUl0isq7t3K3BPTDA3prB7UZ/4tu6w\n\t\t\t\t\tl3sl8Ksukr0P637cmwvE7nRFIlsVAn58XoemrJ3unpS4CY92T6qGUHXtkWG6CF7+\n\t\t\t\t\tl/Qz3V5BYPYO9qI9LVK3NqWM1fxae4NrvmL+ck5HytGa+xADGxGjG1fdNwLrBUN7\n\t\t\t\t\tIkOOh0uRIEWAAKlESm3PGLSMtSp6NER3aHjWEAJuP5LrPwFoj5rUSbPtFbGgYpnm\n\t\t\t\t\twkbvjXIQasUh6zQrEZN2bxRlwH6tpT0c6txJMRoXKorCcn5dR4iUPWwv0lRh4Wrf\n\t\t\t\t\tcvre8YhCUDnJJBSMPkYWdmJSjb2VF5iRHztgN/3AH4MZCsHXggBr8D1M39snRp9J\n\t\t\t\t\tEXxKW55zFE2flJfDfNhPig+nj22Mr9ktKZinrWpJ5S+ItWnb1RRqfXN8CcRv/WWl\n\t\t\t\t\tQfxWLF+Zc03zRw5jcBJIHhc65gCZdscOyIoZQHDF/WaTCO0jxmQDLGS4TaQ7jV88\n\t\t\t\t\ty1dhgzdR6dq/Bo1UdKbjApWycwgKRBM2F5eK9NC2uva9Xn4xFHxsGihuOQuJDYPX\n\t\t\t\t\toEuQWWOMJQYkIpWoftgHR6K4+fw7Zp5Q4AnJbMqPKaE7EkxqPq033P7u6TCmRiPT\n\t\t\t\t\tKjn0N8zQBl+SE/RZg/EQv9eK9yE3kOsHJ3Bedvo4EKDwvbAXCmyZT24C+GoMXjF8\n\t\t\t\t\tjwbBCpwpkrTrXnJngK4wBq74E0gfl9kW3r5R3eTnBZSpO75Y33Vn87vgAGtWFWDh\n\t\t\t\t\t57+kbm7We4ebuvhQ6y3fd2/W/fueeage4YzSyYyAqEdUw8MxjIDUbW476MIuZEw0\n\t\t\t\t\tuYNrw/DDOY7CSsA9WVCQZXlLD9SJN+4F+/QIhbqnMwKiHiEA88mMgHuzrlKzsmMH\n\t\t\t\t\tA9mPa1UfqufHvWMNcZKWoSvLBpX2Jbc0ysU19dMRzO+xwANzr9JD/UKu91sMFD+e\n\t\t\t\t\tOZKmMraTQRfcV7fJDQ7XRk12h+BX4lSgaDGwkf94Bk7sMJHWKPkeBorvy+vNOCOP\n\t\t\t\t\tyVydodUkBWnO9xiXVfureNgpuqldzRRtdglMcxUGCiqYQz/k7U3JRTmF2FrNkj0V\n\t\t\t\t\tHor2huEsGllcF/FNiKQFyH/tIRcywhhAXsA1qfuBYQ66mMy7W0LUbPpulM9AnwoP\n\t\t\t\t\tRXtD8PrT4aF5F+VYeCgRXKP/qQfN/1DGYBneeYkh8hYRxx/UcPFlbu6C4uOj2HOx\n\t\t\t\t\tYG20OKQX0zvgLurTitwfMhGcl+9Ej7tv6UrmB6W5Ri8b2F7z42ED6bbxM/Bbg+Si\n\t\t\t\t\tDbF6ewGGroEAGw9EB6Ikw7dBImPnTwDYnpPAXeKnh0RkEnhXoCQjZaeZekI96mZv\n\t\t\t\t\tbNZSk68P1GSUy9FQLmeaN7cYfxX5gtRdvPSOYYnKLR4tRShoiDpOwhYJThu8M3EC\n\t\t\t\t\toXTngZdMQfQmMVIr/yl0DBcMI/vgFypTttUwVlH5fa4YU4yr956Y/U+zsij20KyG\n\t\t\t\t\touquKD+SGSu4P3WPe0Z8UhsWXd81I7EHVZS4ZX61beRqFBXhxJPqB9gy4YB/99Kr\n\t\t\t\t\t/dISJk6sRGpLZC8SWKmzexAp+DipcyFifz5wZ3OZ0Of/JKr9M+XxbROZQwW9irOS\n\t\t\t\t\tBF0nH0herIxyHjPTSCgYqmKgtuwXCr92SEP+hmrmVPpeP3OXaua7yNmIrNz4KMsT\n\t\t\t\t\tYvDPJS+340FOyLRl6OOTabo4NbY38vFt5I6Z1sBdXYA2Nzyy7neYtY95zM8C/AgQ\n\t\t\t\t\tWPBqw5s5jp49RugJ2H56xjUX0jyHpmuz1eAz8+4dzgNRhC1gIRCE3D2K/+EFcMTY\n\t\t\t\t\tc/I7x95KuFMTLLghcRaiCz5mgFYdSyvzaOBezv1xJ6Llr/8EOGK+aOKXBeMQFGM3\n\t\t\t\t\tnVSkKOtpLNKZGueTHOxA0kndraXCLVdnrtPU+11Q8p4mhYljaehfLrISh9aF81CM\n\t\t\t\t\t22Yfh9iFOMBuhiBukI1O2B8P18KF12aNLNklMLdofe/Iyn+p45EUKIC15Vk1SOAw\n\t\t\t\t\t2ggvVE3YTwrG8jBVbIAbaIcXj6CT4EN5SRPi0NFCwtcpgR86FAb7XYxlh/ga1hBQ\n\t\t\t\t\tzEDU6n8KCLqFKtvqssI0HUfAGG8FS8AlmDX0QDoRr6ZZ6dX8jfMCxuBpY9kXj8T2\n\t\t\t\t\tYCeu5l7oB/2x18ACoA+uCJ1iHGUxHpl+3F4LWyQQeIbfKRK7axN3J40jOKM+NYWs\n\t\t\t\t\tnClnGY7YFaXJLrgjlqcU5uaobiP3zq/8Ous981zlvmLCiib+1lTrwZIkl9CXb1SV\n\t\t\t\t\tpv6c4rDiPn5OcZhaXHeMebK9umddRQIkTXTbK4kgAQuHrs9if4xNQpy/6LYT+M8Y\n\t\t\t\t\tdMXylDiN8lqnM8tuoZk5Vn9oFEhOhZT0B2446w/vE88hL8HjVGpsF0LusN7+vZ5M\n\t\t\t\t\tij3AEVHEB5GZrTSLQuPytgwi293iqE3RCcMtdQZWNcIcUwMotDiCy0KI21ECi86Q\n\t\t\t\t\t+Aq0lOFjo20XDF8LnGj4qBjLmReilfMqM7AcCZw03FJnYFG0ThxumXOgsyQsM4/P\n\t\t\t\t\tLpRbsihMlsMO2SGi5piCSM+wf6c29X0Gc6J5mG21xJLnCqDt2HIZLk9vxueEg22q\n\t\t\t\t\tdvCLbIA46o/NS3H3dOlqZyiVej75OzWrPGMnaTUX2+abkVg5ub7dfDKu2KGQU46r\n\t\t\t\t\tlzOt077EqawN324vqcqNOtF2DJDOtUyE1ccRi+4N6MzRUro4zfV7aANfpNM69ViT\n\t\t\t\t\t8izE3DwfSmbSYd+RlC0MVykvv+Zm29x0X5KL3Nw7zm1O9yb6OWavzPX/Yoztm+Og\n\t\t\t\t\tyMspToQqj4PywssZxmIexGhEdt0y574twa7e1Xyb5urCRtYHLii3uBOB6nn5jO3v\n\t\t\t\t\t9etUkVOSElqn1GxL4215U8O94T9XuJdud/44uUWWyPLEIFGYLqdGQLXzEppN6zw0\n\t\t\t\t\t1Bfvxw3zYwk88ct2KxyifrgAmGogpzusy9CPYGPXqABwkyXOpUe7GnfAYN7MfLsJ\n\t\t\t\t\tAhAl8Pm6+C66FTbVT2U8T6Ca3VNacdPRhcEmyir5IbIbJULbQvxDCj0kWgZ5c+tN\n\t\t\t\t\t0fmFic5Rbqi4cbjlcuxOAP6iJUAmIAqwFERUdoUJDg+KTKPv+gENAU7E2nfvDO/l\n\t\t\t\t\tE51XDuSqTgUdNt1Xi86NNX/0uxe1u3Wl9ap0sDVfjrenpk5WTU196Ex++hBfPU1q\n\t\t\t\t\tokjRdTp9W6F/ZAtAwoZNt6OlgFAfzY+0owWEe6bE6fFjogeAtw8/vpmjSImx1xhc\n\t\t\t\t\tNw0fJ7QmjklTf7GrZXwVDqhEfRN6ATjSlmf5Lv5sxNDhu+lz6NuY1KTxHPq2sjXb\n\t\t\t\t\tAEh8UUM0Pg1L/QS4Y6PK+ak8GGSmPJjCV1rVoKvKTW0vfwF22V32hNKEFXqh25th\n\t\t\t\t\tT4AfD0EvzOcSVkNmcoGAKxd52EYr7KKUlldn6ra1F7x4dlnmCUJhf8NhDkMlYcdu\n\t\t\t\t\tM+fATLscezTJGUe8K16QWyxqvEpjdi91Gt+rXl3u6Pmk+ogI4/mDjnjySyv/44xc\n\t\t\t\t\tE8WRjiQPoU5Wlq6Qkw+U0MmbnvnL9I/gCPjEsyjgFuiuxl4DB2BAUA0OorNE4+bH\n\t\t\t\t\tvVCGwhCJt5JJe4oB+cC9iXAcvGeBhg8M+J3DOb7ZXHTbC5HcNaTViSQ4xxD+1198\n\t\t\t\t\t/0i6obibTD2fbqjxVud/E93OmsrL5wXTxj5NFDp3wTRm7BxUTlTbnPT8RXHxhYoe\n\t\t\t\t\tlsmzNLOVV311Fqm05fdCoY/1TBYiQVe02pvDhLa1K5GbwkNzf6F00M18gHSfYyRK\n\t\t\t\t\tQ6xvBIcfo2PQ5iEOPb3CqNoCu5LIsF0T15fw+SltagzaCDdxTDPO6n4XGUMnIfys\n\t\t\t\t\tAYFVA3QHQs2X2yYHvbB0kOqUBq00UzRV4QXOz6W8DUF+7pWLwrQzHxRKyN46uVQN\n\t\t\t\t\teYSPvVGZyHeOTFNBKuOSTVlj6kZLxVvLQ1Bz+Ug6C2lOgpOrEksumDakPYXD7CCh\n\t\t\t\t\tuTGgAoaowwFfiNhbY4A9AGUo3UswTTKQISzp9qjVwHYsiVnFMWiptTnz3GEN+7eZ\n\t\t\t\t\tFG1qee4sEgg6Cq8quRxhiefAyVENUcx+Opw8jYoyTcSlJHu4yWqUDjVslXUJ2ZFb\n\t\t\t\t\tnqb3tpaPx/ODs7cu7+hZ9fkORx3eFHFsuGsgLzLvDT9NUvTx4/WLZjyzp6ArepEX\n\t\t\t\t\tjsDr9QwxduAzwyUz57UNMmH2HVMGI3m1jL8DxjM1QJkCDiJCV5nYC4V8IP1QwlZ0\n\t\t\t\t\t7XwHU34JRXnHYua9U40wKJ2vNvUEJmvNp7v7y8/+7fZ2tjya8ERbovGdB4YvFbEL\n\t\t\t\t\tcUqFMgZPBt42zmLxVuDZ1j0X5CS8wSL5HA62hbydXjKC5UdVuN9T2gvytoQb5+bP\n\t\t\t\t\tsSXKy2FbkijD/0ZB7DO46ANxTLnKs8mznvFh5zZmHFSH4IkcLdltOnKzUAAFhyGk\n\t\t\t\t\tSIki6kSBan6S6XzhtS4jbE7vfF15pxnrsLJYlE0pc+inAs2TxbCcX6BPzhrnbIWi\n\t\t\t\t\trb5hdqjcdA4zuXeqxBJUzQhNNZmxzw/fwth+jB9OcNlOeKgf7llDkFB/7kHwLcad\n\t\t\t\t\tQDBfDg8ImUM4B7Yz9MDw3SF3Uh0+lhzih5cnEZ7gh7OXc0rf3Z1yoi8VCO9JFptb\n\t\t\t\t\tFpOiq17w0wvI7XSWbLggJkAsr0XKUinSI0TZlqSUiI4zKWUX5XUJgW1yjaz6LhzJ\n\t\t\t\t\tPpnmXGLc7zvMFhALIHr8BQnU5bjNO8mpHImv583VejJ+OXw5I1C9NzEWufpuu+aN\n\t\t\t\t\t0R936n5ghpJmFjk1Dxn8YwcZaRP/e8hA35O4fVGY5yQdapnOlFUcEbnMwU/0o3ty\n\t\t\t\t\tmvICvCG9OH/7OqOZSJcoFbz23gWmFinkq6V1s26zWPcozJPlftRC/oLg1kZWYnlV\n\t\t\t\t\tGOnu/tKTjtOkg9Z03Hu3J+mAQyPQmjdBzK5iZAmEO4XNdxKcgk2WvVn37Tm2EVjC\n\t\t\t\t\tdpIXXzerlBVukNLj2rlMzyOOUHQK5dcDk5WHilNelpTTmIlTOfaYVnUCFh6IBXyr\n\t\t\t\t\t/G8T/gXdHaKq9BJnzBevHEZqjHGVlf+SgnMRHPAt4CzH5i+atUF3WOcpKNGgZUA4\n\t\t\t\t\tMUqQS0xgxc4eIvgKlnRWoLnq4Mou4eV/D/mLRNEtVSi5CdNbThdpkoICUX6l71Tp\n\t\t\t\t\tbVnIZ6mGwnnR/8KlRnhKIQL7mAcZsMrZijO4J6VXK3vDmuawniffTG/wYarctiQr\n\t\t\t\t\tUWsSvVTAs0E7euYGrbifH5wsPEEG36iWFZq9nM7h3hxAhZ1fh5StVfp44xwc4SzQ\n\t\t\t\t\tMTu87FjlLJB0Fv2ForNAEK+Gb/cC7OdGTgjQpYa4Rp5GnFdPA8UFktmHcCZiPxic\n\t\t\t\t\tgDgl6Tyu7Fh2FnY0wmw4C5OUCIonIEw4cYftvjkCtBz7GYMj4KOfaeogiRl1NUVq\n\t\t\t\t\tVJSaVY/SGegK5dYrNbezn6leGoJzqRH37J7w1a710CE9PDzMwDe9c3UZtux0NkBg\n\t\t\t\t\tAxths2xHAlsJ8LvhU4D46E/076zIQbMX3qRdb3r8An4FP06Z6HPiw36LCNvWlSM5\n\t\t\t\t\tBzqdpJjHBmv3bERaHiGE+36hTJP3Tnn9etZ0XTvTirey62SUO9r5qW8FYhZ6zjSl\n\t\t\t\t\t8jntyCTF7S233fBjq/4tUyBHoyubdSKEwlQYRIYBzgFEqwW+VgJ+VSwaAtmXk8sZ\n\t\t\t\t\tHPKldNH3+i5SILWUAY5r7fcMjUxbfZX3k2P2wT81w8CWr+cabV+pfoG86k2bjree\n\t\t\t\t\t0GkO38h3UEyfceqdMwcKRKLmM/FSNBWbtHWgr6xR6Ww4+WFqelgyS2VzmnL7prCV\n\t\t\t\t\tUaHRmP8ELTZpzQYLZrJhm2qkTFYQOU8XzFr/rQgb7CFV+22wG9YVlpxxwsnCD5sN\n\t\t\t\t\tEOiaFyP6PAK/fLoGgV96rpzL6+Yafl/34mEyuDbqIF7sg88j7LX0EjgLYJ0GtlPD\n\t\t\t\t\t/K8IewhtefGEDSyOhS4Wksg6JupmE3aCHlLK6O2T0lm0JtWaihyAjvItltsGr6cs\n\t\t\t\t\t5dWz13+xRtumIZMhONITJHOmbgV3CkrOWxLWBOIviAAbYOVhz/0ZtiGAHzGV4R1E\n\t\t\t\t\thVFd2KOFb4Olb5lzOcYEBSk++NFiMB4hQCVECLkM58GLb7Td2D06Zl/wVX3Km9qi\n\t\t\t\t\tnX2HHw215c/Z2Yne1Ap5eNrpttRzprup+S/yq1YtmYVzRZOs/U6dGmYQXq2YfdXg\n\t\t\t\t\tmrzlzwedahaLhgdvd4aIhkb5XAtWP57Ra09TdlnUyvyrLE1cfUdc/EonCxVi9gxC\n\t\t\t\t\tT2hCHeo+tL4lu+yxYHYHfHL0kEFhrjh/0WD0j7ciADN4+v2xY+H4BRDmmgjnoHa/\n\t\t\t\t\tA3bZapOMqONi+SCtHVzwK324yEOHTRXK6g6N23wEqMK/rcJP7tqWq601MdK7YXU4\n\t\t\t\t\tzDlhxjQWE9Rv+2k72iP73dp5UD76vcJH97W+cJS8n8roz5nGoyx52Yzjpu605Jeh\n\t\t\t\t\tSO5g00d1+MzKt1Fr47RGB7H0MU6JoZa1TujbYiVgddDORyML0Y1/BtnkdiLSrZZ8\n\t\t\t\t\toZBBOkHxqCdIUTHD2xuHbBlrnY1U1JL5MTdfWuGTQvX8heHS1JqD0PusJX5X8/1E\n\t\t\t\t\tdUguM4aaULHYMAlSfytfjpLY3WOPsnwnJSuJH55LKun0gsd0KFv5QT5P0yzK8SRQ\n\t\t\t\t\tvySc5Xh2xEGXRtuIsGlKclPalgDHB87KDMH80kVD79S8UCx9OzLh7NRePpylOJ2U\n\t\t\t\t\tROnQUZPcpvVDNjcUDzNq8ncZD0jKn0NqeKQIb34YBBSQmaoke8pYST2mlGlmjppU\n\t\t\t\t\tWs64sRs/fA7QX5GyHsdCgoRimOcC7eZeEc0M7LeHim6Nk0rlvD8eruDXiW/f4QiC\n\t\t\t\t\t1T6YCzoHz7DqaNJJd55u1dWm7idU1AUN3Y+WESLdq17dMpjKO0PRGZWhTnjFKhkq\n\t\t\t\t\tk92cwB9PgRVTyJ/KH//H4fuFJWP0BhF1N+jyGMFrw/LtyQykcY65XS8RdRGD7nBH\n\t\t\t\t\t4AhczV483+9HbEBNp6DUFGQ8zLNLjPKIKNhQ9PqGny9SdqOLbOzoMiW5wYe5pkpd\n\t\t\t\t\tkgF1QxVg5fnDM8wW8eW0zrJczruUAOmJpZHh5Yptoioof3n0htgoOe6EqO+lPcRh\n\t\t\t\t\tyYZP4CthCEuAtYPAwmpbXuxA8NFcfQ/0hh8pGUc64UM+UjaVbtEAo/N8qNsn1kxX\n\t\t\t\t\t5f7X6iuvjbc6sL7dkpmnpNTnC7ad8CtHs9PzCJ8C8xsjZa519KyBWU85pBQPRwns\n\t\t\t\t\tNNp5WFRHyovS3aRL1Csz74cEGJpa5RmpQpKLo5kFIulG4Dw1EUducEk27o/BAKJN\n\t\t\t\t\tdW9iHPUkILjwxw5YMRCfPcOT0VE6sRSrAwwyy6eVYjnAOFdGoECaxymgWwUQyPY/\n\t\t\t\t\tN0BlW7mJskZs7EzcbxpTsEPYtVVjASct9XiRUfel7f/qSkE2V4GpA3LSTCC8lw0d\n\t\t\t\t\tHi0hlF0K9ybsjzsz/MwAQ11qum03aKfCqUE9mZehtDuhuH7p0OF76lghvcFtB7l5\n\t\t\t\t\t7or0nQOr4qTa1BjCK72/4FrIoyrP5y2gTtCBoM40pWOxtMJO9YK/WoX7VA60SlDm\n\t\t\t\t\trjTUWUVF6Zbn1MHGqXYK2PxFCPA3YEz7MEykckCUwELhYEsQpTpsaCQTP+jjzHYc\n\t\t\t\t\tiDv2Gj5mqMMr0Bd36++BAJ90w9OFgi9QWHemYMUZ1R+hRHp9xgp7dooOwiLWaDZy\n\t\t\t\t\tR0tVema5YOP4hODddM5XfilVVmDYG6KDCOnBVKBtXu4lm6Lm0nfv1iAna5XX8rvY\n\t\t\t\t\t1eTBgW8vpNVe42AE0W1DXHY1A0UAvnb04k3RmXqdzaz7EV9nt2/0KGWqRxPXs6xs\n\t\t\t\t\tWOb2pHTQhUrO94iSa2M5RzJK6CmF+aSl23pGJb0uIs8Z9UDtnSll8i3fBQ3VLt5h\n\t\t\t\t\tho2vvMkw4fE+MX4FIseIMrApJIoUoyp6PagWLAos6C7gi61m4GDZtW+rpUmnDssP\n\t\t\t\t\tlRUAc7Q7quQSOA9OywmIEpdA/tWvmHF8aTH4QeZ5hNJCcOAES3og/X50cgYfTGXX\n\t\t\t\t\t8s+2+WBf8k1DXCBvZQ+qJ9riV6o+Wsg86nZ5J39X3K1ADzLMjRWt+upy21SlEpHH\n\t\t\t\t\tKRgMVXrbl+veleimfvYm6IWbWNp3eNBNsO7YRQ/uKRz+sDOjkjX4GxICbZHMZjIZ\n\t\t\t\t\tVrFFPgeDgaboxCkXm9xB6fnffvg3eaZQEDQUkCdk1RWB3quCxLZ2n1pitjqcxapM\n\t\t\t\t\tYfUt2RZ2ywkzJJbRDWDFr8B2jBIvMBJwKmf9sbAGtoNDAsIB7Ixnoc8xXPrhJRmB\n\t\t\t\t\tcPji2Ra2yYkmcv2iOPR1YoWqdp8V1x7XB5\n \n \n
\n
\n
\n
\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector GET", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has service response\", function () {", + " pm.expect(response).to.have.property('response');", + "});", + "", + "if (response.hasOwnProperty('response')) {", + " var packet = response['response']['packets']['packet'];", + "", + " var header = packet['header'];", + " ", + " var message_id = header['transportUUID'];", + " ", + " console.log(packet['message']['content']);", + " console.log(message_id);", + " ", + " pm.globals.set('message_uuid', message_id);", + " ", + " pm.test(\"Content is OK\", function () {", + " pm.expect(packet['message']['content']).to.be.an('object');", + " });", + " ", + " pm.test(\"message_id is OK\", function () {", + " pm.expect(message_id).to.have.lengthOf(36);", + " });", + "}" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system2_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n \r\n {{system2_id}}\r\n system.name\r\n \r\n 1\r\n 0\r\n \r\n \r\n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector ACK", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is 200\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system2_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n {{message_uuid}}\r\n \r\n \r\n\r\n\r\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + }, + { + "name": "uniform-exchange-connector xml in context", + "item": [ + { + "name": "uniform-exchange-connector SEND", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is OK\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system1_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n
\n 2b5df363-410e-4917-8209-d2fd580a44e1\n \n {{system2_id}}\n \n
\n \n 2b5df363-410e-4917-8209-d2fd580a44e1\n ВыгрузкаДанных\n \n object_id\n 3a4623e2-8b12-11ea-a250-000c297cfa2a\n \n \n object_date\n 63724982760122\n \n \n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\tfalse\n\t\t\t\t\t\t3a4623e2-8b12-11ea-a250-000c297cfa2a\n\t\t\t\t\t\tfalse\n\t\t\t\t\t\t5205e857-c7ba-11e9-a23f-000c297cfa2a\n\t\t\t\t\t\t00000000-0000-0000-0000-000000000000\n\t\t\t\t\t\tТест\n\t\t\t\t\t\tПерВыг_ПКО_Отправка\n\t\t\t\t\t\tf75b1344-4081-46b0-bc1e-79f9dd3c0f22\n\t\t\t\t\t\t0\n\t\t\t\t\t\t\n\t\t\t\t\t\tdff80fe7-2e66-4b9c-bdcc-f8e8d29c8ea5\n\t\t\t\t\t\t\n\t\t\t\t\t\t5ce4815e-7f4b-11ea-a24e-000c297cfa2a\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n \n \n
\n
\n
\n
\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector GET", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "var response = getSoapBody();", + "", + "pm.test(\"Has service response\", function () {", + " pm.expect(response).to.have.property('response');", + "});", + "", + "if (response.hasOwnProperty('response')) {", + " var packet = response['response']['packets']['packet'];", + "", + " var header = packet['header'];", + " ", + " var message_id = header['transportUUID'];", + " ", + " console.log(packet['message']['content']);", + " console.log(message_id);", + " ", + " pm.globals.set('message_uuid', message_id);", + " ", + " pm.test(\"Content is OK\", function () {", + " pm.expect(packet['message']['content']).to.be.an('object');", + " });", + " ", + " pm.test(\"message_id is OK\", function () {", + " pm.expect(message_id).to.have.lengthOf(36);", + " });", + "}" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system2_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n \r\n {{system2_id}}\r\n system.name\r\n \r\n 1\r\n 0\r\n \r\n \r\n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + }, + { + "name": "uniform-exchange-connector ACK", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is 200\", function () {", + " var response = getSoapBody();", + " pm.expect(response['response']['status']).to.eql('200');", + "});", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml; charset=UTF-8", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{system2_id}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\r\n \r\n \r\n \r\n {{message_uuid}}\r\n \r\n \r\n\r\n\r\n" + }, + "url": { + "raw": "{{base_url}}/uniform-exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "uniform-exchange" + ] + } + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + }, + { + "name": "clean esb", + "item": [ + { + "name": "Remove profile system1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system1_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Remove profile system2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var jsonObject = xml2Json(responseBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n {{system2_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/system-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "system-management" + ] + } + }, + "response": [] + }, + { + "name": "Remove Account system1", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n {{system1_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + } + }, + "response": [] + }, + { + "name": "Remove Account system2", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Body matches true\", function () {", + " pm.expect(pm.response.text()).to.include(\"true\");", + "});", + "", + "function getSoapBody() {", + " var soapBody = responseBody.match(//g);", + " var jsonObject = xml2Json(soapBody);", + " return jsonObject['soap:Envelope']['soap:Body'];", + "}", + "", + "pm.test(\"Response is true\", function () {", + " var response = getSoapBody();", + " pm.expect(response.response._).to.eql('true');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/xml", + "type": "text" + }, + { + "key": "X-ForwardedUser", + "value": "{{adminLogin}}", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "\n \n \n \n \n {{system2_id}}\n \n \n", + "options": { + "raw": { + "language": "xml" + } + } + }, + "url": { + "raw": "{{base_url}}/basic-auth-management", + "host": [ + "{{base_url}}" + ], + "path": [ + "basic-auth-management" + ] + } + }, + "response": [] + } + ] + } + ], + "description": "для тестирования нужно добавть в environment: system1_id, system2_id", + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + } + ] +} \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/uniform-service-endpoint/LICENSE.txt b/platform/runtime/modules/uniform-service/uniform-service-endpoint/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/platform/runtime/modules/uniform-service/uniform-service-endpoint/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/platform/runtime/modules/uniform-service/uniform-service-endpoint/pom.xml b/platform/runtime/modules/uniform-service/uniform-service-endpoint/pom.xml new file mode 100644 index 00000000..106c59e4 --- /dev/null +++ b/platform/runtime/modules/uniform-service/uniform-service-endpoint/pom.xml @@ -0,0 +1,66 @@ + + + + ru.entaxy.esb.platform.runtime.modules + uniform-service + 1.8.0 + + 4.0.0 + + ru.entaxy.esb.platform.runtime.modules.uniform.service + uniform-service-endpoint + bundle + + ENTAXY :: PLATFORM :: RUNTIME :: MODULES :: UNIFORM :: SERVICE :: ENDPOINT + ENTAXY :: PLATFORM :: RUNTIME :: MODULES :: UNIFORM :: SERVICE :: ENDPOINT + + + + javax.xml.soap*;version="[1.3,2)", + javax.jws.*;version="[2.0.0,3.0.0)", + javax.jws.soap.*;version="[2.0.0,3.0.0)", + javax.xml.ws.*;version="[2.2.0,3.0.0)", + ru.entaxy.esb.system.core.common.error.handler.interceptor, + ru.entaxy.esb.system.core.template, + ru.entaxy.esb.system.profile.commons, + ru.entaxy.esb.system.profile.commons.connectors.in, + ru.entaxy.esb.system.profile.commons.connectors.out, + javax.xml.bind;version="[2,3)", + javax.xml.bind.annotation;version="[2,3)", + javax.persistence;version="[2,3)", + ru.entaxy.esb.platform.runtime.modules.uniform-service.wsdl, + ru.entaxy.esb.platform.runtime.modules.uniform-service.xslt, + ru.entaxy.esb.platform.runtime.modules.uniform-service.xslt.type, + * + + + + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + ru.entaxy.esb.system.registry.systems.profile + system-profile-api + ${project.version} + + + ru.entaxy.esb.system.registry.systems.profile + system-profile-collector + ${project.version} + + + org.apache.cxf + cxf-rt-transports-http + + + org.apache.cxf + cxf-rt-transports-http-jetty + + + \ No newline at end of file diff --git a/platform/runtime/modules/uniform-service/uniform-service-endpoint/src/main/resources/OSGI-INF/blueprint/camel-context.xml b/platform/runtime/modules/uniform-service/uniform-service-endpoint/src/main/resources/OSGI-INF/blueprint/camel-context.xml new file mode 100644 index 00000000..54f7cc91 --- /dev/null +++ b/platform/runtime/modules/uniform-service/uniform-service-endpoint/src/main/resources/OSGI-INF/blueprint/camel-context.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + uniform-service + + + + + diff --git a/platform/runtime/pom.xml b/platform/runtime/pom.xml new file mode 100644 index 00000000..2d03b2a1 --- /dev/null +++ b/platform/runtime/pom.xml @@ -0,0 +1,25 @@ + + + + platform + ru.entaxy.esb + 1.8.0 + + 4.0.0 + + ru.entaxy.esb.platform + runtime + + ENTAXY :: PLATFORM :: RUNTIME + Entaxy Platform runtime + pom + + + base + core + modules + + + \ No newline at end of file diff --git a/platform/src/main/features/features.xml b/platform/src/main/features/features.xml new file mode 100644 index 00000000..bcc5f4fe --- /dev/null +++ b/platform/src/main/features/features.xml @@ -0,0 +1,35 @@ + + + + + + + + + mvn:ru.entaxy.esb.platform.runtime.base/branding/${project.version}/properties/branding + + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..93f2a14c --- /dev/null +++ b/pom.xml @@ -0,0 +1,830 @@ + + + 4.0.0 + + ru.entaxy.esb + root + 1.8.0 + pom + + ENTAXY :: ESB :: ROOT + ENTAXY :: ESB :: ROOT + + + system + features + platform + + + + + UTF-8 + UTF-8 + + 4.2.9 + 4.2.1 + + + 1.9.16 + + 3.4.4 + 2.17.0 + 6.0.0 + 3.3.6 + 5.2.17.Final + 2.1.0 + 1.1.0 + 4.2.1 + 1.3.1.Final + 2.8.1 + 3.9.1 + 2.8.5 + 3.6.3 + 7.4.1.jre8 + 42.2.5 + 1.7.30 + 1.2 + 1.2 + 1.3.2 + 3.2.1 + 2.6 + 2.12.0 + 2.0.1 + 1.14 + 1.2.17 + 5.1.1 + 2.4.0-b180830.0438 + 2.3.1 + 2.3.2 + 2.3.0.1 + 2.2.11 + 2.3.1 + 1.1 + 2.3.3 + * + + + + + + + 2.22.2 + 2.5.2 + 2.8.2 + + + + + + + org.osgi + osgi.core + ${osgi.version} + provided + + + + + org.apache.camel + camel-parent + ${camel.version} + import + pom + + + + + org.apache.camel + camel-core + ${camel.version} + provided + + + org.apache.camel.karaf + camel-blueprint + ${camel.version} + provided + + + org.apache.camel + camel-cxf + ${camel.version} + provided + + + org.slf4j + slf4j-api + + + + + org.apache.camel + camel-sql + ${camel.version} + provided + + + org.apache.camel + camel-jms + ${camel.version} + provided + + + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb.version} + + + com.sun.xml.ws + jaxws-rt + ${jaxws.version} + + + com.sun.xml.ws + jaxws-ri + ${jaxws.version} + pom + + + javax.xml.bind + jaxb-api + ${jaxb-api.version} + + + com.sun.xml.bind + jaxb-core + ${jaxb-core.version} + + + com.sun.xml.bind + jaxb-impl + ${jaxb-impl.version} + + + + + org.apache.logging.log4j + log4j-api + runtime + + + org.apache.logging.log4j + log4j-core + runtime + + + org.apache.logging.log4j + log4j-slf4j-impl + runtime + + + org.slf4j + slf4j-api + ${slf4j.version} + provided + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + provided + + + org.slf4j + jul-to-slf4j + ${slf4j.version} + provided + + + log4j + log4j + ${log4j.version} + provided + + + + + org.liquibase + liquibase-core + ${liquibase.version} + provided + + + com.microsoft.sqlserver + mssql-jdbc + ${mssql.version} + provided + + + org.postgresql + postgresql + ${postgresql.version} + provided + + + + com.google.code.gson + gson + ${gson.version} + + + + + + + + + src/main/resources + true + + + + src/main/resources + + **/*context.xml + **/*blueprint.xml + + false + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + org.apache.maven.plugins + maven-install-plugin + ${maven-install-plugin.version} + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + + org.codehaus.mojo + license-maven-plugin + 2.0.0 + + + + + + org.apache.felix + maven-bundle-plugin + ${maven-bundle-plugin.version} + true + + NONE + + ${project.artifactId} + ${project.description} + ${bundle.osgi.export.pkg} + ${bundle.osgi.import.pkg} + ${bundle.osgi.dynamicimport.pkg} + + ${bundle.osgi.embed.dependency} + ${bundle.osgi.persistence} + ${bundle.osgi.activator} + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + UTF-8 + + + + process-resources + + resources + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 11 + + + + org.apache.karaf.tooling + karaf-maven-plugin + ${karaf.version} + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.2 + + + org.apache.maven.plugins + maven-antrun-plugin + 3.0.0 + + + org.codehaus.mojo + build-helper-maven-plugin + 3.2.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + private-deploy + + + !skipPrivateDeploy + + + + + entaxy-private-releases + entaxy-private-releases + false + default + + https://nexus.entaxy.ru/nexus/repository/entaxy-private-releases/ + + + + entaxy-private-snapshots + entaxy-private-snapshots + false + default + + https://nexus.entaxy.ru/nexus/repository/entaxy-private-snapshots/ + + + + + + public-deploy + + false + + + + entaxy-public-entaxy + entaxy-public-entaxy + false + default + + https://nexus.entaxy.ru/nexus/repository/entaxy-public-entaxy/ + + + + + + + + emdev.repo + + + + private-snapshots + EmDev Private Snapshots + http://build.emdev.ru/nexus/content/repositories/private-snapshots/ + + + emdev-private + EmDev Private + http://build.emdev.ru/nexus/content/repositories/emdev-private/ + + + + + release_plugins + + + docker.reposilite + + + entaxy-maven-repo + http://127.0.0.1:8081/snapshots + + + + + docker.file.repo + + + entaxy-maven-repo-file + file:./temp/entaxy-docker/karaf/repo + + + + + features + + + + src/main/features + true + + **/features.xml + + ${project.build.directory}/features + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.12 + + + attach-artifacts + package + + attach-artifact + + + + + target/features/features.xml + xml + features + + + + + + + + + + + src/main/features/features.xml + + + + + + + + license + + + !skipLicence + + + + + + + EmDev LLC + + 2020 + ${project.artifactId} + ${license.organizationName} + apache_v2 + + ~~~~~~licensing~~~~~~ + ~~~~~~/licensing~~~~~~ + ========== + + + + + + + + + false + ${project.build.directory}/generated-sources/license + + + + META-INF/* + + + + + *.txt + + + + + + + org.codehaus.mojo + license-maven-plugin + + + update-project-license + + update-project-license + + + ${license.organizationName} + ${license.inceptionYear} + ${license.projectName} + ${license.copyrightOwners} + ${license.licenseName} + + META-INF/LICENSE + true + + + + + add-third-party + + add-third-party + + + META-INF/DEPENDENCIES + + + true + + false + test, provided + + + ^ru\.entaxy\.esb + + + Apache License, Version 2.0|The Apache Software License, Version 2.0|The Apache License, Version 2.0|Apache 2.0 License + EDL 1.0|Eclipse Distribution License v. 1.0|Eclipse Distribution License - v 1.0 + EPL 2.0|Eclipse Public License v. 2.0 + EPL 1.0|Eclipse Public License v. 1.0|Eclipse Public License v1.0 + CDDL/GPLv2+CE|CDDL + GPLv2 with classpath exception + GPLv2+CE|GPL2 w/ CPE + CDDL/GPL|CDDL+GPL License + LGPL|lgpl|GNU Lesser General Public License + BSD|The BSD License + MIT|MIT License + + + + + + update-file-header + + update-file-header + + process-sources + + ${license.organizationName} + ${license.inceptionYear} + ${license.projectName} + ${license.copyrightOwners} + ${license.licenseName} + + + false + false + + + **/*.json + + + + properties + + + true + true + + ${license.processStartTag} + ${license.processEndTag} + ${license.sectionDelimiter} + + + + + + + + + + + + license-aggregate + + + aggregate.marker + + + + + + + org.codehaus.mojo + license-maven-plugin + + + + aggregate-add-third-party + + aggregate-add-third-party + + prepare-package + + ${project.build.directory}/generated-sources/license + ALL-DEPENDENCIES + + false + false + true + ^ru\.entaxy\.esb + test, provided + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-artifacts + package + + attach-artifact + + + + + target/generated-sources/license/ALL-DEPENDENCIES + deps + aggregated + + + + + + + + + + + + + + + http://www.emdev.ru + EmDev + + + Jenkins + http://build.emdev.ru/jenkins/ + + + scm:git:https://git.emdev.ru/entaxy/entaxy-framework + + + + + + + entaxy-public + entaxy-public + + https://nexus.entaxy.ru/nexus/repository/entaxy-public/ + default + + true + warn + never + + + false + + + + + + entaxy-private + entaxy-private + + https://nexus.entaxy.ru/nexus/repository/entaxy-private/ + default + + true + warn + never + + + true + warn + never + + + + + + + + entaxy-public + entaxy-public + + https://nexus.entaxy.ru/nexus/repository/entaxy-public/ + default + + true + warn + never + + + false + + + + + diff --git a/system/LICENSE.txt b/system/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/auth/LICENSE.txt b/system/auth/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/auth/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/auth/basic-auth/LICENSE.txt b/system/auth/basic-auth/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/auth/basic-auth/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/auth/basic-auth/README.md b/system/auth/basic-auth/README.md new file mode 100644 index 00000000..5dcf4ad5 --- /dev/null +++ b/system/auth/basic-auth/README.md @@ -0,0 +1,71 @@ +# SYSTEM :: ENTAXY :: AUTH BASIC + +Реализация web-сервиса для загрузки актуальных или измененных пользователей и их параметры аутентификации (логин АД или данные Basic авторизации) + +##Admin + +Стартовый пользователь **admin/admin**, записывается через liquibase, без связанной системы. + +По умолчанию выданы права на управленческий слой, сервисы: + - system-management + - basic-auth-management + - permission-management + - topic-management + +!!!Требуется сменить пароль!!! + +Файл Htpasswd не генерируется до первого обращения к сервису basic-auth-management. + +## Сборка + +Сборка осуществляется командой + +``` +mvn clean install +``` +По умолчанию запускается профиль dev, в котором прописаны параметры соединения к разработческой базе. + +Запуск профиля для production: + +``` +mvn clean install -Denv=prod +``` + +Параметры соединения хранятся в свойствах профилей в pom.xml + +## Установка в karaf + +Добавление репозитория в karaf + +``` +feature:repo-add mvn:ru.entaxy.esb/karaf-features/LATEST/xml/features +``` + +Установка auth basic + +``` +feature:install basic-auth +``` + +## Подключение cxf interceptor для идентификации систем + +``` + + + + + + + +``` + +Интерцептор принимает заголовок с логином **X-ForwardedUser** от nginX + +Данные по определённой системе записываются в заголовки + +- **X-SystemName** +- **X-SystemUuid** +- **X-SystemId** + + diff --git a/system/auth/basic-auth/basic-auth-api/LICENSE.txt b/system/auth/basic-auth/basic-auth-api/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/auth/basic-auth/basic-auth-api/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/auth/basic-auth/basic-auth-api/pom.xml b/system/auth/basic-auth/basic-auth-api/pom.xml new file mode 100644 index 00000000..eea99d65 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-api/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + + ru.entaxy.esb.system.auth.basic + basic-auth + 1.8.0 + + + ru.entaxy.esb.system.auth.basic.api + basic-auth-api + bundle + + SYSTEM :: ENTAXY :: BASIC AUTH SERVICE API + SYSTEM :: ENTAXY :: BASIC AUTH SERVICE API + + + + ru.entaxy.esb.system.auth.basic.jpa.api, + ru.entaxy.esb.system.auth.basic.jpa.api.entity, + ru.entaxy.esb.system.auth.basic.jpa.api.entity.field, + ru.entaxy.esb.system.auth.basic.jpa.api.exception + + + javax.persistence;version="[2,3)", + org.hibernate.proxy;version="[5,6)", + javassist.util.proxy, + * + + + + + + org.eclipse.persistence + javax.persistence + ${jpa.version} + + + org.hibernate + hibernate-core + ${hibernate.version} + + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + diff --git a/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/BasicAuthService.java b/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/BasicAuthService.java new file mode 100644 index 00000000..00e1ab41 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/BasicAuthService.java @@ -0,0 +1,51 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.jpa.api; + +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount; +import ru.entaxy.esb.system.auth.basic.jpa.api.exception.BadPasswordException; + +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.Optional; + +public interface BasicAuthService { + + List list(); + + Optional get(String login); + + Optional getByAuthorizationHeaderHash(String authorizationHeaderHash); + + BasicAuthAccount save(BasicAuthAccount basicAuthAccount, boolean isExist); + + public BasicAuthAccount saveFull(String login, String passwordHash, String encryptionAlgorithm, String systemUUID, + String authorizationHeaderHash, String description, String createdBy, String editedBy); + + BasicAuthAccount saveCommon(String login, String passwordHash, String systemUUID, String createdBy, String editedBy) + throws NoSuchAlgorithmException, BadPasswordException; + + BasicAuthAccount saveShort(String login, String passwordHash, String createdBy, String editedBy) throws NoSuchAlgorithmException, BadPasswordException; + + void remove(String login); + + boolean check(String login, String password); + +} diff --git a/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/entity/BasicAuthAccount.java b/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/entity/BasicAuthAccount.java new file mode 100644 index 00000000..19fac0e7 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/entity/BasicAuthAccount.java @@ -0,0 +1,185 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.jpa.api.entity; + +import com.sun.istack.NotNull; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.field.EncryptionAlgorithm; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.field.EncryptionAlgorithmAttributeConverter; + +import javax.persistence.*; +import java.util.Date; +import java.util.Objects; + +@Entity +@Table(name = "basic_auth_account") +public class BasicAuthAccount { + + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @NotNull + @Column(name = "login") + private String login; + @NotNull + @Column(name = "password_hash") + private String passwordHash; + @Column(name = "encryption_algorithm") + @Convert(converter = EncryptionAlgorithmAttributeConverter.class) + private EncryptionAlgorithm encryptionAlgorithm; + @Column(name = "system_uuid") + private String systemUUID; + @NotNull + @Column(name = "authorization_header_hash") + private String authorizationHeaderHash; + @Column(name = "description") + private String description; + @NotNull + @Column(name = "create_date") + private Date createDate; + @Column(name = "edit_date") + private Date editDate; + @NotNull + @Column(name = "created_by") + private String createdBy; + @Column(name = "edited_by") + private String editedBy; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getPasswordHash() { + return passwordHash; + } + + public void setPasswordHash(String passwordHash) { + this.passwordHash = passwordHash; + } + + public EncryptionAlgorithm getEncryptionAlgorithm() { + return encryptionAlgorithm; + } + + public void setEncryptionAlgorithm(EncryptionAlgorithm encryptionAlgorithm) { + this.encryptionAlgorithm = encryptionAlgorithm; + } + + public String getSystemUUID() { + return systemUUID; + } + + public void setSystemUUID(String systemUUID) { + this.systemUUID = systemUUID; + } + + public String getAuthorizationHeaderHash() { + return authorizationHeaderHash; + } + + public void setAuthorizationHeaderHash(String authorizationHeaderHash) { + this.authorizationHeaderHash = authorizationHeaderHash; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public Date getEditDate() { + return editDate; + } + + public void setEditDate(Date editDate) { + this.editDate = editDate; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public String getEditedBy() { + return editedBy; + } + + public void setEditedBy(String editedBy) { + this.editedBy = editedBy; + } + + @Override + public int hashCode() { + return Objects.hash(authorizationHeaderHash, createDate, createdBy, description, editDate, editedBy, + encryptionAlgorithm, login, passwordHash, systemUUID); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BasicAuthAccount other = (BasicAuthAccount) obj; + return Objects.equals(authorizationHeaderHash, other.authorizationHeaderHash) + && Objects.equals(createDate, other.createDate) && Objects.equals(createdBy, other.createdBy) + && Objects.equals(description, other.description) && Objects.equals(editDate, other.editDate) + && Objects.equals(editedBy, other.editedBy) + && Objects.equals(encryptionAlgorithm, other.encryptionAlgorithm) && Objects.equals(login, other.login) + && Objects.equals(passwordHash, other.passwordHash) + && Objects.equals(systemUUID, other.systemUUID); + } + + @Override + public String toString() { + return "BasicAuthAccount [login=" + login + ", passwordHash=" + passwordHash + ", encryptionAlgorithm=" + + encryptionAlgorithm + ", systemUUID=" + systemUUID + ", authorizationHeaderHash=" + authorizationHeaderHash + + ", description=" + description + ", createDate=" + createDate + ", editDate=" + editDate + + ", createdBy=" + createdBy + ", editedBy=" + editedBy + "]"; + } + +} diff --git a/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/entity/field/EncryptionAlgorithm.java b/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/entity/field/EncryptionAlgorithm.java new file mode 100644 index 00000000..b2707c7c --- /dev/null +++ b/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/entity/field/EncryptionAlgorithm.java @@ -0,0 +1,59 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.jpa.api.entity.field; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public enum EncryptionAlgorithm { + + PLAIN("PLAIN"), + MD5("MD5"), + SHA1("SHA-1"), + SHA256("SHA-256"), + SHA384("SHA-384"), + SHA512("SHA-512"); + + private static Map map = null; + private final String name; + + EncryptionAlgorithm(String name) { + this.name = name; + } + + public String getAlgorithmName() { + return name; + } + + public boolean equalsName(String checkingName) { + return checkingName != null && this.name.equals(checkingName.toUpperCase()); + } + + public static EncryptionAlgorithm getByName(String name) { + return map.get(name.toUpperCase()); + } + + static { + map = Arrays.stream(EncryptionAlgorithm.values()) + .collect(Collectors.toMap(EncryptionAlgorithm::getAlgorithmName, Function.identity())); + } +} diff --git a/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/entity/field/EncryptionAlgorithmAttributeConverter.java b/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/entity/field/EncryptionAlgorithmAttributeConverter.java new file mode 100644 index 00000000..63d936b6 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/entity/field/EncryptionAlgorithmAttributeConverter.java @@ -0,0 +1,38 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.jpa.api.entity.field; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; + +@Converter +public class EncryptionAlgorithmAttributeConverter implements AttributeConverter { + + @Override + public String convertToDatabaseColumn(EncryptionAlgorithm attribute) { + return attribute.getAlgorithmName(); + } + + @Override + public EncryptionAlgorithm convertToEntityAttribute(String dbData) { + return EncryptionAlgorithm.getByName(dbData.toUpperCase()); + } + +} diff --git a/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/exception/BadPasswordException.java b/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/exception/BadPasswordException.java new file mode 100644 index 00000000..0a5f65ce --- /dev/null +++ b/system/auth/basic-auth/basic-auth-api/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/api/exception/BadPasswordException.java @@ -0,0 +1,46 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.jpa.api.exception; + +public class BadPasswordException extends Exception { + + private static final long serialVersionUID = -1675249900871877617L; + + public BadPasswordException() { + } + + public BadPasswordException(String message) { + super(message); + } + + public BadPasswordException(Throwable cause) { + super(cause); + } + + public BadPasswordException(String message, Throwable cause) { + super(message, cause); + } + + public BadPasswordException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/system/auth/basic-auth/basic-auth-impl/LICENSE.txt b/system/auth/basic-auth/basic-auth-impl/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/auth/basic-auth/basic-auth-impl/pom.xml b/system/auth/basic-auth/basic-auth-impl/pom.xml new file mode 100644 index 00000000..4fc4e6e3 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/pom.xml @@ -0,0 +1,141 @@ + + + 4.0.0 + + + ru.entaxy.esb.system.auth.basic + basic-auth + 1.8.0 + + + ru.entaxy.esb.system.auth.basic.impl + basic-auth-impl + bundle + + SYSTEM :: ENTAXY :: BASIC AUTH SERVICE IMPL + SYSTEM :: ENTAXY :: BASIC AUTH SERVICE IMPL + + + + ru.entaxy.esb.system.auth.basic.jpa.api, + ru.entaxy.esb.system.auth.basic.jpa.api.entity, + ru.entaxy.esb.system.auth.basic.jpa.api.entity.field, + ru.entaxy.esb.system.auth.basic.htpasswd, + ru.entaxy.esb.system.auth.basic.jpa.api.exception, + ru.entaxy.esb.system.core.permission.jpa.entity, + ru.entaxy.esb.system.common.util, + javax.persistence;version="[2,3)", + org.hibernate, + org.hibernate.cfg, + org.hibernate.service, + org.hibernate.jpa, + org.hibernate.proxy, + javassist.util.proxy, + org.apache.commons.codec.binary, + * + + + + + + ru.entaxy.esb.system.auth.basic.api + basic-auth-api + ${project.version} + + + ru.entaxy.esb.system.auth.basic.htpasswd + htpasswd + ${project.version} + + + ru.entaxy.esb.system.registry.systems + system-api + ${project.version} + compile + + + ru.entaxy.esb.system.core.permission + permission-api + ${project.version} + provided + + + ru.entaxy.esb.system.core.permission + permission-common + ${project.version} + provided + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + org.osgi + osgi.core + ${osgi.version} + provided + + + org.eclipse.persistence + javax.persistence + ${jpa.version} + + + javax.transaction + javax.transaction-api + ${javax.transaction.version} + + + javax.interceptor + javax.interceptor-api + ${javax.interceptor.version} + + + org.hibernate + hibernate-core + ${hibernate.version} + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + + + + + dev + + + env + dev + + + + true + true + + + + + prod + + + env + !dev + + + + false + false + + + + + diff --git a/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/interceptor/AuthenticationInterceptor.java b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/interceptor/AuthenticationInterceptor.java new file mode 100644 index 00000000..3a87ab61 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/interceptor/AuthenticationInterceptor.java @@ -0,0 +1,131 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-impl + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.interceptor; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.common.util.Base64Exception; +import org.apache.cxf.common.util.Base64Utility; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.interceptor.security.AuthenticationException; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.AbstractPhaseInterceptor; +import org.apache.cxf.phase.Phase; +import org.apache.cxf.transport.http.Headers; +import ru.entaxy.esb.system.auth.basic.jpa.api.BasicAuthService; +import ru.entaxy.esb.system.common.util.SystemHeadersConstants; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class AuthenticationInterceptor extends AbstractPhaseInterceptor { + + private static final Log LOG = LogFactory.getLog(AuthenticationInterceptor.class); + + private boolean enabled = false; + private BasicAuthService basicAuthService; + + private static final String BASIC = "Basic"; + private static final String AUTHORIZATION = "Authorization"; + private static final String WWW_AUTHENTICATE = "WWW-Authenticate"; + private static final String WWW_AUTHENTICATE_MESSAGE = "Basic realm=\"Access to Entaxy\""; + + + public AuthenticationInterceptor() { + super(Phase.RECEIVE); + } + + @Override + public void handleMessage(Message message) throws Fault { + LOG.debug("AuthenticationInterceptor enabled=" + enabled); + if (!enabled) { + return; + } + + + Map> headers = Headers.getSetProtocolHeaders(message); + //reset passed value + headers.put(SystemHeadersConstants.HEADER_USER_LOGIN, Collections.emptyList()); + + Optional auth = Optional.ofNullable(headers.get(AUTHORIZATION)). + orElse(Collections.emptyList()) + .stream().findFirst(); + + if (auth.isPresent()) { + String[] namePassword = prepareAuthData(message, auth); + if (namePassword.length == 2 && isAuthenticated(namePassword[0], namePassword[1])) { + // let request to continue + LOG.trace(namePassword[0] + " authenticated"); + headers.put(SystemHeadersConstants.HEADER_USER_LOGIN, Collections.singletonList(namePassword[0])); + } else { + faultAction(message); + } + } else { + faultAction(message); + } + } + + private String[] prepareAuthData(Message message, Optional auth) { + String[] parts = auth.get().split(" "); + if (parts.length != 2 || !BASIC.equals(parts[0])) { + faultAction(message); + } + String decodedValue = null; + try { + decodedValue = new String(Base64Utility.decode(parts[1])); + } catch (Base64Exception ex) { + faultAction(message); + } + String[] namePassword = decodedValue.split(":"); + return namePassword; + } + + private void faultAction(Message message) { + Map> headers = Headers.getSetProtocolHeaders(message); + headers.put(WWW_AUTHENTICATE, Collections.singletonList(WWW_AUTHENTICATE_MESSAGE)); + Fault fault = new Fault(new AuthenticationException("Unauthorized Access")); + fault.setFaultCode(Fault.FAULT_CODE_CLIENT); + fault.setStatusCode(401); + throw fault; + } + + private boolean isAuthenticated(String name, String password) { + return basicAuthService.check(name, password); + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public BasicAuthService getBasicAuthService() { + return basicAuthService; + } + + public void setBasicAuthService(BasicAuthService basicAuthService) { + this.basicAuthService = basicAuthService; + } + +} diff --git a/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/interceptor/SystemInterceptor.java b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/interceptor/SystemInterceptor.java new file mode 100644 index 00000000..5411c18b --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/interceptor/SystemInterceptor.java @@ -0,0 +1,110 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-impl + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.interceptor; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.AbstractPhaseInterceptor; +import org.apache.cxf.phase.Phase; +import org.apache.cxf.transport.http.Headers; +import ru.entaxy.esb.system.auth.basic.jpa.api.BasicAuthService; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount; +import ru.entaxy.esb.system.common.util.SystemHeadersConstants; +import ru.entaxy.esb.system.jpa.SystemService; +import ru.entaxy.esb.system.jpa.entity.System; + +import javax.ws.rs.ForbiddenException; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class SystemInterceptor extends AbstractPhaseInterceptor { + + private static final Log LOG = LogFactory.getLog(SystemInterceptor.class); + + private BasicAuthService basicAuthService; + + private SystemService systemService; + + public SystemInterceptor() { + super(Phase.PRE_PROTOCOL); + } + + @Override + public void handleMessage(Message message) throws Fault { + Map> headers = Headers.getSetProtocolHeaders(message); + + Optional login = Optional.ofNullable(headers.get(SystemHeadersConstants.HEADER_USER_LOGIN)). + orElse(Collections.emptyList()) + .stream().findFirst(); + + //TEST +// login = Optional.of("user"); + + LOG.trace(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>SystemInterceptor <<< headers.get( HEADER_USER_LOGIN ) " + login.orElse("NULL")); + + if (login.isPresent()) { + Optional accountOpt = basicAuthService.get(login.get()); + + if (accountOpt.isPresent()) { + BasicAuthAccount account = accountOpt.get(); + headers.put(SystemHeadersConstants.HEADER_USER_ID, Collections.singletonList(String.valueOf(account.getId()))); + + headers.put(SystemHeadersConstants.HEADER_SYSTEM_UUID, Collections.singletonList(account.getSystemUUID())); + + System system = account.getSystemUUID() != null && !account.getSystemUUID().isEmpty() + ? systemService.getByUuid(account.getSystemUUID()) + : null; + if (system != null) { + headers.put(SystemHeadersConstants.HEADER_SYSTEM_NAME, Collections.singletonList(system.getName())); + headers.put(SystemHeadersConstants.HEADER_SYSTEM_ID, Collections.singletonList(String.valueOf(system.getId()))); + } + } else { + throw new ForbiddenException(); + } + } + +// It stops the process +// else { +// message.getInterceptorChain().abort(); +// } + + } + + public BasicAuthService getBasicAuthService() { + return basicAuthService; + } + + public void setBasicAuthService(BasicAuthService basicAuthService) { + this.basicAuthService = basicAuthService; + } + + public SystemService getSystemService() { + return systemService; + } + + public void setSystemService(SystemService systemService) { + this.systemService = systemService; + } + +} diff --git a/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/impl/BasicAuthServiceImpl.java b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/impl/BasicAuthServiceImpl.java new file mode 100644 index 00000000..067508f7 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/impl/BasicAuthServiceImpl.java @@ -0,0 +1,247 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-impl + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.jpa.impl; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.system.auth.basic.jpa.api.BasicAuthService; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.field.EncryptionAlgorithm; +import ru.entaxy.esb.system.auth.basic.jpa.api.exception.BadPasswordException; +import ru.entaxy.esb.system.auth.basic.jpa.util.EncryptionHelper; +import ru.entaxy.esb.system.core.permission.common.PermissionConstants; +import ru.entaxy.esb.system.core.permission.jpa.PermissionService; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.security.NoSuchAlgorithmException; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +public class BasicAuthServiceImpl implements BasicAuthService { + + private static final Logger LOG = LoggerFactory.getLogger(BasicAuthServiceImpl.class); + + private SessionFactory sessionFactory; + private String еncryptionAlgorithm; + private String encryptionSalt; + private PermissionService permissionService; + + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public Session getSession() { + return sessionFactory.openSession(); + } + + public void setЕncryptionAlgorithm(String еncryptionAlgorithm) { + this.еncryptionAlgorithm = еncryptionAlgorithm; + } + + public void setEncryptionSalt(String encryptionSalt) { + this.encryptionSalt = encryptionSalt; + } + + public PermissionService getPermissionService() { + return permissionService; + } + + public void setPermissionService(PermissionService permissionService) { + this.permissionService = permissionService; + } + + @Override + public List list() { + List list; + try (Session s = getSession()) { + s.getTransaction().begin(); + CriteriaQuery cq = s.getCriteriaBuilder().createQuery(BasicAuthAccount.class); + cq.from(BasicAuthAccount.class); + list = s.createQuery(cq).getResultList(); + s.getTransaction().commit(); + s.close(); + } + + return list; + } + + @Override + public Optional get(String login) { + Optional basicAuthAccount; + try (Session s = getSession()) { + s.getTransaction().begin(); + + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(BasicAuthAccount.class); + Root root = criteriaQuery.from(BasicAuthAccount.class); + criteriaQuery.where(builder.equal(root.get("login"), login)); + basicAuthAccount = s.createQuery(criteriaQuery).uniqueResultOptional(); + + s.getTransaction().commit(); + s.close(); + } + return basicAuthAccount; + } + + public Optional get(Session session, String login) { + Optional basicAuthAccount; + CriteriaBuilder builder = session.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(BasicAuthAccount.class); + Root root = criteriaQuery.from(BasicAuthAccount.class); + criteriaQuery.where(builder.equal(root.get("login"), login)); + basicAuthAccount = session.createQuery(criteriaQuery).uniqueResultOptional(); + return basicAuthAccount; + } + + @Override + public Optional getByAuthorizationHeaderHash(String authorizationHeaderHash) { + Optional basicAuthAccount; + try (Session s = getSession()) { + s.getTransaction().begin(); + + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(BasicAuthAccount.class); + Root root = criteriaQuery.from(BasicAuthAccount.class); + criteriaQuery.where(builder.equal(root.get("authorizationHeaderHash"), authorizationHeaderHash)); + basicAuthAccount = s.createQuery(criteriaQuery).uniqueResultOptional(); + + s.getTransaction().commit(); + s.close(); + } + return basicAuthAccount; + } + + @Override + public BasicAuthAccount save(BasicAuthAccount basicAuthAccount, boolean isExist) { + try (Session s = getSession()) { + s.getTransaction().begin(); + if (isExist) { + s.update(basicAuthAccount); + } else { + s.persist(basicAuthAccount); + } + s.getTransaction().commit(); + s.close(); + } + return basicAuthAccount; + } + + @Override + public BasicAuthAccount saveFull(String login, String passwordHash, String encryptionAlgorithm, String systemUUID, + String authorizationHeaderHash, String description, String createdBy, String editedBy) { + + LOG.debug("Parameters " + login + " " + passwordHash + " " + encryptionAlgorithm + + " " + systemUUID + " " + authorizationHeaderHash + " " + description + " " + createdBy + " " + editedBy); + + Optional existingBasicAuthAccount = get(login); + + EncryptionAlgorithm encryptionAlgorithmObj = EncryptionAlgorithm.getByName(encryptionAlgorithm.toUpperCase()); + + BasicAuthAccount basicAuthAccount = existingBasicAuthAccount.orElseGet(BasicAuthAccount::new); + settingBasicAuthAccount(login, passwordHash, encryptionAlgorithmObj, systemUUID, authorizationHeaderHash, + description, createdBy, editedBy, basicAuthAccount, existingBasicAuthAccount.isPresent()); + + return save(basicAuthAccount, existingBasicAuthAccount.isPresent()); + } + + private BasicAuthAccount settingBasicAuthAccount(String login, String passwordHash, EncryptionAlgorithm encryptionAlgorithm, + String systemUUID, String authorizationHeaderHash, + String description, String createdBy, String editedBy, + BasicAuthAccount basicAuthAccount, boolean isExist) { + if (!isExist) { + basicAuthAccount.setLogin(login); + basicAuthAccount.setCreateDate(new Date()); + basicAuthAccount.setCreatedBy(createdBy); + } else { + basicAuthAccount.setEditDate(new Date()); + basicAuthAccount.setEditedBy(editedBy); + } + + basicAuthAccount.setPasswordHash(passwordHash); + basicAuthAccount.setEncryptionAlgorithm(encryptionAlgorithm); + basicAuthAccount.setSystemUUID(systemUUID); + basicAuthAccount.setAuthorizationHeaderHash(authorizationHeaderHash); + basicAuthAccount.setDescription(description); + return basicAuthAccount; + } + + @Override + public BasicAuthAccount saveCommon(String login, String passwordHash, String systemUUID, String createdBy, String editedBy) + throws NoSuchAlgorithmException, BadPasswordException { + if (null != passwordHash && !passwordHash.isEmpty()) { + passwordHash = EncryptionHelper.encrypt(passwordHash, this.еncryptionAlgorithm, this.encryptionSalt); + } else { + throw new BadPasswordException("Password not passed or empty!"); + } + return saveFull(login, passwordHash, this.еncryptionAlgorithm, systemUUID, "", "", createdBy, editedBy); + } + + @Override + public BasicAuthAccount saveShort(String login, String passwordHash, String createdBy, String editedBy) + throws NoSuchAlgorithmException, BadPasswordException { + return saveCommon(login, passwordHash, "", createdBy, editedBy); + } + + @Override + public void remove(String login) { + try (Session s = getSession()) { + s.getTransaction().begin(); + + Optional basicAuthAccount = get(s, login); + basicAuthAccount.ifPresent((basicAuthAccount1) -> removeProc(s, basicAuthAccount1)); + s.getTransaction().commit(); + s.close(); + } + } + + private void removeProc(Session session, BasicAuthAccount account) { + permissionService.removeAll(session, account.getId(), PermissionConstants.TYPE_ACCOUNT); + session.flush(); + session.delete(BasicAuthAccount.class.getName(), account); + } + + @Override + public boolean check(String login, String password) { + if (login != null && password != null) { + Optional basicAuthAccountOpt = get(login); + if (basicAuthAccountOpt.isPresent()) { + BasicAuthAccount basicAuthAccount = basicAuthAccountOpt.get(); + try { + String passedPasswordHash = EncryptionHelper.encrypt(password, + basicAuthAccount.getEncryptionAlgorithm().getAlgorithmName(), + this.encryptionSalt); + if (passedPasswordHash.equals(basicAuthAccount.getPasswordHash())) { + return true; + } + } catch (NoSuchAlgorithmException e) { + LOG.error("Encription algorithm error", e); + } + } + } + return false; + } + + +} diff --git a/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/listener/BasicAuthPostEventListener.java b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/listener/BasicAuthPostEventListener.java new file mode 100644 index 00000000..64e9864b --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/listener/BasicAuthPostEventListener.java @@ -0,0 +1,118 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-impl + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.jpa.listener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.event.spi.*; +import org.hibernate.persister.entity.EntityPersister; +import ru.entaxy.esb.system.auth.basic.htpasswd.HtpasswdGenerator; +import ru.entaxy.esb.system.auth.basic.jpa.api.BasicAuthService; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount; + +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.util.List; + +public class BasicAuthPostEventListener implements PostCommitInsertEventListener, PostCommitUpdateEventListener, PostCommitDeleteEventListener { + + private static final long serialVersionUID = -6603994118756820823L; + private static final Log LOG = LogFactory.getLog(BasicAuthPostEventListener.class); + + private BasicAuthService basicAuthService; + private HtpasswdGenerator htpasswdGenerator; + private String encryptionSalt; + + public void setEncryptionSalt(String encryptionSalt) { + this.encryptionSalt = encryptionSalt; + } + + @Override + public boolean requiresPostCommitHanding(EntityPersister persister) { + return true; + } + + @Override + public void onPostDelete(PostDeleteEvent event) { + LOG.debug("Delete handler event " + event.getSession()); + LOG.debug("Delete handler event " + event.getEntity()); + if (event.getEntity() instanceof BasicAuthAccount) { + generateHtpasswd(); + } + + } + + @Override + public void onPostUpdate(PostUpdateEvent event) { + LOG.debug("Update handler event " + event); + LOG.debug("Update handler event " + event.getEntity()); + generateHtpasswd(); + } + + @Override + public void onPostInsert(PostInsertEvent event) { + LOG.debug("Insert handler event " + event); + LOG.debug("Insert handler event " + event.getEntity()); + generateHtpasswd(); + } + + private void generateHtpasswd() { + List accounts = basicAuthService.list(); + + try { + htpasswdGenerator.generateHtpasswd(accounts, encryptionSalt); + } catch (NoSuchAlgorithmException | IOException e) { + LOG.error(e); + } + } + + @Override + public void onPostDeleteCommitFailed(PostDeleteEvent event) { + LOG.debug("Delete failed event " + event.getEntity()); + } + + @Override + public void onPostUpdateCommitFailed(PostUpdateEvent event) { + LOG.debug("Update failed event " + event.getEntity()); + + } + + @Override + public void onPostInsertCommitFailed(PostInsertEvent event) { + LOG.debug("Insert failed event " + event.getEntity()); + } + + public BasicAuthService getBasicAuthService() { + return basicAuthService; + } + + public void setBasicAuthService(BasicAuthService basicAuthService) { + this.basicAuthService = basicAuthService; + } + + public HtpasswdGenerator getHtpasswdGenerator() { + return htpasswdGenerator; + } + + public void setHtpasswdGenerator(HtpasswdGenerator htpasswdGenerator) { + this.htpasswdGenerator = htpasswdGenerator; + } + +} diff --git a/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/listener/EntityEventListenerRegistry.java b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/listener/EntityEventListenerRegistry.java new file mode 100644 index 00000000..ed44b3a9 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/listener/EntityEventListenerRegistry.java @@ -0,0 +1,87 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-impl + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.jpa.listener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.SessionFactory; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.event.service.spi.EventListenerRegistry; +import org.hibernate.event.spi.EventType; + +public class EntityEventListenerRegistry { + + private static final Log LOG = LogFactory.getLog(EntityEventListenerRegistry.class); + private static final int SESSION_WAIT_TIMEOUT = 5000; + + private SessionFactory sessionFactory; + private BasicAuthPostEventListener basicAuthPostEventListener; + private int initLimiter = 0; + + + public void registerListeners() { + LOG.info("Init EntityEventListenerRegistry " + sessionFactory.getClass().getName()); + + EventListenerRegistry registry = prepareRegistry(); + registry.getEventListenerGroup(EventType.POST_COMMIT_INSERT).appendListener(basicAuthPostEventListener); + registry.getEventListenerGroup(EventType.POST_COMMIT_UPDATE).appendListener(basicAuthPostEventListener); + registry.getEventListenerGroup(EventType.POST_COMMIT_DELETE).appendListener(basicAuthPostEventListener); + } + + private EventListenerRegistry prepareRegistry() { + try { + SessionFactoryImplementor sessionFactoryImpl = sessionFactory.unwrap(SessionFactoryImplementor.class); + EventListenerRegistry registry = sessionFactoryImpl.getServiceRegistry().getService(EventListenerRegistry.class); + return registry; + } catch (Exception e) { + LOG.error(e.getMessage()); + if (initLimiter == 10) { + LOG.error(e); + } + try { + LOG.warn("Wait sessionFactory initialization..."); + Thread.sleep(SESSION_WAIT_TIMEOUT); + } catch (InterruptedException e1) { + } + + } + return initLimiter++ <= 9 + ? prepareRegistry() + : null; + } + + + public SessionFactory getSessionFactory() { + return sessionFactory; + } + + public BasicAuthPostEventListener getBasicAuthPostEventListener() { + return basicAuthPostEventListener; + } + + public void setBasicAuthPostEventListener(BasicAuthPostEventListener basicAuthPostEventListener) { + this.basicAuthPostEventListener = basicAuthPostEventListener; + } + + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + +} diff --git a/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/util/EncryptionHelper.java b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/util/EncryptionHelper.java new file mode 100644 index 00000000..3e8da07d --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/src/main/java/ru/entaxy/esb/system/auth/basic/jpa/util/EncryptionHelper.java @@ -0,0 +1,65 @@ +/*- + * ~~~~~~licensing~~~~~~ + * basic-auth-impl + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.jpa.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.codec.digest.Md5Crypt; +import org.apache.commons.codec.digest.Sha2Crypt; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.field.EncryptionAlgorithm; + +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; + +public class EncryptionHelper { + + private static final Logger LOG = LoggerFactory.getLogger(EncryptionHelper.class); + + static final String APR1_PREFIX = "$apr1$"; + static final String SHA512_PREFIX = "$6$"; + + private EncryptionHelper() { + throw new IllegalStateException("Utility class"); + } + + public static String encrypt(String plaintext, String cipher, String salt) throws NoSuchAlgorithmException { + String passwordHash; + + if (EncryptionAlgorithm.MD5.equalsName(cipher)) { + passwordHash = Md5Crypt.apr1Crypt((plaintext.getBytes(StandardCharsets.UTF_8)), salt); + passwordHash = passwordHash.substring(passwordHash.lastIndexOf("$") + 1); + } else if (EncryptionAlgorithm.SHA1.equalsName(cipher)) { + passwordHash = Base64.encodeBase64String( + DigestUtils.sha1((plaintext + salt).getBytes(StandardCharsets.UTF_8))); + } else if (EncryptionAlgorithm.SHA512.equalsName(cipher)) { + passwordHash = Sha2Crypt.sha512Crypt((plaintext.getBytes(StandardCharsets.UTF_8)), SHA512_PREFIX + salt); + passwordHash = passwordHash.substring(passwordHash.lastIndexOf("$")); + } else if (EncryptionAlgorithm.PLAIN.equalsName(cipher)) { + passwordHash = plaintext; + } else { + throw new NoSuchAlgorithmException(); + } + + return passwordHash; + } + +} diff --git a/system/auth/basic-auth/basic-auth-impl/src/main/resources/OSGI-INF/blueprint/camel-context.xml b/system/auth/basic-auth/basic-auth-impl/src/main/resources/OSGI-INF/blueprint/camel-context.xml new file mode 100644 index 00000000..5b2878d7 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/src/main/resources/OSGI-INF/blueprint/camel-context.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/auth/basic-auth/basic-auth-impl/src/main/resources/hibernate.cfg.xml b/system/auth/basic-auth/basic-auth-impl/src/main/resources/hibernate.cfg.xml new file mode 100644 index 00000000..c26ebf52 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/src/main/resources/hibernate.cfg.xml @@ -0,0 +1,38 @@ + + + + + + + + osgi:service/entaxy.esb.storage + + validate + + true + + + + + + diff --git a/system/auth/basic-auth/basic-auth-impl/src/main/resources/log4j2.properties b/system/auth/basic-auth/basic-auth-impl/src/main/resources/log4j2.properties new file mode 100644 index 00000000..56ebd1f2 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-impl/src/main/resources/log4j2.properties @@ -0,0 +1,30 @@ +### +# ~~~~~~licensing~~~~~~ +# basic-auth-impl +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +appender.file.type=File +appender.file.name=file +appender.file.fileName=target/camel-test.log +appender.file.layout.type=PatternLayout +appender.file.layout.pattern=%d %-5p %c{1} - %m %n +appender.out.type=Console +appender.out.name=out +appender.out.layout.type=PatternLayout +appender.out.layout.pattern=[%30.30t] %-30.30c{1} %-5p %m%n +rootLogger.level=DEBUG +rootLogger.appenderRef.out.ref=out diff --git a/system/auth/basic-auth/basic-auth-soap/LICENSE.txt b/system/auth/basic-auth/basic-auth-soap/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/auth/basic-auth/basic-auth-soap/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/auth/basic-auth/basic-auth-soap/pom.xml b/system/auth/basic-auth/basic-auth-soap/pom.xml new file mode 100644 index 00000000..baf59097 --- /dev/null +++ b/system/auth/basic-auth/basic-auth-soap/pom.xml @@ -0,0 +1,18 @@ + + + + basic-auth + ru.entaxy.esb.system.auth.basic + 1.8.0 + + 4.0.0 + + basic-auth-soap + bundle + + SYSTEM :: ENTAXY :: BASIC AUTH SOAP + SYSTEM :: ENTAXY :: BASIC AUTH SOAP + + \ No newline at end of file diff --git a/system/auth/basic-auth/basic-auth-soap/src/main/resources/OSGI-INF/blueprint/camel-context.xml b/system/auth/basic-auth/basic-auth-soap/src/main/resources/OSGI-INF/blueprint/camel-context.xml new file mode 100644 index 00000000..c9c5e62a --- /dev/null +++ b/system/auth/basic-auth/basic-auth-soap/src/main/resources/OSGI-INF/blueprint/camel-context.xml @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${headers.operationName} in 'addAccount,updateAccount' + + + + ${headers.operationName} == 'removeAccount' + + + + ${headers.operationName} in 'addAccountPermission,removeAccountPermission' + + + + + + + + + + //bas:accountList/bas:account + + + + + //bas:account/bas:login + + + //bas:account/bas:password + + + //bas:account/bas:systemUUID + + + + + + + + + <response xmlns="http://www.entaxy.ru/basic-auth-service/">true</response> + + + + java.lang.Exception + + + + <response xmlns="http://www.entaxy.ru/basic-auth-service/">false</response> + + + + + + + + + + + //bas:loginList/bas:login + + + + + //bas:login + + + + + + <response xmlns="http://www.entaxy.ru/basic-auth-service/">true</response> + + + + java.lang.Exception + + + <response xmlns="http://www.entaxy.ru/basic-auth-service/">false</response> + + + + + + + + + + + //bas:permissionList/bas:permission + + + + + + + + + + + + + ${body.isPresent()} + + + ${body.get()} + + + + + ${headers.operationName} == 'addAccountPermission' + + + + ${headers.operationName} == 'removeAccountPermission' + + + + + + + + + + + + + + + <response xmlns="http://www.entaxy.ru/basic-auth-service/">true</response> + + + + + java.lang.Exception + + + + <response xmlns="http://www.entaxy.ru/basic-auth-service/">false</response> + + + + + + + + + + //bas:permission/bas:login + + + //bas:permission/bas:subject + + + //bas:permission/bas:subjectType + + + //bas:permission/bas:action + + + + + diff --git a/system/auth/basic-auth/basic-auth-soap/src/main/resources/wsdl/basic-auth-service.wsdl b/system/auth/basic-auth/basic-auth-soap/src/main/resources/wsdl/basic-auth-service.wsdl new file mode 100644 index 00000000..edbe1f8a --- /dev/null +++ b/system/auth/basic-auth/basic-auth-soap/src/main/resources/wsdl/basic-auth-service.wsdl @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/auth/basic-auth/htpasswd/LICENSE.txt b/system/auth/basic-auth/htpasswd/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/auth/basic-auth/htpasswd/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/auth/basic-auth/htpasswd/README.md b/system/auth/basic-auth/htpasswd/README.md new file mode 100644 index 00000000..5912de12 --- /dev/null +++ b/system/auth/basic-auth/htpasswd/README.md @@ -0,0 +1,78 @@ +# SYSTEM :: ENTAXY :: BASIC AUTH :: HTPASSWD + +Генерация htpasswd файла, сервис выдачи файла и checksum +Работает с nginX шифрования MD5 и SHA-1 + +Описание данного подхода аутентификации: +1. Nginx по умолчанию собран с модулем +ngx_http_auth_basic_module, который проводит +базовую аутентификацию через файлы htpasswd. +2. Файл passwd периодически или по событиям +синхронизируется между нодами при помощи скрипта синхронизации, +который вызывает Rest сервис +шины. (Rsync использовать нельзя, так как порты +закрыты.) +3. Аутентификация делается только на Nginx без доп. +нагрузки на шину +4. Файл хранится на сервере nginx и аутентификация +будет работать всегда +5. Подход рассчитан на балансировщики реализующие basic аутентификацию + с использованием htpasswd + + +## Сборка + +Сборка осуществляется командой + +``` +mvn clean install +``` + +Файл конфигурации модуля ru.entaxy.esb.system.basic_auth.htpasswd.cfg хранится в SYSTEM :: ENTAXY :: Features + +## Сервис Htpasswd + +**Настраивается свойствами** + +htpasswd.service.host по умолчанию 0.0.0.0 + +htpasswd.service.port по умолчанию 9091 + +htpasswd.service.root.path по умолчанию /htpasswd + +**Методы:** + +GET http://localhost:9091/htpasswd - получение содержимого файла htpasswd + +GET http://localhost:9091/htpasswd/checksum - получение checksum текущего htpasswd + +**Кластер:** + +Для избежания рассинхронизации файлов htpasswd на разных серверах требуется настроить шару между карафами и установить адрес этой папки в свойство + +htpasswd.file.directory=/mnt/share + +## Скрипт сихронизации htpasswd для nginX + +Расположен в папке resources/script/htpasswd-checker.sh + +Запускается из любой папки расположенной на сервере. + +Перед запуском проверить и при необходимости поправить переменные в скрипте + +* KARAF_HOST_NAMES=("http://192.168.122.93:9091" "http://192.168.122.94:9091") - караф сервера с запущеным сервисом htpasswd +* HTPASSWD_STORAGE=/etc/nginx/htpasswd - адрес файла htpasswd, на который настроен nginX + +Добавить запуск скрипта через cron +sudo crontab -e + +``` +раз в минут +*/5 * * * * + +либо раз в минуту +*/1 * * * * +``` + + + \ No newline at end of file diff --git a/system/auth/basic-auth/htpasswd/pom.xml b/system/auth/basic-auth/htpasswd/pom.xml new file mode 100644 index 00000000..e088979e --- /dev/null +++ b/system/auth/basic-auth/htpasswd/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + + ru.entaxy.esb.system.auth.basic + basic-auth + 1.8.0 + + + ru.entaxy.esb.system.auth.basic.htpasswd + htpasswd + bundle + + SYSTEM :: ENTAXY :: BASIC AUTH :: HTPASSWD + SYSTEM :: ENTAXY :: BASIC AUTH :: HTPASSWD + + + + ru.entaxy.esb.system.auth.basic.htpasswd, + + + ru.entaxy.esb.system.auth.basic.jpa.api, + ru.entaxy.esb.system.auth.basic.jpa.api.entity, + ru.entaxy.esb.system.auth.basic.jpa.api.entity.field, + org.apache.cxf.jaxrs.impl, + org.apache.camel.component.cxf.jaxrs.blueprint, + org.apache.camel.component.cxf.blueprint, + org.apache.commons.codec.binary, + * + + + + + + ru.entaxy.esb.system.auth.basic.api + basic-auth-api + ${project.version} + + + commons-codec + commons-codec + ${commons-codec.version} + + + org.apache.camel + camel-cxf + ${camel.version} + + + org.apache.camel.karaf + camel-cxf-blueprint + ${camel.version} + + + diff --git a/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/HtpasswdGenerator.java b/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/HtpasswdGenerator.java new file mode 100644 index 00000000..3a161dcf --- /dev/null +++ b/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/HtpasswdGenerator.java @@ -0,0 +1,93 @@ +/*- + * ~~~~~~licensing~~~~~~ + * htpasswd + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.htpasswd; + +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import ru.entaxy.esb.system.auth.basic.htpasswd.entity.Htpasswd; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.NoSuchAlgorithmException; +import java.util.List; + +public class HtpasswdGenerator { + + private static final Log LOG = LogFactory.getLog(HtpasswdGenerator.class); + + private String checkSumFileName; + + public Htpasswd htpasswd; + + public void generateHtpasswd(List accounts, String salt) throws IOException, NoSuchAlgorithmException { + htpasswd.setMasterSalt(salt); + htpasswd.prepare(accounts); + createFile(); + } + + private void createFile() throws IOException { + String content = htpasswd.toString(); + LOG.trace("HTTPASSWD " + content); + String storeFolder = htpasswd.getDirectory(); + File folder = new File(storeFolder); + folder.mkdirs(); + + File htpasswdFile = new File(folder.getAbsolutePath() + File.separator + htpasswd.getFileName()); + + Path path = Paths.get(htpasswdFile.getAbsolutePath()); + Files.write(path, content.getBytes()); + + String checkSum = calculateCheckSum(path); + File checkSumFile = new File(folder.getAbsolutePath() + File.separator + checkSumFileName); + path = Paths.get(checkSumFile.getAbsolutePath()); + Files.write(path, checkSum.getBytes()); + } + + private String calculateCheckSum(Path path) throws IOException { + String md5; + try (InputStream is = Files.newInputStream(path)) { + md5 = DigestUtils.md5Hex(is); + } + return md5; + } + + public Htpasswd getHtpasswd() { + return htpasswd; + } + + public void setHtpasswd(Htpasswd htpasswd) { + this.htpasswd = htpasswd; + } + + public String getCheckSumFileName() { + return checkSumFileName; + } + + public void setCheckSumFileName(String checkSumFileName) { + this.checkSumFileName = checkSumFileName; + } + +} diff --git a/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/entity/Htpasswd.java b/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/entity/Htpasswd.java new file mode 100644 index 00000000..9ca93ea8 --- /dev/null +++ b/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/entity/Htpasswd.java @@ -0,0 +1,98 @@ +/*- + * ~~~~~~licensing~~~~~~ + * htpasswd + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.htpasswd.entity; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount; + +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; + +public class Htpasswd { + + private static final Log LOG = LogFactory.getLog(Htpasswd.class); + private String directory; + private String fileName; + private String masterSalt = null; + private final List entries = new ArrayList<>(); + + public Htpasswd() { + } + + public void prepare(List accounts) throws NoSuchAlgorithmException { + if (masterSalt == null || masterSalt.isEmpty()) { + throw new IllegalArgumentException("masterSalt not setted!"); + } + if (accounts != null && accounts.size() > 0) { + entries.clear(); + for (BasicAuthAccount account : accounts) { + entries.add(new HtpasswdEntry( + account.getLogin(), + account.getPasswordHash(), + masterSalt, + account.getEncryptionAlgorithm().getAlgorithmName())); + } + } + } + + public void addString(String login, String passwordHash, String encryptionAlgorithm) throws NoSuchAlgorithmException { + entries.add(new HtpasswdEntry( + login, + passwordHash, + masterSalt, + encryptionAlgorithm)); + } + + public String getDirectory() { + return directory; + } + + public void setDirectory(String directory) { + this.directory = directory; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getMasterSalt() { + return masterSalt; + } + + public void setMasterSalt(String masterSalt) { + this.masterSalt = masterSalt; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + for (HtpasswdEntry entry : entries) { + builder.append(entry.toString()); + } + return builder.toString(); + } + +} diff --git a/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/entity/HtpasswdEntry.java b/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/entity/HtpasswdEntry.java new file mode 100644 index 00000000..37c211fe --- /dev/null +++ b/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/entity/HtpasswdEntry.java @@ -0,0 +1,86 @@ +/*- + * ~~~~~~licensing~~~~~~ + * htpasswd + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.htpasswd.entity; + +import org.apache.commons.codec.binary.Base64; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.field.EncryptionAlgorithm; + +import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; + +public class HtpasswdEntry { + + private static final String APR1_PREFIX = "$apr1$"; + private static final String SHA512_PREFIX = "$6$"; + private static final String SALTED_SHA1_PREFIX = "{SSHA}"; + private static final String PLAIN_PREFIX = "{PLAIN}"; + + private static final String COLON = ":"; + private final String resultLine; + + public HtpasswdEntry(String login, String passwordHash, String salt, String encryptionAlgorithm) throws NoSuchAlgorithmException { + this(login, passwordHash, salt, encryptionAlgorithm, true); + } + + public HtpasswdEntry(String login, String passwordHash, String salt, String encryptionAlgorithm, boolean addLineSeparator) throws NoSuchAlgorithmException { + StringBuilder content = new StringBuilder(); + content.append(login).append(COLON); + + if (EncryptionAlgorithm.MD5.equalsName(encryptionAlgorithm)) { + content + .append(APR1_PREFIX) + .append(salt) + .append("$") + .append(passwordHash); + } else if (EncryptionAlgorithm.SHA1.equalsName(encryptionAlgorithm)) { + content.append(SALTED_SHA1_PREFIX); + byte[] digest = Base64.decodeBase64(passwordHash); + byte[] saltBytes = salt.getBytes(StandardCharsets.UTF_8); + + int l1 = digest.length; + int l2 = saltBytes.length; + byte[] resultArr = new byte[l1 + l2]; + System.arraycopy(digest, 0, resultArr, 0, l1); + System.arraycopy(saltBytes, 0, resultArr, l1, l2); + + content.append(Base64.encodeBase64String(resultArr)); + } else if (EncryptionAlgorithm.SHA512.equalsName(encryptionAlgorithm)) { + content + .append(SHA512_PREFIX) + .append(salt) + .append("$") + .append(passwordHash); + } else if (EncryptionAlgorithm.PLAIN.equalsName(encryptionAlgorithm)) { + content + .append(PLAIN_PREFIX) + .append(passwordHash); + } else { + content.append(passwordHash); + } + content.append(System.lineSeparator()); + + this.resultLine = content.toString(); + } + + @Override + public String toString() { + return resultLine; + } +} diff --git a/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/rest/HtpasswdService.java b/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/rest/HtpasswdService.java new file mode 100644 index 00000000..7ca93a36 --- /dev/null +++ b/system/auth/basic-auth/htpasswd/src/main/java/ru/entaxy/esb/system/auth/basic/htpasswd/rest/HtpasswdService.java @@ -0,0 +1,43 @@ +/*- + * ~~~~~~licensing~~~~~~ + * htpasswd + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.auth.basic.htpasswd.rest; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import java.io.File; + +@Path("/") +public class HtpasswdService { + + @GET + @Produces("application/octet-stream") + public File getFile() { + return null; + } + + @GET + @Path("/checksum") + @Produces("plain/text") + public String getCheckSum() { + return null; + } + +} diff --git a/system/auth/basic-auth/htpasswd/src/main/resources/OSGI-INF/blueprint/htpasswd-context.xml b/system/auth/basic-auth/htpasswd/src/main/resources/OSGI-INF/blueprint/htpasswd-context.xml new file mode 100644 index 00000000..3e753158 --- /dev/null +++ b/system/auth/basic-auth/htpasswd/src/main/resources/OSGI-INF/blueprint/htpasswd-context.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + file:${properties:htpasswd.file.directory}?noop=true&fileName=${properties:htpasswd.file.name}&idempotent=false + + + + + + + + + file:${properties:htpasswd.file.directory}?noop=true&fileName=${properties:htpasswd.file.checksum}&idempotent=false + + + + + diff --git a/system/auth/basic-auth/htpasswd/src/main/resources/script/htpasswd-checker.sh b/system/auth/basic-auth/htpasswd/src/main/resources/script/htpasswd-checker.sh new file mode 100644 index 00000000..97792e98 --- /dev/null +++ b/system/auth/basic-auth/htpasswd/src/main/resources/script/htpasswd-checker.sh @@ -0,0 +1,67 @@ +### +# ~~~~~~licensing~~~~~~ +# htpasswd +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +# !/bin/sh +KARAF_HOST_NAMES=("http://192.168.122.93:9091" "http://192.168.122.94:9091") +HTPASSWD_PATH=/htpasswd +CHECKSUM_PATH=$HTPASSWD_PATH/checksum +HTPASSWD_STORAGE=/etc/nginx/htpasswd +LOGFILE="htpasswd-sync.log" +TIMESTAMP=`date "+%Y-%m-%d %H:%M:%S"` + +currentChecksum=`md5sum $HTPASSWD_STORAGE | awk '{ print $1 }'` + +log(){ + echo "$TIMESTAMP $1" >> $LOGFILE +} + +#download actual checksum from karaf +for actualHost in ${KARAF_HOST_NAMES[*]}; do + wget -O checksum $actualHost$CHECKSUM_PATH + newChecksum=`cat checksum` + rm checksum + if [[ -n $newChecksum ]] + then + log "checksum received from host $actualHost" + break + else + log "host $actualHost did not give checksum data" + fi +done + +log "newChecksum $newChecksum" +log "currentChecksum $currentChecksum" + +if [[ -n $newChecksum ]] && { [[ -z $currentChecksum ]] || [ $currentChecksum != $newChecksum ]; }; +then + wget -O htpasswd $actualHost$HTPASSWD_PATH + sudo mv htpasswd $HTPASSWD_STORAGE + sudo chmod 644 $HTPASSWD_STORAGE + sudo chown root:root $HTPASSWD_STORAGE + sudo systemctl reload nginx + log ">>>>>>>>>>>>>>>>> Htpasswd updated" +else + if [[ -n $newChecksum ]] + then + log ">>>>>>>>>>>>>>>>> Htpasswd is up to date" + else + log ">>>>>>>>>>>>>>>>> Script finished with error: new checksum not received!" + #error action + fi +fi diff --git a/system/auth/basic-auth/pom.xml b/system/auth/basic-auth/pom.xml new file mode 100644 index 00000000..fead85d7 --- /dev/null +++ b/system/auth/basic-auth/pom.xml @@ -0,0 +1,27 @@ + + + + 4.0.0 + + + ru.entaxy.esb.system.auth + system-auth + 1.8.0 + + + ru.entaxy.esb.system.auth.basic + basic-auth + pom + + SYSTEM :: ENTAXY :: AUTH BASIC + SYSTEM :: ENTAXY :: AUTH BASIC + + + basic-auth-api + basic-auth-impl + htpasswd + basic-auth-soap + + + diff --git a/system/auth/pom.xml b/system/auth/pom.xml new file mode 100644 index 00000000..2fc4ca78 --- /dev/null +++ b/system/auth/pom.xml @@ -0,0 +1,24 @@ + + + + 4.0.0 + + + ru.entaxy.esb.system + system-parent + 1.8.0 + + + ru.entaxy.esb.system.auth + system-auth + pom + + SYSTEM :: ENTAXY :: AUTH + SYSTEM :: ENTAXY :: AUTH + + + basic-auth + + + diff --git a/system/commons/LICENSE.txt b/system/commons/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/commons/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/commons/README.md b/system/commons/README.md new file mode 100644 index 00000000..e2a70303 --- /dev/null +++ b/system/commons/README.md @@ -0,0 +1,4 @@ +# SYSTEM :: ENTAXY :: COMMONS + +модуль osgi - общий механизм регистрации профилей систем и групп систем(в виде bundle, реализующий определнный интерфейс, +для системы и для групп систем свой), в котором как минимум есть метод отправить сообщение. \ No newline at end of file diff --git a/system/commons/pom.xml b/system/commons/pom.xml new file mode 100644 index 00000000..3d1d71ad --- /dev/null +++ b/system/commons/pom.xml @@ -0,0 +1,162 @@ + + + + 4.0.0 + + + ru.entaxy.esb.system + system-parent + 1.8.0 + + + ru.entaxy.esb.system.commons + system-commons + bundle + + SYSTEM :: ENTAXY :: COMMONS + SYSTEM :: ENTAXY :: COMMONS + + + + ru.entaxy.esb.system.common.osgi, + ru.entaxy.esb.system.common.osgi.impl, + ru.entaxy.esb.system.common.exception, + ru.entaxy.esb.system.common.aggregation.*, + ru.entaxy.esb.system.common.interceptor, + ru.entaxy.esb.system.common.util, + ru.entaxy.esb.system.common.validator + + + com.google.gson, + org.osgi.service.blueprint.container, + javax.xml.soap*;version="[1.3,2)", + javax.jws.*;version="[2.0.0,3.0.0)", + javax.jws.soap.*;version="[2.0.0,3.0.0)", + javax.xml.ws.*;version="[2.2.0,3.0.0)", + !com.sun.xml.*, + javax.xml.bind;version="[2,3)", + javax.xml.bind.annotation;version="[2,3)", + javax.persistence;version="[2,3)", + org.hibernate, + org.hibernate.cfg, + org.hibernate.service, + org.hibernate.jpa, + org.hibernate.proxy, + org.apache.ignite, + org.apache.ignite.internal.processors.cluster, + org.apache.ignite.internal.processors.marshaller, + org.apache.ignite.internal.util.lang.gridfunc, + org.apache.ignite.spi.discovery.tcp.internal, + org.apache.ignite.transactions, + org.apache.ignite.internal.*, + javassist.util.proxy, + org.apache.commons.lang3, + * + + + + + + com.google.code.gson + gson + ${gson.version} + + + xerces + xercesImpl + ${xerces.version} + + + org.osgi + org.osgi.core + ${osgi.version} + + + commons-collections + commons-collections + + + commons-lang + commons-lang + ${commons-lang.version} + + + org.apache.aries.blueprint + org.apache.aries.blueprint.cm + + + org.osgi + osgi.core + ${osgi.version} + provided + + + org.eclipse.persistence + javax.persistence + ${jpa.version} + + + org.hibernate + hibernate-core + ${hibernate.version} + + + javax.transaction + javax.transaction-api + ${javax.transaction.version} + + + javax.interceptor + javax.interceptor-api + ${javax.interceptor.version} + + + org.apache.cxf + cxf-rt-transports-http + + + org.apache.cxf + cxf-rt-transports-http-jetty + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.apache.ignite + ignite-core + ${ignite.version} + + + + org.apache.ignite + ignite-jcl + ${ignite.version} + + + + com.hazelcast + hazelcast + ${hazelcast.version} + + + org.apache.camel + camel-core + + + org.apache.camel + camel-jms + + + org.apache.camel + camel-sql + + + org.apache.camel + camel-cxf + + + diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/AggregationProcessorBean.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/AggregationProcessorBean.java new file mode 100644 index 00000000..799a0339 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/AggregationProcessorBean.java @@ -0,0 +1,221 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.aggregation; + +import com.hazelcast.core.HazelcastInstance; +import org.apache.camel.*; +import org.apache.camel.model.OptionalIdentifiedDefinition; +import org.apache.camel.model.ToDefinition; +import org.apache.camel.model.language.SimpleExpression; +import org.apache.camel.processor.CamelInternalProcessor; +import org.apache.camel.processor.aggregate.AggregationStrategyBeanAdapter; +import org.apache.camel.reifier.ProcessorReifier; +import org.apache.camel.spi.AggregationRepository; +import org.apache.camel.spi.IdAware; +import org.apache.camel.spi.RouteIdAware; +import org.apache.camel.util.concurrent.SynchronousExecutorService; +import ru.entaxy.esb.system.common.aggregation.hazelcast.DisconnectedMembershipListener; +import ru.entaxy.esb.system.common.aggregation.repo.IgniteAggregationRepository; + +public class AggregationProcessorBean implements Processor { + + private static final String routeName = "aggregation"; + private CamelContext camelContext; + private String aggregationStrategyRef; + private AggregationStrategy aggregationStrategy; + private String aggregationStrategyMethodName; + private String aggregateExpression = "ENTAXY_AcknowledgeMsgID"; + private String toDefinition = "direct-vm:common-revert-no-acknowledge-messages?block=true&timeout=60000"; + private int completionSize = 2; + //10 min in mc + private int completionTimeout = 600_000; + private String aggregationRepositoryRef; + private AggregationRepository aggregationRepository; + + private HazelcastInstance hazelcastInstance; + + private AggregationProcessorWithRestoreTimeout aggregationProcessorWithRestoreTimeout; + + public void initAggregateProcessor() throws Exception { + Route route = camelContext.getRoute(routeName); + + aggregationProcessorWithRestoreTimeout = new AggregationProcessorWithRestoreTimeout(camelContext, + getCamelDestinationProcessor(route), + getCorrelationExpression(route), + createAggregationStrategy(camelContext), + new SynchronousExecutorService(), + false); + settingsAggregationProcessorWithRestoreTimeout(route); + aggregationProcessorWithRestoreTimeout.doStart(); + + addHazelcastMembershipListener(); + } + + private void settingsAggregationProcessorWithRestoreTimeout(Route route) { + AggregationRepository repository = createAggregationRepository(route); + if (repository != null) { + aggregationProcessorWithRestoreTimeout.setAggregationRepository(repository); + } + aggregationProcessorWithRestoreTimeout.setCompletionSize(completionSize); + aggregationProcessorWithRestoreTimeout.setCompletionTimeout(completionTimeout); + } + + private void addHazelcastMembershipListener() { + hazelcastInstance.getCluster().addMembershipListener(new DisconnectedMembershipListener(aggregationProcessorWithRestoreTimeout, camelContext)); + } + + private Expression getCorrelationExpression(Route route) { + return new SimpleExpression(aggregateExpression); + } + + private CamelInternalProcessor getCamelDestinationProcessor(Route route) throws Exception { + Processor childProcessor = createChildProcessor(route, true); + + // wrap the aggregate route in a unit of work processor + CamelInternalProcessor internal = new CamelInternalProcessor(camelContext, childProcessor); + internal.addAdvice(new CamelInternalProcessor.UnitOfWorkProcessorAdvice(route, camelContext)); + return internal; + } + + private Processor createChildProcessor(Route route, boolean mandatory) throws Exception { + Processor children = null; + ToDefinition definition = new ToDefinition(toDefinition); + // at first use custom factory + if (camelContext.adapt(ExtendedCamelContext.class).getProcessorFactory() != null) { + children = camelContext.adapt(ExtendedCamelContext.class).getProcessorFactory().createChildProcessor(route, + definition, mandatory); + } + // fallback to default implementation if factory did not create the + // child + if (children == null) { + children = createOutputsProcessor(route, definition); + } + + if (children == null && mandatory) { + throw new IllegalArgumentException("Definition has no children on " + definition); + } + return children; + } + + protected Processor createOutputsProcessor(Route route, ToDefinition definition) throws Exception { + Processor processor = ProcessorReifier.reifier(route, definition).createProcessor(); + + // inject id + if (processor instanceof IdAware) { + String id = getId(definition); + ((IdAware) processor).setId(id); + } + if (processor instanceof RouteIdAware) { + ((RouteIdAware) processor).setRouteId(route.getRouteId()); + } + + return processor; + } + + protected String getId(OptionalIdentifiedDefinition def) { + return def.idOrCreate(camelContext.adapt(ExtendedCamelContext.class).getNodeIdFactory()); + } + + + private AggregationRepository createAggregationRepository(Route route) { + if (aggregationRepository == null && aggregationRepositoryRef != null) { + aggregationRepository = (AggregationRepository) route.getCamelContext().getRegistry().lookupByName(aggregationRepositoryRef); + } + return aggregationRepository; + } + + private AggregationStrategy createAggregationStrategy(CamelContext camelContext) { + if (aggregationStrategy == null && aggregationStrategyRef != null) { + Object aggStrategy = camelContext.getRegistry().lookupByNameAndType(aggregationStrategyRef, Object.class); + if (aggStrategy instanceof AggregationStrategy) { + aggregationStrategy = (AggregationStrategy) aggStrategy; + } else if (aggStrategy != null) { + aggregationStrategy = new AggregationStrategyBeanAdapter(aggStrategy, aggregationStrategyMethodName); + } else { + throw new IllegalArgumentException("Cannot find AggregationStrategy in Registry with name: " + aggregationStrategyRef); + } + } + + if (aggregationStrategy == null) { + throw new IllegalArgumentException("AggregationStrategy or AggregationStrategyRef must be set on " + this); + } + + if (aggregationStrategy instanceof CamelContextAware) { + ((CamelContextAware) aggregationStrategy).setCamelContext(camelContext); + } + + return aggregationStrategy; + } + + @Override + public void process(Exchange exchange) throws Exception { + aggregationProcessorWithRestoreTimeout.process(exchange); + } + + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + public void setAggregationStrategyRef(String aggregationStrategyRef) { + this.aggregationStrategyRef = aggregationStrategyRef; + } + + public void setAggregationStrategy(AggregationStrategy aggregationStrategy) { + this.aggregationStrategy = aggregationStrategy; + } + + public void setAggregationStrategyMethodName(String aggregationStrategyMethodName) { + this.aggregationStrategyMethodName = aggregationStrategyMethodName; + } + + public void setAggregateExpression(String aggregateExpression) { + this.aggregateExpression = aggregateExpression; + } + + public void setToDefinition(String toDefinition) { + this.toDefinition = toDefinition; + } + + public void setCompletionSize(int completionSize) { + this.completionSize = completionSize; + } + + public void setCompletionTimeout(int completionTimeout) { + this.completionTimeout = completionTimeout; + } + + public void setAggregationRepositoryRef(String aggregationRepositoryRef) { + this.aggregationRepositoryRef = aggregationRepositoryRef; + } + + public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { + this.hazelcastInstance = hazelcastInstance; + } + + public void init() throws Exception { + camelContext.addStartupListener((a, b) -> initAggregateProcessor()); + } + + public void doStop() throws Exception { + aggregationProcessorWithRestoreTimeout.doStop(); + if (aggregationRepository instanceof IgniteAggregationRepository) + ((IgniteAggregationRepository) aggregationRepository).doStop(); + } +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/AggregationProcessorWithRestoreTimeout.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/AggregationProcessorWithRestoreTimeout.java new file mode 100644 index 00000000..cedfe608 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/AggregationProcessorWithRestoreTimeout.java @@ -0,0 +1,1947 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.aggregation; + +import org.apache.camel.*; +import org.apache.camel.component.jms.JmsMessage; +import org.apache.camel.processor.aggregate.*; +import org.apache.camel.spi.*; +import org.apache.camel.support.*; +import org.apache.camel.support.service.ServiceHelper; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.StopWatch; +import org.apache.camel.util.TimeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.jms.JMSException; +import javax.jms.Session; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * An implementation of the Aggregator pattern where a batch of + * messages are processed (up to a maximum amount or until some timeout is reached) and messages for the same + * correlation key are combined together using some kind of {@link AggregationStrategy} (by default the latest message + * is used) to compress many message exchanges into a smaller number of exchanges. + *

+ * A good example of this is stock market data; you may be receiving 30,000 messages/second and you may want to throttle + * it right down so that multiple messages for the same stock are combined (or just the latest message is used and older + * prices are discarded). Another idea is to combine line item messages together into a single invoice message. + */ + +// Class clazz = getCamelContext().getClassResolver().resolveMandatoryClass( +// "org.apache.camel.component.cxf.jaxrs.blueprint.CxfRsBlueprintEndpointFactoryBean", +// CxfRsEndpointFactoryBean.class); + +public class AggregationProcessorWithRestoreTimeout extends AggregateProcessor implements AsyncProcessor, + Navigate, Traceable, ShutdownPrepared, ShutdownAware, IdAware { + + public static final String AGGREGATE_TIMEOUT_CHECKER = "AggregateTimeoutChecker"; + public static final String AGGREGATE_OPTIMISTIC_LOCKING_EXECUTOR = "AggregateOptimisticLockingExecutor"; + public static final String AGGREGATION_COMPLETED_NODE_TIME = "AggregationCompletedNodeTime"; + public static final int MAX_TIME_WORKING_WITH_COMPLETED_MESSAGE = 3000; + + public static final String COMPLETED_BY_SIZE = "size"; + public static final String COMPLETED_BY_PREDICATE = "predicate"; + public static final String COMPLETED_BY_CONSUMER = "consumer"; + public static final String COMPLETED_BY_STRATEGY = "strategy"; + public static final String COMPLETED_BY_INTERVAL = "interval"; + public static final String COMPLETED_BY_TIMEOUT = "timeout"; + public static final String COMPLETED_BY_FORCE = "force"; + + private static final Logger LOG = LoggerFactory.getLogger(AggregateProcessor.class); + + private volatile Lock lock; + private final AtomicBoolean aggregateRepositoryWarned = new AtomicBoolean(); + private final CamelContext camelContext; + private final ReactiveExecutor reactiveExecutor; + private final AsyncProcessor processor; + private String id; + private String routeId; + private AggregationStrategy aggregationStrategy; + private boolean preCompletion; + private Expression correlationExpression; + private AggregateController aggregateController; + private final ExecutorService executorService; + private final boolean shutdownExecutorService; + private OptimisticLockRetryPolicy optimisticLockRetryPolicy = new OptimisticLockRetryPolicy(); + private ScheduledExecutorService timeoutCheckerExecutorService; + private boolean shutdownTimeoutCheckerExecutorService; + private ScheduledExecutorService optimisticLockingExecutorService; + private boolean shutdownOptimisticLockingExecutorService; + private ScheduledExecutorService recoverService; + // store correlation key -> exchange id in timeout map + private TimeoutMap timeoutMap; + private ExceptionHandler exceptionHandler; + private AggregationRepository aggregationRepository; + private Map closedCorrelationKeys; + private final Set batchConsumerCorrelationKeys = new ConcurrentSkipListSet<>(); + private final Set inProgressCompleteExchanges = Collections.newSetFromMap(new ConcurrentHashMap<>()); + private final Map redeliveryState = new ConcurrentHashMap<>(); + + private final AggregateProcessorStatistics statistics = new Statistics(); + private final AtomicLong totalIn = new AtomicLong(); + private final AtomicLong totalCompleted = new AtomicLong(); + private final AtomicLong completedBySize = new AtomicLong(); + private final AtomicLong completedByStrategy = new AtomicLong(); + private final AtomicLong completedByInterval = new AtomicLong(); + private final AtomicLong completedByTimeout = new AtomicLong(); + private final AtomicLong completedByPredicate = new AtomicLong(); + private final AtomicLong completedByBatchConsumer = new AtomicLong(); + private final AtomicLong completedByForce = new AtomicLong(); + private final AtomicLong discarded = new AtomicLong(); + + // keep booking about redelivery + private class RedeliveryData { + int redeliveryCounter; + } + + private class Statistics implements AggregateProcessorStatistics { + + private boolean statisticsEnabled = true; + + @Override + public long getTotalIn() { + return totalIn.get(); + } + + @Override + public long getTotalCompleted() { + return totalCompleted.get(); + } + + @Override + public long getCompletedBySize() { + return completedBySize.get(); + } + + @Override + public long getCompletedByStrategy() { + return completedByStrategy.get(); + } + + @Override + public long getCompletedByInterval() { + return completedByInterval.get(); + } + + @Override + public long getCompletedByTimeout() { + return completedByTimeout.get(); + } + + @Override + public long getCompletedByPredicate() { + return completedByPredicate.get(); + } + + @Override + public long getCompletedByBatchConsumer() { + return completedByBatchConsumer.get(); + } + + @Override + public long getCompletedByForce() { + return completedByForce.get(); + } + + @Override + public long getDiscarded() { + return discarded.get(); + } + + @Override + public void reset() { + totalIn.set(0); + totalCompleted.set(0); + completedBySize.set(0); + completedByStrategy.set(0); + completedByTimeout.set(0); + completedByPredicate.set(0); + completedByBatchConsumer.set(0); + completedByForce.set(0); + discarded.set(0); + } + + @Override + public boolean isStatisticsEnabled() { + return statisticsEnabled; + } + + @Override + public void setStatisticsEnabled(boolean statisticsEnabled) { + this.statisticsEnabled = statisticsEnabled; + } + } + + // options + private boolean ignoreInvalidCorrelationKeys; + private Integer closeCorrelationKeyOnCompletion; + private boolean parallelProcessing; + private boolean optimisticLocking; + + // different ways to have completion triggered + private boolean eagerCheckCompletion; + private Predicate completionPredicate; + private long completionTimeout; + private Expression completionTimeoutExpression; + private long completionInterval; + private int completionSize; + private Expression completionSizeExpression; + private boolean completionFromBatchConsumer; + private boolean completionOnNewCorrelationGroup; + private final AtomicInteger batchConsumerCounter = new AtomicInteger(); + private boolean discardOnCompletionTimeout; + private boolean discardOnAggregationFailure; + private boolean forceCompletionOnStop; + private boolean completeAllOnStop; + private long completionTimeoutCheckerInterval = 1000; + + private ProducerTemplate deadLetterProducerTemplate; + + public AggregationProcessorWithRestoreTimeout(CamelContext camelContext, AsyncProcessor processor, + Expression correlationExpression, AggregationStrategy aggregationStrategy, + ExecutorService executorService, boolean shutdownExecutorService) { + super(camelContext, processor, correlationExpression, aggregationStrategy, executorService, shutdownExecutorService); + ObjectHelper.notNull(camelContext, "camelContext"); + ObjectHelper.notNull(processor, "processor"); + ObjectHelper.notNull(correlationExpression, "correlationExpression"); + ObjectHelper.notNull(aggregationStrategy, "aggregationStrategy"); + ObjectHelper.notNull(executorService, "executorService"); + this.camelContext = camelContext; + this.reactiveExecutor = camelContext.adapt(ExtendedCamelContext.class).getReactiveExecutor(); + this.processor = processor; + this.correlationExpression = correlationExpression; + this.aggregationStrategy = aggregationStrategy; + this.executorService = executorService; + this.shutdownExecutorService = shutdownExecutorService; + this.exceptionHandler = new LoggingExceptionHandler(camelContext, getClass()); + } + + @Override + public String toString() { + return id; + } + + @Override + public String getTraceLabel() { + return "aggregate[" + correlationExpression + "]"; + } + + @Override + public List next() { + if (!hasNext()) { + return null; + } + List answer = new ArrayList<>(1); + answer.add(processor); + return answer; + } + + @Override + public boolean hasNext() { + return processor != null; + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + public String getRouteId() { + return routeId; + } + + public void setRouteId(String routeId) { + this.routeId = routeId; + } + + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + try { + return doProcess(exchange, callback); + } catch (Throwable e) { + exchange.setException(e); + callback.done(true); + return true; + } + } + + protected boolean doProcess(Exchange exchange, AsyncCallback callback) throws Exception { + if (getStatistics().isStatisticsEnabled()) { + totalIn.incrementAndGet(); + } + + //check for the special header to force completion of all groups (and ignore the exchange otherwise) + if (isCompleteAllGroups(exchange)) { + removeFlagCompleteAllGroups(exchange); + forceCompletionOfAllGroups(); + callback.done(true); + return true; + } + + // compute correlation expression + String key = correlationExpression.evaluate(exchange, String.class); + if (ObjectHelper.isEmpty(key)) { + // we have a bad correlation key + if (isIgnoreInvalidCorrelationKeys()) { + LOG.debug("Invalid correlation key. This Exchange will be ignored: {}", exchange); + } else { + exchange.setException(new CamelExchangeException("Invalid correlation key", exchange)); + } + callback.done(true); + return true; + } + + // is the correlation key closed? + if (closedCorrelationKeys != null && closedCorrelationKeys.containsKey(key)) { + exchange.setException(new ClosedCorrelationKeyException(key, exchange)); + callback.done(true); + return true; + } + + if (optimisticLocking) { + return doInOptimisticLock(exchange, key, callback, 0, true); + } else { + return doProcess(exchange, key, callback, true); + } + } + + protected boolean doInOptimisticLock(Exchange exchange, String key, AsyncCallback callback, int attempt, boolean sync) { + while (true) { + attempt++; + try { + return doProcess(exchange, key, callback, sync); + } catch (OptimisticLockingAggregationRepository.OptimisticLockingException e) { + LOG.trace( + "On attempt {} OptimisticLockingAggregationRepository: {} threw OptimisticLockingException while trying to aggregate exchange: {}", + attempt, aggregationRepository, exchange, e); + if (optimisticLockRetryPolicy.shouldRetry(attempt)) { + long delay = optimisticLockRetryPolicy.getDelay(attempt); + if (delay > 0) { + int nextAttempt = attempt; + getOptimisticLockingExecutorService().schedule( + () -> doInOptimisticLock(exchange, key, callback, nextAttempt, false), delay, + TimeUnit.MILLISECONDS); + return false; + } + } else { + exchange.setException(new CamelExchangeException( + "Exhausted optimistic locking retry attempts, tried " + attempt + " times", exchange, + new OptimisticLockingAggregationRepository.OptimisticLockingException())); + callback.done(sync); + return sync; + } + } + } + } + + protected boolean doProcess(Exchange exchange, String key, AsyncCallback callback, boolean sync) { + // copy exchange, and do not share the unit of work + // the aggregated output runs in another unit of work + Exchange copy = ExchangeHelper.createCorrelatedCopy(exchange, false); + + // remove the complete all groups flags as it should not be on the copy + removeFlagCompleteCurrentGroup(copy); + removeFlagCompleteAllGroups(copy); + removeFlagCompleteAllGroupsInclusive(copy); + + List aggregated = null; + lock.lock(); + try { + aggregated = doAggregation(key, copy); + } catch (CamelExchangeException e) { + exchange.setException(e); + } finally { + lock.unlock(); + } + + // we are completed so do that work outside the lock + if (aggregated != null) { + // we are completed so submit to completion + aggregated.forEach(agg -> { + onSubmitCompletion(key, agg); + aggregationRepository.confirm(camelContext, key); + }); + } + + // check for the special header to force completion of all groups (inclusive of the message) + if (isCompleteAllGroupsInclusive(exchange)) { + removeFlagCompleteAllGroupsInclusive(exchange); + forceCompletionOfAllGroups(); + } + + callback.done(sync); + return sync; + } + + private Object removeFlagCompleteCurrentGroup(Exchange exchange) { + //before everywhere : return exchange.getIn().removeHeader(Exchange.AGGREGATION_COMPLETE_CURRENT_GROUP); + return exchange.removeProperty(Exchange.AGGREGATION_COMPLETE_CURRENT_GROUP); + } + + private Boolean isCompleteCurrentGroup(Exchange exchange) { + return exchange.getProperty(Exchange.AGGREGATION_COMPLETE_CURRENT_GROUP, false, boolean.class); + } + + private Object removeFlagCompleteAllGroups(Exchange exchange) { + Object removedHeader = exchange.getIn().removeHeader(Exchange.AGGREGATION_COMPLETE_ALL_GROUPS); + Object removedProp = exchange.removeProperty(Exchange.AGGREGATION_COMPLETE_ALL_GROUPS); + return removedHeader == null ? removedProp : removedHeader; + } + + private Boolean isCompleteAllGroups(Exchange exchange) { + boolean retVal = exchange.getIn().getHeader(Exchange.AGGREGATION_COMPLETE_ALL_GROUPS, false, boolean.class); + if (!retVal) { + // according to doc it is a property but it is sometimes read as header + // some test don't fail because they use the header expression which contains a fallback to properties + retVal = exchange.getProperty(Exchange.AGGREGATION_COMPLETE_ALL_GROUPS, false, boolean.class); + } + return retVal; + } + + private Object removeFlagCompleteAllGroupsInclusive(Exchange exchange) { + return exchange.getIn().removeHeader(Exchange.AGGREGATION_COMPLETE_ALL_GROUPS_INCLUSIVE); + } + + private Boolean isCompleteAllGroupsInclusive(Exchange exchange) { + return exchange.getIn().getHeader(Exchange.AGGREGATION_COMPLETE_ALL_GROUPS_INCLUSIVE, false, boolean.class); + } + + /** + * Aggregates the exchange with the given correlation key + *

+ * This method must be run synchronized as we cannot aggregate the same correlation key in parallel. + *

+ * The returned {@link Exchange} should be send downstream using the + * method which sends out the aggregated and + * completed {@link Exchange}. + * + * @param key the correlation key + * @param newExchange the exchange + * @return the aggregated exchange(s) which is complete, or null if + * not yet complete + * @throws CamelExchangeException is thrown if error aggregating + */ + private List doAggregation(String key, Exchange newExchange) throws CamelExchangeException { + LOG.trace("onAggregation +++ start +++ with correlation key: {}", key); + + List list = new ArrayList<>(); + String complete = null; + + Exchange answer; + Exchange originalExchange = aggregationRepository.get(newExchange.getContext(), key); + Exchange oldExchange = originalExchange; + + Integer size = 1; + if (oldExchange != null) { + // hack to support legacy AggregationStrategy's that modify and return the oldExchange, these will not + // working when using an identify based approach for optimistic locking like the MemoryAggregationRepository. + if (optimisticLocking && aggregationRepository instanceof MemoryAggregationRepository) { + oldExchange = originalExchange.copy(); + } + size = oldExchange.getProperty(Exchange.AGGREGATED_SIZE, 0, Integer.class); + size++; + } + + // prepare the exchanges for aggregation + ExchangeHelper.prepareAggregation(oldExchange, newExchange); + + // check if we are pre complete + if (preCompletion) { + try { + // put the current aggregated size on the exchange so its avail during completion check + newExchange.setProperty(Exchange.AGGREGATED_SIZE, size); + complete = isPreCompleted(key, oldExchange, newExchange); + // make sure to track timeouts if not complete + if (complete == null) { + trackTimeout(key, newExchange); + } + // remove it afterwards + newExchange.removeProperty(Exchange.AGGREGATED_SIZE); + } catch (Throwable e) { + // must catch any exception from aggregation + throw new CamelExchangeException("Error occurred during preComplete", newExchange, e); + } + } else if (isEagerCheckCompletion()) { + // put the current aggregated size on the exchange so its avail during completion check + newExchange.setProperty(Exchange.AGGREGATED_SIZE, size); + complete = isCompleted(key, newExchange); + // make sure to track timeouts if not complete + if (complete == null) { + trackTimeout(key, newExchange); + } + // remove it afterwards + newExchange.removeProperty(Exchange.AGGREGATED_SIZE); + } + + if (preCompletion && complete != null) { + // need to pre complete the current group before we aggregate + doAggregationComplete(complete, list, key, originalExchange, oldExchange, false); + // as we complete the current group eager, we should indicate the new group is not complete + complete = null; + // and clear old/original exchange as we start on a new group + oldExchange = null; + originalExchange = null; + // and reset the size to 1 + size = 1; + // make sure to track timeout as we just restart the correlation group when we are in pre completion mode + trackTimeout(key, newExchange); + } + + // aggregate the exchanges + boolean aggregateFailed = false; + try { + answer = onAggregation(oldExchange, newExchange); + } catch (Throwable e) { + aggregateFailed = true; + if (isDiscardOnAggregationFailure()) { + // discard due failure in aggregation strategy + LOG.debug( + "Aggregation for correlation key {} discarding aggregated exchange: {} due to failure in AggregationStrategy caused by: {}", + key, oldExchange, e.getMessage()); + complete = COMPLETED_BY_STRATEGY; + answer = oldExchange; + if (answer == null) { + // first message in group failed during aggregation and we should just discard this + return null; + } + } else { + // must catch any exception from aggregation + throw new CamelExchangeException("Error occurred during aggregation", newExchange, e); + } + } + if (answer == null) { + throw new CamelExchangeException( + "AggregationStrategy " + aggregationStrategy + " returned null which is not allowed", newExchange); + } + + // check for the special exchange property to force completion of all groups + if (isCompleteAllGroups(answer)) { + removeFlagCompleteAllGroups(answer); + forceCompletionOfAllGroups(); + } else if (isCompletionOnNewCorrelationGroup() && originalExchange == null) { + // its a new group so force complete of all existing groups + forceCompletionOfAllGroups(); + } + + // special for some repository implementations + if (aggregationRepository instanceof RecoverableAggregationRepository) { + boolean valid = oldExchange == null || answer.getExchangeId().equals(oldExchange.getExchangeId()); + if (!valid && aggregateRepositoryWarned.compareAndSet(false, true)) { + LOG.warn( + "AggregationStrategy should return the oldExchange instance instead of the newExchange whenever possible" + + " as otherwise this can lead to unexpected behavior with some RecoverableAggregationRepository implementations"); + } + } + + // update the aggregated size + answer.setProperty(Exchange.AGGREGATED_SIZE, size); + + // maybe we should check completion after the aggregation + if (!preCompletion && !isEagerCheckCompletion()) { + complete = isCompleted(key, answer); + // make sure to track timeouts if not complete + if (complete == null) { + trackTimeout(key, newExchange); + } + } + + if (!aggregateFailed && complete == null) { + // only need to update aggregation repository if we are not complete + doAggregationRepositoryAdd(newExchange.getContext(), key, originalExchange, answer); + } else { + // if we are complete then add the answer to the list + doAggregationComplete(complete, list, key, originalExchange, answer, aggregateFailed); + } + + LOG.trace("onAggregation +++ end +++ with correlation key: {}", key); + return list; + } + + protected void doAggregationComplete( + String complete, List list, String key, + Exchange originalExchange, Exchange answer, boolean aggregateFailed) { + if (COMPLETED_BY_CONSUMER.equals(complete)) { + for (String batchKey : batchConsumerCorrelationKeys) { + Exchange batchAnswer; + if (batchKey.equals(key)) { + // skip the current aggregated key as we have already aggregated it and have the answer + batchAnswer = answer; + } else { + batchAnswer = aggregationRepository.get(camelContext, batchKey); + } + + if (batchAnswer != null) { + batchAnswer.setProperty(Exchange.AGGREGATED_COMPLETED_BY, complete); + onCompletion(batchKey, originalExchange, batchAnswer, false, aggregateFailed); + list.add(batchAnswer); + } + } + batchConsumerCorrelationKeys.clear(); + // we have already submitted to completion, so answer should be null + answer = null; + } else if (answer != null) { + // we are complete for this exchange + answer.setProperty(Exchange.AGGREGATED_COMPLETED_BY, complete); + answer = onCompletion(key, originalExchange, answer, false, aggregateFailed); + } + + if (answer != null) { + list.add(answer); + } + } +// TODO bad +// protected void doAggregationRepositoryAdd( +// CamelContext camelContext, String key, Exchange oldExchange, Exchange newExchange) { +// LOG.trace("In progress aggregated oldExchange: {}, newExchange: {} with correlation key: {}", oldExchange, newExchange, +// key); +// if (optimisticLocking) { +// try { +// ((OptimisticLockingAggregationRepository) aggregationRepository).add(camelContext, key, oldExchange, +// newExchange); +// } catch (OptimisticLockingAggregationRepository.OptimisticLockingException e) { +// onOptimisticLockingFailure(oldExchange, newExchange); +// throw e; +// } +// } else { +// aggregationRepository.add(camelContext, key, newExchange); +// } +// } + + protected void doAggregationRepositoryAdd(CamelContext camelContext, String key, Exchange oldExchange, Exchange newExchange) { + LOG.trace("In progress aggregated oldExchange: {}, newExchange: {} with correlation key: {}", oldExchange, newExchange, key); + if (optimisticLocking) { + try { + ((OptimisticLockingAggregationRepository) aggregationRepository).add(camelContext, key, oldExchange, newExchange); + + // обработка CLIENT_ACKNOWLEDGE для обработки внезапных отсановок + JmsMessage jms = newExchange.getIn(JmsMessage.class); + Session session = jms.getJmsSession(); + if (session != null && Session.CLIENT_ACKNOWLEDGE == session.getAcknowledgeMode()) { + jms.getJmsMessage().acknowledge(); + } + } catch (OptimisticLockingAggregationRepository.OptimisticLockingException e) { + onOptimisticLockingFailure(oldExchange, newExchange); + throw e; + } catch (JMSException e) { + LOG.error("Error in CLIENT_ACKNOWLEDGE.", e); + } + } else { + aggregationRepository.add(camelContext, key, newExchange); + } + } + + protected void onOptimisticLockingFailure(Exchange oldExchange, Exchange newExchange) { + aggregationStrategy.onOptimisticLockFailure(oldExchange, newExchange); + } + + /** + * Tests whether the given exchanges is pre-complete or not + * + * @param key the correlation key + * @param oldExchange the existing exchange + * @param newExchange the incoming exchange + * @return null if not pre-completed, otherwise a String with the type that triggered the + * pre-completion + */ + protected String isPreCompleted(String key, Exchange oldExchange, Exchange newExchange) { + return aggregationStrategy.preComplete(oldExchange, newExchange) ? "strategy" : null; + } + + /** + * Tests whether the given exchange is complete or not + * + * @param key the correlation key + * @param exchange the incoming exchange + * @return null if not completed, otherwise a String with the type that triggered the completion + */ + protected String isCompleted(String key, Exchange exchange) { + // batch consumer completion must always run first + if (isCompletionFromBatchConsumer()) { + batchConsumerCorrelationKeys.add(key); + batchConsumerCounter.incrementAndGet(); + int size = exchange.getProperty(Exchange.BATCH_SIZE, 0, Integer.class); + if (size > 0 && batchConsumerCounter.intValue() >= size) { + // batch consumer is complete then reset the counter + batchConsumerCounter.set(0); + return COMPLETED_BY_CONSUMER; + } + } + + if (isCompleteCurrentGroup(exchange)) { + removeFlagCompleteCurrentGroup(exchange); + return COMPLETED_BY_STRATEGY; + } + + if (getCompletionPredicate() != null) { + boolean answer = getCompletionPredicate().matches(exchange); + if (answer) { + return COMPLETED_BY_PREDICATE; + } + } + + boolean sizeChecked = false; + if (getCompletionSizeExpression() != null) { + Integer value = getCompletionSizeExpression().evaluate(exchange, Integer.class); + if (value != null && value > 0) { + // mark as already checked size as expression takes precedence over static configured + sizeChecked = true; + int size = exchange.getProperty(Exchange.AGGREGATED_SIZE, 1, Integer.class); + if (size >= value) { + return COMPLETED_BY_SIZE; + } + } + } + if (!sizeChecked && getCompletionSize() > 0) { + int size = exchange.getProperty(Exchange.AGGREGATED_SIZE, 1, Integer.class); + if (size >= getCompletionSize()) { + return COMPLETED_BY_SIZE; + } + } + + // not complete + return null; + } + + protected void trackTimeout(String key, Exchange exchange) { + // timeout can be either evaluated based on an expression or from a fixed value + // expression takes precedence + boolean timeoutSet = false; + if (getCompletionTimeoutExpression() != null) { + Long value = getCompletionTimeoutExpression().evaluate(exchange, Long.class); + if (value != null && value > 0) { + if (LOG.isTraceEnabled()) { + LOG.trace("Updating correlation key {} to timeout after {} ms. as exchange received: {}", + key, value, exchange); + } + addExchangeToTimeoutMap(key, exchange, value); + timeoutSet = true; + } + } + if (!timeoutSet && getCompletionTimeout() > 0) { + // timeout is used so use the timeout map to keep an eye on this + if (LOG.isTraceEnabled()) { + LOG.trace("Updating correlation key {} to timeout after {} ms. as exchange received: {}", + key, getCompletionTimeout(), exchange); + } + addExchangeToTimeoutMap(key, exchange, getCompletionTimeout()); + } + } + + protected Exchange onAggregation(Exchange oldExchange, Exchange newExchange) { + return aggregationStrategy.aggregate(oldExchange, newExchange); + } + + protected Exchange onCompletion( + final String key, final Exchange original, final Exchange aggregated, boolean fromTimeout, + boolean aggregateFailed) { + // store the correlation key as property before we remove so the repository has that information + if (original != null) { + original.setProperty(Exchange.AGGREGATED_CORRELATION_KEY, key); + } + aggregated.setProperty(Exchange.AGGREGATED_CORRELATION_KEY, key); + + // only remove if we have previous added (as we could potentially complete with only 1 exchange) + // (if we have previous added then we have that as the original exchange) + if (original != null) { + // remove from repository as its completed, we do this first as to trigger any OptimisticLockingException's + original.getMessage().setHeader(AGGREGATION_COMPLETED_NODE_TIME, System.currentTimeMillis()); + + aggregationRepository.remove(aggregated.getContext(), key, original); + } + + if (!fromTimeout && timeoutMap != null) { + // cleanup timeout map if it was a incoming exchange which triggered the timeout (and not the timeout checker) + LOG.trace("Removing correlation key {} from timeout", key); + timeoutMap.remove(key); + } + + // this key has been closed so add it to the closed map + if (closedCorrelationKeys != null) { + closedCorrelationKeys.put(key, key); + } + + if (fromTimeout) { + // invoke timeout to allow any custom processing before discarding the exchange + long timeout = getCompletionTimeout() > 0 ? getCompletionTimeout() : -1; + aggregationStrategy.timeout(aggregated, -1, -1, timeout); + } + + Exchange answer; + if (fromTimeout && isDiscardOnCompletionTimeout()) { + // this exchange is discarded + discarded.incrementAndGet(); + // discard due timeout + LOG.debug("Aggregation for correlation key {} discarding aggregated exchange: {}", key, aggregated); + // must confirm the discarded exchange + // перенесено на подтерждение, после отправки в очередь, т к при остановке карафа сообщения из бд забирались, + // а в маршрут не успевали кластся(в результате чего просиходили потери сообщений) +// aggregationRepository.confirm(aggregated.getContext(), aggregated.getExchangeId()); + // and remove redelivery state as well + redeliveryState.remove(aggregated.getExchangeId()); + // the completion was from timeout and we should just discard it + answer = null; + } else if (aggregateFailed && isDiscardOnAggregationFailure()) { + // this exchange is discarded + discarded.incrementAndGet(); + // discard due aggregation failed (or by force) + LOG.debug("Aggregation for correlation key {} discarding aggregated exchange: {}", key, aggregated); + // must confirm the discarded exchange + // перенесено на подтерждение, после отправки в очередь, т к при остановке карафа сообщения из бд забирались, + // а в маршрут не успевали кластся(в результате чего просиходили потери сообщений) +// aggregationRepository.confirm(aggregated.getContext(), aggregated.getExchangeId()); + // and remove redelivery state as well + redeliveryState.remove(aggregated.getExchangeId()); + // the completion was failed during aggregation and we should just discard it + answer = null; + } else { + // the aggregated exchange should be published (sent out) + answer = aggregated; + } + + return answer; + } + + private void onSubmitCompletion(final String key, final Exchange exchange) { + LOG.debug("Aggregation complete for correlation key {} sending aggregated exchange: {}", key, exchange); + + // add this as in progress before we submit the task + inProgressCompleteExchanges.add(exchange.getExchangeId()); + + // invoke the on completion callback + aggregationStrategy.onCompletion(exchange); + + if (getStatistics().isStatisticsEnabled()) { + totalCompleted.incrementAndGet(); + + String completedBy = exchange.getProperty(Exchange.AGGREGATED_COMPLETED_BY, String.class); + switch (completedBy) { + case COMPLETED_BY_INTERVAL: + completedByInterval.incrementAndGet(); + break; + case COMPLETED_BY_TIMEOUT: + completedByTimeout.incrementAndGet(); + break; + case COMPLETED_BY_FORCE: + completedByForce.incrementAndGet(); + break; + case COMPLETED_BY_CONSUMER: + completedByBatchConsumer.incrementAndGet(); + break; + case COMPLETED_BY_PREDICATE: + completedByPredicate.incrementAndGet(); + break; + case COMPLETED_BY_SIZE: + completedBySize.incrementAndGet(); + break; + case COMPLETED_BY_STRATEGY: + completedByStrategy.incrementAndGet(); + break; + default: + LOG.error("Invalid value of {} property: {}", Exchange.AGGREGATED_COMPLETED_BY, exchange); + break; + } + } + + LOG.debug("Processing aggregated exchange: {}", exchange); + + // add on completion task so we remember to update the inProgressCompleteExchanges + exchange.adapt(ExtendedExchange.class).addOnCompletion(new AggregateOnCompletion(exchange.getExchangeId())); + + // send this exchange + // the call to schedule is needed to ensure in-order processing of the aggregates + executorService.execute(() -> reactiveExecutor.schedule(() -> processor.process(exchange, done -> { + // log exception if there was a problem + if (exchange.getException() != null) { + // if there was an exception then let the exception handler handle it + //восстаналиваю сообщение, т к processor.process(exchange); происходит в ассинхронном режиме и в момент, + // когда маршрут уже выключен, а бин в процессе остановки, и подтверждение приходит + exchange.setException(null); + aggregationRepository.add(camelContext, key, exchange); + + getExceptionHandler().handleException("Error processing aggregated exchange", exchange, + exchange.getException()); + } else { + LOG.trace("Processing aggregated exchange: {} complete.", exchange); + } + }))); + } + + /** + * Restores the timeout map with timeout values from the aggregation repository. + *

+ * This is needed in case the aggregator has been stopped and started again (for example a server restart). Then the + * existing exchanges from the {@link AggregationRepository} must have their timeout conditions restored. + */ + public void restoreTimeoutMapFromAggregationRepository() throws Exception { + // grab the timeout value for each partly aggregated exchange + Set keys = aggregationRepository.getKeys(); + if (keys == null || keys.isEmpty()) { + return; + } + + StopWatch watch = new StopWatch(); + LOG.trace("Starting restoring CompletionTimeout for {} existing exchanges from the aggregation repository...", + keys.size()); + + for (String key : keys) { + Exchange exchange = aggregationRepository.get(camelContext, key); + // grab the timeout value + long timeout = exchange.hasProperties() ? exchange.getProperty(Exchange.AGGREGATED_TIMEOUT, 0, long.class) : 0; + if (timeout > 0) { + if (LOG.isTraceEnabled()) { + LOG.trace("Restoring CompletionTimeout for exchangeId: {} with timeout: {} millis.", + exchange.getExchangeId(), timeout); + } + addExchangeToTimeoutMap(key, exchange, timeout); + } + } + + // log duration of this task so end user can see how long it takes to pre-check this upon starting + LOG.info("Restored {} CompletionTimeout conditions in the AggregationTimeoutChecker in {}", + timeoutMap.size(), TimeUtils.printDuration(watch.taken())); + } + + //TODO + // изенен порядок восстановления сообщения из таблицы completed, из-за состояния гонки. И работы с одним и тем же + // сообщением в кластере. + public void recoverCompletedMessageFromAggregationRepository(CamelContext camelContext) { + // copy the current in progress before doing scan + final Set copyOfInProgress = new LinkedHashSet<>(inProgressCompleteExchanges); + RecoverableAggregationRepository recoverable = ((RecoverableAggregationRepository) aggregationRepository); + + // grab the timeout value for each partly aggregated exchange + Set keys = recoverable.scan(camelContext); + if (keys == null || keys.isEmpty()) { + return; + } + + for (String key : keys) { + if (!optimisticLocking) { + lock.lock(); + } + + if (!copyOfInProgress.contains(key) && !inProgressCompleteExchanges.contains(key)) { + try { + // consider in progress if it was in progress before we did the scan, or currently after we did the scan + // its safer to consider it in progress than risk duplicates due both in progress + recovered && checkOnDisconnectedNode(exchange, disconnectedNodeId) + Exchange exchange = recoverable.recover(camelContext, key); + if (exchange != null && checkCorrectTimeout(exchange) + && !inProgressCompleteExchanges.contains(key)) { + LOG.debug("Loading aggregated exchange with id: {} to be recovered.", key); + // and mark it as redelivered + exchange.getIn().setHeader(Exchange.REDELIVERED, Boolean.TRUE); + + // get the current redelivery data + Integer redeliveryCounter = (Integer) exchange.getIn().getHeader(Exchange.REDELIVERY_COUNTER); + + // if we are exhausted, then move to dead letter channel + if (redeliveryCounter != null && recoverable.getMaximumRedeliveries() > 0 && redeliveryCounter >= recoverable.getMaximumRedeliveries()) { + LOG.warn("The recovered exchange is exhausted after " + recoverable.getMaximumRedeliveries() + + " attempts, will now be moved to dead letter channel: " + recoverable.getDeadLetterUri()); + + // send to DLC + try { + // set redelivery counter + exchange.getIn().setHeader(Exchange.REDELIVERY_COUNTER, redeliveryCounter); + exchange.getIn().setHeader(Exchange.REDELIVERY_EXHAUSTED, Boolean.TRUE); + deadLetterProducerTemplate.send(recoverable.getDeadLetterUri(), exchange); + } catch (Throwable e) { + exchange.setException(e); + } + + // handle if failed + if (exchange.getException() != null) { + getExceptionHandler().handleException("Failed to move recovered Exchange to dead letter channel: " + + recoverable.getDeadLetterUri(), exchange.getException()); + } else { + // it was ok, so confirm after it has been moved to dead letter channel, so we wont recover it again + recoverable.confirm(camelContext, key); + } + } else { + // update current redelivery state + if (redeliveryCounter == null) { + // create new data + redeliveryCounter = 0; + } + redeliveryCounter++; + + // set redelivery counter + exchange.getIn().setHeader(Exchange.REDELIVERY_COUNTER, redeliveryCounter); + if (recoverable.getMaximumRedeliveries() > 0) { + exchange.getIn().setHeader(Exchange.REDELIVERY_MAX_COUNTER, recoverable.getMaximumRedeliveries()); + } + + LOG.debug("Delivery attempt: {} to recover aggregated exchange with id: {}", redeliveryCounter, key); + + // not exhaust so resubmit the recovered exchange + aggregationRepository.add(camelContext, key, exchange); + aggregationRepository.confirm(camelContext, key); + } + } + } finally { + if (!optimisticLocking) { + lock.unlock(); + } + } + } + } + } + + private boolean checkCorrectTimeout(Exchange exchange) { + long completedNodeTime = (Long) exchange.getMessage().getHeader(AGGREGATION_COMPLETED_NODE_TIME); + + return (System.currentTimeMillis() - completedNodeTime) > MAX_TIME_WORKING_WITH_COMPLETED_MESSAGE; + } + + /** + * Adds the given exchange to the timeout map, which is used by the timeout checker task to trigger timeouts. + * + * @param key the correlation key + * @param exchange the exchange + * @param timeout the timeout value in millis + */ + private void addExchangeToTimeoutMap(String key, Exchange exchange, long timeout) { + // store the timeout value on the exchange as well, in case we need it later + exchange.setProperty(Exchange.AGGREGATED_TIMEOUT, timeout); + timeoutMap.put(key, exchange.getExchangeId(), timeout); + } + + /** + * Current number of closed correlation keys in the memory cache + */ + public int getClosedCorrelationKeysCacheSize() { + if (closedCorrelationKeys != null) { + return closedCorrelationKeys.size(); + } else { + return 0; + } + } + + /** + * Clear all the closed correlation keys stored in the cache + */ + public void clearClosedCorrelationKeysCache() { + if (closedCorrelationKeys != null) { + closedCorrelationKeys.clear(); + } + } + + public AggregateProcessorStatistics getStatistics() { + return statistics; + } + + public int getInProgressCompleteExchanges() { + return inProgressCompleteExchanges.size(); + } + + public Predicate getCompletionPredicate() { + return completionPredicate; + } + + public void setCompletionPredicate(Predicate completionPredicate) { + this.completionPredicate = completionPredicate; + } + + public boolean isEagerCheckCompletion() { + return eagerCheckCompletion; + } + + public void setEagerCheckCompletion(boolean eagerCheckCompletion) { + this.eagerCheckCompletion = eagerCheckCompletion; + } + + public long getCompletionTimeout() { + return completionTimeout; + } + + public void setCompletionTimeout(long completionTimeout) { + this.completionTimeout = completionTimeout; + } + + public Expression getCompletionTimeoutExpression() { + return completionTimeoutExpression; + } + + public void setCompletionTimeoutExpression(Expression completionTimeoutExpression) { + this.completionTimeoutExpression = completionTimeoutExpression; + } + + public long getCompletionInterval() { + return completionInterval; + } + + public void setCompletionInterval(long completionInterval) { + this.completionInterval = completionInterval; + } + + public int getCompletionSize() { + return completionSize; + } + + public void setCompletionSize(int completionSize) { + this.completionSize = completionSize; + } + + public Expression getCompletionSizeExpression() { + return completionSizeExpression; + } + + public void setCompletionSizeExpression(Expression completionSizeExpression) { + this.completionSizeExpression = completionSizeExpression; + } + + public boolean isIgnoreInvalidCorrelationKeys() { + return ignoreInvalidCorrelationKeys; + } + + public void setIgnoreInvalidCorrelationKeys(boolean ignoreInvalidCorrelationKeys) { + this.ignoreInvalidCorrelationKeys = ignoreInvalidCorrelationKeys; + } + + public Integer getCloseCorrelationKeyOnCompletion() { + return closeCorrelationKeyOnCompletion; + } + + public void setCloseCorrelationKeyOnCompletion(Integer closeCorrelationKeyOnCompletion) { + this.closeCorrelationKeyOnCompletion = closeCorrelationKeyOnCompletion; + } + + public boolean isCompletionFromBatchConsumer() { + return completionFromBatchConsumer; + } + + public void setCompletionFromBatchConsumer(boolean completionFromBatchConsumer) { + this.completionFromBatchConsumer = completionFromBatchConsumer; + } + + public boolean isCompletionOnNewCorrelationGroup() { + return completionOnNewCorrelationGroup; + } + + public void setCompletionOnNewCorrelationGroup(boolean completionOnNewCorrelationGroup) { + this.completionOnNewCorrelationGroup = completionOnNewCorrelationGroup; + } + + public boolean isCompleteAllOnStop() { + return completeAllOnStop; + } + + public long getCompletionTimeoutCheckerInterval() { + return completionTimeoutCheckerInterval; + } + + public void setCompletionTimeoutCheckerInterval(long completionTimeoutCheckerInterval) { + this.completionTimeoutCheckerInterval = completionTimeoutCheckerInterval; + } + + public ExceptionHandler getExceptionHandler() { + return exceptionHandler; + } + + public void setExceptionHandler(ExceptionHandler exceptionHandler) { + this.exceptionHandler = exceptionHandler; + } + + public boolean isParallelProcessing() { + return parallelProcessing; + } + + public void setParallelProcessing(boolean parallelProcessing) { + this.parallelProcessing = parallelProcessing; + } + + public boolean isOptimisticLocking() { + return optimisticLocking; + } + + public void setOptimisticLocking(boolean optimisticLocking) { + this.optimisticLocking = optimisticLocking; + } + + public AggregationRepository getAggregationRepository() { + return aggregationRepository; + } + + public void setAggregationRepository(AggregationRepository aggregationRepository) { + this.aggregationRepository = aggregationRepository; + } + + public boolean isDiscardOnCompletionTimeout() { + return discardOnCompletionTimeout; + } + + public void setDiscardOnCompletionTimeout(boolean discardOnCompletionTimeout) { + this.discardOnCompletionTimeout = discardOnCompletionTimeout; + } + + public boolean isDiscardOnAggregationFailure() { + return discardOnAggregationFailure; + } + + public void setDiscardOnAggregationFailure(boolean discardOnAggregationFailure) { + this.discardOnAggregationFailure = discardOnAggregationFailure; + } + + public void setForceCompletionOnStop(boolean forceCompletionOnStop) { + this.forceCompletionOnStop = forceCompletionOnStop; + } + + public void setCompleteAllOnStop(boolean completeAllOnStop) { + this.completeAllOnStop = completeAllOnStop; + } + + public void setTimeoutCheckerExecutorService(ScheduledExecutorService timeoutCheckerExecutorService) { + this.timeoutCheckerExecutorService = timeoutCheckerExecutorService; + } + + public ScheduledExecutorService getTimeoutCheckerExecutorService() { + return timeoutCheckerExecutorService; + } + + public boolean isShutdownTimeoutCheckerExecutorService() { + return shutdownTimeoutCheckerExecutorService; + } + + public void setShutdownTimeoutCheckerExecutorService(boolean shutdownTimeoutCheckerExecutorService) { + this.shutdownTimeoutCheckerExecutorService = shutdownTimeoutCheckerExecutorService; + } + + public void setOptimisticLockingExecutorService(ScheduledExecutorService optimisticLockingExecutorService) { + this.optimisticLockingExecutorService = optimisticLockingExecutorService; + } + + public ScheduledExecutorService getOptimisticLockingExecutorService() { + return optimisticLockingExecutorService; + } + + public boolean isShutdownOptimisticLockingExecutorService() { + return shutdownOptimisticLockingExecutorService; + } + + public void setShutdownOptimisticLockingExecutorService(boolean shutdownOptimisticLockingExecutorService) { + this.shutdownOptimisticLockingExecutorService = shutdownOptimisticLockingExecutorService; + } + + public void setOptimisticLockRetryPolicy(OptimisticLockRetryPolicy optimisticLockRetryPolicy) { + this.optimisticLockRetryPolicy = optimisticLockRetryPolicy; + } + + public OptimisticLockRetryPolicy getOptimisticLockRetryPolicy() { + return optimisticLockRetryPolicy; + } + + public AggregationStrategy getAggregationStrategy() { + return aggregationStrategy; + } + + public void setAggregationStrategy(AggregationStrategy aggregationStrategy) { + this.aggregationStrategy = aggregationStrategy; + } + + public Expression getCorrelationExpression() { + return correlationExpression; + } + + public void setCorrelationExpression(Expression correlationExpression) { + this.correlationExpression = correlationExpression; + } + + public AggregateController getAggregateController() { + return aggregateController; + } + + public void setAggregateController(AggregateController aggregateController) { + this.aggregateController = aggregateController; + } + + /** + * On completion task which keeps the booking of the in progress up to date + */ + private final class AggregateOnCompletion implements Synchronization { + private final String exchangeId; + + private AggregateOnCompletion(String exchangeId) { + // must use the original exchange id as it could potentially change if send over SEDA etc. + this.exchangeId = exchangeId; + } + + @Override + public void onFailure(Exchange exchange) { + LOG.trace("Aggregated exchange onFailure: {}", exchange); + + // must remember to remove in progress when we failed + inProgressCompleteExchanges.remove(exchangeId); + // do not remove redelivery state as we need it when we redeliver again later + } + + @Override + public void onComplete(Exchange exchange) { + LOG.trace("Aggregated exchange onComplete: {}", exchange); + + // only confirm if we processed without a problem + try { + aggregationRepository.confirm(exchange.getContext(), exchangeId); + // and remove redelivery state as well + redeliveryState.remove(exchangeId); + } finally { + // must remember to remove in progress when we are complete + inProgressCompleteExchanges.remove(exchangeId); + } + } + + @Override + public String toString() { + return "AggregateOnCompletion"; + } + } + + /** + * Background task that looks for aggregated exchanges which is triggered by completion timeouts. + */ + private final class AggregationTimeoutMap extends DefaultTimeoutMap { + + private AggregationTimeoutMap(ScheduledExecutorService executor, long requestMapPollTimeMillis) { + // do NOT use locking on the timeout map as this aggregator has its own shared lock we will use instead + super(executor, requestMapPollTimeMillis, optimisticLocking); + addListener(this::onEviction); + } + + @Override + protected void purge() { + // wait for lock to be created + if (lock != null) { + // must acquire the shared aggregation lock to be able to purge + lock.lock(); + try { + super.purge(); + } finally { + lock.unlock(); + } + } + } + + private void onEviction(Listener.Type type, String key, String exchangeId) { + if (type != Listener.Type.Evict) { + return; + } + log.debug("Completion timeout triggered for correlation key: {}", key); + + boolean inProgress = inProgressCompleteExchanges.contains(exchangeId); + if (inProgress) { + log.trace("Aggregated exchange with id: {} is already in progress.", exchangeId); + return; + } + + // get the aggregated exchange + boolean evictionStolen = false; + Exchange answer = aggregationRepository.get(camelContext, key); + if (answer == null) { + evictionStolen = true; + } else { + // indicate it was completed by timeout + answer.setProperty(Exchange.AGGREGATED_COMPLETED_BY, COMPLETED_BY_TIMEOUT); + try { + answer = onCompletion(key, answer, answer, true, false); + if (answer != null) { + onSubmitCompletion(key, answer); + aggregationRepository.confirm(answer.getContext(), key); + } + } catch (OptimisticLockingAggregationRepository.OptimisticLockingException e) { + evictionStolen = true; + } + } + + if (optimisticLocking && evictionStolen) { + log.debug("Another Camel instance has already successfully correlated or processed this timeout eviction " + + "for exchange with id: {} and correlation id: {}", + exchangeId, key); + } + } + } + + /** + * Background task that triggers completion based on interval. + */ + private final class AggregationIntervalTask implements Runnable { + + @Override + public void run() { + // only run if CamelContext has been fully started + if (!camelContext.getStatus().isStarted()) { + LOG.trace("Completion interval task cannot start due CamelContext({}) has not been started yet", + camelContext.getName()); + return; + } + + LOG.trace("Starting completion interval task"); + + // trigger completion for all in the repository + Set keys = aggregationRepository.getKeys(); + + if (keys != null && !keys.isEmpty()) { + // must acquire the shared aggregation lock to be able to trigger interval completion + lock.lock(); + try { + for (String key : keys) { + boolean stolenInterval = false; + Exchange exchange = aggregationRepository.get(camelContext, key); + if (exchange == null) { + stolenInterval = true; + } else { + LOG.trace("Completion interval triggered for correlation key: {}", key); + // indicate it was completed by interval + exchange.setProperty(Exchange.AGGREGATED_COMPLETED_BY, COMPLETED_BY_INTERVAL); + try { + Exchange answer = onCompletion(key, exchange, exchange, false, false); + if (answer != null) { + onSubmitCompletion(key, answer); + aggregationRepository.confirm(camelContext, key); + } + } catch (OptimisticLockingAggregationRepository.OptimisticLockingException e) { + stolenInterval = true; + } + } + if (optimisticLocking && stolenInterval) { + LOG.debug( + "Another Camel instance has already processed this interval aggregation for exchange with correlation id: {}", + key); + } + } + } finally { + lock.unlock(); + } + } + + LOG.trace("Completion interval task complete"); + } + } + + /** + * Background task that looks for aggregated exchanges to recover. + */ + private final class RecoverTask implements Runnable { + private final RecoverableAggregationRepository recoverable; + + private RecoverTask(RecoverableAggregationRepository recoverable) { + this.recoverable = recoverable; + } + + @Override + public void run() { + // only run if CamelContext has been fully started + if (!camelContext.getStatus().isStarted()) { + LOG.trace("Recover check cannot start due CamelContext({}) has not been started yet", camelContext.getName()); + return; + } + + LOG.trace("Starting recover check"); + +// TODO + // copy the current in progress before doing scan +// final Set copyOfInProgress = new LinkedHashSet<>(inProgressCompleteExchanges); +// +// Set exchangeIds = recoverable.scan(camelContext); +// for (String exchangeId : exchangeIds) { +// +// // we may shutdown while doing recovery +// if (!isRunAllowed()) { +// LOG.info("We are shutting down so stop recovering"); +// return; +// } +// lock.lock(); +// try { +// // consider in progress if it was in progress before we did the scan, or currently after we did the scan +// // its safer to consider it in progress than risk duplicates due both in progress + recovered +// boolean inProgress +// = copyOfInProgress.contains(exchangeId) || inProgressCompleteExchanges.contains(exchangeId); +// if (inProgress) { +// LOG.trace("Aggregated exchange with id: {} is already in progress.", exchangeId); +// } else { +// LOG.debug("Loading aggregated exchange with id: {} to be recovered.", exchangeId); +// Exchange exchange = recoverable.recover(camelContext, exchangeId); +// if (exchange != null) { +// // get the correlation key +// String key = exchange.getProperty(Exchange.AGGREGATED_CORRELATION_KEY, String.class); +// // and mark it as redelivered +// exchange.getIn().setHeader(Exchange.REDELIVERED, Boolean.TRUE); +// +// // get the current redelivery data +// AggregateProcessor.RedeliveryData data = redeliveryState.get(exchange.getExchangeId()); +// +// // if we are exhausted, then move to dead letter channel +// if (data != null && recoverable.getMaximumRedeliveries() > 0 +// && data.redeliveryCounter >= recoverable.getMaximumRedeliveries()) { +// LOG.warn("The recovered exchange is exhausted after " + recoverable.getMaximumRedeliveries() +// + " attempts, will now be moved to dead letter channel: " +// + recoverable.getDeadLetterUri()); +// +// // send to DLC +// try { +// // set redelivery counter +// exchange.getIn().setHeader(Exchange.REDELIVERY_COUNTER, data.redeliveryCounter); +// // and prepare for sending to DLC +// exchange.adapt(ExtendedExchange.class).setRedeliveryExhausted(false); +// exchange.adapt(ExtendedExchange.class).setRollbackOnly(false); +// deadLetterProducerTemplate.send(recoverable.getDeadLetterUri(), exchange); +// } catch (Throwable e) { +// exchange.setException(e); +// } +// +// // handle if failed +// if (exchange.getException() != null) { +// getExceptionHandler() +// .handleException("Failed to move recovered Exchange to dead letter channel: " +// + recoverable.getDeadLetterUri(), +// exchange.getException()); +// } else { +// // it was ok, so confirm after it has been moved to dead letter channel, so we wont recover it again +// recoverable.confirm(camelContext, exchangeId); +// } +// } else { +// // update current redelivery state +// if (data == null) { +// // create new data +// data = new AggregateProcessor.RedeliveryData(); +// redeliveryState.put(exchange.getExchangeId(), data); +// } +// data.redeliveryCounter++; +// +// // set redelivery counter +// exchange.getIn().setHeader(Exchange.REDELIVERY_COUNTER, data.redeliveryCounter); +// if (recoverable.getMaximumRedeliveries() > 0) { +// exchange.getIn().setHeader(Exchange.REDELIVERY_MAX_COUNTER, +// recoverable.getMaximumRedeliveries()); +// } +// +// LOG.debug("Delivery attempt: {} to recover aggregated exchange with id: {}", +// data.redeliveryCounter, exchangeId); +// +// // not exhaust so resubmit the recovered exchange +// onSubmitCompletion(key, exchange); +// } +// } +// } +// } finally { +// lock.unlock(); +// } +// } +// +// LOG.trace("Recover check complete"); + recoverCompletedMessageFromAggregationRepository(camelContext); + } + } + + @Override + @SuppressWarnings("unchecked") + protected void doStart() throws Exception { + if (aggregationStrategy instanceof CamelContextAware) { + ((CamelContextAware) aggregationStrategy).setCamelContext(camelContext); + } + if (aggregationStrategy.canPreComplete()) { + preCompletion = true; + LOG.info("PreCompletionAwareAggregationStrategy detected. Aggregator {} is in pre-completion mode.", getId()); + } + + if (!preCompletion) { + // if not in pre completion mode then check we configured the completion required + if (getCompletionTimeout() <= 0 && getCompletionInterval() <= 0 && getCompletionSize() <= 0 + && getCompletionPredicate() == null + && !isCompletionFromBatchConsumer() && getCompletionTimeoutExpression() == null + && getCompletionSizeExpression() == null) { + throw new IllegalStateException( + "At least one of the completions options" + + " [completionTimeout, completionInterval, completionSize, completionPredicate, completionFromBatchConsumer] must be set"); + } + } + + if (getCloseCorrelationKeyOnCompletion() != null) { + if (getCloseCorrelationKeyOnCompletion() > 0) { + LOG.info("Using ClosedCorrelationKeys with a LRUCache with a capacity of {}", + getCloseCorrelationKeyOnCompletion()); + closedCorrelationKeys = LRUCacheFactory.newLRUCache(getCloseCorrelationKeyOnCompletion()); + } else { + LOG.info("Using ClosedCorrelationKeys with unbounded capacity"); + closedCorrelationKeys = new ConcurrentHashMap<>(); + } + } + + if (aggregationRepository == null) { + aggregationRepository = new MemoryAggregationRepository(optimisticLocking); + LOG.info("Defaulting to MemoryAggregationRepository"); + } + + if (optimisticLocking) { + if (!(aggregationRepository instanceof OptimisticLockingAggregationRepository)) { + throw new IllegalArgumentException( + "Optimistic locking cannot be enabled without using an AggregationRepository that implements OptimisticLockingAggregationRepository"); + } + LOG.info("Optimistic locking is enabled"); + } + + ServiceHelper.startService(aggregationStrategy, processor, aggregationRepository); + + // should we use recover checker + if (aggregationRepository instanceof RecoverableAggregationRepository) { + RecoverableAggregationRepository recoverable = (RecoverableAggregationRepository) aggregationRepository; + if (recoverable.isUseRecovery()) { + long interval = recoverable.getRecoveryIntervalInMillis(); + if (interval <= 0) { + throw new IllegalArgumentException( + "AggregationRepository has recovery enabled and the RecoveryInterval option must be a positive number, was: " + + interval); + } + + // create a background recover thread to check every interval + recoverService + = camelContext.getExecutorServiceManager().newScheduledThreadPool(this, "AggregateRecoverChecker", 1); + Runnable recoverTask = new RecoverTask(recoverable); + LOG.info("Using RecoverableAggregationRepository by scheduling recover checker to run every {} millis.", + interval); + // use fixed delay so there is X interval between each run + recoverService.scheduleWithFixedDelay(recoverTask, 1000L, interval, TimeUnit.MILLISECONDS); + + if (recoverable.getDeadLetterUri() != null) { + int max = recoverable.getMaximumRedeliveries(); + if (max <= 0) { + throw new IllegalArgumentException("Option maximumRedeliveries must be a positive number, was: " + max); + } + LOG.info("After {} failed redelivery attempts Exchanges will be moved to deadLetterUri: {}", max, + recoverable.getDeadLetterUri()); + + // dead letter uri must be a valid endpoint + Endpoint endpoint = camelContext.getEndpoint(recoverable.getDeadLetterUri()); + if (endpoint == null) { + throw new NoSuchEndpointException(recoverable.getDeadLetterUri()); + } + deadLetterProducerTemplate = camelContext.createProducerTemplate(); + } + } + } + + if (getCompletionInterval() > 0 && getCompletionTimeout() > 0) { + throw new IllegalArgumentException("Only one of completionInterval or completionTimeout can be used, not both."); + } + if (getCompletionInterval() > 0) { + LOG.info("Using CompletionInterval to run every {} millis.", getCompletionInterval()); + if (getTimeoutCheckerExecutorService() == null) { + setTimeoutCheckerExecutorService(camelContext.getExecutorServiceManager().newSingleThreadScheduledExecutor(this, + AGGREGATE_TIMEOUT_CHECKER)); + shutdownTimeoutCheckerExecutorService = true; + } + // trigger completion based on interval + getTimeoutCheckerExecutorService().scheduleAtFixedRate(new AggregationIntervalTask(), getCompletionInterval(), + getCompletionInterval(), TimeUnit.MILLISECONDS); + } + + // start timeout service if its in use + if (getCompletionTimeout() > 0 || getCompletionTimeoutExpression() != null) { + LOG.info("Using CompletionTimeout to trigger after {} millis of inactivity.", getCompletionTimeout()); + if (getTimeoutCheckerExecutorService() == null) { + setTimeoutCheckerExecutorService(camelContext.getExecutorServiceManager().newSingleThreadScheduledExecutor(this, + AGGREGATE_TIMEOUT_CHECKER)); + shutdownTimeoutCheckerExecutorService = true; + } + // check for timed out aggregated messages once every second + timeoutMap = new AggregationTimeoutMap(getTimeoutCheckerExecutorService(), getCompletionTimeoutCheckerInterval()); + // fill in existing timeout values from the aggregation repository, for example if a restart occurred, then we + // need to re-establish the timeout map so timeout can trigger + //TODO + recoverCompletedMessageFromAggregationRepository(camelContext); + restoreTimeoutMapFromAggregationRepository(); + ServiceHelper.startService(timeoutMap); + } + + if (aggregateController == null) { + aggregateController = new DefaultAggregateController(); + } + aggregateController.onStart(this); + + if (optimisticLocking) { + lock = NoLock.INSTANCE; + if (getOptimisticLockingExecutorService() == null) { + setOptimisticLockingExecutorService(camelContext.getExecutorServiceManager() + .newSingleThreadScheduledExecutor(this, AGGREGATE_OPTIMISTIC_LOCKING_EXECUTOR)); + shutdownOptimisticLockingExecutorService = true; + } + } else { + lock = new ReentrantLock(); + } + } + + @Override + public void doStop() throws Exception { + // note: we cannot do doForceCompletionOnStop from this doStop method + // as this is handled in the prepareShutdown method which is also invoked when stopping a route + // and is better suited for preparing to shutdown than this doStop method is + + if (aggregateController != null) { + aggregateController.onStop(this); + } + + if (recoverService != null) { + camelContext.getExecutorServiceManager().shutdown(recoverService); + } + + if (shutdownTimeoutCheckerExecutorService && timeoutCheckerExecutorService != null) { + camelContext.getExecutorServiceManager().shutdown(timeoutCheckerExecutorService); + timeoutCheckerExecutorService = null; + shutdownTimeoutCheckerExecutorService = false; + } + + ServiceHelper.stopService(timeoutMap, processor, deadLetterProducerTemplate); + + if (closedCorrelationKeys != null) { + // it may be a service so stop it as well + ServiceHelper.stopService(closedCorrelationKeys); + closedCorrelationKeys.clear(); + } + batchConsumerCorrelationKeys.clear(); + redeliveryState.clear(); + } + + @Override + public void prepareShutdown(boolean suspendOnly, boolean forced) { + // we are shutting down, so force completion if this option was enabled + // but only do this when forced=false, as that is when we have chance to + // send out new messages to be routed by Camel. When forced=true, then + // we have to shutdown in a hurry + if (!forced && forceCompletionOnStop) { + doForceCompletionOnStop(); + } + } + + @Override + public boolean deferShutdown(ShutdownRunningTask shutdownRunningTask) { + // not in use + return true; + } + + @Override + public int getPendingExchangesSize() { + if (completeAllOnStop) { + // we want to regard all pending exchanges in the repo as inflight + Set keys = getAggregationRepository().getKeys(); + return keys != null ? keys.size() : 0; + } else { + return 0; + } + } + + private void doForceCompletionOnStop() { + int expected = forceCompletionOfAllGroups(); + + StopWatch watch = new StopWatch(); + while (inProgressCompleteExchanges.size() > 0) { + LOG.trace("Waiting for {} inflight exchanges to complete", getInProgressCompleteExchanges()); + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // break out as we got interrupted such as the JVM terminating + LOG.warn("Interrupted while waiting for {} inflight exchanges to complete.", getInProgressCompleteExchanges()); + break; + } + } + + if (expected > 0) { + LOG.info("Forcing completion of all groups with {} exchanges completed in {}", expected, + TimeUtils.printDuration(watch.taken())); + } + } + + @Override + protected void doShutdown() throws Exception { + // shutdown aggregation the strategy + ServiceHelper.stopAndShutdownServices(aggregationStrategy); + + // cleanup when shutting down + inProgressCompleteExchanges.clear(); + + if (shutdownExecutorService) { + camelContext.getExecutorServiceManager().shutdownNow(executorService); + } + if (shutdownTimeoutCheckerExecutorService) { + camelContext.getExecutorServiceManager().shutdownNow(timeoutCheckerExecutorService); + timeoutCheckerExecutorService = null; + } + if (shutdownOptimisticLockingExecutorService) { + camelContext.getExecutorServiceManager().shutdownNow(optimisticLockingExecutorService); + optimisticLockingExecutorService = null; + } + + super.doShutdown(); + + // shutdown aggregation repository + ServiceHelper.stopAndShutdownServices(aggregationRepository); + } + + public int forceCompletionOfGroup(String key) { + // must acquire the shared aggregation lock to be able to trigger force completion + int total = 0; + + lock.lock(); + try { + Exchange exchange = aggregationRepository.get(camelContext, key); + if (exchange != null) { + total = 1; + LOG.trace("Force completion triggered for correlation key: {}", key); + // indicate it was completed by a force completion request + exchange.setProperty(Exchange.AGGREGATED_COMPLETED_BY, COMPLETED_BY_FORCE); + Exchange answer = onCompletion(key, exchange, exchange, false, false); + if (answer != null) { + onSubmitCompletion(key, answer); + aggregationRepository.confirm(camelContext, key); + } + } + } finally { + lock.unlock(); + } + LOG.trace("Completed force completion of group {}", key); + + if (total > 0) { + LOG.debug("Forcing completion of group {} with {} exchanges", key, total); + } + return total; + } + + public int forceCompletionOfAllGroups() { + + // only run if CamelContext has been fully started or is stopping + boolean allow = camelContext.getStatus().isStarted() || camelContext.getStatus().isStopping(); + if (!allow) { + LOG.warn("Cannot start force completion of all groups because CamelContext({}) has not been started", + camelContext.getName()); + return 0; + } + + LOG.trace("Starting force completion of all groups task"); + + // trigger completion for all in the repository + Set keys = aggregationRepository.getKeys(); + + int total = 0; + if (keys != null && !keys.isEmpty()) { + // must acquire the shared aggregation lock to be able to trigger force completion + lock.lock(); + total = keys.size(); + try { + for (String key : keys) { + Exchange exchange = aggregationRepository.get(camelContext, key); + if (exchange != null) { + LOG.trace("Force completion triggered for correlation key: {}", key); + // indicate it was completed by a force completion request + exchange.setProperty(Exchange.AGGREGATED_COMPLETED_BY, COMPLETED_BY_FORCE); + Exchange answer = onCompletion(key, exchange, exchange, false, false); + if (answer != null) { + onSubmitCompletion(key, answer); + aggregationRepository.confirm(camelContext, key); + } + } + } + } finally { + lock.unlock(); + } + } + LOG.trace("Completed force completion of all groups task"); + + if (total > 0) { + LOG.debug("Forcing completion of all groups with {} exchanges", total); + } + return total; + } + + public int forceDiscardingOfGroup(String key) { + // must acquire the shared aggregation lock to be able to trigger force completion + int total = 0; + + lock.lock(); + try { + Exchange exchange = aggregationRepository.get(camelContext, key); + if (exchange != null) { + total = 1; + LOG.trace("Force discarded triggered for correlation key: {}", key); + // force discarding by setting aggregate failed as true + onCompletion(key, exchange, exchange, false, true); + } + } finally { + lock.unlock(); + } + LOG.trace("Completed force discarded of group {}", key); + + if (total > 0) { + LOG.debug("Forcing discarding of group {} with {} exchanges", key, total); + } + return total; + } + + public int forceDiscardingOfAllGroups() { + + // only run if CamelContext has been fully started or is stopping + boolean allow = camelContext.getStatus().isStarted() || camelContext.getStatus().isStopping(); + if (!allow) { + LOG.warn("Cannot start force discarding of all groups because CamelContext({}) has not been started", + camelContext.getName()); + return 0; + } + + LOG.trace("Starting force discarding of all groups task"); + + // trigger completion for all in the repository + Set keys = aggregationRepository.getKeys(); + + int total = 0; + if (keys != null && !keys.isEmpty()) { + // must acquire the shared aggregation lock to be able to trigger force completion + lock.lock(); + total = keys.size(); + try { + for (String key : keys) { + Exchange exchange = aggregationRepository.get(camelContext, key); + if (exchange != null) { + LOG.trace("Force discarded triggered for correlation key: {}", key); + // force discarding by setting aggregate failed as true + onCompletion(key, exchange, exchange, false, true); + } + } + } finally { + lock.unlock(); + } + } + LOG.trace("Completed force discarding of all groups task"); + + if (total > 0) { + LOG.debug("Forcing discarding of all groups with {} exchanges", total); + } + return total; + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/HeaderMergeAggregatorImpl.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/HeaderMergeAggregatorImpl.java new file mode 100644 index 00000000..6deb149d --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/HeaderMergeAggregatorImpl.java @@ -0,0 +1,44 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.aggregation; + +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.camel.AggregationStrategy; +import org.apache.camel.Exchange; + +public class HeaderMergeAggregatorImpl implements AggregationStrategy { + + @Override + public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { + if (oldExchange != null && newExchange != null) { + Map oldHeaders = oldExchange.getIn().getHeaders(); + Map newHeaders = newExchange.getIn().getHeaders(); + + oldHeaders = oldHeaders.entrySet().stream() + .filter(e -> !newHeaders.containsKey(e.getKey())) + .collect(Collectors.toMap(e->e.getKey(), e->e.getValue())); + newExchange.getIn().getHeaders().putAll(oldHeaders); + } + return newExchange; + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/TimeoutAwareAggregationStrategyImpl.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/TimeoutAwareAggregationStrategyImpl.java new file mode 100644 index 00000000..8cd7abff --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/TimeoutAwareAggregationStrategyImpl.java @@ -0,0 +1,55 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.aggregation; + +import org.apache.camel.AggregationStrategy; +import org.apache.camel.Exchange; + +public class TimeoutAwareAggregationStrategyImpl implements AggregationStrategy { + + private static final String ACK_MESSAGE_HEADER = "NTX_AckMessage"; + + private final String nameHeaderAcknowledge; + + public TimeoutAwareAggregationStrategyImpl(String nameHeaderAcknowledge) { + this.nameHeaderAcknowledge = nameHeaderAcknowledge; + } + + @Override + public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { + if (oldExchange == null) { + return newExchange; + } else { + oldExchange.getMessage().setHeader(nameHeaderAcknowledge, checkOnCorrectPair(oldExchange, newExchange)); + return oldExchange; + } + } + + private boolean checkOnCorrectPair(Exchange oldExchange, Exchange newExchange) { + return (oldExchange != null && oldExchange.getMessage().getHeader(ACK_MESSAGE_HEADER) == null && + (newExchange == null || newExchange.getMessage().getHeader(ACK_MESSAGE_HEADER) == null)); + } + + @Override + public void timeout(Exchange oldExchange, int index, int total, long timeout) { + oldExchange.getMessage().setHeader(nameHeaderAcknowledge, + (oldExchange.getMessage().getHeader(ACK_MESSAGE_HEADER) == null)); + } +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/hazelcast/DisconnectedMembershipListener.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/hazelcast/DisconnectedMembershipListener.java new file mode 100644 index 00000000..3638693d --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/hazelcast/DisconnectedMembershipListener.java @@ -0,0 +1,59 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.aggregation.hazelcast; + +import com.hazelcast.core.MemberAttributeEvent; +import com.hazelcast.core.MembershipEvent; +import com.hazelcast.core.MembershipListener; +import org.apache.camel.CamelContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.system.common.aggregation.AggregationProcessorWithRestoreTimeout; + +public class DisconnectedMembershipListener implements MembershipListener { + + protected static final Logger log = LoggerFactory.getLogger(DisconnectedMembershipListener.class); + private final AggregationProcessorWithRestoreTimeout aggregationProcessorWithRestoreTimeout; + private final CamelContext camelContext; + + public DisconnectedMembershipListener(AggregationProcessorWithRestoreTimeout aggregationProcessorWithRestoreTimeout, + CamelContext camelContext) { + this.aggregationProcessorWithRestoreTimeout = aggregationProcessorWithRestoreTimeout; + this.camelContext = camelContext; + } + + @Override + public void memberAdded(MembershipEvent membershipEvent) { + } + + @Override + public void memberRemoved(MembershipEvent membershipEvent) { + try { + aggregationProcessorWithRestoreTimeout.recoverCompletedMessageFromAggregationRepository(camelContext); + aggregationProcessorWithRestoreTimeout.restoreTimeoutMapFromAggregationRepository(); + } catch (Exception e) { + log.error("Can't restore Timeout from Aggregator. Please restart bundle.", e); + } + } + + @Override + public void memberAttributeChanged(MemberAttributeEvent memberAttributeEvent) { + } +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/repo/IgniteAggregationRepository.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/repo/IgniteAggregationRepository.java new file mode 100644 index 00000000..914f60d6 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/repo/IgniteAggregationRepository.java @@ -0,0 +1,427 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.aggregation.repo; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.processor.aggregate.jdbc.DefaultJdbcOptimisticLockingExceptionMapper; +import org.apache.camel.processor.aggregate.jdbc.JdbcCamelCodec; +import org.apache.camel.processor.aggregate.jdbc.JdbcOptimisticLockingExceptionMapper; +import org.apache.camel.spi.OptimisticLockingAggregationRepository; +import org.apache.camel.spi.RecoverableAggregationRepository; +import org.apache.camel.support.service.ServiceSupport; +import org.apache.camel.util.ObjectHelper; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteTransactions; +import org.apache.ignite.Ignition; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.cache.CacheMode; +import org.apache.ignite.cache.CacheRebalanceMode; +import org.apache.ignite.cache.query.ScanQuery; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.configuration.TransactionConfiguration; +import org.apache.ignite.logger.jcl.JclLogger; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.transactions.Transaction; +import org.jetbrains.annotations.NotNull; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.EmptyResultDataAccessException; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import static org.apache.ignite.IgniteSystemProperties.IGNITE_QUIET; + +public class IgniteAggregationRepository extends ServiceSupport implements RecoverableAggregationRepository, OptimisticLockingAggregationRepository { + + private static final Logger LOG = LoggerFactory.getLogger(IgniteAggregationRepository.class); + public static final String AGGREGATION = "aggregation"; + public static final String AGGREGATION_COMPLETED = "aggregationCompleted"; + public static final int MAX_ATTEMPT_COUNT = 3; + + private JdbcOptimisticLockingExceptionMapper jdbcOptimisticLockingExceptionMapper = new DefaultJdbcOptimisticLockingExceptionMapper(); + private boolean returnOldExchange; + private final JdbcCamelCodec codec = new JdbcCamelCodec(); + private long recoveryInterval = 5000; + private boolean useRecovery = true; + private int maximumRedeliveries; + private String deadLetterUri; + private boolean allowSerializedHeaders; + private int backups = 2; + private String workDirectory; + private String addresses = "127.0.0.1:47500,127.0.0.1:47501"; + + private Ignite ignite; + private IgniteTransactions transactions; + + private IgniteCache aggregationCache; + private CacheConfiguration aggregationCfg; + + private IgniteCache aggregationCompleted; + private CacheConfiguration aggregationCompletedCfg; + + private BundleContext bundleContext; + + /** + * Creates an ignite aggregation repository + */ + public IgniteAggregationRepository() { + } + + /** + * Creates an ignite aggregation repository with the two mandatory parameters + */ + public IgniteAggregationRepository(BundleContext bundleContext, String workDirectory) { + this.setBundleContext(bundleContext); + this.setWorkDirectory(workDirectory); + } + + @Override + public Exchange add(final CamelContext camelContext, final String correlationId, + final Exchange oldExchange, final Exchange newExchange) throws OptimisticLockingException { + + try { + return add(camelContext, correlationId, newExchange); + } catch (Exception e) { + if (jdbcOptimisticLockingExceptionMapper != null && jdbcOptimisticLockingExceptionMapper.isOptimisticLocking(e)) { + throw new OptimisticLockingException(); + } else { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } + } + } + + @Override + public Exchange add(final CamelContext camelContext, final String correlationId, final Exchange exchange) { + Exchange result = null; + final String key = correlationId; + + try { + LOG.debug("Adding exchange with key: [{}]", key); + + boolean present = aggregationCache.get(key) != null; + + // Recover existing exchange with that ID + if (isReturnOldExchange() && present) { + result = get(key, camelContext); + } + + final byte[] data = codec.marshallExchange(camelContext, exchange, allowSerializedHeaders); + try (Transaction tx = transactions.txStart()) { + aggregationCache.put(key, data); + tx.commit(); + } + + } catch (Exception e) { + throw new RuntimeException("Error adding with key " + key, e); + } + + return result; + } + + public Exchange insert(final CamelContext camelContext, final String correlationId, final Exchange exchange) throws IOException { + Exchange result = null; + LOG.debug("Adding exchange with key: [{}]", correlationId); + + final byte[] data = codec.marshallExchange(camelContext, exchange, allowSerializedHeaders); + aggregationCompleted.put(correlationId, data); + + return result; + } + + @Override + public Exchange get(final CamelContext camelContext, final String correlationId) { + Exchange result = get(correlationId, camelContext); + + LOG.debug("Getting key [{}] -> {}", correlationId, result); + + return result; + } + + private Exchange get(final String key, final CamelContext camelContext) { + try { + final byte[] data = aggregationCache.get(key); + return codec.unmarshallExchange(camelContext, data); + } catch (EmptyResultDataAccessException | NullPointerException ex) { + return null; + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + @Override + public void remove(final CamelContext camelContext, final String correlationId, final Exchange exchange) { + try (Transaction tx = transactions.txStart()) { + insert(camelContext, correlationId, exchange); + if (!aggregationCache.remove(correlationId)) { + throw new RuntimeException("Error removing key " + correlationId + " from repository " + AGGREGATION); + } + tx.commit(); + } catch (Exception exception) { + throw new RuntimeException("Error removing key " + correlationId + " from repository " + AGGREGATION, exception); + } + } + + @Override + public void confirm(final CamelContext camelContext, final String exchangeId) { + confirm(camelContext, exchangeId, 0); + } + + private void confirm(final CamelContext camelContext, final String exchangeId, int attemptCount) { + if (attemptCount <= MAX_ATTEMPT_COUNT) { + try (Transaction tx = transactions.txStart()) { + aggregationCompleted.remove(exchangeId); + tx.commit(); + } catch (Exception exception) { + confirm(camelContext, exchangeId, ++attemptCount); + } + } + } + + @Override + public Set getKeys() { + Set keys = new HashSet<>(); + aggregationCache.query(new ScanQuery<>(null)).forEach(entry -> keys.add((String) entry.getKey())); + return keys; + } + + @Override + public Set scan(CamelContext camelContext) { + Set keys = new HashSet<>(); + aggregationCompleted.query(new ScanQuery<>(null)).forEach(entry -> keys.add((String) entry.getKey())); + return keys; + } + + @Override + public Exchange recover(CamelContext camelContext, String exchangeId) { + final byte[] data = aggregationCompleted.get(exchangeId); + Exchange answer = null; + try { + answer = codec.unmarshallExchange(camelContext, data); + } catch (IOException | ClassNotFoundException e) { + LOG.error("Exception in recovering exchangeId {}", exchangeId, e); + } + + LOG.debug("Recovering exchangeId [{}] -> {}", exchangeId, answer); + + return answer; + } + + /** + * If recovery is enabled then a background task is run every x'th time to scan for failed exchanges to recover + * and resubmit. By default this interval is 5000 millis. + * + * @param interval the interval + * @param timeUnit the time unit + */ + public void setRecoveryInterval(long interval, TimeUnit timeUnit) { + this.recoveryInterval = timeUnit.toMillis(interval); + } + + public void setRecoveryInterval(long interval) { + this.recoveryInterval = interval; + } + + public long getRecoveryIntervalInMillis() { + return recoveryInterval; + } + + public boolean isUseRecovery() { + return useRecovery; + } + + /** + * @param useRecovery Whether or not recovery is enabled. This option is by default true. When enabled the Camel + * Aggregator automatic recover failed aggregated exchange and have them resubmittedd + */ + public void setUseRecovery(boolean useRecovery) { + this.useRecovery = useRecovery; + } + + public int getMaximumRedeliveries() { + return maximumRedeliveries; + } + + public void setMaximumRedeliveries(int maximumRedeliveries) { + this.maximumRedeliveries = maximumRedeliveries; + } + + public String getDeadLetterUri() { + return deadLetterUri; + } + + /** + * @param deadLetterUri An endpoint uri for a Dead Letter Channel where exhausted recovered Exchanges will be + * moved. If this option is used then the maximumRedeliveries option must also be provided. + * Important note : if the deadletter route throws an exception, it will be send again to DLQ + * until it succeed ! + */ + public void setDeadLetterUri(String deadLetterUri) { + this.deadLetterUri = deadLetterUri; + } + + public boolean isReturnOldExchange() { + return returnOldExchange; + } + + /** + * @param returnOldExchange Whether the get operation should return the old existing Exchange if any existed. + * By default this option is false to optimize as we do not need the old exchange when + * aggregating + */ + public void setReturnOldExchange(boolean returnOldExchange) { + this.returnOldExchange = returnOldExchange; + } + + public boolean isAllowSerializedHeaders() { + return allowSerializedHeaders; + } + + public void setAllowSerializedHeaders(boolean allowSerializedHeaders) { + this.allowSerializedHeaders = allowSerializedHeaders; + } + + public JdbcOptimisticLockingExceptionMapper getJdbcOptimisticLockingExceptionMapper() { + return jdbcOptimisticLockingExceptionMapper; + } + + public void setJdbcOptimisticLockingExceptionMapper(JdbcOptimisticLockingExceptionMapper jdbcOptimisticLockingExceptionMapper) { + this.jdbcOptimisticLockingExceptionMapper = jdbcOptimisticLockingExceptionMapper; + } + + @Override + protected void doStart() throws Exception { + ObjectHelper.notNull(bundleContext, "BundleContext"); + ObjectHelper.notNull(workDirectory, "WorkDirectory"); + + settingsIgnite(); + + // log number of existing exchanges + int current = getKeys().size(); + int completed = scan(null).size(); + + if (current > 0) { + LOG.info("On startup there are " + current + " aggregate exchanges (not completed) in repository: " + AGGREGATION); + } else { + LOG.info("On startup there are no existing aggregate exchanges (not completed) in repository: {}", AGGREGATION); + } + if (completed > 0) { + LOG.warn("On startup there are " + completed + " completed exchanges to be recovered in repository: " + AGGREGATION_COMPLETED); + } else { + LOG.info("On startup there are no completed exchanges to be recovered in repository: {}", AGGREGATION_COMPLETED); + } + } + + @Override + public void doStop() throws Exception { + if (ignite != null) { + ignite.close(); + } + } + + private void settingsIgnite() { + IgniteConfiguration cfg = new IgniteConfiguration(); + cfg.setDiscoverySpi(getTcpDiscoverySpi()); + cfg.setGridLogger(new JclLogger()); + cfg.setTransactionConfiguration(new TransactionConfiguration()); + + settingsPersistence(cfg); + + aggregationCfg = getCacheConfiguration(AGGREGATION); + cfg.setCacheConfiguration(aggregationCfg); + + aggregationCompletedCfg = getCacheConfiguration(AGGREGATION_COMPLETED); + cfg.setCacheConfiguration(aggregationCompletedCfg); + + startIgnite(cfg); + + createCache(); + } + + private void settingsPersistence(IgniteConfiguration cfg) { + DataStorageConfiguration storageCfg = new DataStorageConfiguration(); + storageCfg.getDefaultDataRegionConfiguration().setPersistenceEnabled(true); + cfg.setWorkDirectory(workDirectory); + cfg.setDataStorageConfiguration(storageCfg); + } + + private void createCache() { + transactions = ignite.transactions(); + aggregationCache = ignite.getOrCreateCache(aggregationCfg); + aggregationCompleted = ignite.getOrCreateCache(aggregationCompletedCfg); + + // Set the baseline topology that is represented by these nodes. + ignite.cluster().setBaselineTopology(ignite.cluster().localNode().order()); + } + + private void startIgnite(IgniteConfiguration cfg) { + System.setProperty(IGNITE_QUIET, "false"); + ignite = Ignition.getOrStart(cfg); + ignite.cluster().active(true); + } + + @NotNull + private CacheConfiguration getCacheConfiguration(String cacheName) { + CacheConfiguration cacheCfg = new CacheConfiguration(); + cacheCfg.setName(cacheName); + cacheCfg.setRebalanceMode(CacheRebalanceMode.SYNC); + cacheCfg.setCacheMode(CacheMode.REPLICATED); + cacheCfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL); + cacheCfg.setBackups(backups); + return cacheCfg; + } + + @NotNull + private TcpDiscoverySpi getTcpDiscoverySpi() { + TcpDiscoverySpi spi = new TcpDiscoverySpi(); + spi.setIpFinder(new TcpDiscoveryVmIpFinder(false) { + { + setAddresses(Arrays.asList(addresses.split(","))); + } + }); + return spi; + } + + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + public void setWorkDirectory(String workDirectory) { + this.workDirectory = workDirectory; + } + + public void setBackups(int backups) { + this.backups = backups; + } + + public void setAddresses(String addresses) { + this.addresses = addresses; + } +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/repo/JdbcAggregationRepository.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/repo/JdbcAggregationRepository.java new file mode 100644 index 00000000..acb19d57 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/repo/JdbcAggregationRepository.java @@ -0,0 +1,649 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.aggregation.repo; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.processor.aggregate.jdbc.DefaultJdbcOptimisticLockingExceptionMapper; +import org.apache.camel.processor.aggregate.jdbc.JdbcCamelCodec; +import org.apache.camel.processor.aggregate.jdbc.JdbcOptimisticLockingExceptionMapper; +import org.apache.camel.spi.OptimisticLockingAggregationRepository; +import org.apache.camel.spi.RecoverableAggregationRepository; +import org.apache.camel.support.service.ServiceSupport; +import org.apache.camel.util.ObjectHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.Constants; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.support.AbstractLobCreatingPreparedStatementCallback; +import org.springframework.jdbc.support.lob.DefaultLobHandler; +import org.springframework.jdbc.support.lob.LobCreator; +import org.springframework.jdbc.support.lob.LobHandler; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.DefaultTransactionDefinition; +import org.springframework.transaction.support.TransactionCallbackWithoutResult; +import org.springframework.transaction.support.TransactionTemplate; + +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Types; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * JDBC based {@link org.apache.camel.spi.AggregationRepository} JdbcAggregationRepository will only preserve any + * Serializable compatible data types. If a data type is not such a type its dropped and a WARN is logged. And it only + * persists the Message body and the Message headers. The Exchange properties are not persisted. + */ +public class JdbcAggregationRepository extends ServiceSupport + implements RecoverableAggregationRepository, OptimisticLockingAggregationRepository { + + protected static final String EXCHANGE = "exchange"; + protected static final String ID = "id"; + protected static final String BODY = "body"; + + // optimistic locking: version identifier needed to avoid the lost update problem + private static final String VERSION = "version"; + private static final String VERSION_PROPERTY = "CamelOptimisticLockVersion"; + + private static final Logger LOG = LoggerFactory.getLogger(JdbcAggregationRepository.class); + private static final Constants PROPAGATION_CONSTANTS = new Constants(TransactionDefinition.class); + + private JdbcOptimisticLockingExceptionMapper jdbcOptimisticLockingExceptionMapper + = new DefaultJdbcOptimisticLockingExceptionMapper(); + private PlatformTransactionManager transactionManager; + private DataSource dataSource; + private TransactionTemplate transactionTemplate; + private TransactionTemplate transactionTemplateReadOnly; + private int propagationBehavior = TransactionDefinition.PROPAGATION_REQUIRED; + private JdbcTemplate jdbcTemplate; + private LobHandler lobHandler = new DefaultLobHandler(); + private String repositoryName; + private boolean returnOldExchange; + private JdbcCamelCodec codec = new JdbcCamelCodec(); + private long recoveryInterval = 5000; + private boolean useRecovery = true; + private int maximumRedeliveries; + private String deadLetterUri; + private List headersToStoreAsText; + private boolean storeBodyAsText; + private boolean allowSerializedHeaders; + + /** + * Creates an aggregation repository + */ + public JdbcAggregationRepository() { + } + + /** + * Creates an aggregation repository with the three mandatory parameters + */ + public JdbcAggregationRepository(PlatformTransactionManager transactionManager, String repositoryName, + DataSource dataSource) { + this.setRepositoryName(repositoryName); + this.setTransactionManager(transactionManager); + this.setDataSource(dataSource); + } + + /** + * Sets the name of the repository + */ + public final void setRepositoryName(String repositoryName) { + this.repositoryName = repositoryName; + } + + public final void setTransactionManager(PlatformTransactionManager transactionManager) { + this.transactionManager = transactionManager; + } + + /** + * Sets the DataSource to use for accessing the database + */ + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + + jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public Exchange add( + final CamelContext camelContext, final String correlationId, + final Exchange oldExchange, final Exchange newExchange) + throws OptimisticLockingException { + + try { + return add(camelContext, correlationId, newExchange); + } catch (Exception e) { + if (jdbcOptimisticLockingExceptionMapper != null && jdbcOptimisticLockingExceptionMapper.isOptimisticLocking(e)) { + throw new OptimisticLockingException(); + } else { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } + } + } + + @Override + public Exchange add(final CamelContext camelContext, final String correlationId, final Exchange exchange) { + return transactionTemplate.execute(status -> { + Exchange result = null; + final String key = correlationId; + + try { + LOG.debug("Adding exchange with key {}", key); + + boolean present = jdbcTemplate.queryForObject( + "SELECT COUNT(1) FROM " + getRepositoryName() + " WHERE " + ID + " = ?", Integer.class, key) != 0; + + // Recover existing exchange with that ID + if (isReturnOldExchange() && present) { + result = get(key, getRepositoryName(), camelContext); + } + + if (present) { + long version = exchange.getProperty(VERSION_PROPERTY, Long.class); + LOG.debug("Updating record with key {} and version {}", key, version); + update(camelContext, correlationId, exchange, getRepositoryName(), version); + } else { + LOG.debug("Inserting record with key {}", key); + insert(camelContext, correlationId, exchange, getRepositoryName(), 1L); + } + + } catch (Exception e) { + throw new RuntimeException("Error adding to repository " + repositoryName + " with key " + key, e); + } + + return result; + }); + } + + /** + * Updates the current exchange details in the given repository table. + * + * @param camelContext Current CamelContext + * @param key Correlation key + * @param exchange Aggregated exchange + * @param repositoryName Table's name + * @param version Version identifier + */ + protected void update( + final CamelContext camelContext, final String key, final Exchange exchange, String repositoryName, Long version) + throws Exception { + StringBuilder queryBuilder = new StringBuilder() + .append("UPDATE ").append(repositoryName) + .append(" SET ") + .append(EXCHANGE).append(" = ?") + .append(", ") + .append(VERSION).append(" = ?"); + if (storeBodyAsText) { + queryBuilder.append(", ").append(BODY).append(" = ?"); + } + + if (hasHeadersToStoreAsText()) { + for (String headerName : headersToStoreAsText) { + queryBuilder.append(", ").append(headerName).append(" = ?"); + } + } + + queryBuilder.append(" WHERE ") + .append(ID).append(" = ?") + .append(" AND ") + .append(VERSION).append(" = ?"); + + String sql = queryBuilder.toString(); + updateHelper(camelContext, key, exchange, sql, version); + } + + /** + * Inserts a new record into the given repository table. Note: the exchange properties are NOT persisted. + * + * @param camelContext Current CamelContext + * @param correlationId Correlation key + * @param exchange Aggregated exchange to insert + * @param repositoryName Table's name + * @param version Version identifier + */ + protected void insert( + final CamelContext camelContext, final String correlationId, final Exchange exchange, String repositoryName, + Long version) + throws Exception { + // The default totalParameterIndex is 3 for ID, Exchange and version. Depending on logic this will be increased. + int totalParameterIndex = 3; + StringBuilder queryBuilder = new StringBuilder() + .append("INSERT INTO ").append(repositoryName) + .append('(').append(EXCHANGE) + .append(", ").append(ID) + .append(", ").append(VERSION); + + if (storeBodyAsText) { + queryBuilder.append(", ").append(BODY); + totalParameterIndex++; + } + + if (hasHeadersToStoreAsText()) { + for (String headerName : headersToStoreAsText) { + queryBuilder.append(", ").append(headerName); + totalParameterIndex++; + } + } + + queryBuilder.append(") VALUES ("); + + for (int i = 0; i < totalParameterIndex - 1; i++) { + queryBuilder.append("?, "); + } + queryBuilder.append("?)"); + + String sql = queryBuilder.toString(); + + insertHelper(camelContext, correlationId, exchange, sql, version); + } + + protected int insertHelper( + final CamelContext camelContext, final String key, final Exchange exchange, String sql, final Long version) + throws Exception { + final byte[] data = codec.marshallExchange(camelContext, exchange, allowSerializedHeaders); + Integer insertCount = jdbcTemplate.execute(sql, + new AbstractLobCreatingPreparedStatementCallback(getLobHandler()) { + @Override + protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException { + int totalParameterIndex = 0; + lobCreator.setBlobAsBytes(ps, ++totalParameterIndex, data); + ps.setString(++totalParameterIndex, key); + ps.setLong(++totalParameterIndex, version); + if (storeBodyAsText) { + ps.setString(++totalParameterIndex, exchange.getIn().getBody(String.class)); + } + if (hasHeadersToStoreAsText()) { + for (String headerName : headersToStoreAsText) { + String headerValue = exchange.getIn().getHeader(headerName, String.class); + ps.setString(++totalParameterIndex, headerValue); + } + } + } + }); + return insertCount == null ? 0 : insertCount; + } + + protected int updateHelper( + final CamelContext camelContext, final String key, final Exchange exchange, String sql, final Long version) + throws Exception { + final byte[] data = codec.marshallExchange(camelContext, exchange, allowSerializedHeaders); + Integer updateCount = jdbcTemplate.execute(sql, + new AbstractLobCreatingPreparedStatementCallback(getLobHandler()) { + @Override + protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException { + int totalParameterIndex = 0; + lobCreator.setBlobAsBytes(ps, ++totalParameterIndex, data); + ps.setLong(++totalParameterIndex, version + 1); + if (storeBodyAsText) { + ps.setString(++totalParameterIndex, exchange.getIn().getBody(String.class)); + } + if (hasHeadersToStoreAsText()) { + for (String headerName : headersToStoreAsText) { + String headerValue = exchange.getIn().getHeader(headerName, String.class); + ps.setString(++totalParameterIndex, headerValue); + } + } + ps.setString(++totalParameterIndex, key); + ps.setLong(++totalParameterIndex, version); + } + }); + if (updateCount == 1) { + return updateCount; + } else { + // Found stale version while updating record + throw new OptimisticLockingException(); + } + } + + @Override + public Exchange get(final CamelContext camelContext, final String correlationId) { + final String key = correlationId; + Exchange result = get(key, getRepositoryName(), camelContext); + LOG.debug("Getting key {} -> {}", key, result); + return result; + } + + private Exchange get(final String key, final String repositoryName, final CamelContext camelContext) { + return transactionTemplateReadOnly.execute(status -> { + try { + + Map columns = jdbcTemplate.queryForMap( + String.format("SELECT %1$s, %2$s FROM %3$s WHERE %4$s=?", EXCHANGE, VERSION, repositoryName, ID), + new Object[]{key}, new int[]{Types.VARCHAR}); + + byte[] marshalledExchange = (byte[]) columns.get(EXCHANGE); + long version = (long) columns.get(VERSION); + + Exchange result = codec.unmarshallExchange(camelContext, marshalledExchange); + result.setProperty(VERSION_PROPERTY, version); + return result; + + } catch (EmptyResultDataAccessException ex) { + return null; + } catch (IOException ex) { + // Rollback the transaction + throw new RuntimeException("Error getting key " + key + " from repository " + repositoryName, ex); + } catch (ClassNotFoundException ex) { + // Rollback the transaction + throw new RuntimeException(ex); + } + }); + } + + + @Override + public void remove(final CamelContext camelContext, final String correlationId, final Exchange exchange) { + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + protected void doInTransactionWithoutResult(TransactionStatus status) { + final String key = correlationId; + final String confirmKey = exchange.getExchangeId(); + final long version = exchange.getProperty(VERSION_PROPERTY, Long.class); + try { + LOG.debug("Removing key {}", key); + + // добавлена проверка на корректное удаление из таблицы, т к возникала ситуация гонки на узлах. + // один узел уже удалил из completed, а второй в процессе, соответственно ошибки дублирования + // не появляется появляется дубликат в очереди + if (jdbcTemplate.update("DELETE FROM " + getRepositoryName() + " WHERE " + ID + " = ? AND " + VERSION + " = ?", + key, version) == 1) { + insert(camelContext, confirmKey, exchange, getRepositoryNameCompleted(), version); + } else { + throw new RuntimeException("Error removing key " + key + " from repository " + repositoryName); + } + + } catch (Exception e) { + throw new RuntimeException("Error removing key " + key + " from repository " + repositoryName, e); + } + } + }); + } + + @Override + public void confirm(final CamelContext camelContext, final String exchangeId) { + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + protected void doInTransactionWithoutResult(TransactionStatus status) { + LOG.debug("Confirming exchangeId {}", exchangeId); + final String confirmKey = exchangeId; + + jdbcTemplate.update("DELETE FROM " + getRepositoryNameCompleted() + " WHERE " + ID + " = ?", + confirmKey); + + } + }); + } + + @Override + public Set getKeys() { + return getKeys(getRepositoryName()); + } + + @Override + public Set scan(CamelContext camelContext) { + return getKeys(getRepositoryNameCompleted()); + } + + /** + * Returns the keys in the given repository + * + * @param repositoryName The name of the table + * @return Set of keys in the given repository name + */ + protected Set getKeys(final String repositoryName) { + return transactionTemplateReadOnly.execute(status -> { + List keys = jdbcTemplate.query("SELECT " + ID + " FROM " + repositoryName, + (rs, rowNum) -> { + String id = rs.getString(ID); + LOG.trace("getKey {}", id); + return id; + }); + return new LinkedHashSet<>(keys); + }); + } + + @Override + public Exchange recover(CamelContext camelContext, String exchangeId) { + final String key = exchangeId; + Exchange answer = get(key, getRepositoryNameCompleted(), camelContext); + LOG.debug("Recovering exchangeId {} -> {}", key, answer); + return answer; + } + + /** + * If recovery is enabled then a background task is run every x'th time to scan for failed exchanges to recover and + * resubmit. By default this interval is 5000 millis. + */ + @Override + public void setRecoveryInterval(long interval, TimeUnit timeUnit) { + this.recoveryInterval = timeUnit.toMillis(interval); + } + + @Override + public void setRecoveryInterval(long interval) { + this.recoveryInterval = interval; + } + + @Override + public long getRecoveryIntervalInMillis() { + return recoveryInterval; + } + + @Override + public boolean isUseRecovery() { + return useRecovery; + } + + /** + * Whether or not recovery is enabled. This option is by default true. When enabled the Camel Aggregator automatic + * recover failed aggregated exchange and have them resubmitted. + */ + @Override + public void setUseRecovery(boolean useRecovery) { + this.useRecovery = useRecovery; + } + + @Override + public int getMaximumRedeliveries() { + return maximumRedeliveries; + } + + @Override + public void setMaximumRedeliveries(int maximumRedeliveries) { + this.maximumRedeliveries = maximumRedeliveries; + } + + @Override + public String getDeadLetterUri() { + return deadLetterUri; + } + + /** + * An endpoint uri for a Dead Letter Channel where exhausted recovered Exchanges will be moved. If this option is + * used then the maximumRedeliveries option must also be provided. Important note : if the deadletter route throws + * an exception, it will be send again to DLQ until it succeed ! + */ + @Override + public void setDeadLetterUri(String deadLetterUri) { + this.deadLetterUri = deadLetterUri; + } + + public boolean isReturnOldExchange() { + return returnOldExchange; + } + + /** + * Whether the get operation should return the old existing Exchange if any existed. By default this option is false + * to optimize as we do not need the old exchange when aggregating. + */ + public void setReturnOldExchange(boolean returnOldExchange) { + this.returnOldExchange = returnOldExchange; + } + + public void setJdbcCamelCodec(JdbcCamelCodec codec) { + this.codec = codec; + } + + public boolean hasHeadersToStoreAsText() { + return this.headersToStoreAsText != null && !this.headersToStoreAsText.isEmpty(); + } + + public List getHeadersToStoreAsText() { + return headersToStoreAsText; + } + + /** + * Allows to store headers as String which is human readable. By default this option is disabled, storing the + * headers in binary format. + * + * @param headersToStoreAsText the list of headers to store as String + */ + public void setHeadersToStoreAsText(List headersToStoreAsText) { + this.headersToStoreAsText = headersToStoreAsText; + } + + public boolean isStoreBodyAsText() { + return storeBodyAsText; + } + + /** + * Whether to store the message body as String which is human readable. By default this option is false storing the + * body in binary format. + */ + public void setStoreBodyAsText(boolean storeBodyAsText) { + this.storeBodyAsText = storeBodyAsText; + } + + public boolean isAllowSerializedHeaders() { + return allowSerializedHeaders; + } + + public void setAllowSerializedHeaders(boolean allowSerializedHeaders) { + this.allowSerializedHeaders = allowSerializedHeaders; + } + + public int getPropagationBehavior() { + return propagationBehavior; + } + + /** + * Sets propagation behavior to use with spring transaction templates which are used for database access. The + * default is TransactionDefinition.PROPAGATION_REQUIRED. + */ + public void setPropagationBehavior(int propagationBehavior) { + this.propagationBehavior = propagationBehavior; + } + + /** + * Sets propagation behavior to use with spring transaction templates which are used for database access. The + * default is TransactionDefinition.PROPAGATION_REQUIRED. This setter accepts names of the constants, like + * "PROPAGATION_REQUIRED". + * + * @param propagationBehaviorName + */ + public void setPropagationBehaviorName(String propagationBehaviorName) { + if (!propagationBehaviorName.startsWith(DefaultTransactionDefinition.PREFIX_PROPAGATION)) { + throw new IllegalArgumentException("Only propagation constants allowed"); + } + setPropagationBehavior(PROPAGATION_CONSTANTS.asNumber(propagationBehaviorName).intValue()); + } + + public LobHandler getLobHandler() { + return lobHandler; + } + + /** + * Sets a custom LobHandler to use + */ + public void setLobHandler(LobHandler lobHandler) { + this.lobHandler = lobHandler; + } + + public JdbcOptimisticLockingExceptionMapper getJdbcOptimisticLockingExceptionMapper() { + return jdbcOptimisticLockingExceptionMapper; + } + + public void setJdbcOptimisticLockingExceptionMapper( + JdbcOptimisticLockingExceptionMapper jdbcOptimisticLockingExceptionMapper) { + this.jdbcOptimisticLockingExceptionMapper = jdbcOptimisticLockingExceptionMapper; + } + + public String getRepositoryName() { + return repositoryName; + } + + public String getRepositoryNameCompleted() { + return getRepositoryName() + "_completed"; + } + + @Override + protected void doInit() throws Exception { + super.doInit(); + + ObjectHelper.notNull(repositoryName, "RepositoryName"); + ObjectHelper.notNull(transactionManager, "TransactionManager"); + ObjectHelper.notNull(dataSource, "DataSource"); + + transactionTemplate = new TransactionTemplate(transactionManager); + transactionTemplate.setPropagationBehavior(propagationBehavior); + + transactionTemplateReadOnly = new TransactionTemplate(transactionManager); + transactionTemplateReadOnly.setPropagationBehavior(propagationBehavior); + transactionTemplateReadOnly.setReadOnly(true); + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + + // log number of existing exchanges + int current = getKeys().size(); + int completed = scan(null).size(); + + if (current > 0) { + LOG.info("On startup there are " + current + " aggregate exchanges (not completed) in repository: " + + getRepositoryName()); + } else { + LOG.info("On startup there are no existing aggregate exchanges (not completed) in repository: {}", + getRepositoryName()); + } + if (completed > 0) { + LOG.warn("On startup there are " + completed + " completed exchanges to be recovered in repository: " + + getRepositoryNameCompleted()); + } else { + LOG.info("On startup there are no completed exchanges to be recovered in repository: {}", + getRepositoryNameCompleted()); + } + } + + @Override + protected void doStop() throws Exception { + // noop + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/repo/PostgresAggregationRepository.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/repo/PostgresAggregationRepository.java new file mode 100644 index 00000000..e751b27f --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/aggregation/repo/PostgresAggregationRepository.java @@ -0,0 +1,97 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.aggregation.repo; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.sql.DataSource; + +/** + * PostgreSQL specific {@link JdbcAggregationRepository} that deals with SQL Violation Exceptions using special + * {@code INSERT INTO .. ON CONFLICT DO NOTHING} claues. + */ +public class PostgresAggregationRepository extends JdbcAggregationRepository { + + /** + * Creates an aggregation repository + */ + public PostgresAggregationRepository() { + } + + /** + * Creates an aggregation repository with the three mandatory parameters + */ + public PostgresAggregationRepository(PlatformTransactionManager transactionManager, String repositoryName, + DataSource dataSource) { + super(transactionManager, repositoryName, dataSource); + } + + /** + * Inserts a new record into the given repository table + * + * @param camelContext the current CamelContext + * @param correlationId the correlation key + * @param exchange the aggregated exchange + * @param repositoryName The name of the table + */ + protected void insert( + final CamelContext camelContext, final String correlationId, final Exchange exchange, String repositoryName) + throws Exception { + // The default totalParameterIndex is 2 for ID and Exchange. Depending on logic this will be increased + int totalParameterIndex = 2; + StringBuilder queryBuilder = new StringBuilder() + .append("INSERT INTO ").append(repositoryName) + .append('(') + .append(EXCHANGE).append(", ") + .append(ID); + + if (isStoreBodyAsText()) { + queryBuilder.append(", ").append(BODY); + totalParameterIndex++; + } + + if (hasHeadersToStoreAsText()) { + for (String headerName : getHeadersToStoreAsText()) { + queryBuilder.append(", ").append(headerName); + totalParameterIndex++; + } + } + + queryBuilder.append(") VALUES ("); + + for (int i = 0; i < totalParameterIndex - 1; i++) { + queryBuilder.append("?, "); + } + queryBuilder.append("?)"); + + queryBuilder.append(" ON CONFLICT DO NOTHING"); + + String sql = queryBuilder.toString(); + + int updateCount = insertHelper(camelContext, correlationId, exchange, sql, 1L); + if (updateCount == 0 && getRepositoryName().equals(repositoryName)) { + throw new DataIntegrityViolationException("No row was inserted due to data violation"); + } + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/BundleNotFound.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/BundleNotFound.java new file mode 100644 index 00000000..5f8a489a --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/BundleNotFound.java @@ -0,0 +1,44 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.exception; + +public class BundleNotFound extends RuntimeException { + + public BundleNotFound() { + super(); + } + + public BundleNotFound(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public BundleNotFound(String message, Throwable cause) { + super(message, cause); + } + + public BundleNotFound(String message) { + super(message); + } + + public BundleNotFound(Throwable cause) { + super(cause); + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/ConnectorNotFound.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/ConnectorNotFound.java new file mode 100644 index 00000000..b1508803 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/ConnectorNotFound.java @@ -0,0 +1,44 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.exception; + +public class ConnectorNotFound extends RuntimeException { + + public ConnectorNotFound() { + super(); + } + + public ConnectorNotFound(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public ConnectorNotFound(String message, Throwable cause) { + super(message, cause); + } + + public ConnectorNotFound(String message) { + super(message); + } + + public ConnectorNotFound(Throwable cause) { + super(cause); + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/EsbNotFound.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/EsbNotFound.java new file mode 100644 index 00000000..a64c0ace --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/EsbNotFound.java @@ -0,0 +1,44 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.exception; + +public class EsbNotFound extends RuntimeException { + + public EsbNotFound() { + super(); + } + + public EsbNotFound(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public EsbNotFound(String message, Throwable cause) { + super(message, cause); + } + + public EsbNotFound(String message) { + super(message); + } + + public EsbNotFound(Throwable cause) { + super(cause); + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/ProfileNotFound.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/ProfileNotFound.java new file mode 100644 index 00000000..5760c718 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/ProfileNotFound.java @@ -0,0 +1,46 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.exception; + +public class ProfileNotFound extends RuntimeException { + + private static final long serialVersionUID = 6701844035750412423L; + + public ProfileNotFound() { + super(); + } + + public ProfileNotFound(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public ProfileNotFound(String message, Throwable cause) { + super(message, cause); + } + + public ProfileNotFound(String message) { + super(message); + } + + public ProfileNotFound(Throwable cause) { + super(cause); + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/TemplateNotFound.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/TemplateNotFound.java new file mode 100644 index 00000000..470068c9 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/exception/TemplateNotFound.java @@ -0,0 +1,44 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.exception; + +public class TemplateNotFound extends RuntimeException { + + public TemplateNotFound() { + super(); + } + + public TemplateNotFound(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public TemplateNotFound(String message, Throwable cause) { + super(message, cause); + } + + public TemplateNotFound(String message) { + super(message); + } + + public TemplateNotFound(Throwable cause) { + super(cause); + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/interceptor/SoapHeaderInterceptor.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/interceptor/SoapHeaderInterceptor.java new file mode 100644 index 00000000..1f773002 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/interceptor/SoapHeaderInterceptor.java @@ -0,0 +1,70 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.interceptor; + +import org.apache.cxf.binding.soap.SoapMessage; +import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; +import org.apache.cxf.headers.Header; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.jaxb.JAXBDataBinding; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.Phase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.xml.bind.JAXBException; +import javax.xml.namespace.QName; +import java.util.List; +import java.util.Map; + +public class SoapHeaderInterceptor extends AbstractSoapInterceptor { + + private static final Logger log = LoggerFactory.getLogger(SoapHeaderInterceptor.class); + + private static final String HEADER_USER_LOGIN = "X-ForwardedUser"; + private static final String HEADER_CREATED_BY = "createdBy"; + private String namespaceUri = ""; + + public SoapHeaderInterceptor() { + super(Phase.READ); + } + + public void handleMessage(SoapMessage message) throws Fault { + try { + Map> headers = (Map>) message.get(Message.PROTOCOL_HEADERS); + List

soapHeaders = message.getHeaders(); + soapHeaders.add(new Header(new QName(namespaceUri, HEADER_CREATED_BY), + getSystemName(headers), new JAXBDataBinding(String.class))); + message.put(Header.HEADER_LIST, soapHeaders); + } catch (JAXBException e) { + log.error("Error", e); + throw new Fault(e); + } + } + + private String getSystemName(Map> headers) { + List list = headers.get(HEADER_USER_LOGIN); + return list != null && !list.isEmpty() ? headers.get(HEADER_USER_LOGIN).get(0) : null; + } + + public void setNamespaceUri(String namespaceUri) { + this.namespaceUri = namespaceUri; + } +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/BundleMarkerService.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/BundleMarkerService.java new file mode 100644 index 00000000..b3f396d8 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/BundleMarkerService.java @@ -0,0 +1,37 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.osgi; + +import java.util.List; + +/** + * @author starovoitenkov_sv + * + */ +public interface BundleMarkerService { + + public static final String CATEGORY_PROPERTY_NAME = "ru.entaxy.esb.system.common.marker.category"; + + public long getBundleId(); + + public String getMarkerCategory(); + + public List getMarkers(); +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/NamedReferenceListener.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/NamedReferenceListener.java new file mode 100644 index 00000000..c177d718 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/NamedReferenceListener.java @@ -0,0 +1,32 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.osgi; + +import java.util.List; + +public interface NamedReferenceListener extends ReferenceListener { + + public List getReferenceNames(); + + public T getReference(String referenceName); + + public boolean isRegistered(String referenceName); + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/OSGIUtils.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/OSGIUtils.java new file mode 100644 index 00000000..c11ea0ca --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/OSGIUtils.java @@ -0,0 +1,36 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.osgi; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; + +public class OSGIUtils { + + static public Object getServiceReference(BundleContext bundle, String className) { + Object result = null; + ServiceReference ref = bundle.getServiceReference(className); + if (ref != null) { + result = bundle.getService(ref); + } + return result; + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/ReferenceListener.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/ReferenceListener.java new file mode 100644 index 00000000..8a25039b --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/ReferenceListener.java @@ -0,0 +1,26 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.osgi; + +public interface ReferenceListener { + public void register(T service) throws Exception; + + public void unregister(T service) throws Exception; +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/UniformBundleTracker.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/UniformBundleTracker.java new file mode 100644 index 00000000..5c260661 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/UniformBundleTracker.java @@ -0,0 +1,58 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.osgi; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleEvent; +import org.osgi.util.tracker.BundleTrackerCustomizer; + +public abstract class UniformBundleTracker implements BundleTrackerCustomizer { + + @Override + public Object addingBundle(Bundle bundle, BundleEvent event) { + if (event == null) { + // existing bundles first added to the tracker with no event change + checkInitialBundle(bundle); + } else { + bundleChanged(event); + } + return bundle; + } + + @Override + public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) { + if (event == null) { + // cannot think of why we would be interested in a modified bundle with no bundle event + return; + } + bundleChanged(event); + } + + @Override + public void removedBundle(Bundle bundle, BundleEvent event, Object object) { + // TODO Auto-generated method stub + + } + + protected abstract void checkInitialBundle(Bundle bundle); + + protected abstract void bundleChanged(BundleEvent event); + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/impl/BundleMarkerServiceImpl.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/impl/BundleMarkerServiceImpl.java new file mode 100644 index 00000000..e0a534c4 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/impl/BundleMarkerServiceImpl.java @@ -0,0 +1,113 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.osgi.impl; + +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.blueprint.container.BlueprintContainer; +import ru.entaxy.esb.system.common.osgi.BundleMarkerService; + +import java.util.*; + +/** + * @author starovoitenkov_sv + * + */ +public class BundleMarkerServiceImpl implements BundleMarkerService { + + protected Bundle bundle = null; + protected BlueprintContainer container = null; + protected List markers = new ArrayList(); + protected String category = null; + protected ServiceRegistration serviceRegistration = null; + protected Map serviceProperties = new HashMap(); + + /* (non-Javadoc) + * @see ru.entaxy.esb.system.common.osgi.BundleMarkerService#getBundleId() + */ + @Override + public long getBundleId() { + return (bundle == null ? -1 : bundle.getBundleId()); + } + + /* (non-Javadoc) + * @see ru.entaxy.esb.system.common.osgi.BundleMarkerService#getMarkerCategory() + */ + @Override + public String getMarkerCategory() { + return category; + } + + /* (non-Javadoc) + * @see ru.entaxy.esb.system.common.osgi.BundleMarkerService#getMarkers() + */ + @Override + public List getMarkers() { + return markers; + } + + // LOCAL + + @SuppressWarnings({"rawtypes", "unchecked"}) + public void init() throws Exception { + if (bundle == null) + throw new Exception("Bundle not set"); + if (container == null) + throw new Exception("Container not set"); + Dictionary properties = new Hashtable(); + + for (Map.Entry entry : serviceProperties.entrySet()) + properties.put(entry.getKey(), entry.getValue()); + properties.put(BundleMarkerService.CATEGORY_PROPERTY_NAME, category); + serviceRegistration = bundle.getBundleContext().registerService(BundleMarkerService.class.getName(), this, properties); + } + + public void destroy() { + if (serviceRegistration != null) + serviceRegistration.unregister(); + } + + // ACCESSORS + + public void setBundle(Bundle bundle) { + this.bundle = bundle; + } + + public void setContainer(BlueprintContainer container) { + this.container = container; + } + + public void setMarkers(List markers) { + this.markers = markers; + } + + public void setCategory(String category) { + this.category = category; + } + + public Map getServiceProperties() { + return serviceProperties; + } + + public void setServiceProperties(Map serviceProperties) { + this.serviceProperties = serviceProperties; + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/impl/CommonNamedReferenceListener.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/impl/CommonNamedReferenceListener.java new file mode 100644 index 00000000..ab6a8863 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/impl/CommonNamedReferenceListener.java @@ -0,0 +1,71 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.osgi.impl; + +import org.osgi.framework.ServiceReference; +import ru.entaxy.esb.system.common.osgi.NamedReferenceListener; + +import java.util.*; + +public abstract class CommonNamedReferenceListener implements NamedReferenceListener { + + protected Map registeredReferences = new HashMap(); + + public void register(T service) throws Exception { + if (service instanceof ServiceReference) + return; + String key = getObjectName(service); + registeredReferences.put(key, service); + doAfterRegister(service); + } + + protected void doAfterRegister(T service) throws Exception { + + } + + protected void doBeforeUnregister(T service) throws Exception { + + } + + public void unregister(T service) throws Exception { + if (service == null || service instanceof ServiceReference) + return; + doBeforeUnregister(service); + registeredReferences.remove(getObjectName(service)); + } + + @Override + public List getReferenceNames() { + List result = new ArrayList(registeredReferences.keySet()); + Collections.sort(result); + return result; + } + + @Override + public T getReference(String referenceName) { + return registeredReferences.get(referenceName); + } + + public boolean isRegistered(String referenceName) { + return registeredReferences.containsKey(referenceName); + } + + protected abstract String getObjectName(T object); +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/impl/CommonReferenceListener.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/impl/CommonReferenceListener.java new file mode 100644 index 00000000..148c2009 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/osgi/impl/CommonReferenceListener.java @@ -0,0 +1,56 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.osgi.impl; + +import org.osgi.framework.ServiceReference; +import ru.entaxy.esb.system.common.osgi.ReferenceListener; + +import java.util.ArrayList; +import java.util.List; + +public class CommonReferenceListener implements ReferenceListener { + + protected List registeredReferences = new ArrayList(); + + public void register(T service) { + if (service instanceof ServiceReference) + return; + registeredReferences.add(service); + doAfterRegister(service); + } + + protected void doAfterRegister(T service) { + // to override + } + + protected void doBeforeUnregister(T service) { + // to override + } + + public void unregister(T service) { + if (service instanceof ServiceReference) + return; + if (registeredReferences.contains(service)) { + doBeforeUnregister(service); + registeredReferences.remove(service); + } + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/util/CustomHeader.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/util/CustomHeader.java new file mode 100644 index 00000000..9db01434 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/util/CustomHeader.java @@ -0,0 +1,60 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.util; + +public class CustomHeader { + + private String id; + private String type; + private String value; + + public CustomHeader() { + } + + public CustomHeader(String id, String type, String value) { + this.id = id; + this.type = type; + this.value = value; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/util/HeadersConverter.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/util/HeadersConverter.java new file mode 100644 index 00000000..757dc893 --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/util/HeadersConverter.java @@ -0,0 +1,183 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.util; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.apache.camel.Exchange; +import org.apache.xerces.dom.DocumentImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class HeadersConverter { + protected static final Logger log = LoggerFactory.getLogger(HeadersConverter.class); + + private String customHeaders; + private String customHeaderPrefix; + private String namespace; + + public void xml2camelHeaders(Exchange exchange) { + NodeList nodes = exchange.getIn().getHeader(customHeaders, NodeList.class); + + if (nodes == null) { + log.warn(customHeaders + " not found"); + return; + } + + for (int i = 0; i < nodes.getLength(); ++i) { + Node child = nodes.item(i).getFirstChild(); + String headerName = ""; + String headerValue = ""; + while (child != null) { + if ("id".equals(child.getLocalName())) { + headerName = customHeaderPrefix + child.getTextContent(); + } else if ("value".equals(child.getLocalName())) { + headerValue = child.getTextContent(); + } + child = child.getNextSibling(); + } + if (!headerName.isEmpty()) { + exchange.getIn().setHeader(headerName, headerValue); + } + } + + log.debug("Parsed xml custom headers count {}", nodes.getLength()); + } + + public void camelHeaders2xml(Exchange exchange) { + Node item = null; + Node child = null; + Document xmlDoc = new DocumentImpl(); + Node list = xmlDoc.createElement("list"); + + for (Map.Entry entry : exchange.getIn().getHeaders().entrySet()) { + if (entry.getKey().startsWith(customHeaderPrefix)) { + String name = entry.getKey().substring(customHeaderPrefix.length()); + if (entry.getValue() == null) break; + String value = entry.getValue().toString(); + + item = xmlDoc.createElementNS(namespace, "customHeader"); + + child = xmlDoc.createElementNS(namespace, "id"); + child.appendChild(xmlDoc.createTextNode(name)); + item.appendChild(child); + + child = xmlDoc.createElementNS(namespace, "value"); + child.appendChild(xmlDoc.createTextNode(value)); + item.appendChild(child); + + list.appendChild(item); + } + } + + exchange.getIn().setHeader(customHeaders, list); + } + + public void xml2Json(Exchange exchange) { + NodeList nodes = exchange.getIn().getHeader(customHeaders, NodeList.class); + + if (nodes == null) { + log.warn(customHeaders + " not found"); + return; + } + + List customHeaders = new ArrayList<>(); + for (int i = 0; i < nodes.getLength(); ++i) { + Node child = nodes.item(i).getFirstChild(); + String headerName = ""; + String headerValue = ""; + String headerType = ""; + while (child != null) { + if ("id".equals(child.getLocalName())) { + headerName = child.getTextContent(); + } else if ("value".equals(child.getLocalName())) { + headerValue = child.getTextContent(); + } else if ("type".equals(child.getLocalName())) { + headerType = child.getTextContent(); + } + child = child.getNextSibling(); + } + if (!headerName.isEmpty()) { + customHeaders.add(new CustomHeader(headerName, headerType, headerValue)); + } + } + Gson gson = new Gson(); + exchange.getIn().setHeader(this.customHeaders, gson.toJson(customHeaders)); + + log.debug("Parsed xml custom headers count {}", nodes.getLength()); + } + + public void json2xml(Exchange exchange) { + String headers = exchange.getIn().getHeader(customHeaders, String.class); + + if (headers == null) { + log.warn(customHeaders + " not found"); + return; + } + + Gson gson = new Gson(); + List customHeaders = gson.fromJson(headers, new TypeToken>() { + }.getType()); + + Node item = null; + Node child = null; + Document xmlDoc = new DocumentImpl(); + Node list = xmlDoc.createElement("list"); + + for (CustomHeader customHeader : customHeaders) { + item = xmlDoc.createElementNS(namespace, "customHeader"); + + child = xmlDoc.createElementNS(namespace, "id"); + child.appendChild(xmlDoc.createTextNode(customHeader.getId())); + item.appendChild(child); + + child = xmlDoc.createElementNS(namespace, "type"); + child.appendChild(xmlDoc.createTextNode(customHeader.getType())); + item.appendChild(child); + + child = xmlDoc.createElementNS(namespace, "value"); + child.appendChild(xmlDoc.createTextNode(customHeader.getValue())); + item.appendChild(child); + + list.appendChild(item); + } + + exchange.getIn().setHeader(this.customHeaders, list); + } + + public void setCustomHeaderPrefix(String customHeaderPrefix) { + this.customHeaderPrefix = customHeaderPrefix; + } + + public void setCustomHeaders(String customHeaders) { + this.customHeaders = customHeaders; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/util/PropertiesHelper.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/util/PropertiesHelper.java new file mode 100644 index 00000000..ad82851d --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/util/PropertiesHelper.java @@ -0,0 +1,151 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class PropertiesHelper { + + private static final Log LOG = LogFactory.getLog(PropertiesHelper.class.getName()); + + private static final String EMPTY_STRING = ""; + + private String configPath; + private static final String karafEtcPath = System.getProperty("karaf.etc"); + private String configFile; + + private Properties properties; + + public PropertiesHelper() { + } + + public PropertiesHelper(String configPath) { + LOG.debug("Set custom path: " + configPath + " file: " + configFile); + this.configPath = configPath; + } + + public PropertiesHelper(String configPath, String configFile) { + LOG.debug("Load properties from custom path: " + configPath + " file: " + configFile); + this.configPath = configPath; + this.configFile = configFile; + loadProperties(configPath, configFile); + } + + public PropertiesHelper(String configFile, boolean loadKarafEtc) { + this.configFile = configFile; + LOG.debug("Load properties from karaf etc: " + karafEtcPath + " file: " + configFile); + if (loadKarafEtc) { + loadProperties(karafEtcPath, configFile); + LOG.debug("Loaded properties: " + (properties != null ? properties.size() : "null")); + } + } + + public Properties load() { + if (this.configPath != null && !this.configPath.isEmpty() + && this.configFile != null && !this.configFile.isEmpty()) { + return loadProperties(configPath, configFile); + } else if (this.configFile != null && !this.configFile.isEmpty()) { + return loadProperties(karafEtcPath, configFile); + } else { + throw new IllegalArgumentException("configPath OR configFile NOT SETTED"); + } + } + + protected Properties loadProperties(String path, String configFile) { + try (InputStream input = new FileInputStream(path + File.separator + configFile)) { + properties = new Properties(); + properties.load(input); + } catch (IOException ex) { + LOG.error(ex); + } + return properties; + } + + public long getInteger(String name) { + return getInteger(name, 0); + } + + public long getInteger(String name, int defaultValue) { + String value = this.properties.getProperty(name); + return value != null && !EMPTY_STRING.equals(value) ? Integer.valueOf(value) : defaultValue; + } + + public int getInteger(String name, String defaultValue) { + return Integer.valueOf(this.properties.getProperty(name, defaultValue)); + } + + public long getLong(String name) { + return getLong(name, 0L); + } + + public long getLong(String name, long defaultValue) { + String value = this.properties.getProperty(name); + return value != null && !EMPTY_STRING.equals(value) ? Long.valueOf(value) : defaultValue; + } + + public long getLong(String name, String defaultValue) { + return Long.valueOf(this.properties.getProperty(name, defaultValue)); + } + + public String getString(String name) { + return this.properties.getProperty(name, EMPTY_STRING); + } + + public String getString(String name, String defaultValue) { + return this.properties.getProperty(name, defaultValue); + } + + public String[] getStringArray(String name, String[] defaultValue) { + String value = this.properties.getProperty(name, EMPTY_STRING); + return !value.equals(EMPTY_STRING) ? value.split(",") : defaultValue; + } + + public String getConfigPath() { + return configPath; + } + + public void setConfigPath(String configPath) { + this.configPath = configPath; + } + + public String getConfigFile() { + return configFile; + } + + public void setConfigFile(String configFile) { + this.configFile = configFile; + } + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/util/SimpleOutHeaderFilterStrategy.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/util/SimpleOutHeaderFilterStrategy.java new file mode 100644 index 00000000..85b811ce --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/util/SimpleOutHeaderFilterStrategy.java @@ -0,0 +1,50 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.util; + +import org.apache.camel.Exchange; +import org.apache.camel.spi.HeaderFilterStrategy; + +import java.util.HashSet; +import java.util.Set; + +public class SimpleOutHeaderFilterStrategy implements HeaderFilterStrategy { + + private Set outFilter; + + public void setOutFilter(Set value) { + if (value == null) { + outFilter = new HashSet<>(); + } else { + outFilter = value; + } + } + + @Override + public boolean applyFilterToCamelHeaders(String headerName, Object headerValue, Exchange exchange) { + return !outFilter.contains(headerName); + } + + @Override + public boolean applyFilterToExternalHeaders(String headerName, Object headerValue, Exchange exchange) { + return false; + } + +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/util/SystemHeadersConstants.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/util/SystemHeadersConstants.java new file mode 100644 index 00000000..2812fdcd --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/util/SystemHeadersConstants.java @@ -0,0 +1,31 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.util; + +public class SystemHeadersConstants { + public static final String HEADER_USER_LOGIN = "X-ForwardedUser"; + public static final String HEADER_USER_ID = "X-ForwardedUserId"; + public static final String HEADER_SYSTEM_NAME = "X-SystemName"; + public static final String HEADER_SYSTEM_UUID = "X-SystemUuid"; + public static final String HEADER_SYSTEM_ID = "X-SystemId"; + + private SystemHeadersConstants() { + } +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/validator/ValidateInterceptor.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/validator/ValidateInterceptor.java new file mode 100644 index 00000000..18410d1d --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/validator/ValidateInterceptor.java @@ -0,0 +1,116 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.validator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.binding.soap.SoapMessage; +import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.phase.AbstractPhaseInterceptor; +import org.apache.cxf.phase.Phase; +import org.apache.cxf.service.Service; +import org.apache.cxf.service.model.ServiceModelUtil; +import org.apache.cxf.ws.addressing.EndpointReferenceUtils; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +import javax.xml.soap.SOAPMessage; +import javax.xml.stream.XMLStreamException; +import javax.xml.transform.dom.DOMSource; +import javax.xml.validation.Schema; +import javax.xml.validation.Validator; +import javax.xml.xpath.XPathExpressionException; +import java.io.IOException; +import java.util.List; + +public class ValidateInterceptor extends AbstractPhaseInterceptor { + + private static final Log LOG = LogFactory.getLog(ValidateInterceptor.class); + + private final SAAJInInterceptor saajIn; + private final XmlParser xmlParser; + private boolean schemaValidationEnabled; + + public ValidateInterceptor() { + super(Phase.PRE_PROTOCOL); + saajIn = new SAAJInInterceptor(); + xmlParser = new XmlParser(); + + getAfter().add(SAAJInInterceptor.class.getName()); + } + + @Override + public void handleMessage(SoapMessage message) throws Fault { + try { + Node body = getMessageBody((DOMSource) getSOAPMessage(message).getSOAPPart().getContent()); + if (body != null) + validate(body, message); + else + throw new XMLStreamException("Can't find the tag \"Body\""); + } catch (RuntimeException re) { + throw re; + } catch (Exception e) { + throw new Fault(e); + } + } + + private Node getMessageBody(DOMSource source) throws XPathExpressionException { + Node node = source.getNode().cloneNode(true); + List nodeList = xmlParser.getNodes(node.getLastChild(), "Body"); + return !nodeList.isEmpty() ? nodeList.get(0) : null; + } + + private void validate(Node node, SoapMessage soapMessage) throws IOException, SAXException, XPathExpressionException { + Validator validator = getValidator(soapMessage); + validator.validate(new DOMSource(getNodeForValidate(node))); + } + + private Node getNodeForValidate(Node node) throws XPathExpressionException { + if (schemaValidationEnabled && node.getLocalName().contains("packets")) { + Element element = (Element) node; + for (Node content : xmlParser.getNodes(element, "content")) { + content.getParentNode().removeChild(content); + } + return element; + } + return node; + } + + private Validator getValidator(SoapMessage soapMessage) { + Service service = ServiceModelUtil.getService(soapMessage.getExchange()); + Schema schema = EndpointReferenceUtils.getSchema(service.getServiceInfos().get(0), soapMessage.getExchange().getBus()); + return schema.newValidator(); + } + + private SOAPMessage getSOAPMessage(SoapMessage smsg) { + SOAPMessage soapMessage = smsg.getContent(SOAPMessage.class); + if (soapMessage == null) { + saajIn.handleMessage(smsg); + soapMessage = smsg.getContent(SOAPMessage.class); + } + return soapMessage; + } + + public void setSchemaValidationEnabled(boolean schemaValidationEnabled) { + this.schemaValidationEnabled = schemaValidationEnabled; + } +} diff --git a/system/commons/src/main/java/ru/entaxy/esb/system/common/validator/XmlParser.java b/system/commons/src/main/java/ru/entaxy/esb/system/common/validator/XmlParser.java new file mode 100644 index 00000000..76f5ec2b --- /dev/null +++ b/system/commons/src/main/java/ru/entaxy/esb/system/common/validator/XmlParser.java @@ -0,0 +1,50 @@ +/*- + * ~~~~~~licensing~~~~~~ + * system-commons + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.common.validator; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.*; +import java.util.ArrayList; +import java.util.List; + +public class XmlParser { + + public List getNodes(Node node, String elementName) throws XPathExpressionException { + XPath xpath = XPathFactory.newInstance().newXPath(); + + XPathExpression expr = xpath.compile("//*[local-name()='" + elementName + "']/child::node()"); + NodeList nodeList = (NodeList) expr.evaluate(node.getOwnerDocument(), XPathConstants.NODESET); + + return getNotNullNodes(nodeList); + } + + private List getNotNullNodes(NodeList nodeList) { + List result = new ArrayList<>(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + if (node.getLocalName() != null) { + result.add(node); + } + } + return result; + } +} diff --git a/system/commons/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/system/commons/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 00000000..e847141c --- /dev/null +++ b/system/commons/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/commons/src/main/resources/config/bus.commons.cfg b/system/commons/src/main/resources/config/bus.commons.cfg new file mode 100644 index 00000000..df365efb --- /dev/null +++ b/system/commons/src/main/resources/config/bus.commons.cfg @@ -0,0 +1,20 @@ +### +# ~~~~~~licensing~~~~~~ +# system-commons +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +output.charset=Cp1251 diff --git a/system/component-bean-fix/LICENSE.txt b/system/component-bean-fix/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/component-bean-fix/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/component-bean-fix/pom.xml b/system/component-bean-fix/pom.xml new file mode 100644 index 00000000..b21aef6b --- /dev/null +++ b/system/component-bean-fix/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + + ru.entaxy.esb.system + system-parent + 1.8.0 + + + component-bean-fix + 1.8.0 + bundle + + CAMEL COMPONENT :: BEAN :: FIX + CAMEL COMPONENT :: BEAN :: FIX + + + + org.apache.camel + camel-support + ${camel.version} + + + org.apache.camel + camel-bean + + + + + + + org.codehaus.mojo + license-maven-plugin + + + update-file-header + none + + + + + + \ No newline at end of file diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/AbstractBeanProcessor.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/AbstractBeanProcessor.java new file mode 100644 index 00000000..abf407b7 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/AbstractBeanProcessor.java @@ -0,0 +1,249 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.*; +import org.apache.camel.support.AsyncProcessorSupport; +import org.apache.camel.support.service.ServiceHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A {@link Processor} which converts the inbound exchange to a method + * invocation on a POJO + */ +public abstract class AbstractBeanProcessor extends AsyncProcessorSupport { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractBeanProcessor.class); + + private final BeanHolder beanHolder; + private transient Processor processor; + private transient boolean lookupProcessorDone; + private final Object lock = new Object(); + private BeanScope scope; + private String method; + private boolean shorthandMethod; + + public AbstractBeanProcessor(Object pojo, BeanInfo beanInfo) { + this(new ConstantBeanHolder(pojo, beanInfo)); + } + + public AbstractBeanProcessor(Object pojo, CamelContext camelContext, ParameterMappingStrategy parameterMappingStrategy) { + this(pojo, new BeanInfo(camelContext, pojo.getClass(), parameterMappingStrategy)); + } + + public AbstractBeanProcessor(Object pojo, CamelContext camelContext) { + this(pojo, camelContext, BeanInfo.createParameterMappingStrategy(camelContext)); + } + + public AbstractBeanProcessor(BeanHolder beanHolder) { + this.beanHolder = beanHolder; + } + + @Override + public String toString() { + return "BeanProcessor[" + beanHolder + (method != null ? "#" + method : "") + "]"; + } + + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + // do we have an explicit method name we always should invoke (either configured on endpoint or as a header) + String explicitMethodName = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, method, String.class); + + Object bean; + BeanInfo beanInfo; + try { + bean = beanHolder.getBean(exchange); + // get bean info for this bean instance (to avoid thread issue) + beanInfo = beanHolder.getBeanInfo(bean); + if (beanInfo == null) { + // fallback and use old way + beanInfo = beanHolder.getBeanInfo(); + } + } catch (Throwable e) { + exchange.setException(e); + callback.done(true); + return true; + } + + // do we have a custom adapter for this POJO to a Processor + // but only do this if allowed + // we need to check beanHolder is Processor is support, to avoid the bean cached issue + if (allowProcessor(explicitMethodName, beanInfo)) { + Processor target = getProcessor(); + if (target == null) { + // only attempt to lookup the processor once or nearly once + // allow cache by default or if the scope is singleton + boolean allowCache = scope == null || scope == BeanScope.Singleton; + if (allowCache) { + if (!lookupProcessorDone) { + synchronized (lock) { + lookupProcessorDone = true; + // so if there is a custom type converter for the bean to processor + target = exchange.getContext().getTypeConverter().tryConvertTo(Processor.class, exchange, bean); + processor = target; + } + } + } else { + // so if there is a custom type converter for the bean to processor + target = exchange.getContext().getTypeConverter().tryConvertTo(Processor.class, exchange, bean); + } + } + if (target != null) { + if (LOG.isTraceEnabled()) { + LOG.trace("Using a custom adapter as bean invocation: {}", target); + } + try { + target.process(exchange); + } catch (Throwable e) { + exchange.setException(e); + } + callback.done(true); + return true; + } + } + + Message in = exchange.getIn(); + + // set explicit method name to invoke as a header, which is how BeanInfo can detect it + if (explicitMethodName != null) { + in.setHeader(Exchange.BEAN_METHOD_NAME, explicitMethodName); + } + + MethodInvocation invocation; + try { + invocation = beanInfo.createInvocation(bean, exchange); + } catch (Throwable e) { + exchange.setException(e); + callback.done(true); + return true; + } finally { + // must remove headers as they were provisional + if (explicitMethodName != null) { + in.removeHeader(Exchange.BEAN_METHOD_NAME); + } + } + + if (invocation == null) { + exchange.setException(new IllegalStateException("No method invocation could be created, no matching method could be found on: " + bean)); + callback.done(true); + return true; + } + + // invoke invocation + return invocation.proceed(callback); + } + + protected Processor getProcessor() { + return processor; + } + + protected BeanHolder getBeanHolder() { + return this.beanHolder; + } + + public Object getBean() { + return beanHolder.getBean(null); + } + + // Properties + // ----------------------------------------------------------------------- + + public String getMethod() { + return method; + } + + public BeanScope getScope() { + return scope; + } + + public void setScope(BeanScope scope) { + this.scope = scope; + } + + /** + * Sets the method name to use + */ + public void setMethod(String method) { + this.method = method; + } + + public boolean isShorthandMethod() { + return shorthandMethod; + } + + /** + * Sets whether to support getter style method name, so you can + * say the method is called 'name' but it will invoke the 'getName' method. + *

+ * Is by default turned off. + */ + public void setShorthandMethod(boolean shorthandMethod) { + this.shorthandMethod = shorthandMethod; + } + + // Implementation methods + //------------------------------------------------------------------------- + @Override + protected void doStart() throws Exception { + // optimize to only get (create) a processor if really needed + if (beanHolder.supportProcessor() && allowProcessor(method, beanHolder.getBeanInfo())) { + processor = beanHolder.getProcessor(); + ServiceHelper.startService(processor); + } else if (beanHolder instanceof ConstantBeanHolder) { + try { + // Start the bean if it implements Service interface and if cached + // so meant to be reused + ServiceHelper.startService(beanHolder.getBean(null)); + } catch (NoSuchBeanException e) { + // ignore + } + } + } + + @Override + protected void doStop() throws Exception { + if (processor != null) { + ServiceHelper.stopService(processor); + } else if (beanHolder instanceof ConstantBeanHolder) { + try { + // Stop the bean if it implements Service interface and if cached + // so meant to be reused + ServiceHelper.stopService(beanHolder.getBean(null)); + } catch (NoSuchBeanException e) { + // ignore + } + } + } + + private boolean allowProcessor(String explicitMethodName, BeanInfo info) { + if (explicitMethodName != null) { + // don't allow if explicit method name is given, as we then must invoke this method + return false; + } + + // don't allow if any of the methods has a @Handler annotation + // as the @Handler annotation takes precedence and is supposed to trigger invocation + // of the given method + if (info.hasAnyMethodHandlerAnnotation()) { + return false; + } + + // fallback and allow using the processor + return true; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/AbstractCamelInvocationHandler.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/AbstractCamelInvocationHandler.java new file mode 100644 index 00000000..985d1a25 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/AbstractCamelInvocationHandler.java @@ -0,0 +1,321 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.*; +import org.apache.camel.support.DefaultExchange; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.StringHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.*; + +public abstract class AbstractCamelInvocationHandler implements InvocationHandler { + + private static final Logger LOG = LoggerFactory.getLogger(CamelInvocationHandler.class); + private static final List EXCLUDED_METHODS = new ArrayList<>(); + private static ExecutorService executorService; + protected final Endpoint endpoint; + protected final Producer producer; + + static { + // exclude all java.lang.Object methods as we dont want to invoke them + EXCLUDED_METHODS.addAll(Arrays.asList(Object.class.getMethods())); + } + + public AbstractCamelInvocationHandler(Endpoint endpoint, Producer producer) { + this.endpoint = endpoint; + this.producer = producer; + } + + private static Object getBody(Exchange exchange, Class type) throws InvalidPayloadException { + if (exchange.getMessage().getBody() != null) { + return exchange.getMessage().getMandatoryBody(type); + } else { + return null; + } + } + + @Override + public final Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + if (isValidMethod(method)) { + return doInvokeProxy(proxy, method, args); + } else { + // invalid method then invoke methods on this instead + if ("toString".equals(method.getName())) { + return this.toString(); + } else if ("hashCode".equals(method.getName())) { + return this.hashCode(); + } else if ("equals".equals(method.getName())) { + return Boolean.FALSE; + } + return null; + } + } + + public abstract Object doInvokeProxy(Object proxy, Method method, Object[] args) throws Throwable; + + @SuppressWarnings("unchecked") + protected Object invokeProxy(final Method method, final ExchangePattern pattern, Object[] args, boolean binding) throws Throwable { + final Exchange exchange = new DefaultExchange(endpoint, pattern); + + //Need to check if there are mutiple arguments and the parameters have no annotations for binding, + //then use the original bean invocation. + + boolean canUseBinding = method.getParameterCount() == 1; + + if (!canUseBinding) { + for (Parameter parameter : method.getParameters()) { + if (parameter.isAnnotationPresent(Header.class) + || parameter.isAnnotationPresent(Headers.class) + || parameter.isAnnotationPresent(ExchangeProperty.class) + || parameter.isAnnotationPresent(Body.class)) { + canUseBinding = true; + } + } + } + + if (binding && canUseBinding) { + // in binding mode we bind the passed in arguments (args) to the created exchange + // using the existing Camel @Body, @Header, @Headers, @ExchangeProperty annotations + // if no annotation then its bound as the message body + int index = 0; + for (Annotation[] row : method.getParameterAnnotations()) { + Object value = args[index]; + if (row == null || row.length == 0) { + // assume its message body when there is no annotations + exchange.getIn().setBody(value); + } else { + for (Annotation ann : row) { + if (ann.annotationType().isAssignableFrom(Header.class)) { + Header header = (Header) ann; + String name = header.value(); + exchange.getIn().setHeader(name, value); + } else if (ann.annotationType().isAssignableFrom(Headers.class)) { + Map map = exchange.getContext().getTypeConverter().tryConvertTo(Map.class, exchange, value); + if (map != null) { + exchange.getIn().getHeaders().putAll(map); + } + } else if (ann.annotationType().isAssignableFrom(ExchangeProperty.class)) { + ExchangeProperty ep = (ExchangeProperty) ann; + String name = ep.value(); + exchange.setProperty(name, value); + } else if (ann.annotationType().isAssignableFrom(Body.class)) { + exchange.getIn().setBody(value); + } else { + // assume its message body when there is no annotations + exchange.getIn().setBody(value); + } + } + } + index++; + } + } else { + if (args != null) { + if (args.length == 1) { + exchange.getIn().setBody(args[0]); + } else { + exchange.getIn().setBody(args); + } + } + } + + if (binding) { + LOG.trace("Binding to service interface as @Body,@Header,@ExchangeProperty detected when calling proxy method: {}", method); + } else { + LOG.trace("No binding to service interface as @Body,@Header,@ExchangeProperty not detected when calling proxy method: {}", method); + } + + return doInvoke(method, exchange); + } + + protected Object invokeWithBody(final Method method, Object body, final ExchangePattern pattern) throws Throwable { + final Exchange exchange = new DefaultExchange(endpoint, pattern); + exchange.getIn().setBody(body); + + return doInvoke(method, exchange); + } + + protected Object doInvoke(final Method method, final Exchange exchange) throws Throwable { + + // is the return type a future + final boolean isFuture = method.getReturnType() == Future.class; + + // create task to execute the proxy and gather the reply + FutureTask task = new FutureTask<>(new Callable() { + public Object call() throws Exception { + // process the exchange + LOG.trace("Proxied method call {} invoking producer: {}", method.getName(), producer); + producer.process(exchange); + + Object answer = afterInvoke(method, exchange, exchange.getPattern(), isFuture); + LOG.trace("Proxied method call {} returning: {}", method.getName(), answer); + return answer; + } + }); + + if (isFuture) { + // submit task and return future + if (LOG.isTraceEnabled()) { + LOG.trace("Submitting task for exchange id {}", exchange.getExchangeId()); + } + getExecutorService(exchange.getContext()).submit(task); + return task; + } else { + // execute task now + try { + task.run(); + return task.get(); + } catch (ExecutionException e) { + // we don't want the wrapped exception from JDK + throw e.getCause(); + } + } + } + + protected Object afterInvoke(Method method, Exchange exchange, ExchangePattern pattern, boolean isFuture) throws Exception { + // check if we had an exception + Throwable cause = exchange.getException(); + if (cause != null) { + Throwable found = findSuitableException(cause, method); + if (found != null) { + if (found instanceof Exception) { + throw (Exception) found; + } else { + // wrap as exception + throw new CamelExchangeException("Error processing exchange", exchange, cause); + } + } + // special for runtime camel exceptions as they can be nested + if (cause instanceof RuntimeCamelException) { + // if the inner cause is a runtime exception we can throw it + // directly + if (cause.getCause() instanceof RuntimeException) { + throw (RuntimeException) ((RuntimeCamelException) cause).getCause(); + } + throw (RuntimeCamelException) cause; + } + // okay just throw the exception as is + if (cause instanceof Exception) { + throw (Exception) cause; + } else { + // wrap as exception + throw new CamelExchangeException("Error processing exchange", exchange, cause); + } + } + + Class to = isFuture ? getGenericType(exchange.getContext(), method.getGenericReturnType()) : method.getReturnType(); + + // do not return a reply if the method is VOID + if (to == Void.TYPE) { + return null; + } + + return getBody(exchange, to); + } + + protected static Class getGenericType(CamelContext context, Type type) throws ClassNotFoundException { + if (type == null) { + // fallback and use object + return Object.class; + } + + // unfortunately java dont provide a nice api for getting the generic + // type of the return type + // due type erasure, so we have to gather it based on a String + // representation + String name = StringHelper.between(type.toString(), "<", ">"); + if (name != null) { + if (name.contains("<")) { + // we only need the outer type + name = StringHelper.before(name, "<"); + } + return context.getClassResolver().resolveMandatoryClass(name); + } else { + // fallback and use object + return Object.class; + } + } + + protected static synchronized ExecutorService getExecutorService(CamelContext context) { + // CamelContext will shutdown thread pool when it shutdown so we can + // lazy create it on demand + // but in case of hot-deploy or the likes we need to be able to + // re-create it (its a shared static instance) + if (executorService == null || executorService.isTerminated() || executorService.isShutdown()) { + // try to lookup a pool first based on id/profile + executorService = context.getRegistry().lookupByNameAndType("CamelInvocationHandler", ExecutorService.class); + if (executorService == null) { + executorService = context.getExecutorServiceManager().newThreadPool(CamelInvocationHandler.class, "CamelInvocationHandler", "CamelInvocationHandler"); + } + if (executorService == null) { + executorService = context.getExecutorServiceManager().newDefaultThreadPool(CamelInvocationHandler.class, "CamelInvocationHandler"); + } + } + return executorService; + } + + /** + * Tries to find the best suited exception to throw. + *

+ * It looks in the exception hierarchy from the caused exception and matches + * this against the declared exceptions being thrown on the method. + * + * @param cause the caused exception + * @param method the method + * @return the exception to throw, or null if not possible to find + * a suitable exception + */ + protected Throwable findSuitableException(Throwable cause, Method method) { + if (method.getExceptionTypes() == null || method.getExceptionTypes().length == 0) { + return null; + } + + // see if there is any exception which matches the declared exception on + // the method + for (Class type : method.getExceptionTypes()) { + Object fault = ObjectHelper.getException(type, cause); + if (fault != null) { + return Throwable.class.cast(fault); + } + } + + return null; + } + + protected boolean isValidMethod(Method method) { + // must not be in the excluded list + for (Method excluded : EXCLUDED_METHODS) { + if (ObjectHelper.isOverridingMethod(excluded, method)) { + // the method is overriding an excluded method so its not valid + return false; + } + } + return true; + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/AmbiguousMethodCallException.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/AmbiguousMethodCallException.java new file mode 100644 index 00000000..6d6c1cac --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/AmbiguousMethodCallException.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Exchange; +import org.apache.camel.RuntimeExchangeException; + +import java.util.Collection; + +/** + * An exception thrown if an attempted method invocation resulted in an ambiguous method + * such that multiple methods match the inbound message exchange + */ +public class AmbiguousMethodCallException extends RuntimeExchangeException { + + private final Collection methods; + + public AmbiguousMethodCallException(Exchange exchange, Collection methods) { + super("Ambiguous method invocations possible: " + methods, exchange); + this.methods = methods; + } + + /** + * The ambiguous methods for which a single method could not be chosen + */ + public Collection getMethods() { + return methods; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanAnnotationExpressionFactory.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanAnnotationExpressionFactory.java new file mode 100644 index 00000000..8456ca21 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanAnnotationExpressionFactory.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.CamelContext; +import org.apache.camel.Expression; +import org.apache.camel.spi.Language; +import org.apache.camel.support.ObjectHelper; +import org.apache.camel.support.language.DefaultAnnotationExpressionFactory; +import org.apache.camel.support.language.LanguageAnnotation; +import org.apache.camel.util.StringHelper; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; + +public class BeanAnnotationExpressionFactory extends DefaultAnnotationExpressionFactory { + + @Override + public Expression createExpression(CamelContext camelContext, Annotation annotation, LanguageAnnotation languageAnnotation, Class expressionReturnType) { + String beanName = getFromAnnotation(annotation, "ref"); + String method = getFromAnnotation(annotation, "method"); + + // ref is mandatory + StringHelper.notEmpty(beanName, "ref", annotation); + + // method is optional but provide it as null to the bean expression + if (org.apache.camel.util.ObjectHelper.isEmpty(method)) { + method = null; + } + + Language lan = camelContext.resolveLanguage("bean"); + if (method != null) { + return lan.createExpression(beanName + "?method=" + method); + } else { + return lan.createExpression(beanName); + } + } + + protected String getFromAnnotation(Annotation annotation, String attribute) { + try { + Method method = annotation.getClass().getMethod(attribute); + Object value = ObjectHelper.invokeMethod(method, annotation); + if (value == null) { + throw new IllegalArgumentException("Cannot determine the " + attribute + " from the annotation: " + annotation); + } + return value.toString(); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException("Cannot determine the " + attribute + + " of the annotation: " + annotation + " as it does not have a " + attribute + "() method"); + } + } +} + diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanComponent.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanComponent.java new file mode 100644 index 00000000..0bc376ca --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanComponent.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.BeanScope; +import org.apache.camel.Endpoint; +import org.apache.camel.spi.Metadata; +import org.apache.camel.support.DefaultComponent; +import org.apache.camel.support.LRUCache; +import org.apache.camel.support.LRUCacheFactory; +import org.apache.camel.util.PropertiesHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; + +/** + * The bean component is for invoking Java beans from Camel. + */ +@org.apache.camel.spi.annotations.Component("bean-fix") +public class BeanComponent extends DefaultComponent { + + private static final Logger LOG = LoggerFactory.getLogger(BeanComponent.class); + + // use an internal soft cache for BeanInfo as they are costly to introspect + // for example the bean language using OGNL expression runs much faster reusing the BeanInfo from this cache + @SuppressWarnings("unchecked") + private final Map beanInfoCache = LRUCacheFactory.newLRUSoftCache(1000); + + @Deprecated + @Metadata(defaultValue = "true", description = "Use singleton option instead.") + private Boolean cache; + @Metadata(defaultValue = "Singleton", description = "Scope of bean." + + " When using singleton scope (default) the bean is created or looked up only once and reused for the lifetime of the endpoint." + + " The bean should be thread-safe in case concurrent threads is calling the bean at the same time." + + " When using request scope the bean is created or looked up once per request (exchange). This can be used if you want to store state on a bean" + + " while processing a request and you want to call the same bean instance multiple times while processing the request." + + " The bean does not have to be thread-safe as the instance is only called from the same request." + + " When using delegate scope, then the bean will be looked up or created per call. However in case of lookup then this is delegated " + + " to the bean registry such as Spring or CDI (if in use), which depends on their configuration can act as either singleton or prototype scope." + + " so when using prototype then this depends on the delegated registry.") + private BeanScope scope = BeanScope.Singleton; + + public BeanComponent() { + } + + // Implementation methods + //----------------------------------------------------------------------- + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception { + BeanEndpoint endpoint = new BeanEndpoint(uri, this); + endpoint.setBeanName(remaining); + if (cache != null) { + endpoint.setCache(cache); + } + endpoint.setScope(scope); + setProperties(endpoint, parameters); + + // the bean.xxx options is for the bean + Map options = PropertiesHelper.extractProperties(parameters, "bean."); + endpoint.setParameters(options); + return endpoint; + } + + BeanInfo getBeanInfoFromCache(BeanInfoCacheKey key) { + return beanInfoCache.get(key); + } + + void addBeanInfoToCache(BeanInfoCacheKey key, BeanInfo beanInfo) { + beanInfoCache.put(key, beanInfo); + } + + @Override + protected void doShutdown() throws Exception { + if (LOG.isDebugEnabled() && beanInfoCache instanceof LRUCache) { + LRUCache cache = (LRUCache) this.beanInfoCache; + LOG.debug("Clearing BeanInfo cache[size={}, hits={}, misses={}, evicted={}]", cache.size(), cache.getHits(), cache.getMisses(), cache.getEvicted()); + } + beanInfoCache.clear(); + } + + @Deprecated + public Boolean getCache() { + return scope == BeanScope.Singleton; + } + + @Deprecated + public void setCache(Boolean cache) { + if (cache) { + scope = BeanScope.Singleton; + } else { + scope = BeanScope.Prototype; + } + } + + public BeanScope getScope() { + return scope; + } + + public void setScope(BeanScope scope) { + this.scope = scope; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanConstants.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanConstants.java new file mode 100644 index 00000000..d34e2ad3 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanConstants.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +public final class BeanConstants { + + public static final String BEAN_PARAMETER_MAPPING_STRATEGY = "CamelBeanParameterMappingStrategy"; + + private BeanConstants() { + // Utility class + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanEndpoint.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanEndpoint.java new file mode 100644 index 00000000..a4a773a8 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanEndpoint.java @@ -0,0 +1,185 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.*; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.UriEndpoint; +import org.apache.camel.spi.UriParam; +import org.apache.camel.spi.UriPath; +import org.apache.camel.support.DefaultEndpoint; + +import java.util.Map; + +/** + * Invoke methods of Java beans stored in Camel registry. + */ +@UriEndpoint(firstVersion = "1.0.0", scheme = "bean", title = "Bean", syntax = "bean:beanName", producerOnly = true, category = {Category.CORE, Category.JAVA}) +public class BeanEndpoint extends DefaultEndpoint { + private transient BeanHolder beanHolder; + private transient BeanProcessor processor; + @UriPath(label = "common", description = "Sets the name of the bean to invoke") + @Metadata(required = true) + private String beanName; + @UriParam(label = "common", description = "Sets the name of the method to invoke on the bean") + private String method; + @Deprecated + @UriParam(label = "common", description = "Use scope option instead.") + private Boolean cache; + @UriParam(label = "common", defaultValue = "Singleton", description = "Scope of bean." + + " When using singleton scope (default) the bean is created or looked up only once and reused for the lifetime of the endpoint." + + " The bean should be thread-safe in case concurrent threads is calling the bean at the same time." + + " When using request scope the bean is created or looked up once per request (exchange). This can be used if you want to store state on a bean" + + " while processing a request and you want to call the same bean instance multiple times while processing the request." + + " The bean does not have to be thread-safe as the instance is only called from the same request." + + " When using prototype scope, then the bean will be looked up or created per call. However in case of lookup then this is delegated " + + " to the bean registry such as Spring or CDI (if in use), which depends on their configuration can act as either singleton or prototype scope." + + " so when using prototype then this depends on the delegated registry.") + private BeanScope scope = BeanScope.Singleton; + @UriParam(prefix = "bean.", label = "advanced", description = "Used for configuring additional properties on the bean", multiValue = true) + private Map parameters; + + public BeanEndpoint() { + setExchangePattern(ExchangePattern.InOut); + } + + public BeanEndpoint(String endpointUri, Component component, BeanProcessor processor) { + super(endpointUri, component); + this.processor = processor; + setExchangePattern(ExchangePattern.InOut); + } + + public BeanEndpoint(String endpointUri, Component component) { + super(endpointUri, component); + setExchangePattern(ExchangePattern.InOut); + } + + @Override + public Producer createProducer() throws Exception { + return new BeanProducer(this, processor); + } + + @Override + public Consumer createConsumer(Processor processor) throws Exception { + throw new UnsupportedOperationException("You cannot consume from a bean endpoint"); + } + + public BeanProcessor getProcessor() { + return processor; + } + + @Override + protected void doInit() throws Exception { + super.doInit(); + + if (processor == null) { + BeanHolder holder = getBeanHolder(); + if (holder == null) { + RegistryBean registryBean = new RegistryBean(getCamelContext(), beanName); + if (scope == BeanScope.Singleton) { + // if singleton then create a cached holder that use the same singleton instance + holder = registryBean.createCacheHolder(); + } else { + holder = registryBean; + } + } + if (scope == BeanScope.Request) { + // wrap in registry scoped + holder = new RequestBeanHolder(holder); + } + processor = new BeanProcessor(holder); + if (method != null) { + processor.setMethod(method); + } + processor.setScope(scope); + if (parameters != null) { + holder.setOptions(parameters); + } + } + } + + @Override + protected void doStop() throws Exception { + super.doStop(); + // noop + } + + // Properties + //------------------------------------------------------------------------- + + public String getBeanName() { + return beanName; + } + + public void setBeanName(String beanName) { + this.beanName = beanName; + } + + @Deprecated + public Boolean getCache() { + return scope == BeanScope.Singleton; + } + + @Deprecated + public void setCache(Boolean cache) { + if (cache) { + scope = BeanScope.Singleton; + } else { + scope = BeanScope.Prototype; + } + } + + public BeanScope getScope() { + return scope; + } + + public void setScope(BeanScope scope) { + this.scope = scope; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public BeanHolder getBeanHolder() { + return beanHolder; + } + + public void setBeanHolder(BeanHolder beanHolder) { + this.beanHolder = beanHolder; + } + + public Map getParameters() { + return parameters; + } + + public void setParameters(Map parameters) { + this.parameters = parameters; + } + + // Implementation methods + //------------------------------------------------------------------------- + + @Override + protected String createEndpointUri() { + return "bean:" + getBeanName() + (method != null ? "?method=" + method : ""); + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanExpressionProcessor.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanExpressionProcessor.java new file mode 100644 index 00000000..2fdaf59a --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanExpressionProcessor.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +/** + * A bean processor that is optimised for being invoked one time from an {@link org.apache.camel.language.bean.BeanExpression}. + * Where as {@link BeanProcessor} is a bean that is a {@link org.apache.camel.Service} and intended for long lifecycle. + */ +public class BeanExpressionProcessor extends AbstractBeanProcessor { + + public BeanExpressionProcessor(BeanHolder beanHolder) { + super(beanHolder); + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanHelper.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanHelper.java new file mode 100644 index 00000000..359bb649 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanHelper.java @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.spi.ClassResolver; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.StringHelper; + +/** + * Helper for the bean component. + */ +public final class BeanHelper { + + private BeanHelper() { + // utility class + } + + /** + * Determines and maps the given value is valid according to the supported + * values by the bean component. + * + * @param value the value + * @return the parameter type the given value is being mapped as, or null if not valid. + */ + public static Class getValidParameterType(String value) { + if (ObjectHelper.isEmpty(value)) { + return null; + } + + // trim value + value = value.trim(); + + // single quoted is valid + if (value.startsWith("'") && value.endsWith("'")) { + return String.class; + } + + // double quoted is valid + if (value.startsWith("\"") && value.endsWith("\"")) { + return String.class; + } + + // true or false is valid (boolean) + if (value.equals("true") || value.equals("false")) { + return Boolean.class; + } + + // null is valid (to force a null value) + if (value.equals("null")) { + return Object.class; + } + + // simple language tokens is valid + if (StringHelper.hasStartToken(value, "simple")) { + return Object.class; + } + + // numeric is valid + boolean numeric = true; + for (char ch : value.toCharArray()) { + if (!Character.isDigit(ch)) { + numeric = false; + break; + } + } + if (numeric) { + return Number.class; + } + + // not valid + return null; + } + + /** + * Determines if the given value is valid according to the supported + * values by the bean component. + * + * @param value the value + * @return true if valid, false otherwise + */ + public static boolean isValidParameterValue(String value) { + if (ObjectHelper.isEmpty(value)) { + // empty value is valid + return true; + } + + return getValidParameterType(value) != null; + } + + /** + * Determines if the given parameter type is assignable to the expected type. + *

+ * This implementation will check if the given parameter type matches the expected type as class using either + *

    + *
  • FQN class name - com.foo.MyOrder
  • + *
  • Simple class name - MyOrder
  • + *
+ * If the given parameter type is not a class, then null is returned + * + * @param resolver the class resolver + * @param parameterType the parameter type as a String, can be a FQN or a simple name of the class + * @param expectedType the expected type + * @return null if parameter type is not a class, true if parameter type is assignable, false if not assignable + */ + public static Boolean isAssignableToExpectedType(ClassResolver resolver, String parameterType, Class expectedType) { + // if its a class, then it should be assignable + Class parameterClass = resolver.resolveClass(parameterType); + if (parameterClass == null && parameterType.equals(expectedType.getSimpleName())) { + // it was not the FQN class name, but the simple name instead, which matched + return true; + } + + // not a class so return null + if (parameterClass == null) { + return null; + } + + // if there was a class, then it must be assignable to match + return parameterClass.isAssignableFrom(expectedType); + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanHolder.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanHolder.java new file mode 100644 index 00000000..0a2a6742 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanHolder.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Exchange; +import org.apache.camel.NoSuchBeanException; +import org.apache.camel.Processor; + +import java.util.Map; + +/** + * Object holder for a bean. + */ +public interface BeanHolder { + + /** + * Additional options that should be configured on the bean + */ + Map getOptions(); + + /** + * Sets additional options that should be configured on the bean + */ + void setOptions(Map options); + + /** + * Gets the bean. + * + * @throws NoSuchBeanException is thrown if the bean cannot be found. + */ + Object getBean(Exchange exchange) throws NoSuchBeanException; + + /** + * Gets a {@link Processor} for this bean, if supported. + * + * @return the {@link Processor}, or null if not supported. + */ + Processor getProcessor(); + + /** + * Whether a {@link Processor} is supported by this bean holder. + * + * @return true if the holder can supporting using a processor, false otherwise + */ + boolean supportProcessor(); + + /** + * Gets bean info for the bean. + */ + BeanInfo getBeanInfo(); + + /** + * Gets bean info for the given bean. + *

+ * This implementation allows a thread safe usage for {@link BeanHolder} implementations + * such as the {@link RegistryBean}. + * + * @param bean the bean + * @return null if not supported, then use {@link #getBeanInfo()} instead. + */ + BeanInfo getBeanInfo(Object bean); +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanInfo.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanInfo.java new file mode 100644 index 00000000..79a00ae5 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanInfo.java @@ -0,0 +1,1269 @@ +/*- + * ~~~~~~licensing~~~~~~ + * component-bean-fix + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.*; +import org.apache.camel.spi.Registry; +import org.apache.camel.support.ObjectHelper; +import org.apache.camel.support.builder.ExpressionBuilder; +import org.apache.camel.support.language.AnnotationExpressionFactory; +import org.apache.camel.support.language.DefaultAnnotationExpressionFactory; +import org.apache.camel.support.language.LanguageAnnotation; +import org.apache.camel.util.CastUtils; +import org.apache.camel.util.StringHelper; +import org.apache.camel.util.StringQuoteHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.*; + +/** + * Represents the metadata about a bean type created via a combination of + * introspection and annotations together with some useful sensible defaults + */ +public class BeanInfo { + private static final Logger LOG = LoggerFactory.getLogger(BeanInfo.class); + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + private static final String[] EXCLUDED_METHOD_NAMES = new String[]{ + "clone", "equals", "finalize", "getClass", "hashCode", "notify", "notifyAll", "wait", // java.lang.Object + "getInvocationHandler", "getProxyClass", "isProxyClass", "newProxyInstance" // java.lang.Proxy + }; + private final CamelContext camelContext; + private final BeanComponent component; + private final Class type; + private final ParameterMappingStrategy strategy; + private final MethodInfo defaultMethod; + // shared state with details of operations introspected from the bean, created during the constructor + private Map> operations = new HashMap<>(); + private List operationsWithBody = new ArrayList<>(); + private List operationsWithNoBody = new ArrayList<>(); + private List operationsWithCustomAnnotation = new ArrayList<>(); + private List operationsWithHandlerAnnotation = new ArrayList<>(); + private Map methodMap = new HashMap<>(); + private boolean publicConstructors; + private boolean publicNoArgConstructors; + + public BeanInfo(CamelContext camelContext, Class type) { + this(camelContext, type, createParameterMappingStrategy(camelContext)); + } + + public BeanInfo(CamelContext camelContext, Method explicitMethod) { + this(camelContext, explicitMethod.getDeclaringClass(), explicitMethod, createParameterMappingStrategy(camelContext)); + } + + public BeanInfo(CamelContext camelContext, Class type, ParameterMappingStrategy strategy) { + this(camelContext, type, null, strategy); + } + + public BeanInfo(CamelContext camelContext, Class type, Method explicitMethod, ParameterMappingStrategy strategy) { + //так как при создании прокси перестало использоваться наследование, то мы знаем об оригинальном классе только его интерфейсы + if (type.isSynthetic()) { + for (Class typeInterface : type.getInterfaces()) { + if (explicitMethod != null) { + try { + explicitMethod = typeInterface.getDeclaredMethod(explicitMethod.getName(), explicitMethod.getParameterTypes()); + } catch (NoSuchMethodException e) { + throw new RuntimeCamelException("Unable to find a method " + explicitMethod + " on " + type, e); + } + } + } + } + + this.camelContext = camelContext; + this.type = type; + this.strategy = strategy; + this.component = camelContext.getComponent("bean-fix", BeanComponent.class); + + final BeanInfoCacheKey key = new BeanInfoCacheKey(type, explicitMethod); + + // lookup if we have a bean info cache + BeanInfo beanInfo = component.getBeanInfoFromCache(key); + if (beanInfo != null) { + // copy the values from the cache we need + defaultMethod = beanInfo.defaultMethod; + operations = beanInfo.operations; + operationsWithBody = beanInfo.operationsWithBody; + operationsWithNoBody = beanInfo.operationsWithNoBody; + operationsWithCustomAnnotation = beanInfo.operationsWithCustomAnnotation; + operationsWithHandlerAnnotation = beanInfo.operationsWithHandlerAnnotation; + methodMap = beanInfo.methodMap; + publicConstructors = beanInfo.publicConstructors; + publicNoArgConstructors = beanInfo.publicNoArgConstructors; + return; + } + + if (explicitMethod != null) { + // must be a valid method + if (!isValidMethod(type, explicitMethod)) { + throw new IllegalArgumentException("The method " + explicitMethod + " is not valid (for example the method must be public)"); + } + introspect(getType(), explicitMethod); + } else { + introspect(getType()); + } + + // if there are only 1 method with 1 operation then select it as a default/fallback method + MethodInfo method = null; + if (operations.size() == 1) { + List methods = operations.values().iterator().next(); + if (methods.size() == 1) { + method = methods.get(0); + } + } + defaultMethod = method; + + // mark the operations lists as unmodifiable, as they should not change during runtime + // to keep this code thread safe + operations = Collections.unmodifiableMap(operations); + operationsWithBody = Collections.unmodifiableList(operationsWithBody); + operationsWithNoBody = Collections.unmodifiableList(operationsWithNoBody); + operationsWithCustomAnnotation = Collections.unmodifiableList(operationsWithCustomAnnotation); + operationsWithHandlerAnnotation = Collections.unmodifiableList(operationsWithHandlerAnnotation); + methodMap = Collections.unmodifiableMap(methodMap); + + // add new bean info to cache + component.addBeanInfoToCache(key, this); + } + + public Class getType() { + return type; + } + + public CamelContext getCamelContext() { + return camelContext; + } + + public static ParameterMappingStrategy createParameterMappingStrategy(CamelContext camelContext) { + // lookup in registry first if there is a user define strategy + Registry registry = camelContext.getRegistry(); + ParameterMappingStrategy answer = registry.lookupByNameAndType(BeanConstants.BEAN_PARAMETER_MAPPING_STRATEGY, ParameterMappingStrategy.class); + if (answer == null) { + // no then use the default one + answer = DefaultParameterMappingStrategy.INSTANCE; + } + + return answer; + } + + public MethodInvocation createInvocation(Object pojo, Exchange exchange) + throws AmbiguousMethodCallException, MethodNotFoundException { + + MethodInfo methodInfo = null; + + String methodName = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, String.class); + if (methodName != null) { + + // do not use qualifier for name + String name = methodName; + if (methodName.contains("(")) { + name = StringHelper.before(methodName, "("); + // the must be a ending parenthesis + if (!methodName.endsWith(")")) { + throw new IllegalArgumentException("Method should end with parenthesis, was " + methodName); + } + // and there must be an even number of parenthesis in the syntax + // (we can use betweenOuterPair as it return null if the syntax is invalid) + if (StringHelper.betweenOuterPair(methodName, '(', ')') == null) { + throw new IllegalArgumentException("Method should have even pair of parenthesis, was " + methodName); + } + } + boolean emptyParameters = methodName.endsWith("()"); + + // special for getClass, as we want the user to be able to invoke this method + // for example to log the class type or the likes + if ("class".equals(name) || "getClass".equals(name)) { + try { + Method method = pojo.getClass().getMethod("getClass"); + methodInfo = new MethodInfo(exchange.getContext(), pojo.getClass(), method, Collections.emptyList(), Collections.emptyList(), false, false); + } catch (NoSuchMethodException e) { + throw new MethodNotFoundException(exchange, pojo, "getClass"); + } + // special for length on an array type + } else if ("length".equals(name) && pojo.getClass().isArray()) { + try { + // need to use arrayLength method from ObjectHelper as Camel's bean OGNL support is method invocation based + // and not for accessing fields. And hence we need to create a MethodInfo instance with a method to call + // and therefore use arrayLength from ObjectHelper to return the array length field. + Method method = org.apache.camel.util.ObjectHelper.class.getMethod("arrayLength", Object[].class); + ParameterInfo pi = new ParameterInfo(0, Object[].class, null, ExpressionBuilder.mandatoryBodyExpression(Object[].class, true)); + List lpi = new ArrayList<>(1); + lpi.add(pi); + methodInfo = new MethodInfo(exchange.getContext(), pojo.getClass(), method, lpi, lpi, false, false); + // Need to update the message body to be pojo for the invocation + exchange.getIn().setBody(pojo); + } catch (NoSuchMethodException e) { + throw new MethodNotFoundException(exchange, pojo, "getClass"); + } + } else { + List methods = getOperations(name); + if (methods != null && methods.size() == 1) { + // only one method then choose it + methodInfo = methods.get(0); + + // validate that if we want an explicit no-arg method, then that's what we get + if (emptyParameters && methodInfo.hasParameters()) { + throw new MethodNotFoundException(exchange, pojo, methodName, "(with no parameters)"); + } + } else if (methods != null) { + // there are more methods with that name so we cannot decide which to use + + // but first let's try to choose a method and see if that complies with the name + // must use the method name which may have qualifiers + methodInfo = chooseMethod(pojo, exchange, methodName); + + // validate that if we want an explicit no-arg method, then that's what we get + if (emptyParameters) { + if (methodInfo == null || methodInfo.hasParameters()) { + // we could not find a no-arg method with that name + throw new MethodNotFoundException(exchange, pojo, methodName, "(with no parameters)"); + } + } + + if (methodInfo == null || (name != null && !name.equals(methodInfo.getMethod().getName()))) { + throw new AmbiguousMethodCallException(exchange, methods); + } + } else { + // a specific method was given to invoke but not found + throw new MethodNotFoundException(exchange, pojo, methodName); + } + } + } + + if (methodInfo == null && methodMap.size() >= 2) { + // only try to choose if there is at least 2 methods + methodInfo = chooseMethod(pojo, exchange, null); + } + if (methodInfo == null) { + methodInfo = defaultMethod; + } + if (methodInfo != null) { + LOG.trace("Chosen method to invoke: {} on bean: {}", methodInfo, pojo); + return methodInfo.createMethodInvocation(pojo, methodInfo.hasParameters(), exchange); + } + + LOG.debug("Cannot find suitable method to invoke on bean: {}", pojo); + return null; + } + + /** + * Introspects the given class + * + * @param clazz the class + */ + private void introspect(Class clazz) { + + // does the class have any public constructors? + publicConstructors = clazz.getConstructors().length > 0; + publicNoArgConstructors = org.apache.camel.util.ObjectHelper.hasDefaultPublicNoArgConstructor(clazz); + + MethodsFilter methods = new MethodsFilter(getType()); + introspect(clazz, methods); + + // now introspect the methods and filter non valid methods + for (Method method : methods.asReadOnlyList()) { + boolean valid = isValidMethod(clazz, method); + LOG.trace("Method: {} is valid: {}", method, valid); + if (valid) { + introspect(clazz, method); + } + } + } + + private void introspect(Class clazz, MethodsFilter filteredMethods) { + // get the target clazz as it could potentially have been enhanced by + // CGLIB etc. + clazz = getTargetClass(clazz); + org.apache.camel.util.ObjectHelper.notNull(clazz, "clazz", this); + + LOG.trace("Introspecting class: {}", clazz); + + for (Method m : Arrays.asList(clazz.getDeclaredMethods())) { + filteredMethods.filterMethod(m); + } + + Class superClass = clazz.getSuperclass(); + if (superClass != null && !superClass.equals(Object.class)) { + introspect(superClass, filteredMethods); + } + for (Class superInterface : clazz.getInterfaces()) { + introspect(superInterface, filteredMethods); + } + } + + /** + * Introspects the given method + * + * @param clazz the class + * @param method the method + * @return the method info, is newer null + */ + private MethodInfo introspect(Class clazz, Method method) { + LOG.trace("Introspecting class: {}, method: {}", clazz, method); + String opName = method.getName(); + + MethodInfo methodInfo = createMethodInfo(clazz, method); + + // Foster the use of a potentially already registered most specific override + MethodInfo existingMethodInfo = findMostSpecificOverride(methodInfo); + if (existingMethodInfo != null) { + LOG.trace("This method is already overridden in a subclass, so the method from the sub class is preferred: {}", existingMethodInfo); + return existingMethodInfo; + } + + LOG.trace("Adding operation: {} for method: {}", opName, methodInfo); + + List existing = getOperations(opName); + if (existing != null) { + // we have an overloaded method so add the method info to the same key + existing.add(methodInfo); + } else { + // its a new method we have not seen before so wrap it in a list and add it + List methods = new ArrayList<>(); + methods.add(methodInfo); + operations.put(opName, methods); + } + + if (methodInfo.hasCustomAnnotation()) { + operationsWithCustomAnnotation.add(methodInfo); + } else if (methodInfo.hasBodyParameter()) { + operationsWithBody.add(methodInfo); + } else { + operationsWithNoBody.add(methodInfo); + } + + if (methodInfo.hasHandlerAnnotation()) { + operationsWithHandlerAnnotation.add(methodInfo); + } + + // must add to method map last otherwise we break stuff + methodMap.put(method, methodInfo); + + return methodInfo; + } + + /** + * Returns the {@link MethodInfo} for the given method if it exists or null + * if there is no metadata available for the given method + */ + public MethodInfo getMethodInfo(Method method) { + MethodInfo answer = methodMap.get(method); + if (answer == null) { + // maybe the method overrides, and the method map keeps info of the source override we can use + for (Map.Entry methodEntry : methodMap.entrySet()) { + Method source = methodEntry.getKey(); + if (org.apache.camel.util.ObjectHelper.isOverridingMethod(getType(), source, method, false)) { + answer = methodEntry.getValue(); + break; + } + } + } + + if (answer == null) { + // maybe the method is defined on a base class? + if (type != Object.class) { + Class superclass = type.getSuperclass(); + if (superclass != null && superclass != Object.class) { + BeanInfo superBeanInfo = new BeanInfo(camelContext, superclass, strategy); + return superBeanInfo.getMethodInfo(method); + } + } + } + return answer; + } + + protected MethodInfo createMethodInfo(Class clazz, Method method) { + Class[] parameterTypes = method.getParameterTypes(); + List[] parametersAnnotations = collectParameterAnnotations(clazz, method); + + List parameters = new ArrayList<>(); + List bodyParameters = new ArrayList<>(); + + boolean hasCustomAnnotation = false; + boolean hasHandlerAnnotation = org.apache.camel.util.ObjectHelper.hasAnnotation(method.getAnnotations(), Handler.class); + + if (!hasHandlerAnnotation) { + + } + + int size = parameterTypes.length; + if (LOG.isTraceEnabled()) { + LOG.trace("Creating MethodInfo for class: {} method: {} having {} parameters", clazz, method, size); + } + + for (int i = 0; i < size; i++) { + Class parameterType = parameterTypes[i]; + Annotation[] parameterAnnotations = parametersAnnotations[i].toArray(new Annotation[parametersAnnotations[i].size()]); + Expression expression = createParameterUnmarshalExpression(clazz, method, parameterType, parameterAnnotations); + hasCustomAnnotation |= expression != null; + + ParameterInfo parameterInfo = new ParameterInfo(i, parameterType, parameterAnnotations, expression); + LOG.trace("Parameter #{}: {}", i, parameterInfo); + parameters.add(parameterInfo); + if (expression == null) { + boolean bodyAnnotation = org.apache.camel.util.ObjectHelper.hasAnnotation(parameterAnnotations, Body.class); + LOG.trace("Parameter #{} has @Body annotation", i); + hasCustomAnnotation |= bodyAnnotation; + if (bodyParameters.isEmpty()) { + // okay we have not yet set the body parameter and we have found + // the candidate now to use as body parameter + if (Exchange.class.isAssignableFrom(parameterType)) { + // use exchange + expression = ExpressionBuilder.exchangeExpression(); + } else { + // assume it's the body and it must be mandatory convertible to the parameter type + // but we allow null bodies in case the message really contains a null body + expression = ExpressionBuilder.mandatoryBodyExpression(parameterType, true); + } + LOG.trace("Parameter #{} is the body parameter using expression {}", i, expression); + parameterInfo.setExpression(expression); + bodyParameters.add(parameterInfo); + } else { + // will ignore the expression for parameter evaluation + } + } + LOG.trace("Parameter #{} has parameter info: {}", i, parameterInfo); + } + + // now let's add the method to the repository + return new MethodInfo(camelContext, clazz, method, parameters, bodyParameters, hasCustomAnnotation, hasHandlerAnnotation); + } + + @SuppressWarnings("unchecked") + protected List[] collectParameterAnnotations(Class c, Method m) { + List[] annotations = new List[m.getParameterCount()]; + for (int i = 0; i < annotations.length; i++) { + annotations[i] = new ArrayList<>(); + } + collectParameterAnnotations(c, m, annotations); + return annotations; + } + + protected void collectParameterAnnotations(Class c, Method m, List[] a) { + // because we are only looking for camel annotations then skip all stuff from JDKs + if (c.getName().startsWith("java")) { + return; + } + try { + Annotation[][] pa = c.getDeclaredMethod(m.getName(), m.getParameterTypes()).getParameterAnnotations(); + for (int i = 0; i < pa.length; i++) { + a[i].addAll(Arrays.asList(pa[i])); + } + } catch (NoSuchMethodException e) { + // ignore no method with signature of m declared on c + } + for (Class i : c.getInterfaces()) { + collectParameterAnnotations(i, m, a); + } + if (!c.isInterface() && c.getSuperclass() != null && c.getSuperclass() != Object.class) { + collectParameterAnnotations(c.getSuperclass(), m, a); + } + } + + /** + * Choose one of the available methods to invoke if we can match + * the message body to the body parameter + * + * @param pojo the bean to invoke a method on + * @param exchange the message exchange + * @param name an optional name of the method that must match, use null to indicate all methods + * @return the method to invoke or null if no definitive method could be matched + * @throws AmbiguousMethodCallException is thrown if cannot choose method due to ambiguity + */ + protected MethodInfo chooseMethod(Object pojo, Exchange exchange, String name) throws AmbiguousMethodCallException { + // @Handler should be select first + // then any single method that has a custom @annotation + // or any single method that has a match parameter type that matches the Exchange payload + // and last then try to select the best among the rest + + // must use defensive copy, to avoid altering the shared lists + // and we want to remove unwanted operations from these local lists + List localOperationsWithBody = null; + if (!operationsWithBody.isEmpty()) { + localOperationsWithBody = new ArrayList<>(operationsWithBody); + } + List localOperationsWithNoBody = null; + if (!operationsWithNoBody.isEmpty()) { + localOperationsWithNoBody = new ArrayList<>(operationsWithNoBody); + } + List localOperationsWithCustomAnnotation = null; + if (!operationsWithCustomAnnotation.isEmpty()) { + localOperationsWithCustomAnnotation = new ArrayList<>(operationsWithCustomAnnotation); + } + List localOperationsWithHandlerAnnotation = null; + if (!operationsWithHandlerAnnotation.isEmpty()) { + localOperationsWithHandlerAnnotation = new ArrayList<>(operationsWithHandlerAnnotation); + } + + // remove all abstract methods + if (localOperationsWithBody != null) { + removeAllAbstractMethods(localOperationsWithBody); + } + if (localOperationsWithNoBody != null) { + removeAllAbstractMethods(localOperationsWithNoBody); + } + if (localOperationsWithCustomAnnotation != null) { + removeAllAbstractMethods(localOperationsWithCustomAnnotation); + } + if (localOperationsWithHandlerAnnotation != null) { + removeAllAbstractMethods(localOperationsWithHandlerAnnotation); + } + + if (name != null) { + // filter all lists to only include methods with this name + if (localOperationsWithHandlerAnnotation != null) { + removeNonMatchingMethods(localOperationsWithHandlerAnnotation, name); + } + if (localOperationsWithCustomAnnotation != null) { + removeNonMatchingMethods(localOperationsWithCustomAnnotation, name); + } + if (localOperationsWithBody != null) { + removeNonMatchingMethods(localOperationsWithBody, name); + } + if (localOperationsWithNoBody != null) { + removeNonMatchingMethods(localOperationsWithNoBody, name); + } + } else { + // remove all getter/setter as we do not want to consider these methods + if (localOperationsWithHandlerAnnotation != null) { + removeAllSetterOrGetterMethods(localOperationsWithHandlerAnnotation); + } + if (localOperationsWithCustomAnnotation != null) { + removeAllSetterOrGetterMethods(localOperationsWithCustomAnnotation); + } + if (localOperationsWithBody != null) { + removeAllSetterOrGetterMethods(localOperationsWithBody); + } + if (localOperationsWithNoBody != null) { + removeAllSetterOrGetterMethods(localOperationsWithNoBody); + } + } + + if (localOperationsWithHandlerAnnotation != null && localOperationsWithHandlerAnnotation.size() > 1) { + // if we have more than 1 @Handler then its ambiguous + throw new AmbiguousMethodCallException(exchange, localOperationsWithHandlerAnnotation); + } + + if (localOperationsWithHandlerAnnotation != null && localOperationsWithHandlerAnnotation.size() == 1) { + // methods with handler should be preferred + return localOperationsWithHandlerAnnotation.get(0); + } else if (localOperationsWithCustomAnnotation != null && localOperationsWithCustomAnnotation.size() == 1) { + // if there is one method with an annotation then use that one + return localOperationsWithCustomAnnotation.get(0); + } + + // named method and with no parameters + boolean noParameters = name != null && name.endsWith("()"); + if (noParameters && localOperationsWithNoBody != null && localOperationsWithNoBody.size() == 1) { + // if there was a method name configured and it has no parameters, then use the method with no body (eg no parameters) + return localOperationsWithNoBody.get(0); + } else if (!noParameters && (localOperationsWithBody != null && localOperationsWithBody.size() == 1 && localOperationsWithCustomAnnotation == null)) { + // if there is one method with body then use that one + return localOperationsWithBody.get(0); + } + + if (localOperationsWithBody != null || localOperationsWithCustomAnnotation != null) { + Collection possibleOperations = new ArrayList<>(); + if (localOperationsWithBody != null) { + possibleOperations.addAll(localOperationsWithBody); + } + if (localOperationsWithCustomAnnotation != null) { + possibleOperations.addAll(localOperationsWithCustomAnnotation); + } + + if (!possibleOperations.isEmpty()) { + MethodInfo answer = null; + + if (name != null) { + // do we have hardcoded parameters values provided from the method name then use that for matching + String parameters = StringHelper.between(name, "(", ")"); + if (parameters != null) { + // special as we have hardcoded parameters, so we need to choose method that matches those parameters the best + LOG.trace("Choosing best matching method matching parameters: {}", parameters); + answer = chooseMethodWithMatchingParameters(exchange, parameters, possibleOperations); + } + } + if (answer == null) { + // multiple possible operations so find the best suited if possible + answer = chooseMethodWithMatchingBody(exchange, possibleOperations, localOperationsWithCustomAnnotation); + } + if (answer == null && possibleOperations.size() > 1) { + answer = getSingleCovariantMethod(possibleOperations); + } + + if (answer == null) { + throw new AmbiguousMethodCallException(exchange, possibleOperations); + } else { + return answer; + } + } + } + + // not possible to determine + return null; + } + + private MethodInfo chooseMethodWithMatchingParameters(Exchange exchange, String parameters, Collection operationList) + throws AmbiguousMethodCallException { + // we have hardcoded parameters so need to match that with the given operations + int count = 0; + for (String o : ObjectHelper.createIterable(parameters)) { + count++; + } + + List operations = new ArrayList<>(); + for (MethodInfo info : operationList) { + if (info.getParameters().size() == count) { + operations.add(info); + } + } + + if (operations.isEmpty()) { + return null; + } else if (operations.size() == 1) { + return operations.get(0); + } + + // okay we still got multiple operations, so need to match the best one + List candidates = new ArrayList<>(); + MethodInfo fallbackCandidate = null; + for (MethodInfo info : operations) { + Iterator it = ObjectHelper.createIterator(parameters, ",", false); + int index = 0; + boolean matches = true; + while (it.hasNext()) { + String parameter = (String) it.next(); + if (parameter != null) { + // must trim + parameter = parameter.trim(); + } + + Class parameterType = BeanHelper.getValidParameterType(parameter); + Class expectedType = info.getParameters().get(index).getType(); + + if (parameterType != null && expectedType != null) { + + // if its a simple language then we need to evaluate the expression + // so we have the result and can find out what type the parameter actually is + if (StringHelper.hasStartToken(parameter, "simple")) { + LOG.trace("Evaluating simple expression for parameter #{}: {} to determine the class type of the parameter", index, parameter); + Object out = getCamelContext().resolveLanguage("simple").createExpression(parameter).evaluate(exchange, Object.class); + if (out != null) { + parameterType = out.getClass(); + } + } + + // skip java.lang.Object type, when we have multiple possible methods we want to avoid it if possible + if (Object.class.equals(expectedType)) { + fallbackCandidate = info; + matches = false; + break; + } + + boolean matchingTypes = isParameterMatchingType(parameterType, expectedType); + if (!matchingTypes) { + matches = false; + break; + } + } + + index++; + } + + if (matches) { + candidates.add(info); + } + } + + if (candidates.size() > 1) { + MethodInfo answer = getSingleCovariantMethod(candidates); + if (answer != null) { + return answer; + } + } + return candidates.size() == 1 ? candidates.get(0) : fallbackCandidate; + } + + private boolean isParameterMatchingType(Class parameterType, Class expectedType) { + if (Number.class.equals(parameterType)) { + // number should match long/int/etc. + if (Integer.class.isAssignableFrom(expectedType) || Long.class.isAssignableFrom(expectedType) + || int.class.isAssignableFrom(expectedType) || long.class.isAssignableFrom(expectedType)) { + return true; + } + } + if (Boolean.class.equals(parameterType)) { + // boolean should match both Boolean and boolean + if (Boolean.class.isAssignableFrom(expectedType) || boolean.class.isAssignableFrom(expectedType)) { + return true; + } + } + return parameterType.isAssignableFrom(expectedType); + } + + private MethodInfo getSingleCovariantMethod(Collection candidates) { + // if all the candidates are actually covariant, it doesn't matter which one we call + MethodInfo firstCandidate = candidates.iterator().next(); + for (MethodInfo candidate : candidates) { + if (!firstCandidate.isCovariantWith(candidate)) { + return null; + } + } + return firstCandidate; + } + + private MethodInfo chooseMethodWithMatchingBody(Exchange exchange, Collection operationList, + List operationsWithCustomAnnotation) + throws AmbiguousMethodCallException { + // see if we can find a method whose body param type matches the message body + Message in = exchange.getIn(); + Object body = in.getBody(); + if (body != null) { + Class bodyType = body.getClass(); + if (LOG.isTraceEnabled()) { + LOG.trace("Matching for method with a single parameter that matches type: {}", bodyType.getCanonicalName()); + } + + List possibles = new ArrayList<>(); + List possiblesWithException = null; + for (MethodInfo methodInfo : operationList) { + // test for MEP pattern matching + boolean out = exchange.getPattern().isOutCapable(); + if (out && methodInfo.isReturnTypeVoid()) { + // skip this method as the MEP is Out so the method must return something + continue; + } + + // try to match the arguments + if (methodInfo.bodyParameterMatches(bodyType)) { + LOG.trace("Found a possible method: {}", methodInfo); + if (methodInfo.hasExceptionParameter()) { + // methods with accepts exceptions + if (possiblesWithException == null) { + possiblesWithException = new ArrayList<>(); + } + possiblesWithException.add(methodInfo); + } else { + // regular methods with no exceptions + possibles.add(methodInfo); + } + } + } + + // find best suited method to use + return chooseBestPossibleMethodInfo(exchange, operationList, body, possibles, possiblesWithException, operationsWithCustomAnnotation); + } + + // no match so return null + return null; + } + + private MethodInfo chooseBestPossibleMethodInfo(Exchange exchange, Collection operationList, Object body, + List possibles, List possiblesWithException, + List possibleWithCustomAnnotation) + throws AmbiguousMethodCallException { + + Exception exception = ExpressionBuilder.exchangeExceptionExpression().evaluate(exchange, Exception.class); + if (exception != null && possiblesWithException != null && possiblesWithException.size() == 1) { + LOG.trace("Exchange has exception set so we prefer method that also has exception as parameter"); + // prefer the method that accepts exception in case we have an exception also + return possiblesWithException.get(0); + } else if (possibles.size() == 1) { + return possibles.get(0); + } else if (possibles.isEmpty()) { + LOG.trace("No possible methods so now trying to convert body to parameter types"); + + // let's try converting + Object newBody = null; + MethodInfo matched = null; + int matchCounter = 0; + for (MethodInfo methodInfo : operationList) { + if (methodInfo.getBodyParameterType() != null) { + if (methodInfo.getBodyParameterType().isInstance(body)) { + return methodInfo; + } + + // we should only try to convert, as we are looking for best match + Object value = exchange.getContext().getTypeConverter().tryConvertTo(methodInfo.getBodyParameterType(), exchange, body); + if (value != null) { + if (LOG.isTraceEnabled()) { + LOG.trace("Converted body from: {} to: {}", + body.getClass().getCanonicalName(), methodInfo.getBodyParameterType().getCanonicalName()); + } + matchCounter++; + newBody = value; + matched = methodInfo; + } + } + } + if (matchCounter > 1) { + throw new AmbiguousMethodCallException(exchange, Arrays.asList(matched, matched)); + } + if (matched != null) { + LOG.trace("Setting converted body: {}", body); + Message in = exchange.getIn(); + in.setBody(newBody); + return matched; + } + } else { + // if we only have a single method with custom annotations, let's use that one + if (possibleWithCustomAnnotation != null && possibleWithCustomAnnotation.size() == 1) { + MethodInfo answer = possibleWithCustomAnnotation.get(0); + LOG.trace("There are only one method with annotations so we choose it: {}", answer); + return answer; + } + // try to choose among multiple methods with annotations + MethodInfo chosen = chooseMethodWithCustomAnnotations(possibles); + if (chosen != null) { + return chosen; + } + // just make sure the methods aren't all actually the same + chosen = getSingleCovariantMethod(possibles); + if (chosen != null) { + return chosen; + } + throw new AmbiguousMethodCallException(exchange, possibles); + } + + // cannot find a good method to use + return null; + } + + /** + * Validates whether the given method is a valid candidate for Camel Bean Binding. + * + * @param clazz the class + * @param method the method + * @return true if valid, false to skip the method + */ + protected boolean isValidMethod(Class clazz, Method method) { + // method name must not be in the excluded list + String name = method.getName(); + for (String s : EXCLUDED_METHOD_NAMES) { + if (name.equals(s)) { + return false; + } + } + + // must not be a private method + boolean privateMethod = Modifier.isPrivate(method.getModifiers()); + if (privateMethod) { + return false; + } + + // return type must not be an Exchange and it should not be a bridge method + if ((method.getReturnType() != null && Exchange.class.isAssignableFrom(method.getReturnType())) || method.isBridge()) { + return false; + } + + return true; + } + + /** + * Gets the most specific override of a given method, if any. Indeed, + * overrides may have already been found while inspecting sub classes. Or + * the given method could override an interface extra method. + * + * @param proposedMethodInfo the method for which a more specific override is + * searched + * @return The already registered most specific override if any, otherwise + * null + */ + private MethodInfo findMostSpecificOverride(MethodInfo proposedMethodInfo) { + for (MethodInfo alreadyRegisteredMethodInfo : methodMap.values()) { + Method alreadyRegisteredMethod = alreadyRegisteredMethodInfo.getMethod(); + Method proposedMethod = proposedMethodInfo.getMethod(); + + if (org.apache.camel.util.ObjectHelper.isOverridingMethod(getType(), proposedMethod, alreadyRegisteredMethod, false)) { + return alreadyRegisteredMethodInfo; + } else if (org.apache.camel.util.ObjectHelper.isOverridingMethod(getType(), alreadyRegisteredMethod, proposedMethod, false)) { + return proposedMethodInfo; + } + } + + return null; + } + + private MethodInfo chooseMethodWithCustomAnnotations(Collection possibles) { + // if we have only one method with custom annotations let's choose that + MethodInfo chosen = null; + for (MethodInfo possible : possibles) { + if (possible.hasCustomAnnotation()) { + if (chosen != null) { + chosen = null; + break; + } else { + chosen = possible; + } + } + } + return chosen; + } + + /** + * Creates an expression for the given parameter type if the parameter can + * be mapped automatically or null if the parameter cannot be mapped due to + * insufficient annotations or not fitting with the default type + * conventions. + */ + private Expression createParameterUnmarshalExpression(Class clazz, Method method, + Class parameterType, Annotation[] parameterAnnotation) { + + // look for a parameter annotation that converts into an expression + for (Annotation annotation : parameterAnnotation) { + Expression answer = createParameterUnmarshalExpressionForAnnotation(clazz, method, parameterType, annotation); + if (answer != null) { + return answer; + } + } + // no annotations then try the default parameter mappings + return strategy.getDefaultParameterTypeExpression(parameterType); + } + + private Expression createParameterUnmarshalExpressionForAnnotation(Class clazz, Method method, + Class parameterType, Annotation annotation) { + if (annotation instanceof ExchangeProperty) { + ExchangeProperty propertyAnnotation = (ExchangeProperty) annotation; + return ExpressionBuilder.exchangePropertyExpression(propertyAnnotation.value()); + } else if (annotation instanceof ExchangeProperties) { + return ExpressionBuilder.exchangePropertiesExpression(); + } else if (annotation instanceof Header) { + Header headerAnnotation = (Header) annotation; + return ExpressionBuilder.headerExpression(headerAnnotation.value()); + } else if (annotation instanceof Headers) { + return ExpressionBuilder.headersExpression(); + } else if (annotation instanceof ExchangeException) { + return ExpressionBuilder.exchangeExceptionExpression(CastUtils.cast(parameterType, Exception.class)); + } else if (annotation instanceof PropertyInject) { + PropertyInject propertyAnnotation = (PropertyInject) annotation; + Expression inject = ExpressionBuilder.propertiesComponentExpression(propertyAnnotation.value(), propertyAnnotation.defaultValue()); + return ExpressionBuilder.convertToExpression(inject, parameterType); + } else { + LanguageAnnotation languageAnnotation = annotation.annotationType().getAnnotation(LanguageAnnotation.class); + if (languageAnnotation != null) { + Class type = languageAnnotation.factory(); + if (type == Object.class) { + // use the default factory + type = DefaultAnnotationExpressionFactory.class; + } + Object object = camelContext.getInjector().newInstance(type); + if (object instanceof AnnotationExpressionFactory) { + AnnotationExpressionFactory expressionFactory = (AnnotationExpressionFactory) object; + return expressionFactory.createExpression(camelContext, annotation, languageAnnotation, parameterType); + } else { + LOG.warn("Ignoring bad annotation: " + languageAnnotation + "on method: " + method + + " which declares a factory: " + type.getName() + + " which does not implement " + AnnotationExpressionFactory.class.getName()); + } + } + } + + return null; + } + + private static void removeAllSetterOrGetterMethods(List methods) { + Iterator it = methods.iterator(); + while (it.hasNext()) { + MethodInfo info = it.next(); + if (isGetter(info.getMethod())) { + // skip getters + it.remove(); + } else if (isSetter(info.getMethod())) { + // skip setters + it.remove(); + } + } + } + + private void removeNonMatchingMethods(List methods, String name) { + // method does not match so remove it + methods.removeIf(info -> !matchMethod(info.getMethod(), name)); + } + + private void removeAllAbstractMethods(List methods) { + Iterator it = methods.iterator(); + while (it.hasNext()) { + MethodInfo info = it.next(); + // if the class is an interface then keep the method + boolean isFromInterface = Modifier.isInterface(info.getMethod().getDeclaringClass().getModifiers()); + if (!isFromInterface && Modifier.isAbstract(info.getMethod().getModifiers())) { + // we cannot invoke an abstract method + it.remove(); + } + } + } + + private boolean matchMethod(Method method, String methodName) { + if (methodName == null) { + return true; + } + + if (methodName.contains("(") && !methodName.endsWith(")")) { + throw new IllegalArgumentException("Name must have both starting and ending parenthesis, was: " + methodName); + } + + // do not use qualifier for name matching + String name = methodName; + if (name.contains("(")) { + name = StringHelper.before(name, "("); + } + + // must match name + if (name != null && !name.equals(method.getName())) { + return false; + } + + // is it a method with no parameters + boolean noParameters = methodName.endsWith("()"); + if (noParameters) { + return method.getParameterCount() == 0; + } + + // match qualifier types which is used to select among overloaded methods + String types = StringHelper.between(methodName, "(", ")"); + if (org.apache.camel.util.ObjectHelper.isNotEmpty(types)) { + // we must qualify based on types to match method + String[] parameters = StringQuoteHelper.splitSafeQuote(types, ','); + Class[] parameterTypes = null; + Iterator it = ObjectHelper.createIterator(parameters); + for (int i = 0; i < method.getParameterCount(); i++) { + if (it.hasNext()) { + if (parameterTypes == null) { + parameterTypes = method.getParameterTypes(); + } + Class parameterType = parameterTypes[i]; + + String qualifyType = (String) it.next(); + if (org.apache.camel.util.ObjectHelper.isEmpty(qualifyType)) { + continue; + } + // trim the type + qualifyType = qualifyType.trim(); + + if ("*".equals(qualifyType)) { + // * is a wildcard so we accept and match that parameter type + continue; + } + + if (BeanHelper.isValidParameterValue(qualifyType)) { + // its a parameter value, so continue to next parameter + // as we should only check for FQN/type parameters + continue; + } + + // if qualify type indeed is a class, then it must be assignable with the parameter type + Boolean assignable = BeanHelper.isAssignableToExpectedType(getCamelContext().getClassResolver(), qualifyType, parameterType); + // the method will return null if the qualifyType is not a class + if (assignable != null && !assignable) { + return false; + } + + } else { + // there method has more parameters than was specified in the method name qualifiers + return false; + } + } + + // if the method has no more types then we can only regard it as matched + // if there are no more qualifiers + if (it.hasNext()) { + return false; + } + } + + // the method matched + return true; + } + + private static Class getTargetClass(Class clazz) { + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { + Class superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) { + return superClass; + } + } + return clazz; + } + + /** + * Do we have a method with the given name. + *

+ * Shorthand method names for getters is supported, so you can pass in eg 'name' and Camel + * will can find the real 'getName' method instead. + * + * @param methodName the method name + * @return true if we have such a method. + */ + public boolean hasMethod(String methodName) { + return getOperations(methodName) != null; + } + + /** + * Do we have a static method with the given name. + *

+ * Shorthand method names for getters is supported, so you can pass in eg 'name' and Camel + * will can find the real 'getName' method instead. + * + * @param methodName the method name + * @return true if we have such a static method. + */ + public boolean hasStaticMethod(String methodName) { + List methods = getOperations(methodName); + if (methods == null || methods.isEmpty()) { + return false; + } + for (MethodInfo method : methods) { + if (method.isStaticMethod()) { + return true; + } + } + return false; + } + + /** + * Returns whether the bean class has any public constructors. + */ + public boolean hasPublicConstructors() { + return publicConstructors; + } + + /** + * Returns whether the bean class has any public no-arg constructors. + */ + public boolean hasPublicNoArgConstructors() { + return publicNoArgConstructors; + } + + /** + * Gets the list of methods sorted by A..Z method name. + * + * @return the methods. + */ + public List getMethods() { + if (operations.isEmpty()) { + return Collections.emptyList(); + } + + List methods = new ArrayList<>(); + for (Collection col : operations.values()) { + methods.addAll(col); + } + + if (methods.size() > 1) { + // sort the methods by name A..Z + methods.sort(Comparator.comparing(o -> o.getMethod().getName())); + } + return methods; + } + + /** + * Does any of the methods have a Canel @Handler annotation. + */ + public boolean hasAnyMethodHandlerAnnotation() { + return !operationsWithHandlerAnnotation.isEmpty(); + } + + /** + * Get the operation(s) with the given name. We can have multiple when methods is overloaded. + *

+ * Shorthand method names for getters is supported, so you can pass in eg 'name' and Camel + * will can find the real 'getName' method instead. + * + * @param methodName the method name + * @return the found method, or null if not found + */ + private List getOperations(String methodName) { + // do not use qualifier for name + if (methodName.contains("(")) { + methodName = StringHelper.before(methodName, "("); + } + + List answer = operations.get(methodName); + if (answer != null) { + return answer; + } + + // now try all getters to see if any of those matched the methodName + for (Method method : methodMap.keySet()) { + if (isGetter(method)) { + String shorthandMethodName = getGetterShorthandName(method); + // if the two names matches then see if we can find it using that name + if (methodName != null && methodName.equals(shorthandMethodName)) { + return operations.get(method.getName()); + } + } + } + + return null; + } + + public static boolean isGetter(Method method) { + String name = method.getName(); + Class type = method.getReturnType(); + int parameterCount = method.getParameterCount(); + + // is it a getXXX method + if (name.startsWith("get") && name.length() >= 4 && Character.isUpperCase(name.charAt(3))) { + return parameterCount == 0 && !type.equals(Void.TYPE); + } + + // special for isXXX boolean + if (name.startsWith("is") && name.length() >= 3 && Character.isUpperCase(name.charAt(2))) { + return parameterCount == 0 && type.getSimpleName().equalsIgnoreCase("boolean"); + } + + return false; + } + + public static boolean isSetter(Method method) { + String name = method.getName(); + Class type = method.getReturnType(); + int parameterCount = method.getParameterCount(); + + // is it a setXXX method + boolean validName = name.startsWith("set") && name.length() >= 4 && Character.isUpperCase(name.charAt(3)); + if (validName && parameterCount == 1) { + // a setXXX can also be a builder pattern so check for its return type is itself + return type.equals(Void.TYPE); + } + + return false; + } + + public static String getGetterShorthandName(Method method) { + if (!isGetter(method)) { + return method.getName(); + } + + String name = method.getName(); + if (name.startsWith("get")) { + name = name.substring(3); + name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1); + } else if (name.startsWith("is")) { + name = name.substring(2); + name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1); + } + + return name; + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanInfoCacheKey.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanInfoCacheKey.java new file mode 100644 index 00000000..bb02aa10 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanInfoCacheKey.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import java.lang.reflect.Method; + +/** + * A key used for caching {@link BeanInfo} by the {@link BeanComponent} + */ +public final class BeanInfoCacheKey { + + private final Class type; + private final Method explicitMethod; + + public BeanInfoCacheKey(Class type, Method explicitMethod) { + this.type = type; + this.explicitMethod = explicitMethod; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + BeanInfoCacheKey that = (BeanInfoCacheKey) o; + + if (explicitMethod != null ? !explicitMethod.equals(that.explicitMethod) : that.explicitMethod != null) { + return false; + } + if (!type.equals(that.type)) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result = type.hashCode(); + result = 31 * result + (explicitMethod != null ? explicitMethod.hashCode() : 0); + return result; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanProcessor.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanProcessor.java new file mode 100644 index 00000000..a219316c --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanProcessor.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.*; +import org.apache.camel.support.service.ServiceSupport; + +import java.util.concurrent.CompletableFuture; + +public class BeanProcessor extends ServiceSupport implements AsyncProcessor { + + private final DelegateBeanProcessor delegate; + + public BeanProcessor(Object pojo, BeanInfo beanInfo) { + this.delegate = new DelegateBeanProcessor(pojo, beanInfo); + } + + public BeanProcessor(Object pojo, CamelContext camelContext, ParameterMappingStrategy parameterMappingStrategy) { + this.delegate = new DelegateBeanProcessor(pojo, camelContext, parameterMappingStrategy); + } + + public BeanProcessor(Object pojo, CamelContext camelContext) { + this.delegate = new DelegateBeanProcessor(pojo, camelContext); + } + + public BeanProcessor(BeanHolder beanHolder) { + this.delegate = new DelegateBeanProcessor(beanHolder); + } + + @Override + public void process(Exchange exchange) throws Exception { + delegate.process(exchange); + } + + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + return delegate.process(exchange, callback); + } + + @Override + public CompletableFuture processAsync(Exchange exchange) { + return delegate.processAsync(exchange); + } + + public Processor getProcessor() { + return delegate.getProcessor(); + } + + public BeanHolder getBeanHolder() { + return delegate.getBeanHolder(); + } + + public Object getBean() { + return delegate.getBean(); + } + + public String getMethod() { + return delegate.getMethod(); + } + + public void setMethod(String method) { + delegate.setMethod(method); + } + + public BeanScope getScope() { + return delegate.getScope(); + } + + public void setScope(BeanScope scope) { + delegate.setScope(scope); + } + + public boolean isShorthandMethod() { + return delegate.isShorthandMethod(); + } + + public void setShorthandMethod(boolean shorthandMethod) { + delegate.setShorthandMethod(shorthandMethod); + } + + @Override + protected void doStart() throws Exception { + delegate.doStart(); + } + + @Override + protected void doStop() throws Exception { + delegate.doStop(); + } + + @Override + public String toString() { + return delegate.toString(); + } + + private static final class DelegateBeanProcessor extends AbstractBeanProcessor { + + public DelegateBeanProcessor(Object pojo, BeanInfo beanInfo) { + super(pojo, beanInfo); + } + + public DelegateBeanProcessor(Object pojo, CamelContext camelContext, ParameterMappingStrategy parameterMappingStrategy) { + super(pojo, camelContext, parameterMappingStrategy); + } + + public DelegateBeanProcessor(Object pojo, CamelContext camelContext) { + super(pojo, camelContext); + } + + public DelegateBeanProcessor(BeanHolder beanHolder) { + super(beanHolder); + } + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanProducer.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanProducer.java new file mode 100644 index 00000000..d8ef8d04 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanProducer.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.AsyncCallback; +import org.apache.camel.Exchange; +import org.apache.camel.NoSuchBeanException; +import org.apache.camel.support.DefaultAsyncProducer; +import org.apache.camel.support.service.ServiceHelper; + +/** + * Bean {@link org.apache.camel.Producer} + */ +public class BeanProducer extends DefaultAsyncProducer { + + private final BeanProcessor processor; + private boolean beanStarted; + + public BeanProducer(BeanEndpoint endpoint, BeanProcessor processor) { + super(endpoint); + this.processor = processor; + this.beanStarted = false; + } + + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + return processor.process(exchange, callback); + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + + if (processor.getBeanHolder() instanceof ConstantBeanHolder) { + try { + // Start the bean if it implements Service interface and if cached + // so meant to be reused + ServiceHelper.startService(processor.getBean()); + beanStarted = true; + } catch (NoSuchBeanException e) { + } + } + } + + @Override + protected void doStop() throws Exception { + if (beanStarted) { + try { + // Stop the bean if it implements Service interface and if cached + // so meant to be reused + ServiceHelper.stopService(processor.getBean()); + beanStarted = false; + } catch (NoSuchBeanException e) { + } + } + + super.doStop(); + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanTypeHolder.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanTypeHolder.java new file mode 100644 index 00000000..cc650247 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/BeanTypeHolder.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +/** + * Object holder for a bean type. + */ +public interface BeanTypeHolder extends BeanHolder { + + Class getType(); + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/CamelInvocationHandler.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/CamelInvocationHandler.java new file mode 100644 index 00000000..02b293e4 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/CamelInvocationHandler.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Endpoint; +import org.apache.camel.ExchangePattern; +import org.apache.camel.Producer; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * An {@link java.lang.reflect.InvocationHandler} which invokes a message + * exchange on a camel {@link Endpoint} + */ +public class CamelInvocationHandler extends AbstractCamelInvocationHandler implements InvocationHandler { + private final MethodInfoCache methodInfoCache; + private final boolean binding; + + public CamelInvocationHandler(Endpoint endpoint, boolean binding, Producer producer, MethodInfoCache methodInfoCache) { + super(endpoint, producer); + this.binding = binding; + this.methodInfoCache = methodInfoCache; + } + + @Override + public Object doInvokeProxy(Object proxy, Method method, Object[] args) throws Throwable { + MethodInfo methodInfo = methodInfoCache.getMethodInfo(method); + final ExchangePattern pattern = methodInfo != null ? methodInfo.getPattern() : ExchangePattern.InOut; + return invokeProxy(method, pattern, args, binding); + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ConstantBeanHolder.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ConstantBeanHolder.java new file mode 100644 index 00000000..c9022765 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ConstantBeanHolder.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.support.CamelContextHelper; +import org.apache.camel.support.PropertyBindingSupport; +import org.apache.camel.util.ObjectHelper; + +import java.util.Map; + +/** + * A constant (singleton) bean implementation of {@link org.apache.camel.component.bean.BeanHolder} + */ +public class ConstantBeanHolder implements BeanHolder { + private final Object bean; + private final BeanInfo beanInfo; + private Processor processor; + private Map options; + + public ConstantBeanHolder(Object bean, BeanInfo beanInfo) { + ObjectHelper.notNull(bean, "bean"); + ObjectHelper.notNull(beanInfo, "beanInfo"); + + this.bean = bean; + this.beanInfo = beanInfo; + } + + public ConstantBeanHolder(Object bean, CamelContext context) { + ObjectHelper.notNull(bean, "bean"); + + this.bean = bean; + this.beanInfo = new BeanInfo(context, bean.getClass()); + } + + @Override + public Map getOptions() { + return options; + } + + @Override + public void setOptions(Map options) { + this.options = options; + + // since its a constant we can set the options immediately on the bean + if (options != null && !options.isEmpty()) { + PropertyBindingSupport.build() + .withRemoveParameters(false) + .withCamelContext(getBeanInfo().getCamelContext()) + .withProperties(options) + .withTarget(bean) + .bind(); + } + } + + @Override + public String toString() { + // avoid invoke toString on bean as it may be a remote proxy + return ObjectHelper.className(bean) + "(" + ObjectHelper.getIdentityHashCode(bean) + ")"; + } + + @Override + public Object getBean(Exchange exchange) { + return bean; + } + + @Override + public Processor getProcessor() { + if (this.processor == null) { + this.processor = CamelContextHelper.convertTo(beanInfo.getCamelContext(), Processor.class, bean); + } + return this.processor; + } + + @Override + public boolean supportProcessor() { + return true; + } + + @Override + public BeanInfo getBeanInfo() { + return beanInfo; + } + + @Override + public BeanInfo getBeanInfo(Object bean) { + return null; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ConstantStaticTypeBeanHolder.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ConstantStaticTypeBeanHolder.java new file mode 100644 index 00000000..9bd52554 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ConstantStaticTypeBeanHolder.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; + +/** + * A constant {@link org.apache.camel.component.bean.BeanHolder} for a class or static class + * where the intention is to only invoke static methods, without the need for creating an instance of the type. + */ +public class ConstantStaticTypeBeanHolder extends ConstantTypeBeanHolder { + + public ConstantStaticTypeBeanHolder(Class type, CamelContext context) { + super(type, context); + } + + @Override + public Object getBean(Exchange exchange) { + // we cannot create a bean as there is no default constructor + return null; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ConstantTypeBeanHolder.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ConstantTypeBeanHolder.java new file mode 100644 index 00000000..e072541b --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ConstantTypeBeanHolder.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.support.PropertyBindingSupport; +import org.apache.camel.util.ObjectHelper; + +import java.util.Map; + +/** + * A constant (singleton) bean implementation of {@link org.apache.camel.component.bean.BeanTypeHolder} + */ +public class ConstantTypeBeanHolder implements BeanTypeHolder { + private final Class type; + private final BeanInfo beanInfo; + private Map options; + + public ConstantTypeBeanHolder(Class type, CamelContext context) { + this(type, new BeanInfo(context, type)); + } + + public ConstantTypeBeanHolder(Class type, BeanInfo beanInfo) { + ObjectHelper.notNull(type, "type"); + ObjectHelper.notNull(beanInfo, "beanInfo"); + + this.type = type; + this.beanInfo = beanInfo; + } + + @Override + public Map getOptions() { + return options; + } + + @Override + public void setOptions(Map options) { + this.options = options; + } + + /** + * Creates a cached and constant {@link org.apache.camel.component.bean.BeanHolder} from this holder. + * + * @return a new {@link org.apache.camel.component.bean.BeanHolder} that has cached the lookup of the bean. + */ + public ConstantBeanHolder createCacheHolder() throws Exception { + Object bean = getBean(null); + return new ConstantBeanHolder(bean, beanInfo); + } + + @Override + public String toString() { + return type.toString(); + } + + @Override + public Object getBean(Exchange exchange) { + // only create a bean if we have a default no-arg constructor + if (beanInfo.hasPublicNoArgConstructors()) { + Object bean = getBeanInfo().getCamelContext().getInjector().newInstance(type, false); + if (options != null && !options.isEmpty()) { + PropertyBindingSupport.build() + .withRemoveParameters(false) + .withCamelContext(getBeanInfo().getCamelContext()) + .withProperties(options) + .withTarget(bean) + .bind(); + } + return bean; + } else { + return null; + } + } + + @Override + public Processor getProcessor() { + return null; + } + + @Override + public boolean supportProcessor() { + return false; + } + + @Override + public BeanInfo getBeanInfo() { + return beanInfo; + } + + @Override + public BeanInfo getBeanInfo(Object bean) { + return null; + } + + @Override + public Class getType() { + return type; + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/DefaultBeanProcessorFactory.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/DefaultBeanProcessorFactory.java new file mode 100644 index 00000000..2683b30a --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/DefaultBeanProcessorFactory.java @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.BeanScope; +import org.apache.camel.CamelContext; +import org.apache.camel.Processor; +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.spi.BeanProcessorFactory; +import org.apache.camel.spi.annotations.JdkService; +import org.apache.camel.support.CamelContextHelper; +import org.apache.camel.util.ObjectHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Method; + +@JdkService(BeanProcessorFactory.FACTORY) +public final class DefaultBeanProcessorFactory implements BeanProcessorFactory { + + private static final Logger LOG = LoggerFactory.getLogger(DefaultBeanProcessorFactory.class); + + public DefaultBeanProcessorFactory() { + } + + @Override + public Processor createBeanProcessor(CamelContext camelContext, Object bean, Method method) throws Exception { + BeanInfo info = new BeanInfo(camelContext, method); + return new BeanProcessor(bean, info); + } + + @Override + public Processor createBeanProcessor(CamelContext camelContext, Object bean, String beanType, Class beanClass, String ref, + String method, BeanScope scope) throws Exception { + + BeanProcessor answer; + Class clazz = bean != null ? bean.getClass() : null; + BeanHolder beanHolder; + + if (ObjectHelper.isNotEmpty(ref)) { + if (scope == BeanScope.Singleton) { + // cache the registry lookup which avoids repeat lookup in the registry + beanHolder = new RegistryBean(camelContext, ref).createCacheHolder(); + // bean holder will check if the bean exists + bean = beanHolder.getBean(null); + } else { + // we do not cache so we invoke on-demand + beanHolder = new RegistryBean(camelContext, ref); + } + if (scope == BeanScope.Request) { + // wrap in registry scoped holder + beanHolder = new RequestBeanHolder(beanHolder); + } + answer = new BeanProcessor(beanHolder); + } else { + if (bean == null) { + if (beanType == null && beanClass == null) { + throw new IllegalArgumentException("bean, ref or beanType must be provided"); + } + + // the clazz is either from beanType or beanClass + if (beanType != null) { + try { + clazz = camelContext.getClassResolver().resolveMandatoryClass(beanType); + } catch (ClassNotFoundException e) { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } + } else { + clazz = beanClass; + } + + // attempt to create bean using injector which supports auto-wiring + if (scope == BeanScope.Singleton && camelContext.getInjector().supportsAutoWiring()) { + try { + LOG.debug("Attempting to create new bean instance from class: {} via auto-wiring enabled", clazz); + bean = CamelContextHelper.newInstance(camelContext, clazz); + } catch (Throwable e) { + LOG.debug("Error creating new bean instance from class: " + clazz + ". This exception is ignored", e); + } + } + + // create a bean if there is a default public no-arg constructor + if (bean == null && scope == BeanScope.Singleton && ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) { + LOG.debug("Class has default no-arg constructor so creating a new bean instance: {}", clazz); + bean = CamelContextHelper.newInstance(camelContext, clazz); + ObjectHelper.notNull(bean, "bean", this); + } + } + + // validate the bean type is not from java so you by mistake think its a reference + // to a bean name but the String is being invoke instead + if (bean instanceof String) { + throw new IllegalArgumentException("The bean instance is a java.lang.String type: " + bean + + ". We suppose you want to refer to a bean instance by its id instead. Please use ref."); + } + + // the holder should either be bean or type based + if (bean != null) { + beanHolder = new ConstantBeanHolder(bean, camelContext); + } else { + if (scope == BeanScope.Singleton && ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) { + // we can only cache if we can create an instance of the bean, and for that we need a public constructor + beanHolder = new ConstantTypeBeanHolder(clazz, camelContext).createCacheHolder(); + } else { + if (ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) { + beanHolder = new ConstantTypeBeanHolder(clazz, camelContext); + } else { + // this is only for invoking static methods on the bean + beanHolder = new ConstantStaticTypeBeanHolder(clazz, camelContext); + } + } + } + if (scope == BeanScope.Request) { + // wrap in registry scoped holder + beanHolder = new RequestBeanHolder(beanHolder); + } + answer = new BeanProcessor(beanHolder); + } + + // check for method exists + if (method != null) { + answer.setMethod(method); + + // check there is a method with the given name, and leverage BeanInfo for that + // which we only do if we are caching the bean as otherwise we will create a bean instance for this check + // which we only want to do if we cache the bean + if (scope == BeanScope.Singleton) { + BeanInfo beanInfo = beanHolder.getBeanInfo(); + if (bean != null) { + // there is a bean instance, so check for any methods + if (!beanInfo.hasMethod(method)) { + throw RuntimeCamelException.wrapRuntimeCamelException(new MethodNotFoundException(null, bean, method)); + } + } else if (clazz != null) { + // there is no bean instance, so check for static methods only + if (!beanInfo.hasStaticMethod(method)) { + throw RuntimeCamelException.wrapRuntimeCamelException(new MethodNotFoundException(null, clazz, method, true)); + } + } + } + } + + return answer; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/DefaultBeanProxyFactory.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/DefaultBeanProxyFactory.java new file mode 100644 index 00000000..088219d6 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/DefaultBeanProxyFactory.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Endpoint; +import org.apache.camel.spi.BeanProxyFactory; +import org.apache.camel.spi.annotations.JdkService; + +@JdkService(BeanProxyFactory.FACTORY) +public final class DefaultBeanProxyFactory implements BeanProxyFactory { + + public DefaultBeanProxyFactory() { + } + + @SafeVarargs + @Override + public final T createProxy(Endpoint endpoint, boolean binding, Class... interfaceClasses) throws Exception { + return ProxyHelper.createProxy(endpoint, binding, interfaceClasses); + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/DefaultParameterMappingStrategy.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/DefaultParameterMappingStrategy.java new file mode 100644 index 00000000..16cec292 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/DefaultParameterMappingStrategy.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.*; +import org.apache.camel.spi.Registry; +import org.apache.camel.support.builder.ExpressionBuilder; + +import java.util.HashMap; +import java.util.Map; + +/** + * Represents the strategy used to figure out how to map a message exchange to a POJO method invocation + */ +public final class DefaultParameterMappingStrategy implements ParameterMappingStrategy { + + public static final DefaultParameterMappingStrategy INSTANCE = new DefaultParameterMappingStrategy(); + + private static final Map, Expression> MAP = new HashMap<>(6); + + static { + MAP.put(Exchange.class, ExpressionBuilder.exchangeExpression()); + MAP.put(Message.class, ExpressionBuilder.inMessageExpression()); + MAP.put(Exception.class, ExpressionBuilder.exchangeExceptionExpression()); + MAP.put(TypeConverter.class, ExpressionBuilder.typeConverterExpression()); + MAP.put(Registry.class, ExpressionBuilder.registryExpression()); + MAP.put(CamelContext.class, ExpressionBuilder.camelContextExpression()); + } + + ; + + private DefaultParameterMappingStrategy() { + } + + @Override + public Expression getDefaultParameterTypeExpression(Class parameterType) { + return MAP.get(parameterType); + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodBean.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodBean.java new file mode 100644 index 00000000..949df45e --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodBean.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import java.io.Serializable; +import java.lang.reflect.Method; + +/** + * Represents a {@link Serializable} version of a {@link Method} + */ +public class MethodBean implements Serializable { + private static final long serialVersionUID = -789408217201706532L; + + private String name; + private Class type; + private Class[] parameterTypes; + + public MethodBean() { + } + + public MethodBean(Method method) { + this.name = method.getName(); + this.type = method.getDeclaringClass(); + this.parameterTypes = method.getParameterTypes(); + } + + public Method getMethod() throws NoSuchMethodException { + return type.getMethod(name, parameterTypes); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Class[] getParameterTypes() { + return parameterTypes; + } + + public void setParameterTypes(Class[] parameterTypes) { + this.parameterTypes = parameterTypes; + } + + public Class getType() { + return type; + } + + public void setType(Class type) { + this.type = type; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodInfo.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodInfo.java new file mode 100644 index 00000000..1f9fb9c5 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodInfo.java @@ -0,0 +1,755 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.*; +import org.apache.camel.component.bean.BeanHelper; +import org.apache.camel.support.*; +import org.apache.camel.support.service.ServiceHelper; +import org.apache.camel.util.StringHelper; +import org.apache.camel.util.StringQuoteHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.annotation.Annotation; +import java.lang.reflect.*; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionStage; + +import static org.apache.camel.util.ObjectHelper.asList; +import static org.apache.camel.util.ObjectHelper.asString; + +/** + * Information about a method to be used for invocation. + */ +public class MethodInfo { + private static final Logger LOG = LoggerFactory.getLogger(MethodInfo.class); + + private CamelContext camelContext; + private Class type; + private Method method; + private final List parameters; + private final List bodyParameters; + private final boolean hasCustomAnnotation; + private final boolean hasHandlerAnnotation; + private Expression parametersExpression; + private ExchangePattern pattern = ExchangePattern.InOut; + private AsyncProcessor recipientList; + private AsyncProcessor routingSlip; + private AsyncProcessor dynamicRouter; + + /** + * Adapter to invoke the method which has been annotated with the @DynamicRouter + */ + private final class DynamicRouterExpression extends ExpressionAdapter { + private final Object pojo; + + private DynamicRouterExpression(Object pojo) { + this.pojo = pojo; + } + + @Override + public Object evaluate(Exchange exchange) { + // evaluate arguments on each invocation as the parameters can have changed/updated since last invocation + final Object[] arguments = parametersExpression.evaluate(exchange, Object[].class); + try { + return invoke(method, pojo, arguments, exchange); + } catch (Exception e) { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } + } + + @Override + public String toString() { + return "DynamicRouter[invoking: " + method + " on bean: " + pojo + "]"; + } + } + + public MethodInfo(CamelContext camelContext, Class type, Method method, List parameters, List bodyParameters, + boolean hasCustomAnnotation, boolean hasHandlerAnnotation) { + this.camelContext = camelContext; + this.type = type; + this.method = method; + this.parameters = parameters; + this.bodyParameters = bodyParameters; + this.hasCustomAnnotation = hasCustomAnnotation; + this.hasHandlerAnnotation = hasHandlerAnnotation; + this.parametersExpression = createParametersExpression(); + + Map, Annotation> collectedMethodAnnotation = collectMethodAnnotations(type, method); + + Pattern oneway = findOneWayAnnotation(method); + if (oneway != null) { + pattern = oneway.value(); + } + + org.apache.camel.RoutingSlip routingSlipAnnotation = + (org.apache.camel.RoutingSlip) collectedMethodAnnotation.get(org.apache.camel.RoutingSlip.class); + if (routingSlipAnnotation != null) { + routingSlip = camelContext.adapt(ExtendedCamelContext.class).getAnnotationBasedProcessorFactory().createRoutingSlip(camelContext, routingSlipAnnotation); + // add created routingSlip as a service so we have its lifecycle managed + try { + camelContext.addService(routingSlip); + } catch (Exception e) { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } + } + + org.apache.camel.DynamicRouter dynamicRouterAnnotation = + (org.apache.camel.DynamicRouter) collectedMethodAnnotation.get(org.apache.camel.DynamicRouter.class); + if (dynamicRouterAnnotation != null) { + dynamicRouter = camelContext.adapt(ExtendedCamelContext.class).getAnnotationBasedProcessorFactory().createDynamicRouter(camelContext, dynamicRouterAnnotation); + // add created dynamicRouter as a service so we have its lifecycle managed + try { + camelContext.addService(dynamicRouter); + } catch (Exception e) { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } + } + + org.apache.camel.RecipientList recipientListAnnotation = + (org.apache.camel.RecipientList) collectedMethodAnnotation.get(org.apache.camel.RecipientList.class); + if (recipientListAnnotation != null) { + recipientList = camelContext.adapt(ExtendedCamelContext.class).getAnnotationBasedProcessorFactory().createRecipientList(camelContext, recipientListAnnotation); + // add created recipientList as a service so we have its lifecycle managed + try { + camelContext.addService(recipientList); + } catch (Exception e) { + throw RuntimeCamelException.wrapRuntimeCamelException(e); + } + } + } + + private Map, Annotation> collectMethodAnnotations(Class c, Method method) { + Map, Annotation> annotations = new HashMap<>(); + collectMethodAnnotations(c, method, annotations); + return annotations; + } + + private void collectMethodAnnotations(Class c, Method method, Map, Annotation> annotations) { + for (Class i : c.getInterfaces()) { + collectMethodAnnotations(i, method, annotations); + } + if (!c.isInterface() && c.getSuperclass() != null) { + collectMethodAnnotations(c.getSuperclass(), method, annotations); + } + // make sure the sub class can override the definition + try { + Annotation[] ma = c.getDeclaredMethod(method.getName(), method.getParameterTypes()).getAnnotations(); + for (Annotation a : ma) { + annotations.put(a.annotationType(), a); + } + } catch (SecurityException | NoSuchMethodException e) { + // do nothing here + } + } + + @Override + public String toString() { + return method.toString(); + } + + public MethodInvocation createMethodInvocation(final Object pojo, boolean hasParameters, final Exchange exchange) { + final Object[] arguments; + if (hasParameters) { + arguments = parametersExpression.evaluate(exchange, Object[].class); + } else { + arguments = null; + } + + return new MethodInvocation() { + public Method getMethod() { + return method; + } + + public Object[] getArguments() { + return arguments; + } + + public boolean proceed(AsyncCallback callback) { + try { + // reset cached streams so they can be read again + MessageHelper.resetStreamCache(exchange.getIn()); + return doProceed(callback); + } catch (InvocationTargetException e) { + exchange.setException(e.getTargetException()); + callback.done(true); + return true; + } catch (Throwable e) { + exchange.setException(e); + callback.done(true); + return true; + } + } + + private boolean doProceed(AsyncCallback callback) throws Exception { + // dynamic router should be invoked beforehand + if (dynamicRouter != null) { + if (!ServiceHelper.isStarted(dynamicRouter)) { + ServiceHelper.startService(dynamicRouter); + } + // TODO: Maybe use a new constant than EVALUATE_EXPRESSION_RESULT + // use a expression which invokes the method to be used by dynamic router + Expression expression = new DynamicRouterExpression(pojo); + exchange.setProperty(Exchange.EVALUATE_EXPRESSION_RESULT, expression); + return dynamicRouter.process(exchange, callback); + } + + // invoke pojo + if (LOG.isTraceEnabled()) { + LOG.trace(">>>> invoking: {} on bean: {} with arguments: {} for exchange: {}", method, pojo, asString(arguments), exchange); + } + Object result = invoke(method, pojo, arguments, exchange); + + // the method may be a closure or chained method returning a callable which should be called + if (result instanceof Callable) { + LOG.trace("Method returned Callback which will be called: {}", result); + Object callableResult = ((Callable) result).call(); + if (callableResult != null) { + result = callableResult; + } else { + // if callable returned null we should not change the body + result = Void.TYPE; + } + } + + if (recipientList != null) { + // ensure its started + if (!ServiceHelper.isStarted(recipientList)) { + ServiceHelper.startService(recipientList); + } + exchange.setProperty(Exchange.EVALUATE_EXPRESSION_RESULT, result); + return recipientList.process(exchange, callback); + } + if (routingSlip != null) { + if (!ServiceHelper.isStarted(routingSlip)) { + ServiceHelper.startService(routingSlip); + } + exchange.setProperty(Exchange.EVALUATE_EXPRESSION_RESULT, result); + return routingSlip.process(exchange, callback); + } + + //If it's Java 8 async result + if (CompletionStage.class.isAssignableFrom(method.getReturnType())) { + CompletionStage completionStage = (CompletionStage) result; + + completionStage + .whenComplete((resultObject, e) -> { + if (e != null) { + exchange.setException(e); + } else if (resultObject != null) { + fillResult(exchange, resultObject); + } + callback.done(false); + }); + return false; + } + + // if the method returns something then set the value returned on the Exchange + if (result != Void.TYPE && !method.getReturnType().equals(Void.TYPE)) { + fillResult(exchange, result); + } + + // we did not use any of the eips, but just invoked the bean + // so notify the callback we are done synchronously + callback.done(true); + return true; + } + + public Object getThis() { + return pojo; + } + + public AccessibleObject getStaticPart() { + return method; + } + }; + } + + private void fillResult(Exchange exchange, Object result) { + LOG.trace("Setting bean invocation result : {}", result); + + // the bean component forces OUT if the MEP is OUT capable + boolean out = exchange.hasOut() || ExchangeHelper.isOutCapable(exchange); + Message old; + if (out) { + old = exchange.getOut(); + // propagate headers + exchange.getOut().getHeaders().putAll(exchange.getIn().getHeaders()); + } else { + old = exchange.getIn(); + } + + // create a new message container so we do not drag specialized message objects along + // but that is only needed if the old message is a specialized message + boolean copyNeeded = !(old.getClass().equals(DefaultMessage.class)); + + if (copyNeeded) { + Message msg = new DefaultMessage(exchange.getContext()); + msg.copyFromWithNewBody(old, result); + + // replace message on exchange + ExchangeHelper.replaceMessage(exchange, msg, false); + } else { + // no copy needed so set replace value directly + old.setBody(result); + } + } + + public Class getType() { + return type; + } + + public Method getMethod() { + return method; + } + + /** + * Returns the {@link org.apache.camel.ExchangePattern} that should be used when invoking this method. This value + * defaults to {@link org.apache.camel.ExchangePattern#InOut} unless some {@link org.apache.camel.Pattern} annotation is used + * to override the message exchange pattern. + * + * @return the exchange pattern to use for invoking this method. + */ + public ExchangePattern getPattern() { + return pattern; + } + + public Expression getParametersExpression() { + return parametersExpression; + } + + public List getBodyParameters() { + return bodyParameters; + } + + public Class getBodyParameterType() { + if (bodyParameters.isEmpty()) { + return null; + } + ParameterInfo parameterInfo = bodyParameters.get(0); + return parameterInfo.getType(); + } + + public boolean bodyParameterMatches(Class bodyType) { + Class actualType = getBodyParameterType(); + return actualType != null && org.apache.camel.util.ObjectHelper.isAssignableFrom(bodyType, actualType); + } + + public List getParameters() { + return parameters; + } + + public boolean hasBodyParameter() { + return !bodyParameters.isEmpty(); + } + + public boolean hasCustomAnnotation() { + return hasCustomAnnotation; + } + + public boolean hasHandlerAnnotation() { + return hasHandlerAnnotation; + } + + public boolean hasParameters() { + return !parameters.isEmpty(); + } + + public boolean isReturnTypeVoid() { + return method.getReturnType().getName().equals("void"); + } + + public boolean isStaticMethod() { + return Modifier.isStatic(method.getModifiers()); + } + + /** + * Returns true if this method is covariant with the specified method + * (this method may above or below the specified method in the class hierarchy) + */ + public boolean isCovariantWith(MethodInfo method) { + return + method.getMethod().getName().equals(this.getMethod().getName()) + && (method.getMethod().getReturnType().isAssignableFrom(this.getMethod().getReturnType()) + || this.getMethod().getReturnType().isAssignableFrom(method.getMethod().getReturnType())) + && Arrays.deepEquals(method.getMethod().getParameterTypes(), this.getMethod().getParameterTypes()); + } + + protected Object invoke(Method mth, Object pojo, Object[] arguments, Exchange exchange) throws InvocationTargetException { + try { + return ObjectHelper.invokeMethodSafe(mth, pojo, arguments); + } catch (IllegalAccessException e) { + throw new RuntimeExchangeException("IllegalAccessException occurred invoking method: " + mth + " using arguments: " + asList(arguments), exchange, e); + } catch (IllegalArgumentException e) { + throw new RuntimeExchangeException("IllegalArgumentException occurred invoking method: " + mth + " using arguments: " + asList(arguments), exchange, e); + } + } + + protected Expression[] createParameterExpressions() { + final int size = parameters.size(); + LOG.trace("Creating parameters expression for {} parameters", size); + + final Expression[] expressions = new Expression[size]; + for (int i = 0; i < size; i++) { + Expression parameterExpression = parameters.get(i).getExpression(); + expressions[i] = parameterExpression; + LOG.trace("Parameter #{} has expression: {}", i, parameterExpression); + } + + return expressions; + } + + protected Expression createParametersExpression() { + return new ParameterExpression(createParameterExpressions()); + } + + /** + * Finds the oneway annotation in priority order; look for method level annotations first, then the class level annotations, + * then super class annotations then interface annotations + * + * @param method the method on which to search + * @return the first matching annotation or none if it is not available + */ + protected Pattern findOneWayAnnotation(Method method) { + Pattern answer = getPatternAnnotation(method); + if (answer == null) { + Class type = method.getDeclaringClass(); + + // create the search order of types to scan + List> typesToSearch = new ArrayList<>(); + addTypeAndSuperTypes(type, typesToSearch); + Class[] interfaces = type.getInterfaces(); + for (Class anInterface : interfaces) { + addTypeAndSuperTypes(anInterface, typesToSearch); + } + + // now let's scan for a type which the current declared class overloads + answer = findOneWayAnnotationOnMethod(typesToSearch, method); + if (answer == null) { + answer = findOneWayAnnotation(typesToSearch); + } + } + return answer; + } + + /** + * Returns the pattern annotation on the given annotated element; either as a direct annotation or + * on an annotation which is also annotated + * + * @param annotatedElement the element to look for the annotation + * @return the first matching annotation or null if none could be found + */ + protected Pattern getPatternAnnotation(AnnotatedElement annotatedElement) { + return getPatternAnnotation(annotatedElement, 2); + } + + /** + * Returns the pattern annotation on the given annotated element; either as a direct annotation or + * on an annotation which is also annotated + * + * @param annotatedElement the element to look for the annotation + * @param depth the current depth + * @return the first matching annotation or null if none could be found + */ + protected Pattern getPatternAnnotation(AnnotatedElement annotatedElement, int depth) { + Pattern answer = annotatedElement.getAnnotation(Pattern.class); + int nextDepth = depth - 1; + + if (nextDepth > 0) { + // look at all the annotations to see if any of those are annotated + Annotation[] annotations = annotatedElement.getAnnotations(); + for (Annotation annotation : annotations) { + Class annotationType = annotation.annotationType(); + if (annotation instanceof Pattern || annotationType.equals(annotatedElement)) { + continue; + } else { + Pattern another = getPatternAnnotation(annotationType, nextDepth); + if (pattern != null) { + if (answer == null) { + answer = another; + } else { + LOG.warn("Duplicate pattern annotation: {} found on annotation: {} which will be ignored", another, annotation); + } + } + } + } + } + return answer; + } + + /** + * Adds the current class and all of its base classes (apart from {@link Object} to the given list + */ + protected void addTypeAndSuperTypes(Class type, List> result) { + for (Class t = type; t != null && t != Object.class; t = t.getSuperclass()) { + result.add(t); + } + } + + /** + * Finds the first annotation on the base methods defined in the list of classes + */ + protected Pattern findOneWayAnnotationOnMethod(List> classes, Method method) { + for (Class type : classes) { + try { + Method definedMethod = type.getMethod(method.getName(), method.getParameterTypes()); + Pattern answer = getPatternAnnotation(definedMethod); + if (answer != null) { + return answer; + } + } catch (NoSuchMethodException e) { + // ignore + } + } + return null; + } + + + /** + * Finds the first annotation on the given list of classes + */ + protected Pattern findOneWayAnnotation(List> classes) { + for (Class type : classes) { + Pattern answer = getPatternAnnotation(type); + if (answer != null) { + return answer; + } + } + return null; + } + + protected boolean hasExceptionParameter() { + for (ParameterInfo parameter : parameters) { + if (Exception.class.isAssignableFrom(parameter.getType())) { + return true; + } + } + return false; + } + + /** + * Expression to evaluate the bean parameter parameters and provide the correct values when the method is invoked. + */ + private final class ParameterExpression implements Expression { + private final Expression[] expressions; + + ParameterExpression(Expression[] expressions) { + this.expressions = expressions; + } + + @Override + @SuppressWarnings("unchecked") + public T evaluate(Exchange exchange, Class type) { + Object body = exchange.getIn().getBody(); + + // if there was an explicit method name to invoke, then we should support using + // any provided parameter values in the method name + String methodName = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, String.class); + // the parameter values is between the parenthesis + String methodParameters = StringHelper.betweenOuterPair(methodName, '(', ')'); + // use an iterator to walk the parameter values + Iterator it = null; + if (methodParameters != null) { + // split the parameters safely separated by comma, but beware that we can have + // quoted parameters which contains comma as well, so do a safe quote split + String[] parameters = StringQuoteHelper.splitSafeQuote(methodParameters, ',', true); + it = ObjectHelper.createIterator(parameters, ",", true); + } + + // remove headers as they should not be propagated + // we need to do this before the expressions gets evaluated as it may contain + // a @Bean expression which would by mistake read these headers. So the headers + // must be removed at this point of time + if (methodName != null) { + exchange.getIn().removeHeader(Exchange.BEAN_METHOD_NAME); + } + + Object[] answer = evaluateParameterExpressions(exchange, body, it); + return (T) answer; + } + + /** + * Evaluates all the parameter expressions + */ + private Object[] evaluateParameterExpressions(Exchange exchange, Object body, Iterator it) { + Object[] answer = new Object[expressions.length]; + for (int i = 0; i < expressions.length; i++) { + + if (body instanceof StreamCache) { + // need to reset stream cache for each expression as you may access the message body in multiple parameters + ((StreamCache) body).reset(); + } + + // grab the parameter value for the given index + Object parameterValue = it != null && it.hasNext() ? it.next() : null; + // and the expected parameter type + Class parameterType = parameters.get(i).getType(); + // the value for the parameter to use + Object value = null; + + // prefer to use parameter value if given, as they override any bean parameter binding + // we should skip * as its a type placeholder to indicate any type + if (parameterValue != null && !parameterValue.equals("*")) { + // evaluate the parameter value binding + value = evaluateParameterValue(exchange, i, parameterValue, parameterType); + } + // use bean parameter binding, if still no value + Expression expression = expressions[i]; + if (value == null && expression != null) { + value = evaluateParameterBinding(exchange, expression, i, parameterType); + } + // remember the value to use + if (value != Void.TYPE) { + answer[i] = value; + } + } + + return answer; + } + + /** + * Evaluate using parameter values where the values can be provided in the method name syntax. + *

+ * This methods returns accordingly: + *

    + *
  • null - if not a parameter value
  • + *
  • Void.TYPE - if an explicit null, forcing Camel to pass in null for that given parameter
  • + *
  • a non null value - if the parameter was a parameter value, and to be used
  • + *
+ * + * @since 2.9 + */ + private Object evaluateParameterValue(Exchange exchange, int index, Object parameterValue, Class parameterType) { + Object answer = null; + + // convert the parameter value to a String + String exp = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, parameterValue); + if (exp != null) { + // check if its a valid parameter value + boolean valid = org.apache.camel.component.bean.BeanHelper.isValidParameterValue(exp); + + if (!valid) { + // it may be a parameter type instead, and if so, then we should return null, + // as this method is only for evaluating parameter values + Boolean isClass = org.apache.camel.component.bean.BeanHelper.isAssignableToExpectedType(exchange.getContext().getClassResolver(), exp, parameterType); + // the method will return a non null value if exp is a class + if (isClass != null) { + return null; + } + } + + // use simple language to evaluate the expression, as it may use the simple language to refer to message body, headers etc. + Expression expression = null; + try { + expression = exchange.getContext().resolveLanguage("simple").createExpression(exp); + parameterValue = expression.evaluate(exchange, Object.class); + // use "null" to indicate the expression returned a null value which is a valid response we need to honor + if (parameterValue == null) { + parameterValue = "null"; + } + } catch (Exception e) { + throw new ExpressionEvaluationException(expression, "Cannot create/evaluate simple expression: " + exp + + " to be bound to parameter at index: " + index + " on method: " + getMethod(), exchange, e); + } + + // special for explicit null parameter values (as end users can explicit indicate they want null as parameter) + // see method javadoc for details + if ("null".equals(parameterValue)) { + return Void.TYPE; + } + + // the parameter value may match the expected type, then we use it as-is + if (parameterType.isAssignableFrom(parameterValue.getClass())) { + valid = true; + } else { + // the parameter value was not already valid, but since the simple language have evaluated the expression + // which may change the parameterValue, so we have to check it again to see if its now valid + exp = exchange.getContext().getTypeConverter().tryConvertTo(String.class, parameterValue); + // String values from the simple language is always valid + if (!valid) { + // re validate if the parameter was not valid the first time (String values should be accepted) + valid = parameterValue instanceof String || BeanHelper.isValidParameterValue(exp); + } + } + + if (valid) { + // we need to unquote String parameters, as the enclosing quotes is there to denote a parameter value + if (parameterValue instanceof String) { + parameterValue = StringHelper.removeLeadingAndEndingQuotes((String) parameterValue); + } + if (parameterValue != null) { + try { + // its a valid parameter value, so convert it to the expected type of the parameter + answer = exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType, exchange, parameterValue); + if (LOG.isTraceEnabled()) { + LOG.trace("Parameter #{} evaluated as: {} type: {}", index, answer, org.apache.camel.util.ObjectHelper.type(answer)); + } + } catch (Exception e) { + if (LOG.isDebugEnabled()) { + LOG.debug("Cannot convert from type: {} to type: {} for parameter #{}", org.apache.camel.util.ObjectHelper.type(parameterValue), parameterType, index); + } + throw new ParameterBindingException(e, method, index, parameterType, parameterValue); + } + } + } + } + + return answer; + } + + /** + * Evaluate using classic parameter binding using the pre compute expression + */ + private Object evaluateParameterBinding(Exchange exchange, Expression expression, int index, Class parameterType) { + Object answer = null; + + // use object first to avoid type conversion so we know if there is a value or not + Object result = expression.evaluate(exchange, Object.class); + if (result != null) { + try { + if (parameterType.isInstance(result)) { + // optimize if the value is already the same type + answer = result; + } else { + // we got a value now try to convert it to the expected type + answer = exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType, result); + } + if (LOG.isTraceEnabled()) { + LOG.trace("Parameter #{} evaluated as: {} type: {}", index, answer, org.apache.camel.util.ObjectHelper.type(answer)); + } + } catch (NoTypeConversionAvailableException e) { + if (LOG.isDebugEnabled()) { + LOG.debug("Cannot convert from type: {} to type: {} for parameter #{}", org.apache.camel.util.ObjectHelper.type(result), parameterType, index); + } + throw new ParameterBindingException(e, method, index, parameterType, result); + } + } else { + LOG.trace("Parameter #{} evaluated as null", index); + } + + return answer; + } + + @Override + public String toString() { + return "ParametersExpression: " + Arrays.asList(expressions); + } + + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodInfoCache.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodInfoCache.java new file mode 100644 index 00000000..13ed2a33 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodInfoCache.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.CamelContext; +import org.apache.camel.support.LRUCacheFactory; + +import java.lang.reflect.Method; +import java.util.Map; + +/** + * Represents a cache of {@link org.apache.camel.component.bean.MethodInfo} objects to avoid the expense of introspection for each + * invocation of a method via a proxy. + */ +public class MethodInfoCache { + private final CamelContext camelContext; + private Map methodCache; + private Map, BeanInfo> classCache; + + public MethodInfoCache(CamelContext camelContext) { + this(camelContext, 1000, 10000); + } + + public MethodInfoCache(CamelContext camelContext, int classCacheSize, int methodCacheSize) { + this(camelContext, createClassCache(classCacheSize), createMethodCache(methodCacheSize)); + } + + public MethodInfoCache(CamelContext camelContext, Map, BeanInfo> classCache, Map methodCache) { + this.camelContext = camelContext; + this.classCache = classCache; + this.methodCache = methodCache; + } + + public synchronized MethodInfo getMethodInfo(Method method) { + MethodInfo answer = methodCache.get(method); + if (answer == null) { + answer = createMethodInfo(method); + methodCache.put(method, answer); + } + return answer; + } + + protected MethodInfo createMethodInfo(Method method) { + Class declaringClass = method.getDeclaringClass(); + BeanInfo info = getBeanInfo(declaringClass); + return info.getMethodInfo(method); + } + + protected synchronized BeanInfo getBeanInfo(Class declaringClass) { + BeanInfo beanInfo = classCache.get(declaringClass); + if (beanInfo == null) { + beanInfo = createBeanInfo(declaringClass); + classCache.put(declaringClass, beanInfo); + } + return beanInfo; + } + + protected BeanInfo createBeanInfo(Class declaringClass) { + return new BeanInfo(camelContext, declaringClass); + } + + @SuppressWarnings("unchecked") + protected static Map createLruCache(int size) { + // use a soft cache + return LRUCacheFactory.newLRUSoftCache(size); + } + + private static Map, BeanInfo> createClassCache(int size) { + return createLruCache(size); + } + + private static Map createMethodCache(int size) { + return createLruCache(size); + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodInvocation.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodInvocation.java new file mode 100644 index 00000000..08844ea4 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodInvocation.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.AsyncCallback; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Method; + +/** + * Information used by Camel to perform method invocation. + */ +public interface MethodInvocation { + + Method getMethod(); + + Object[] getArguments(); + + /** + * Proceed and invokes the method. + * + * @param callback the callback + * @return see {@link org.apache.camel.AsyncProcessor#process(org.apache.camel.Exchange, org.apache.camel.AsyncCallback)} + */ + boolean proceed(AsyncCallback callback); + + Object getThis(); + + AccessibleObject getStaticPart(); +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodNotFoundException.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodNotFoundException.java new file mode 100644 index 00000000..c918833a --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodNotFoundException.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Exchange; +import org.apache.camel.RuntimeExchangeException; +import org.apache.camel.util.ObjectHelper; + +public class MethodNotFoundException extends RuntimeExchangeException { + + private final Object bean; + private final String methodName; + + public MethodNotFoundException(Exchange exchange, Object pojo, String methodName) { + super("Method with name: " + methodName + " not found on bean: " + pojo + " of type: " + ObjectHelper.className(pojo), exchange); + this.methodName = methodName; + this.bean = pojo; + } + + public MethodNotFoundException(Exchange exchange, Object pojo, String methodName, String postfix) { + super("Method with name: " + methodName + " " + postfix + " not found on bean: " + pojo + " of type: " + ObjectHelper.className(pojo), exchange); + this.methodName = methodName; + this.bean = pojo; + } + + public MethodNotFoundException(Exchange exchange, Class type, String methodName, boolean isStaticMethod) { + super((isStaticMethod ? "Static method" : "Method") + " with name: " + methodName + " not found on class: " + ObjectHelper.name(type), exchange); + this.methodName = methodName; + this.bean = null; + } + + public MethodNotFoundException(Object pojo, String methodName, Throwable cause) { + super("Method with name: " + methodName + " not found on bean: " + pojo + " of type:" + ObjectHelper.className(pojo), null, cause); + this.methodName = methodName; + this.bean = pojo; + } + + public MethodNotFoundException(Class type, String methodName, Throwable cause) { + super("Method with name: " + methodName + " not found on class: " + ObjectHelper.className(type), null, cause); + this.methodName = methodName; + this.bean = null; + } + + public String getMethodName() { + return methodName; + } + + public Object getBean() { + return bean; + } +} \ No newline at end of file diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodsFilter.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodsFilter.java new file mode 100644 index 00000000..4a0d304e --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/MethodsFilter.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.util.ObjectHelper; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * This class aims at retaining the right methods while parsing a given + * {@link java.lang.Class}. + */ +class MethodsFilter { + + private final List methods = new ArrayList<>(); + private final Class inheritingClass; + + /** + * Creates a MethodsFilter for a given {@link java.lang.Class}. + * + * @param clazz The {@link java.lang.Class} whose methods are to be + * filtered. + */ + public MethodsFilter(Class clazz) { + this.inheritingClass = clazz; + } + + /** + * Retains methods, preferring those from public classes in case of + * overrides. + * + * @param proposedMethod The method proposed to the filter. + */ + void filterMethod(Method proposedMethod) { + if (proposedMethod.isBridge()) { + return; + } + + for (int i = 0; i < methods.size(); i++) { + Method alreadyRegistered = methods.get(i); + + if (Modifier.isPublic(proposedMethod.getDeclaringClass().getModifiers())) { + boolean overridden = ObjectHelper.isOverridingMethod(inheritingClass, proposedMethod, alreadyRegistered, false); + boolean overridding = ObjectHelper.isOverridingMethod(inheritingClass, alreadyRegistered, proposedMethod, false); + + boolean registeredMethodIsPublic = Modifier.isPublic(alreadyRegistered.getDeclaringClass().getModifiers()); + + if (overridden && !registeredMethodIsPublic) { + // Retain the overridden method from a public class + methods.set(i, proposedMethod); + return; + } else if (overridding) { + // Retain the override from a public class + methods.set(i, proposedMethod); + return; + } + } + } + + methods.add(proposedMethod); + } + + List asReadOnlyList() { + return Collections.unmodifiableList(methods); + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ParameterBindingException.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ParameterBindingException.java new file mode 100644 index 00000000..240114b2 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ParameterBindingException.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.util.ObjectHelper; + +import java.lang.reflect.Method; + +public class ParameterBindingException extends RuntimeCamelException { + + private final Method method; + private final int index; + private final Class parameterType; + private final Object parameterValue; + + public ParameterBindingException(Throwable cause, Method method, int index, Class parameterType, Object parameterValue) { + super(createMessage(method, index, parameterType, parameterValue), cause); + this.method = method; + this.index = index; + this.parameterType = parameterType; + this.parameterValue = parameterValue; + } + + public Method getMethod() { + return method; + } + + public int getIndex() { + return index; + } + + public Class getParameterType() { + return parameterType; + } + + public Object getParameterValue() { + return parameterValue; + } + + private static String createMessage(Method method, int index, Class parameterType, Object parameterValue) { + return "Error during parameter binding on method: " + method + " at parameter #" + index + " with type: " + parameterType + + " with value type: " + ObjectHelper.type(parameterValue) + " and value: " + parameterValue; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ParameterInfo.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ParameterInfo.java new file mode 100644 index 00000000..b4d5cf3c --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ParameterInfo.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Expression; + +import java.lang.annotation.Annotation; +import java.util.Arrays; + +/** + * Parameter information to be used for method invocation. + */ +final class ParameterInfo { + + private final int index; + private final Class type; + private final Annotation[] annotations; + private Expression expression; + + ParameterInfo(int index, Class type, Annotation[] annotations, Expression expression) { + this.index = index; + this.type = type; + this.annotations = annotations; + this.expression = expression; + } + + public Annotation[] getAnnotations() { + return annotations; + } + + public Expression getExpression() { + return expression; + } + + public int getIndex() { + return index; + } + + public Class getType() { + return type; + } + + public void setExpression(Expression expression) { + this.expression = expression; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("ParameterInfo"); + sb.append("[index=").append(index); + sb.append(", type=").append(type); + sb.append(", annotations=").append(annotations == null ? "null" : Arrays.asList(annotations).toString()); + sb.append(", expression=").append(expression); + sb.append(']'); + return sb.toString(); + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ParameterMappingStrategy.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ParameterMappingStrategy.java new file mode 100644 index 00000000..4dbb9a1d --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ParameterMappingStrategy.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Expression; + +/** + * A strategy for creating a default parameter expression for a given type + */ +public interface ParameterMappingStrategy { + + /** + * Gets an expression used for evaluation with the current Exchange and its result + * is used as parameter value for the given type + * + * @param parameterType the parameter type + * @return the expression to evaluate as value + */ + Expression getDefaultParameterTypeExpression(Class parameterType); +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/PojoMessageInvocationHandler.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/PojoMessageInvocationHandler.java new file mode 100644 index 00000000..36551b99 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/PojoMessageInvocationHandler.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Endpoint; +import org.apache.camel.ExchangePattern; +import org.apache.camel.Producer; +import org.apache.camel.RuntimeCamelException; + +import java.lang.reflect.Method; + +/** + * Special {@link java.lang.reflect.InvocationHandler} for methods that have only one parameter. This + * parameter is directly sent to as the body of the message. The idea is to use + * that as a very open message format especially when combined with e.g. JAXB + * serialization. + */ +@Deprecated +public class PojoMessageInvocationHandler extends AbstractCamelInvocationHandler { + + public PojoMessageInvocationHandler(Endpoint endpoint, Producer producer) { + super(endpoint, producer); + } + + @Override + public Object doInvokeProxy(Object proxy, Method method, Object[] args) throws Throwable { + int argsLength = (args == null) ? 0 : args.length; + if (argsLength != 1) { + throw new RuntimeCamelException(String.format("Error creating proxy for %s.%s Number of arguments must be 1 but is %d", + method.getDeclaringClass().getName(), + method.getName(), argsLength)); + } + final ExchangePattern pattern = method.getReturnType() != Void.TYPE ? ExchangePattern.InOut : ExchangePattern.InOnly; + return invokeWithBody(method, args[0], pattern); + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/PojoProxyHelper.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/PojoProxyHelper.java new file mode 100644 index 00000000..0e63cd29 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/PojoProxyHelper.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Endpoint; +import org.apache.camel.Producer; +import org.apache.camel.support.service.ServiceHelper; + +import java.lang.reflect.Proxy; + +/** + * Create a dynamic proxy for a given interface and endpoint that sends the parameter object to the endpoint and optionally + * receives a reply. Unlike the ProxyHelper this works only with methods that have only one parameter. + */ +@Deprecated +public final class PojoProxyHelper { + + private PojoProxyHelper() { + } + + @SuppressWarnings("unchecked") + public static T createProxy(Endpoint endpoint, Class... interfaceClasses) throws Exception { + Producer producer = endpoint.createProducer(); + // ensure the producer is started + ServiceHelper.startService(producer); + return (T) Proxy.newProxyInstance(ProxyHelper.getClassLoader(interfaceClasses), interfaceClasses.clone(), new PojoMessageInvocationHandler(endpoint, producer)); + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ProxyHelper.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ProxyHelper.java new file mode 100644 index 00000000..99fe7d88 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/ProxyHelper.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Endpoint; +import org.apache.camel.ExtendedCamelContext; +import org.apache.camel.Producer; + +import java.lang.reflect.Proxy; + +/** + * A helper class for creating proxies which delegate to Camel + */ +public final class ProxyHelper { + + /** + * Utility classes should not have a public constructor. + */ + private ProxyHelper() { + } + + /** + * Creates a Proxy which sends the exchange to the endpoint. + */ + @SuppressWarnings("unchecked") + public static T createProxyObject(Endpoint endpoint, boolean binding, Producer producer, ClassLoader classLoader, Class[] interfaces, MethodInfoCache methodCache) { + return (T) Proxy.newProxyInstance(classLoader, interfaces.clone(), new CamelInvocationHandler(endpoint, binding, producer, methodCache)); + } + + /** + * Creates a Proxy which sends the exchange to the endpoint. + */ + public static T createProxy(Endpoint endpoint, boolean binding, ClassLoader cl, Class interfaceClass, MethodInfoCache methodCache) throws Exception { + return createProxy(endpoint, binding, cl, toArray(interfaceClass), methodCache); + } + + /** + * Creates a Proxy which sends the exchange to the endpoint. + */ + public static T createProxy(Endpoint endpoint, boolean binding, ClassLoader cl, Class[] interfaceClasses, MethodInfoCache methodCache) throws Exception { + Producer producer = endpoint.getCamelContext().adapt(ExtendedCamelContext.class).getDeferServiceFactory().createProducer(endpoint); + return createProxyObject(endpoint, binding, producer, cl, interfaceClasses, methodCache); + } + + /** + * Creates a Proxy which sends the exchange to the endpoint. + */ + public static T createProxy(Endpoint endpoint, ClassLoader cl, Class interfaceClass) throws Exception { + return createProxy(endpoint, true, cl, toArray(interfaceClass)); + } + + /** + * Creates a Proxy which sends the exchange to the endpoint. + */ + public static T createProxy(Endpoint endpoint, boolean binding, ClassLoader cl, Class... interfaceClasses) throws Exception { + return createProxy(endpoint, binding, cl, interfaceClasses, createMethodInfoCache(endpoint)); + } + + /** + * Creates a Proxy which sends the exchange to the endpoint. + */ + public static T createProxy(Endpoint endpoint, Class interfaceClass) throws Exception { + return createProxy(endpoint, true, toArray(interfaceClass)); + } + + /** + * Creates a Proxy which sends the exchange to the endpoint. + */ + public static T createProxy(Endpoint endpoint, boolean binding, Class... interfaceClasses) throws Exception { + return createProxy(endpoint, binding, getClassLoader(interfaceClasses), interfaceClasses); + } + + /** + * Creates a Proxy which sends the exchange to the endpoint. + */ + public static T createProxy(Endpoint endpoint, Producer producer, Class interfaceClass) throws Exception { + return createProxy(endpoint, true, producer, toArray(interfaceClass)); + } + + /** + * Creates a Proxy which sends the exchange to the endpoint. + */ + public static T createProxy(Endpoint endpoint, boolean binding, Producer producer, Class... interfaceClasses) throws Exception { + return createProxyObject(endpoint, binding, producer, getClassLoader(interfaceClasses), interfaceClasses, createMethodInfoCache(endpoint)); + } + + /** + * Returns the class loader of the first interface or throws {@link IllegalArgumentException} if there are no interfaces specified + */ + protected static ClassLoader getClassLoader(Class... interfaces) { + if (interfaces == null || interfaces.length < 1) { + throw new IllegalArgumentException("You must provide at least 1 interface class."); + } + return interfaces[0].getClassLoader(); + } + + protected static MethodInfoCache createMethodInfoCache(Endpoint endpoint) { + return new MethodInfoCache(endpoint.getCamelContext()); + } + + @SuppressWarnings("unchecked") + private static Class[] toArray(Class interfaceClass) { + // this method and it's usage is introduced to avoid compiler warnings + // about the generic Class arrays in the case we've got only one single + // Class to build a Proxy for + return new Class[]{interfaceClass}; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/RegistryBean.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/RegistryBean.java new file mode 100644 index 00000000..de69e4ba --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/RegistryBean.java @@ -0,0 +1,186 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.NoSuchBeanException; +import org.apache.camel.Processor; +import org.apache.camel.spi.Registry; +import org.apache.camel.support.PropertyBindingSupport; + +import java.util.Map; + +/** + * An implementation of a {@link org.apache.camel.component.bean.BeanHolder} which will look up a bean from the registry and act as a cache of its metadata + */ +public class RegistryBean implements BeanHolder { + private final CamelContext context; + private final String name; + private final Registry registry; + private volatile BeanInfo beanInfo; + private volatile Class clazz; + private ParameterMappingStrategy parameterMappingStrategy; + private Map options; + + public RegistryBean(CamelContext context, String name) { + this(context.getRegistry(), context, name); + } + + public RegistryBean(Registry registry, CamelContext context, String name) { + this.registry = registry; + this.context = context; + if (name != null) { + // for ref it may have "ref:" or "bean:" as prefix by mistake + if (name.startsWith("ref:")) { + this.name = name.substring(4); + } else if (name.startsWith("bean:")) { + this.name = name.substring(5); + } else { + this.name = name; + } + } else { + this.name = null; + } + } + + @Override + public String toString() { + return "bean: " + name; + } + + @Override + public Map getOptions() { + return options; + } + + @Override + public void setOptions(Map options) { + this.options = options; + } + + /** + * Creates a singleton (cached and constant) {@link org.apache.camel.component.bean.BeanHolder} from this holder. + */ + public ConstantBeanHolder createCacheHolder() { + Object bean = getBean(null); + BeanInfo info = createBeanInfo(bean); + return new ConstantBeanHolder(bean, info); + } + + @Override + public Object getBean(Exchange exchange) throws NoSuchBeanException { + Object bean = doGetBean(exchange); + if (options != null && !options.isEmpty()) { + PropertyBindingSupport.build() + .withRemoveParameters(false) + .withCamelContext(getBeanInfo().getCamelContext()) + .withProperties(options) + .withTarget(bean) + .bind(); + } + return bean; + } + + private Object doGetBean(Exchange exchange) throws NoSuchBeanException { + // must always lookup bean first + Object value = lookupBean(); + + if (value != null) { + // could be a class then create an instance of it + if (value instanceof Class) { + // bean is a class so create an instance of it + value = context.getInjector().newInstance((Class) value); + } + return value; + } + + // okay bean is not in registry, so try to resolve if its a class name and create a shared instance + if (clazz == null) { + clazz = context.getClassResolver().resolveClass(name); + } + + if (clazz == null) { + // no its not a class then we cannot find the bean + throw new NoSuchBeanException(name); + } + + // bean is a class so create an instance of it + return context.getInjector().newInstance(clazz); + } + + @Override + public Processor getProcessor() { + return null; + } + + @Override + public boolean supportProcessor() { + return false; + } + + @Override + public BeanInfo getBeanInfo() { + if (beanInfo == null) { + Object bean = getBean(null); + this.beanInfo = createBeanInfo(bean); + } + return beanInfo; + } + + @Override + public BeanInfo getBeanInfo(Object bean) { + return createBeanInfo(bean); + } + + public String getName() { + return name; + } + + public Registry getRegistry() { + return registry; + } + + public CamelContext getContext() { + return context; + } + + public ParameterMappingStrategy getParameterMappingStrategy() { + if (parameterMappingStrategy == null) { + parameterMappingStrategy = createParameterMappingStrategy(); + } + return parameterMappingStrategy; + } + + public void setParameterMappingStrategy(ParameterMappingStrategy parameterMappingStrategy) { + this.parameterMappingStrategy = parameterMappingStrategy; + } + + // Implementation methods + //------------------------------------------------------------------------- + protected BeanInfo createBeanInfo(Object bean) { + return new BeanInfo(context, bean.getClass(), getParameterMappingStrategy()); + } + + protected ParameterMappingStrategy createParameterMappingStrategy() { + return BeanInfo.createParameterMappingStrategy(context); + } + + protected Object lookupBean() { + return registry.lookupByName(name); + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/RequestBeanHolder.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/RequestBeanHolder.java new file mode 100644 index 00000000..0fec4bf0 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/bean/fix/RequestBeanHolder.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.bean.fix; + +import org.apache.camel.Exchange; +import org.apache.camel.NoSuchBeanException; +import org.apache.camel.Processor; + +import java.util.Map; + +/** + * Request scoped {@link org.apache.camel.component.bean.BeanHolder} wrapper. + */ +public class RequestBeanHolder implements BeanHolder { + + private final BeanHolder holder; + private final String key; + + public RequestBeanHolder(BeanHolder holder) { + this.holder = holder; + this.key = "CamelBeanRequestScope-" + holder.getBeanInfo().getType().getName(); + } + + @Override + public Map getOptions() { + return holder.getOptions(); + } + + @Override + public void setOptions(Map options) { + this.holder.setOptions(options); + } + + @Override + public Object getBean(Exchange exchange) throws NoSuchBeanException { + Object bean = exchange.getProperty(key); + if (bean == null) { + bean = holder.getBean(exchange); + exchange.setProperty(key, bean); + } + return bean; + } + + @Override + public Processor getProcessor() { + return null; + } + + @Override + public boolean supportProcessor() { + return false; + } + + @Override + public BeanInfo getBeanInfo() { + return holder.getBeanInfo(); + } + + @Override + public BeanInfo getBeanInfo(Object bean) { + return holder.getBeanInfo(bean); + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/beanclass/fix/ClassComponent.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/beanclass/fix/ClassComponent.java new file mode 100644 index 00000000..23bcbd54 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/beanclass/fix/ClassComponent.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.beanclass.fix; + +import org.apache.camel.Endpoint; +import org.apache.camel.component.bean.fix.BeanComponent; +import org.apache.camel.component.bean.fix.BeanHolder; +import org.apache.camel.component.bean.fix.ConstantBeanHolder; +import org.apache.camel.component.bean.fix.ConstantTypeBeanHolder; +import org.apache.camel.util.PropertiesHelper; + +import java.util.Map; + +/** + * The Class Component is for binding JavaBeans to Camel message exchanges based on class name. + *

+ * This component is an extension to the {@link org.apache.camel.component.bean.BeanComponent}. + */ +@org.apache.camel.spi.annotations.Component("class") +public class ClassComponent extends BeanComponent { + + public ClassComponent() { + } + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception { + ClassEndpoint endpoint = new ClassEndpoint(uri, this); + endpoint.setBeanName(remaining); + + // bean name is the FQN + String name = endpoint.getBeanName(); + Class clazz = getCamelContext().getClassResolver().resolveMandatoryClass(name); + + // the bean.xxx options is for the bean + Map options = PropertiesHelper.extractProperties(parameters, "bean."); + endpoint.setParameters(options); + + BeanHolder holder; + + // if there is options then we need to create a bean instance + if (!options.isEmpty()) { + // create bean + Object bean = getCamelContext().getInjector().newInstance(clazz); + + // now set additional properties on it + setProperties(bean, options); + + holder = new ConstantBeanHolder(bean, getCamelContext()); + } else { + // otherwise refer to the type + holder = new ConstantTypeBeanHolder(clazz, getCamelContext()); + } + + validateParameters(uri, options, null); + + // and register the bean as a holder on the endpoint + endpoint.setBeanHolder(holder); + + return endpoint; + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/component/beanclass/fix/ClassEndpoint.java b/system/component-bean-fix/src/main/java/org/apache/camel/component/beanclass/fix/ClassEndpoint.java new file mode 100644 index 00000000..60e7b705 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/component/beanclass/fix/ClassEndpoint.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.component.beanclass.fix; + +import org.apache.camel.Category; +import org.apache.camel.Component; +import org.apache.camel.component.bean.fix.BeanEndpoint; +import org.apache.camel.spi.UriEndpoint; + +/** + * Invoke methods of Java beans specified by class name. + */ +@UriEndpoint(firstVersion = "2.4.0", scheme = "class", title = "Class", syntax = "class:beanName", producerOnly = true, category = {Category.CORE, Category.JAVA}) +public class ClassEndpoint extends BeanEndpoint { + + public ClassEndpoint(String endpointUri, Component component) { + super(endpointUri, component); + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/Bean.java b/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/Bean.java new file mode 100644 index 00000000..63c72e6a --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/Bean.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.language.bean; + +import org.apache.camel.component.bean.fix.BeanAnnotationExpressionFactory; +import org.apache.camel.support.language.LanguageAnnotation; + +import java.lang.annotation.*; + +/** + * Used to inject a bean expression into a field, property, method or parameter when using + * Bean Integration. + */ +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@LanguageAnnotation(language = "bean", factory = BeanAnnotationExpressionFactory.class) +public @interface Bean { + String ref(); + + String method() default ""; +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/BeanExpression.java b/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/BeanExpression.java new file mode 100644 index 00000000..eb82da30 --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/BeanExpression.java @@ -0,0 +1,499 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.language.bean; + +import org.apache.camel.*; +import org.apache.camel.component.bean.fix.*; +import org.apache.camel.spi.Language; +import org.apache.camel.support.CamelContextHelper; +import org.apache.camel.support.ExchangeHelper; +import org.apache.camel.support.LanguageSupport; +import org.apache.camel.util.KeyValueHolder; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.OgnlHelper; +import org.apache.camel.util.StringHelper; + +import java.util.List; +import java.util.Map; + +import static org.apache.camel.util.ObjectHelper.hasDefaultPublicNoArgConstructor; + +/** + * Evaluates an expression using a bean method invocation + */ +public class BeanExpression implements Expression, Predicate, AfterPropertiesConfigured { + private Object bean; + private String beanName; + private Class type; + private String method; + private volatile BeanHolder beanHolder; + + public BeanExpression(Object bean, String method) { + this.bean = bean; + this.method = method; + this.beanName = null; + this.type = null; + } + + public BeanExpression(String beanName, String method) { + this.beanName = beanName; + this.method = method; + this.bean = null; + this.type = null; + } + + public BeanExpression(Class type, String method) { + this.type = type; + this.method = method; + this.bean = null; + this.beanName = null; + } + + public Object getBean() { + return bean; + } + + public void setBean(Object bean) { + this.bean = bean; + } + + public String getBeanName() { + return beanName; + } + + public void setBeanName(String beanName) { + this.beanName = beanName; + } + + public Class getType() { + return type; + } + + public void setType(Class type) { + this.type = type; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + @Override + public void init(CamelContext context) { + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("BeanExpression["); + if (bean != null) { + sb.append(bean.toString()); + } else if (beanName != null) { + sb.append(beanName); + } else if (type != null) { + sb.append(ObjectHelper.className(type)); + } + if (method != null) { + sb.append(" method:").append(method); + } + sb.append("]"); + return sb.toString(); + } + + public Object evaluate(Exchange exchange) { + if (bean == null && type == null && beanName != null && beanName.startsWith("type:")) { + // its a reference to a fqn class so load the class and use type instead + String fqn = beanName.substring(5); + try { + type = exchange.getContext().getClassResolver().resolveMandatoryClass(fqn); + beanName = null; + } catch (ClassNotFoundException e) { + throw new NoSuchBeanException(beanName, e); + } + } + + // if the bean holder doesn't exist then create it using the context from the exchange + if (beanHolder == null) { + beanHolder = createBeanHolder(exchange.getContext()); + } + + // invoking the bean can either be the easy way or using OGNL + if (bean != null || type != null) { + validateHasMethod(exchange.getContext(), bean, type, method); + } + + // validate OGNL + if (OgnlHelper.isInvalidValidOgnlExpression(method)) { + ExpressionIllegalSyntaxException cause = new ExpressionIllegalSyntaxException(method); + throw new RuntimeBeanExpressionException(exchange, beanName, method, cause); + } + + if (OgnlHelper.isValidOgnlExpression(method)) { + // okay the method is an ognl expression + try { + return invokeOgnlMethod(beanHolder, beanName, method, exchange); + } catch (Exception e) { + if (e instanceof RuntimeBeanExpressionException) { + throw (RuntimeBeanExpressionException) e; + } + throw new RuntimeBeanExpressionException(exchange, getBeanName(exchange, beanName, beanHolder), method, e); + } + } else { + // regular non ognl invocation + try { + return invokeBean(beanHolder, beanName, method, exchange); + } catch (Exception e) { + if (e instanceof RuntimeBeanExpressionException) { + throw (RuntimeBeanExpressionException) e; + } + throw new RuntimeBeanExpressionException(exchange, getBeanName(exchange, beanName, beanHolder), method, e); + } + } + } + + @Override + public T evaluate(Exchange exchange, Class type) { + Object result = evaluate(exchange); + if (Object.class == type) { + // do not use type converter if type is Object (optimize) + return (T) result; + } else { + return exchange.getContext().getTypeConverter().convertTo(type, exchange, result); + } + } + + @Override + public boolean matches(Exchange exchange) { + Object value = evaluate(exchange); + return ObjectHelper.evaluateValuePredicate(value); + } + + @Override + public void afterPropertiesConfigured(CamelContext camelContext) { + // lets see if we can do additional validation that the bean has valid method during creation of the expression + Object target = bean; + if (bean == null && type == null && beanName != null) { + if (beanName.startsWith("type:")) { + // its a reference to a fqn class so load the class and use type instead + String fqn = beanName.substring(5); + try { + type = camelContext.getClassResolver().resolveMandatoryClass(fqn); + beanName = null; + } catch (ClassNotFoundException e) { + throw new NoSuchBeanException(beanName, e); + } + } else { + target = CamelContextHelper.mandatoryLookup(camelContext, beanName); + } + } + validateHasMethod(camelContext, target, type, method); + + // if the bean holder doesn't exist then create it + if (beanHolder == null) { + beanHolder = createBeanHolder(camelContext); + } + } + + /** + * Validates the given bean has the method. + *

+ * This implementation will skip trying to validate OGNL method name expressions. + * + * @param context camel context + * @param bean the bean instance + * @param type the bean type + * @param method the method, can be null if no method name provided + * @throws org.apache.camel.RuntimeCamelException is thrown if bean does not have the method + */ + protected void validateHasMethod(CamelContext context, Object bean, Class type, String method) { + if (method == null) { + return; + } + + if (bean == null && type == null) { + throw new IllegalArgumentException("Either bean or type should be provided on " + this); + } + + if (bean == null && hasDefaultPublicNoArgConstructor(type)) { + bean = context.getInjector().newInstance(type); + } + + // do not try to validate ognl methods + if (OgnlHelper.isValidOgnlExpression(method)) { + return; + } + + // if invalid OGNL then fail + if (OgnlHelper.isInvalidValidOgnlExpression(method)) { + ExpressionIllegalSyntaxException cause = new ExpressionIllegalSyntaxException(method); + throw RuntimeCamelException.wrapRuntimeCamelException(new MethodNotFoundException(bean != null ? bean : type, method, cause)); + } + + if (bean != null) { + BeanInfo info = new BeanInfo(context, bean.getClass()); + if (!info.hasMethod(method)) { + throw RuntimeCamelException.wrapRuntimeCamelException(new MethodNotFoundException(null, bean, method)); + } + } else { + BeanInfo info = new BeanInfo(context, type); + // must be a static method as we do not have a bean instance to invoke + if (!info.hasStaticMethod(method)) { + throw RuntimeCamelException.wrapRuntimeCamelException(new MethodNotFoundException(null, type, method, true)); + } + } + } + + private BeanHolder createBeanHolder(CamelContext context) { + // either use registry lookup or a constant bean + BeanHolder holder; + if (bean != null) { + holder = new ConstantBeanHolder(bean, context); + } else if (beanName != null) { + holder = new RegistryBean(context, beanName); + } else if (type != null) { + holder = new ConstantTypeBeanHolder(type, context); + } else { + throw new IllegalArgumentException("Either bean, beanName or type should be set on " + this); + } + return holder; + } + + private static String getBeanName(Exchange exchange, String beanName, BeanHolder beanHolder) { + String name = beanName; + if (name == null && beanHolder != null && beanHolder.getBean(exchange) != null) { + name = beanHolder.getBean(exchange).getClass().getCanonicalName(); + } + if (name == null && beanHolder != null && beanHolder.getBeanInfo() != null && beanHolder.getBeanInfo().getType() != null) { + name = beanHolder.getBeanInfo().getType().getCanonicalName(); + } + return name; + } + + /** + * Invokes the bean and returns the result. If an exception was thrown while invoking the bean, then the + * exception is set on the exchange. + */ + private static Object invokeBean(BeanHolder beanHolder, String beanName, String methodName, Exchange exchange) { + Object result; + + BeanExpressionProcessor processor = new BeanExpressionProcessor(beanHolder); + if (methodName != null) { + processor.setMethod(methodName); + // enable OGNL like invocation + processor.setShorthandMethod(true); + } + try { + // copy the original exchange to avoid side effects on it + Exchange resultExchange = ExchangeHelper.createCopy(exchange, true); + // remove any existing exception in case we do OGNL on the exception + resultExchange.setException(null); + + // force to use InOut to retrieve the result on the OUT message + resultExchange.setPattern(ExchangePattern.InOut); + processor.process(resultExchange); + // the response is always stored in OUT + result = resultExchange.hasOut() ? resultExchange.getOut().getBody() : null; + + // propagate properties and headers from result + if (resultExchange.hasProperties()) { + exchange.getProperties().putAll(resultExchange.getProperties()); + } + if (resultExchange.getOut().hasHeaders()) { + exchange.getIn().getHeaders().putAll(resultExchange.getOut().getHeaders()); + } + + // propagate exceptions + if (resultExchange.getException() != null) { + exchange.setException(resultExchange.getException()); + } + } catch (Throwable e) { + throw new RuntimeBeanExpressionException(exchange, beanName, methodName, e); + } + + return result; + } + + /** + * To invoke a bean using a OGNL notation which denotes the chain of methods to invoke. + *

+ * For more advanced OGNL you may have to look for a real framework such as OGNL, Mvel or dynamic + * programming language such as Groovy. + */ + private static Object invokeOgnlMethod(BeanHolder beanHolder, String beanName, String ognl, Exchange exchange) { + + // we must start with having bean as the result + Object result = beanHolder.getBean(exchange); + + // copy the original exchange to avoid side effects on it + Exchange resultExchange = ExchangeHelper.createCopy(exchange, true); + // remove any existing exception in case we do OGNL on the exception + resultExchange.setException(null); + // force to use InOut to retrieve the result on the OUT message + resultExchange.setPattern(ExchangePattern.InOut); + // do not propagate any method name when using OGNL, as with OGNL we + // compute and provide the method name to explicit to invoke + resultExchange.getIn().removeHeader(Exchange.BEAN_METHOD_NAME); + + // current ognl path as we go along + String ognlPath = ""; + + // loop and invoke each method + Object beanToCall = beanHolder.getBean(exchange); + Class beanType = beanHolder.getBeanInfo().getType(); + + // there must be a bean to call with, we currently does not support OGNL expressions on using purely static methods + if (beanToCall == null && beanType == null) { + throw new IllegalArgumentException("Bean instance and bean type is null. OGNL bean expressions requires to have either a bean instance of the class name of the bean to use."); + } + + if (ognl != null) { + // must be a valid method name according to java identifier ruling + OgnlHelper.validateMethodName(ognl); + } + + // Split ognl except when this is not a Map, Array + // and we would like to keep the dots within the key name + List methods = OgnlHelper.splitOgnl(ognl); + + for (String methodName : methods) { + BeanHolder holder; + if (beanToCall != null) { + holder = new ConstantBeanHolder(beanToCall, exchange.getContext()); + } else if (beanType != null) { + holder = new ConstantTypeBeanHolder(beanType, exchange.getContext()); + } else { + holder = null; + } + + // support the null safe operator + boolean nullSafe = OgnlHelper.isNullSafeOperator(methodName); + + if (holder == null) { + String name = getBeanName(exchange, null, beanHolder); + throw new RuntimeBeanExpressionException(exchange, name, ognl, "last method returned null and therefore cannot continue to invoke method " + methodName + " on a null instance"); + } + + // keep up with how far are we doing + ognlPath += methodName; + + // get rid of leading ?. or . as we only needed that to determine if null safe was enabled or not + methodName = OgnlHelper.removeLeadingOperators(methodName); + + // are we doing an index lookup (eg in Map/List/array etc)? + String key = null; + KeyValueHolder index = OgnlHelper.isOgnlIndex(methodName); + if (index != null) { + methodName = index.getKey(); + key = index.getValue(); + } + + // only invoke if we have a method name to use to invoke + if (methodName != null) { + Object newResult = invokeBean(holder, beanName, methodName, resultExchange); + + // check for exception and rethrow if we failed + if (resultExchange.getException() != null) { + throw new RuntimeBeanExpressionException(exchange, beanName, methodName, resultExchange.getException()); + } + + result = newResult; + } + + // if there was a key then we need to lookup using the key + if (key != null) { + // if key is a nested simple expression then re-evaluate that again + if (LanguageSupport.hasSimpleFunction(key)) { + Language lan = exchange.getContext().resolveLanguage("simple"); + key = lan.createExpression(key).evaluate(exchange, String.class); + } + if (key != null) { + result = lookupResult(resultExchange, key, result, nullSafe, ognlPath, holder.getBean(exchange)); + } + } + + // check null safe for null results + if (result == null && nullSafe) { + return null; + } + + // prepare for next bean to invoke + beanToCall = result; + beanType = null; + } + + return result; + } + + private static Object lookupResult(Exchange exchange, String key, Object result, boolean nullSafe, String ognlPath, Object bean) { + StringHelper.notEmpty(key, "key", "in Simple language ognl path: " + ognlPath); + + // trim key + key = key.trim(); + + // remove any enclosing quotes + key = StringHelper.removeLeadingAndEndingQuotes(key); + + // try map first + Map map = exchange.getContext().getTypeConverter().convertTo(Map.class, result); + if (map != null) { + return map.get(key); + } + + // special for list is last keyword + Integer num = exchange.getContext().getTypeConverter().tryConvertTo(Integer.class, key); + boolean checkList = key.startsWith("last") || num != null; + + if (checkList) { + List list = exchange.getContext().getTypeConverter().convertTo(List.class, result); + if (list != null) { + if (key.startsWith("last")) { + num = list.size() - 1; + + // maybe its an expression to subtract a number after last + String after = StringHelper.after(key, "-"); + if (after != null) { + Integer redux = exchange.getContext().getTypeConverter().tryConvertTo(Integer.class, after.trim()); + if (redux != null) { + num -= redux; + } else { + throw new ExpressionIllegalSyntaxException(key); + } + } + } + if (num != null && num >= 0 && list.size() > num - 1 && list.size() > 0) { + return list.get(num); + } + if (!nullSafe) { + // not null safe then its mandatory so thrown out of bounds exception + throw new IndexOutOfBoundsException("Index: " + num + ", Size: " + list.size() + + " out of bounds with List from bean: " + bean + "using OGNL path [" + ognlPath + "]"); + } + } + } + + if (!nullSafe) { + throw new IndexOutOfBoundsException("Key: " + key + " not found in bean: " + bean + " of type: " + + ObjectHelper.classCanonicalName(bean) + " using OGNL path [" + ognlPath + "]"); + } else { + // null safe so we can return null + return null; + } + } + +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/BeanLanguage.java b/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/BeanLanguage.java new file mode 100644 index 00000000..a22e1c3e --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/BeanLanguage.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.language.bean; + +import org.apache.camel.CamelContext; +import org.apache.camel.Expression; +import org.apache.camel.Predicate; +import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.support.ExpressionToPredicateAdapter; +import org.apache.camel.support.LanguageSupport; +import org.apache.camel.support.component.PropertyConfigurerSupport; +import org.apache.camel.util.StringHelper; + +/** + * A bean language + * which uses a simple text notation to invoke methods on beans to evaluate predicates or expressions + *

+ * The notation is essentially beanName.methodName which is then invoked using the + * beanName to lookup in the bean integration to bind the + * {@link org.apache.camel.Exchange} to the method arguments. + *

+ * As of Camel 1.5 the bean language also supports invoking a provided bean by + * its classname or the bean itself. + */ +@org.apache.camel.spi.annotations.Language("bean") +public class BeanLanguage extends LanguageSupport implements GeneratedPropertyConfigurer { + + private Object bean; + private Class beanType; + private String ref; + private String method; + + public BeanLanguage() { + } + + @Override + public boolean configure(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) { + if (target != this) { + throw new IllegalStateException("Can only configure our own instance !"); + } + switch (ignoreCase ? name.toLowerCase() : name) { + case "bean": + setBean(PropertyConfigurerSupport.property(camelContext, Object.class, value)); + return true; + case "beantype": + case "beanType": + setBeanType(PropertyConfigurerSupport.property(camelContext, Class.class, value)); + return true; + case "ref": + setRef(PropertyConfigurerSupport.property(camelContext, String.class, value)); + return true; + case "method": + setMethod(PropertyConfigurerSupport.property(camelContext, String.class, value)); + return true; + default: + return false; + } + } + + public Object getBean() { + return bean; + } + + public void setBean(Object bean) { + this.bean = bean; + } + + public Class getBeanType() { + return beanType; + } + + public void setBeanType(Class beanType) { + this.beanType = beanType; + } + + public String getRef() { + return ref; + } + + public void setRef(String ref) { + this.ref = ref; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + @Override + public Predicate createPredicate(String expression) { + return ExpressionToPredicateAdapter.toPredicate(createExpression(expression)); + } + + @Override + public Expression createExpression(String expression) { + // favour using the configured options + if (bean != null) { + return new BeanExpression(bean, method); + } else if (beanType != null) { + return new BeanExpression(beanType, method); + } else if (ref != null) { + return new BeanExpression(ref, method); + } + + String beanName = expression; + String method = null; + + // we support both the .method name and the ?method= syntax + // as the ?method= syntax is very common for the bean component + if (expression.contains("?method=")) { + beanName = StringHelper.before(expression, "?"); + method = StringHelper.after(expression, "?method="); + } else { + //first check case :: because of my.own.Bean::method + int doubleColonIndex = expression.indexOf("::"); + //need to check that not inside params + int beginOfParameterDeclaration = expression.indexOf('('); + if (doubleColonIndex > 0 && (!expression.contains("(") || doubleColonIndex < beginOfParameterDeclaration)) { + beanName = expression.substring(0, doubleColonIndex); + method = expression.substring(doubleColonIndex + 2); + } else { + int idx = expression.indexOf('.'); + if (idx > 0) { + beanName = expression.substring(0, idx); + method = expression.substring(idx + 1); + } + } + } + + return new BeanExpression(beanName, method); + } + + @Override + public boolean isSingleton() { + return false; + } +} diff --git a/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/RuntimeBeanExpressionException.java b/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/RuntimeBeanExpressionException.java new file mode 100644 index 00000000..8e0ea74f --- /dev/null +++ b/system/component-bean-fix/src/main/java/org/apache/camel/language/bean/RuntimeBeanExpressionException.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.camel.language.bean; + +import org.apache.camel.Exchange; +import org.apache.camel.RuntimeExpressionException; + +/** + * Exception thrown if invocation of bean failed. + */ +public class RuntimeBeanExpressionException extends RuntimeExpressionException { + private static final long serialVersionUID = -7184254079414493118L; + + private final Exchange exchange; + private final String beanName; + private final String method; + + public RuntimeBeanExpressionException(Exchange exchange, String beanName, String method, Throwable e) { + super("Failed to invoke method: " + method + " on " + beanName + " due to: " + e, e); + this.exchange = exchange; + this.beanName = beanName; + this.method = method; + } + + public RuntimeBeanExpressionException(Exchange exchange, String beanName, String method, String message) { + super("Failed to invoke method: " + method + " on " + beanName + " due " + message); + this.exchange = exchange; + this.beanName = beanName; + this.method = method; + } + + public String getBeanName() { + return beanName; + } + + public Exchange getExchange() { + return exchange; + } + + public String getMethod() { + return method; + } +} diff --git a/system/component-bean-fix/src/main/resources/META-INF/services/org/apache/camel/component/bean-fix b/system/component-bean-fix/src/main/resources/META-INF/services/org/apache/camel/component/bean-fix new file mode 100644 index 00000000..076e89dc --- /dev/null +++ b/system/component-bean-fix/src/main/resources/META-INF/services/org/apache/camel/component/bean-fix @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.component.bean.fix.BeanComponent diff --git a/system/core/LICENSE.txt b/system/core/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/dispatcher/LICENSE.txt b/system/core/dispatcher/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/dispatcher/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/dispatcher/pom.xml b/system/core/dispatcher/pom.xml new file mode 100644 index 00000000..61d86aba --- /dev/null +++ b/system/core/dispatcher/pom.xml @@ -0,0 +1,26 @@ + + + + 4.0.0 + + + ru.entaxy.esb.system.core + system-core + 1.8.0 + ../../core/pom.xml + + + ru.entaxy.esb.system.core.dispatcher + dispatcher + SYSTEM :: ENTAXY :: CORE :: DISPATCHER + bundle + + + + ru.entaxy.esb.system.core.dispatcher + + + + \ No newline at end of file diff --git a/system/core/dispatcher/src/main/java/ru/entaxy/esb/system/core/dispatcher/Addressable.java b/system/core/dispatcher/src/main/java/ru/entaxy/esb/system/core/dispatcher/Addressable.java new file mode 100644 index 00000000..36709f7b --- /dev/null +++ b/system/core/dispatcher/src/main/java/ru/entaxy/esb/system/core/dispatcher/Addressable.java @@ -0,0 +1,23 @@ +/*- + * ~~~~~~licensing~~~~~~ + * dispatcher + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.dispatcher; + +public interface Addressable { +} diff --git a/system/core/error-handler/LICENSE.txt b/system/core/error-handler/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/error-handler/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/error-handler/README.md b/system/core/error-handler/README.md new file mode 100644 index 00000000..392da85c --- /dev/null +++ b/system/core/error-handler/README.md @@ -0,0 +1,116 @@ +# SYSTEM :: ENTAXY :: CORE :: COMMON ERROR HANDLER + +Централизованный обработчик ошибок для формирования кодов ошибок, их синхронного возврата клиенту и для асинхронного дублирования более подробного описания ошибки (для клиента и для Центральной Базы Интеграции). + +## Установка и настройка +Установка модуля происходит через фичу: +``` +feature:install error-handler +``` +Фича включена в общий установочный скрипт и будет устанавливаться вместе с остальными модулями. +Во время установки фичи в караф копируются файлы конфигурации: +``` +ru.entaxy.esb.error.cfg (основная конфигурация) +ru.entaxy.esb.error.code.cfg (справочник исключений с маппингом на коды ошибок) +ru.entaxy.esb.error.text.cfg (справочник кодов ошибок с маппингом на текстовые сообщения) +``` +Есть возможность настройки маппинга уровней журналирования через файл конфигурации `ru.entaxy.esb.error.severity.cfg`. +### ru.entaxy.esb.error.cfg (основная конфигурация) +``` +# асинхронный пакет с ошибкой отправляется от имени: +# false - системы, вызвавшей ошибку в шине +# true - шины (система с идентификатором "-1") +error.bus.always_at_source=false + +# асинхронный пакет с ошибкой в поле description содержит: +# false - сообщение из маппинга в файле ru.entaxy.esb.error.text.cfg +# true - содержит сообщение, сохранённое в исключении +error.description.exception_message=true + +# имя очереди для отправки пакета с ошибкой при недоступности системы, указанной в свойстве error.system.name +error.queue.name=error + +# имя системы для отправки пакета с ошибкой, подразумевается система ЦБИ +error.system.name=error + +# true - включает в пакет с ошибкой весь stacktrace исключения +error.stacktrace.show=true + +# свойство автоматического запуска тестового маршрута, который при старте модуля бросает исключение java.lang.IllegalArgumentException: Test exception thrown +error.test-route.startup=false +``` +### ru.entaxy.esb.error.code.cfg (справочник исключений с маппингом на коды ошибок) +Справочник содержит соответствие имён классов исключений и http кодов ошибок. И будет наполняться по мере использования шины в разных ситуациях. Для исключения, имя которого ещё не указано в этом файле, будет возвращаться http код `520` (Unknown Error). +``` +DefaultException=520 +com.ctc.wstx.exc.WstxParsingException=400 +java.security.AccessControlException=403 +javax.ws.rs.ForbiddenException=403 +ConnectorNotFound=424 +ru.entaxy.esb.system.common.exception.DefaultException=520 +ProfileNotFound=424 +# и т.д. +``` +### ru.entaxy.esb.error.text.cfg (справочник кодов ошибок с маппингом на текстовые сообщения) +Если в основной конфигурации свойство `error.description.exception_message` установлено в `false`, то описание ошибки отправляется из этого файла в соответствие с кодом http ошибки. +``` +# 1xx: Informational +# 2xx: Success +200=OK + +# 3xx: Redirection +# 4xx: Client Error +400=Bad Request +403=Forbidden +424=Failed Dependency + +# 5xx: Server Error +520=Unknown Error +# и т.д. +``` +## Подключение обработчика ошибок +Для подключения обработчика ошибок к маршрутам какого-либо модуля необходимо выполнить следующие шаги: +1. Добавить в модуль обработки ошибок в директорию `src/main/resources/xslt/operation` новый xslt для формирования ответа с ошибкой. Файл должен называться по имени операции, для которой будет формироваться ответ. Например `sendToJMS.xsl`. +1. Добавить в `camelContext` аттрибут `errorHandlerRef="commonErrorHandler"` и внутри зарегистрировать обработчик и политику повторной доставки: +```xml + + + + + + +``` +Для контекстов, содержащих конечные точки cxf, необходимо: +- через `pom.xml` импортировать интерцептор для перехвата ошибок (SoapFault) +```xml + + ru.entaxy.esb.system.core.common.error.handler.interceptor, + ... + +``` +- добавить интерцептор в `cxfEndpoint` и bean с указанием в первом аргументе идентификатора `camelContext` +```xml + + + + + + + + + + + +``` +- в `camelContext` добавить маршрут +```xml + + + + + + +``` diff --git a/system/core/error-handler/pom.xml b/system/core/error-handler/pom.xml new file mode 100644 index 00000000..a9144098 --- /dev/null +++ b/system/core/error-handler/pom.xml @@ -0,0 +1,46 @@ + + + + 4.0.0 + + + ru.entaxy.esb.system.core + system-core + 1.8.0 + ../pom.xml + + + error-handler + bundle + + SYSTEM :: ENTAXY :: CORE :: COMMON ERROR HANDLER + SYSTEM :: ENTAXY :: CORE :: COMMON ERROR HANDLER + + + + ru.entaxy.esb.system.core.common.error.handler.interceptor + + + * + + + + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + org.apache.camel + camel-core + + + org.apache.camel + camel-cxf + + + diff --git a/system/core/error-handler/src/main/java/ru/entaxy/esb/system/core/common/error/handler/interceptor/HandleOutFaultInterceptor.java b/system/core/error-handler/src/main/java/ru/entaxy/esb/system/core/common/error/handler/interceptor/HandleOutFaultInterceptor.java new file mode 100644 index 00000000..d0c9343d --- /dev/null +++ b/system/core/error-handler/src/main/java/ru/entaxy/esb/system/core/common/error/handler/interceptor/HandleOutFaultInterceptor.java @@ -0,0 +1,148 @@ +/*- + * ~~~~~~licensing~~~~~~ + * error-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.common.error.handler.interceptor; + +import org.apache.camel.CamelContext; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.component.cxf.common.message.CxfConstants; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.binding.soap.SoapMessage; +import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; +import org.apache.cxf.endpoint.Endpoint; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.message.Exchange; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.Phase; +import org.apache.cxf.transport.Conduit; +import org.apache.cxf.transport.http.Headers; +import ru.entaxy.esb.system.common.util.SystemHeadersConstants; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class HandleOutFaultInterceptor extends AbstractSoapInterceptor { + private static final Log LOG = LogFactory.getLog(HandleOutFaultInterceptor.class); + + private final ProducerTemplate template; + private final String endpointUri; + + public HandleOutFaultInterceptor(CamelContext camelContext, String endpointUri) { + super(Phase.POST_PROTOCOL); + this.template = camelContext.createProducerTemplate(); + this.endpointUri = endpointUri; + } + + + public void handleMessage(SoapMessage message) { + LOG.debug("HandleOutFaultInterceptor.handleMessage invocation"); +// String inMEssage = message.getExchange().getInMessage().getContent(String.class); +// Fault fault = (Fault) message.getContent(Exception.class); + Map headers = prepareHeaders(message); + String response = template.requestBodyAndHeaders(this.endpointUri, "", headers, String.class); + LOG.debug("HandleOutFaultInterceptor.handleMessage result from camel: \n" + response); + sendErrorResponse(message, 200, response); + } + + private Map prepareHeaders(SoapMessage message) { + Fault fault = (Fault) message.getContent(Exception.class); + Map headers = new HashMap(); + headers.put("NTX_ERROR_HANDLER_SoapFault", fault); +// headers.put("ERROR_HANDLER_EXCEPTION", fault.getCause()); +// headers.put("NTX_ERROR_HANDLER_ExceptionClass", fault.getCause().getClass().getName()); +// headers.put("NTX_ERROR_HANDLER_ExceptionMessage", fault.getCause().getMessage()); + headers.put(CxfConstants.OPERATION_NAME, getOperationName(message)); + try { + addSystemHeaders(message, headers); + } catch (Exception e) { + LOG.info("Unable to add source system information to headers in HandleOutFaultInterceptor"); + } + return headers; + } + + private void addSystemHeaders(SoapMessage message, Map headers) { + Message inMessage = message.getExchange().getInMessage(); + Map> inHeaders = Headers.getSetProtocolHeaders(inMessage); + headers.put(SystemHeadersConstants.HEADER_SYSTEM_NAME, + inHeaders.get(SystemHeadersConstants.HEADER_SYSTEM_NAME).get(0)); + headers.put(SystemHeadersConstants.HEADER_SYSTEM_ID, + inHeaders.get(SystemHeadersConstants.HEADER_SYSTEM_ID).get(0)); + } + + private String getOperationName(SoapMessage message) { + String operation = ""; + try { + operation = message.getExchange().getBindingOperationInfo().getOperationInfo().getName().getLocalPart(); + } catch (Exception e) { + LOG.error(e); + } + LOG.debug("operation name: " + operation); + return operation; + } + + private void sendErrorResponse(Message message, int responseCode, String ret) { + Message outMessage = getOutMessage(message); + outMessage.put(Message.RESPONSE_CODE, responseCode); + // Set the response headers + Map responseHeaders = (Map) outMessage.get(Message.PROTOCOL_HEADERS); + if (responseHeaders != null) { + responseHeaders.clear(); + responseHeaders.put("CAMEL_ERROR", Arrays.asList(ret)); + } + message.getInterceptorChain().abort(); + try { + getConduit(message).prepare(outMessage); + write(outMessage, ret); + } catch (IOException e) { + LOG.warn(e.getMessage(), e); + } + } + + private Message getOutMessage(Message inMessage) { + Exchange exchange = inMessage.getExchange(); + Message outMessage = exchange.getOutMessage(); + if (outMessage == null) { + Endpoint endpoint = exchange.get(Endpoint.class); + outMessage = endpoint.getBinding().createMessage(); + exchange.setOutMessage(outMessage); + } + outMessage.putAll(inMessage); + return outMessage; + } + + private Conduit getConduit(Message inMessage) throws IOException { + Exchange exchange = inMessage.getExchange(); + Conduit conduit = exchange.getDestination().getBackChannel(inMessage); + exchange.setConduit(conduit); + return conduit; + } + + private void write(Message outMessage, String ret) throws IOException { + OutputStream os = outMessage.getContent(OutputStream.class); + os.write(ret.getBytes(StandardCharsets.UTF_8)); + os.flush(); + os.close(); + } +} diff --git a/system/core/error-handler/src/main/java/ru/entaxy/esb/system/core/common/error/handler/processor/ErrorProcessor.java b/system/core/error-handler/src/main/java/ru/entaxy/esb/system/core/common/error/handler/processor/ErrorProcessor.java new file mode 100644 index 00000000..ce698bff --- /dev/null +++ b/system/core/error-handler/src/main/java/ru/entaxy/esb/system/core/common/error/handler/processor/ErrorProcessor.java @@ -0,0 +1,39 @@ +/*- + * ~~~~~~licensing~~~~~~ + * error-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.common.error.handler.processor; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.ProducerTemplate; + +public class ErrorProcessor implements Processor { + + @Override + public void process(Exchange exchange) throws Exception { + + String body = exchange.getIn().getBody(String.class); + Exception cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class); + exchange.getIn().setBody("ErrorProcessor: \n" + cause.getMessage()); + + ProducerTemplate template = exchange.getContext().createProducerTemplate(); +// template.send("xslt:xslt/CreateUniversalErrorPacket.xsl", exchange); + template.send("direct-vm:commonErrorEndpoint", exchange); + } +} diff --git a/system/core/error-handler/src/main/java/ru/entaxy/esb/system/core/common/error/handler/util/Timestamp.java b/system/core/error-handler/src/main/java/ru/entaxy/esb/system/core/common/error/handler/util/Timestamp.java new file mode 100644 index 00000000..9b778a71 --- /dev/null +++ b/system/core/error-handler/src/main/java/ru/entaxy/esb/system/core/common/error/handler/util/Timestamp.java @@ -0,0 +1,30 @@ +/*- + * ~~~~~~licensing~~~~~~ + * error-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.common.error.handler.util; + +public class Timestamp { + public String currentTimeMillis(String body) { + return String.valueOf(System.currentTimeMillis()); + } + + public String unixTime(String body) { + return String.valueOf(System.currentTimeMillis() / 1000L); + } +} diff --git a/system/core/error-handler/src/main/resources/OSGI-INF/blueprint/common-error-handler-context.xml b/system/core/error-handler/src/main/resources/OSGI-INF/blueprint/common-error-handler-context.xml new file mode 100644 index 00000000..8a9815cc --- /dev/null +++ b/system/core/error-handler/src/main/resources/OSGI-INF/blueprint/common-error-handler-context.xml @@ -0,0 +1,410 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Oops... some test error occurred]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + + + + + + ${exception} != null + + ${exception.class.name} + + + ${exception.message} + + + + ${header.NTX_ERROR_HANDLER_SoapFault} != null + + ${header.NTX_ERROR_HANDLER_SoapFault.cause.class.name} + + + ${header.NTX_ERROR_HANDLER_SoapFault.cause.message} + + + + + ru.entaxy.esb.system.common.exception.DefaultException + + + Something wrong + + + + + + ${header.NTX_ERROR_HANDLER_ExceptionClass} + + + ${properties:${header.NTX_ERROR_HANDLER_ExceptionClass}} + + + java.lang.Exception + + ${properties:ru.entaxy.esb.system.common.exception.DefaultException} + + + + + + + + ${properties:error.description.exception_message} == "true" + + ${header.NTX_ERROR_HANDLER_ExceptionMessage} + + + + + ${properties:${header.NTX_ERROR_HANDLER_ResponseCode}} + + + + + + + ${properties:error.stacktrace.show} == "true" + && ${exception.stacktrace} != null + + + ${exception.stacktrace} + + + + + + + + + + + + + + + + + + + + java.lang.Exception + + + + + + + + + + ${headers.X-SystemName} != "esb" + + + + java.lang.Exception + + + + + + + + + + + + + + + + esb + + + + + + + + ${bean:uuidGenerator.toString} + + + ВыгрузкаДанныхКаноническийФормат + + + application/xml + + + String + + + xs:string + + + + + + + + ${properties:error.system.name} + + + + + ${headers.ENTAXY_Source} != null && ${headers.ENTAXY_Source} != "" + + + ${headers.ENTAXY_Source} + + + ${headers.ENTAXY_Source} + + + + ${headers.NTX_SystemId} != null && ${headers.NTX_SystemId} != "" + + ${headers.NTX_SystemId} + + + ${headers.NTX_SystemId} + + + + ${headers.X-SystemName} != null && ${headers.X-SystemName} != "" + + ${headers.X-SystemName} + + + ${headers.X-SystemName} + + + + + esb + + + esb + + + + + + ${headers.X-SystemName} == null || ${headers.X-SystemName} == "" + + esb + + + + + + ${headers.X-SystemId} == null || ${headers.X-SystemId} == "" + + -1 + + + + + + ${properties:error.bus.always_at_source} == "true" + + esb + + + esb + + + -1 + + + + + + ${bean:uuidGenerator.toString} + + + + ${bean:timestamp?method=currentTimeMillis} + + + ${headers.NTX_ERROR_HANDLER_SeverityLevel} == null + + ERROR + + + + + + + + ]]> + + + + + ${headers.NTX_ERROR_HANDLER_GenerateResponseEndpoint} != null + + + + ${headers.operationName} + + + + java.lang.Exception + + + + + + + + + + + + + + diff --git a/system/core/error-handler/src/main/resources/xslt/DefaultResponse.xsl b/system/core/error-handler/src/main/resources/xslt/DefaultResponse.xsl new file mode 100644 index 00000000..bb854641 --- /dev/null +++ b/system/core/error-handler/src/main/resources/xslt/DefaultResponse.xsl @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/system/core/error-handler/src/main/resources/xslt/UniversalErrorPacket.xsl b/system/core/error-handler/src/main/resources/xslt/UniversalErrorPacket.xsl new file mode 100644 index 00000000..c8caf22d --- /dev/null +++ b/system/core/error-handler/src/main/resources/xslt/UniversalErrorPacket.xsl @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + +

+ http://www.entaxy.ru/ServiceInterface/1.0 + 2020-05-20T07:19:59 + 1 +
+ + <Справочник.События> + <КлючевыеСвойства> + <Ссылка> + + + + + + + + + + + + + + + + + + + + Packet.Validation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/core/error-handler/src/main/resources/xslt/WrapSoapEnvelope.xsl b/system/core/error-handler/src/main/resources/xslt/WrapSoapEnvelope.xsl new file mode 100644 index 00000000..7057ed63 --- /dev/null +++ b/system/core/error-handler/src/main/resources/xslt/WrapSoapEnvelope.xsl @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/system/core/error-handler/src/main/resources/xslt/operation/ConfirmGettingPackets.xsl b/system/core/error-handler/src/main/resources/xslt/operation/ConfirmGettingPackets.xsl new file mode 100644 index 00000000..f4ceab04 --- /dev/null +++ b/system/core/error-handler/src/main/resources/xslt/operation/ConfirmGettingPackets.xsl @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/system/core/error-handler/src/main/resources/xslt/operation/GetPackets.xsl b/system/core/error-handler/src/main/resources/xslt/operation/GetPackets.xsl new file mode 100644 index 00000000..f4ceab04 --- /dev/null +++ b/system/core/error-handler/src/main/resources/xslt/operation/GetPackets.xsl @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/system/core/error-handler/src/main/resources/xslt/operation/PutPackets.xsl b/system/core/error-handler/src/main/resources/xslt/operation/PutPackets.xsl new file mode 100644 index 00000000..f4ceab04 --- /dev/null +++ b/system/core/error-handler/src/main/resources/xslt/operation/PutPackets.xsl @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/system/core/error-handler/src/main/resources/xslt/operation/sendAcknowledge.xsl b/system/core/error-handler/src/main/resources/xslt/operation/sendAcknowledge.xsl new file mode 100644 index 00000000..7a6ac059 --- /dev/null +++ b/system/core/error-handler/src/main/resources/xslt/operation/sendAcknowledge.xsl @@ -0,0 +1,24 @@ + + + + + + diff --git a/system/core/error-handler/src/main/resources/xslt/operation/sendToJMS.xsl b/system/core/error-handler/src/main/resources/xslt/operation/sendToJMS.xsl new file mode 100644 index 00000000..7a6ac059 --- /dev/null +++ b/system/core/error-handler/src/main/resources/xslt/operation/sendToJMS.xsl @@ -0,0 +1,24 @@ + + + + + + diff --git a/system/core/error-handler/src/main/resources/xslt/operation/type/response.xsl b/system/core/error-handler/src/main/resources/xslt/operation/type/response.xsl new file mode 100644 index 00000000..3184345f --- /dev/null +++ b/system/core/error-handler/src/main/resources/xslt/operation/type/response.xsl @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/system/core/events/LICENSE.txt b/system/core/events/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/events/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/events/README.md b/system/core/events/README.md new file mode 100644 index 00000000..9e36c6d0 --- /dev/null +++ b/system/core/events/README.md @@ -0,0 +1,3 @@ +#SYSTEM :: ENTAXY :: CORE :: EVENTS + +Информация по настройке находится в документе `Topic-management Rest сервис` \ No newline at end of file diff --git a/system/core/events/events-api/LICENSE.txt b/system/core/events/events-api/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/events/events-api/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/events/events-api/pom.xml b/system/core/events/events-api/pom.xml new file mode 100644 index 00000000..87afaf9e --- /dev/null +++ b/system/core/events/events-api/pom.xml @@ -0,0 +1,57 @@ + + + + + ru.entaxy.esb.system.core.events + events + 1.8.0 + ../../events/pom.xml + + + 4.0.0 + + events-api + SYSTEM :: ENTAXY :: CORE :: EVENTS :: API + bundle + + + + ru.entaxy.esb.system.core.events.jpa, + ru.entaxy.esb.system.core.events.jpa.entity + + + javax.persistence;version="[2,3)", + org.hibernate.proxy, + javassist.util.proxy, + * + + + + + + org.eclipse.persistence + javax.persistence + ${jpa.version} + + + org.hibernate + hibernate-envers + ${hibernate.version} + + + + ru.entaxy.esb.system.registry.systems + system-api + ${project.version} + provided + + + ru.entaxy.esb.system.core.events + events-common + ${project.version} + provided + + + diff --git a/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/EventTopicService.java b/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/EventTopicService.java new file mode 100644 index 00000000..9a40f803 --- /dev/null +++ b/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/EventTopicService.java @@ -0,0 +1,61 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.jpa; + +import ru.entaxy.esb.system.core.events.jpa.entity.EventTopic; + +import java.util.List; +import java.util.Optional; + +public interface EventTopicService { + + List list(); + + List listByDeleted(boolean deleted); + + EventTopic get(long id); + + Optional fetch(long id); + + EventTopic getByName(String name); + + Optional fetchByName(String name); + + EventTopic getByNameAndDeleted(String name, boolean deleted); + + Optional fetchByNameAndDeleted(String name, boolean deleted); + + EventTopic add(EventTopic eventTopic); + + EventTopic add(String name, String createdBy); + + EventTopic update(EventTopic eventTopic); + + EventTopic update(long id, String name, String editedBy); + + void remove(EventTopic eventTopic); + + void remove(long id); + + void markAsDeleted(long id, boolean deleted); + + int clean(); + +} diff --git a/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/SystemSubscriptionService.java b/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/SystemSubscriptionService.java new file mode 100644 index 00000000..2e397da2 --- /dev/null +++ b/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/SystemSubscriptionService.java @@ -0,0 +1,68 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.jpa; + +import org.hibernate.Session; +import ru.entaxy.esb.system.core.events.common.SubscriptionType; +import ru.entaxy.esb.system.core.events.jpa.entity.EventTopic; +import ru.entaxy.esb.system.core.events.jpa.entity.SystemSubscription; +import ru.entaxy.esb.system.jpa.entity.System; + +import java.util.List; + +public interface SystemSubscriptionService { + + List list(); + + List listByDeleted(boolean deleted); + + SystemSubscription get(long id); + + List getBySystem(long systemRegistryId); + + SystemSubscription getBySystemAndTopic(long systemRegistryId, long eventTopicId); + + List getByTopic(long eventTopicId); + + List getByTopic(Session s, long eventTopicId); + + List getByTopicAndType(long eventTopicId, SubscriptionType type); + + List getByType(SubscriptionType type); + + SystemSubscription add(SystemSubscription systemSubscriptionRegistry) throws Exception; + + SystemSubscription add(System system, EventTopic eventTopic, SubscriptionType type) throws Exception; + + SystemSubscription update(SystemSubscription systemSubscriptionRegistry); + + void remove(long id); + + void removeByTopic(long eventTopicId); + + void removeByTopic(Session s, long eventTopicId); + + void markAsDeleted(long id, boolean deleted); + + void markAsDeletedByTopic(long eventTopicId, boolean deleted); + + void markAsDeletedByTopic(Session s, long eventTopicId, boolean deleted); + +} diff --git a/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/entity/EventTopic.java b/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/entity/EventTopic.java new file mode 100644 index 00000000..7170e5d5 --- /dev/null +++ b/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/entity/EventTopic.java @@ -0,0 +1,140 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.jpa.entity; + +import com.sun.istack.NotNull; + +import javax.persistence.*; +import java.util.Date; +import java.util.Objects; + +@Entity +@Table(name = "event_topic") +public class EventTopic { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + @NotNull + @Column(name = "name") + private String name; + @Column(name = "create_date") + private Date createDate; + @Column(name = "edit_date") + private Date editDate; + @Column(name = "created_by") + private String createdBy; + @Column(name = "edited_by") + private String editedBy; + @Column(name = "deleted") + private boolean deleted; + +// @OneToMany(orphanRemoval = true, fetch = FetchType.LAZY) +// @JoinColumn(name = "event_topic_id") +// private List subscriptions; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getCreateDate() { + return createDate; + } + + public void setCreateDate(Date createDate) { + this.createDate = createDate; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public Date getEditDate() { + return editDate; + } + + public void setEditDate(Date editDate) { + this.editDate = editDate; + } + + public String getEditedBy() { + return editedBy; + } + + public void setEditedBy(String editedBy) { + this.editedBy = editedBy; + } + + // public List getSubscriptions() { +// return subscriptions; +// } +// public void setSubscriptions(List subscriptions) { +// this.subscriptions = subscriptions; +// } + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + @Override + public int hashCode() { + return Objects.hash(createDate, createdBy, id, name); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EventTopic other = (EventTopic) obj; + return Objects.equals(createDate, other.createDate) && Objects.equals(createdBy, other.createdBy) + && id == other.id && Objects.equals(name, other.name); + } + + @Override + public String toString() { + return "EventTopic [id=" + id + ", name=" + name + ", createDate=" + createDate + ", createdBy=" + createdBy + + "]"; + } + +} diff --git a/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/entity/SystemSubscription.java b/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/entity/SystemSubscription.java new file mode 100644 index 00000000..fb9c2752 --- /dev/null +++ b/system/core/events/events-api/src/main/java/ru/entaxy/esb/system/core/events/jpa/entity/SystemSubscription.java @@ -0,0 +1,116 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.jpa.entity; + +import ru.entaxy.esb.system.core.events.common.SubscriptionType; +import ru.entaxy.esb.system.jpa.entity.System; + +import javax.persistence.*; +import java.util.Objects; + +@Entity +@Table(name = "system_subscription_registry") +public class SystemSubscription { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "event_topic_id", referencedColumnName = "id") + private EventTopic eventTopic; + + @Column(name = "type") + @Enumerated(EnumType.STRING) + private SubscriptionType type; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "id_system", referencedColumnName = "id") + private System system; + + @Column(name = "deleted") + private boolean deleted; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public EventTopic getEventTopic() { + return eventTopic; + } + + public void setEventTopic(EventTopic eventTopic) { + this.eventTopic = eventTopic; + } + + public SubscriptionType getType() { + return type; + } + + public void setType(SubscriptionType type) { + this.type = type; + } + + public System getSystem() { + return system; + } + + public void setSystem(System system) { + this.system = system; + } + + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + @Override + public int hashCode() { + return Objects.hash(eventTopic, id, system, type); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SystemSubscription other = (SystemSubscription) obj; + return Objects.equals(eventTopic, other.eventTopic) && id == other.id + && Objects.equals(system, other.system) && Objects.equals(type, other.type); + } + + @Override + public String toString() { + return "SystemSubscriptionRegistry [id=" + id + ", eventTopic=" + eventTopic + ", type=" + type + + ", system=" + system + "]"; + } + +} diff --git a/system/core/events/events-common/LICENSE.txt b/system/core/events/events-common/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/events/events-common/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/events/events-common/pom.xml b/system/core/events/events-common/pom.xml new file mode 100644 index 00000000..c22b5714 --- /dev/null +++ b/system/core/events/events-common/pom.xml @@ -0,0 +1,27 @@ + + + + + ru.entaxy.esb.system.core.events + events + 1.8.0 + ../../events/pom.xml + + + 4.0.0 + + events-common + SYSTEM :: ENTAXY :: CORE :: EVENTS :: COMMON + bundle + + + + ru.entaxy.esb.system.core.events.common + + + * + + + diff --git a/system/core/events/events-common/src/main/java/ru/entaxy/esb/system/core/events/common/SubscriptionType.java b/system/core/events/events-common/src/main/java/ru/entaxy/esb/system/core/events/common/SubscriptionType.java new file mode 100644 index 00000000..d469056b --- /dev/null +++ b/system/core/events/events-common/src/main/java/ru/entaxy/esb/system/core/events/common/SubscriptionType.java @@ -0,0 +1,55 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-common + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.common; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public enum SubscriptionType { + + PUSH("PUSH"), + PULL("PULL"); + + private static Map map = null; + private final String name; + + SubscriptionType(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public boolean equalsName(String checkingName) { + return checkingName != null && this.name.equals(checkingName.toUpperCase()); + } + + public static Map getEnumAsMap() { + if (map == null) { + map = Arrays.stream(SubscriptionType.values()) + .collect(Collectors.toMap(SubscriptionType::getName, Function.identity())); + } + return map; + } + +} diff --git a/system/core/events/events-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/system/core/events/events-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 00000000..2744d9bd --- /dev/null +++ b/system/core/events/events-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/system/core/events/events-handler/LICENSE.txt b/system/core/events/events-handler/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/events/events-handler/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/events/events-handler/pom.xml b/system/core/events/events-handler/pom.xml new file mode 100644 index 00000000..cd4a88b0 --- /dev/null +++ b/system/core/events/events-handler/pom.xml @@ -0,0 +1,96 @@ + + + + + ru.entaxy.esb.system.core.events + events + 1.8.0 + ../../events/pom.xml + + + 4.0.0 + + events-handler + SYSTEM :: ENTAXY :: CORE :: EVENTS :: HANDLER + bundle + + + + org.apache.camel.component.jms, + ru.entaxy.esb.system.core.events.jpa, + ru.entaxy.esb.system.core.events.jpa.entity, + ru.entaxy.esb.system.jpa.entity, + com.google.gson.reflect, + * + + 3.1.0 + 1.4.0 + + + + + org.apache.activemq + artemis-jms-client + ${activemq.version} + provided + + + + ru.entaxy.esb.system.registry.systems + system-api + ${project.version} + provided + + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + + ru.entaxy.esb.system.core.events + events-api + ${project.version} + provided + + + ru.entaxy.esb.system.core.events + events-common + ${project.version} + provided + + + + org.apache.camel + camel-eventadmin + ${camel-eventadmin.version} + + + + org.apache.camel + camel-gson + ${camel.version} + + + + com.google.code.gson + gson + ${gson.version} + + + + org.osgi + org.osgi.service.event + ${org.osgi.service.event.version} + provided + + + org.apache.camel + camel-core + + + diff --git a/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/SubscriptionProcessingGenerator.java b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/SubscriptionProcessingGenerator.java new file mode 100644 index 00000000..a392b2cb --- /dev/null +++ b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/SubscriptionProcessingGenerator.java @@ -0,0 +1,152 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.handler; + +import org.apache.camel.Exchange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.system.common.util.PropertiesHelper; +import ru.entaxy.esb.system.core.events.handler.util.EventHelper; +import ru.entaxy.esb.system.core.events.jpa.entity.SystemSubscription; + +import javax.jms.*; +import java.util.List; + +public class SubscriptionProcessingGenerator { + + private static final Logger LOG = LoggerFactory.getLogger(SubscriptionProcessingGenerator.class); + + private EventHelper eventHelper; + private PropertiesHelper propertiesHelper; + private javax.jms.ConnectionFactory connectionFactory; + + public void construct(Exchange exchange) throws Exception { + List subscriptions = (List) exchange.getIn().getBody(); + + //consumer will created automatically with route +// if (subscriptions != null && !subscriptions.isEmpty()) { +// for (SystemSubscription subscription : subscriptions) { +// LOG.debug("Prepare consumer topic: " + subscription.getEventTopic().getName() + " system: " + subscription.getSystem().getName()); +// createDurableConsumer(subscription); +// } +// } + + SubscriptionRouteGenerator generator = new SubscriptionRouteGenerator(subscriptions, eventHelper, propertiesHelper); + exchange.getContext().addRoutes(generator); + } + + private void createDurableConsumer(SystemSubscription subscription) throws JMSException { + try (Connection conn = connectionFactory.createConnection()) { + conn.setClientID(eventHelper.getClientId(subscription)); + + Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + Topic topic = session.createTopic(subscription.getEventTopic().getName()); + + session.createDurableConsumer(topic, EventHelper.CONSUMER_NAME); + session.close(); + } + } + + public void destruct(Exchange exchange) throws Exception { + List subscriptions = (List) exchange.getIn().getBody(); + + boolean processRoute = exchange.getIn().getHeader("processRoute", false, Boolean.class); + + if (processRoute) { + SubscriptionRouteGenerator generator = new SubscriptionRouteGenerator(subscriptions, eventHelper, propertiesHelper); + generator.deleteRoutes(exchange.getContext()); + } + + if (subscriptions != null && !subscriptions.isEmpty()) { + for (SystemSubscription subscription : subscriptions) { + LOG.debug("Delete consumer topic: " + subscription.getEventTopic().getName() + " system " + subscription.getSystem().getName()); + purgeConsumerQueue(subscription); + deleteConsumer(subscription); + } + } + } + + private void deleteConsumer(SystemSubscription subscription) throws JMSException { + try (Connection conn = connectionFactory.createConnection()) { + Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + + session.unsubscribe(eventHelper.getClientId(subscription)); + session.close(); + } + } + + private void purgeConsumerQueue(SystemSubscription subscription) throws JMSException { + try (Connection conn = connectionFactory.createConnection()) { + Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + + Topic topic = session.createTopic(subscription.getEventTopic().getName()); + MessageConsumer consumer = session.createSharedConsumer(topic, eventHelper.getClientId(subscription)); + + conn.start(); + + Message message = null; + do { + message = consumer.receive(500); + } while (message != null); + + conn.stop(); + session.close(); + } + } + +// public void constructRoute(Exchange exchange) throws Exception { +// List subscriptions = (List) exchange.getIn().getBody(); +// +// SubscriptionRouteGenerator generator = new SubscriptionRouteGenerator(subscriptions, eventHelper, propertiesHelper); +// exchange.getContext().addRoutes(generator); +// } + + public void destructRoute(Exchange exchange) throws Exception { + List subscriptions = (List) exchange.getIn().getBody(); + + SubscriptionRouteGenerator generator = new SubscriptionRouteGenerator(subscriptions, eventHelper, propertiesHelper); + generator.deleteRoutes(exchange.getContext()); + } + + public EventHelper getEventHelper() { + return eventHelper; + } + + public void setEventHelper(EventHelper eventHelper) { + this.eventHelper = eventHelper; + } + + public PropertiesHelper getPropertiesHelper() { + return propertiesHelper; + } + + public void setPropertiesHelper(PropertiesHelper propertiesHelper) { + this.propertiesHelper = propertiesHelper; + } + + public javax.jms.ConnectionFactory getConnectionFactory() { + return connectionFactory; + } + + public void setConnectionFactory(javax.jms.ConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + } + +} diff --git a/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/SubscriptionRouteGenerator.java b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/SubscriptionRouteGenerator.java new file mode 100644 index 00000000..9f0f4a20 --- /dev/null +++ b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/SubscriptionRouteGenerator.java @@ -0,0 +1,135 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.handler; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.RouteDefinition; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.system.common.osgi.OSGIUtils; +import ru.entaxy.esb.system.common.util.PropertiesHelper; +import ru.entaxy.esb.system.core.events.common.SubscriptionType; +import ru.entaxy.esb.system.core.events.handler.util.EventHandlerConstant; +import ru.entaxy.esb.system.core.events.handler.util.EventHelper; +import ru.entaxy.esb.system.core.events.jpa.entity.SystemSubscription; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class SubscriptionRouteGenerator extends RouteBuilder { + + private static final Logger LOG = LoggerFactory.getLogger(SubscriptionRouteGenerator.class); + + private static Map routeMap = new HashMap<>(); + + private List subscriptions; + private EventHelper eventHelper; + private final PropertiesHelper propertiesHelper; + + public SubscriptionRouteGenerator(List subscriptions, EventHelper eventHelper, PropertiesHelper propertiesHelper) { + this.subscriptions = subscriptions; + this.eventHelper = eventHelper; + this.propertiesHelper = propertiesHelper; + } + + @Override + public void configure() throws Exception { + LOG.debug("SubscriptionRouteGenerator: finded " + (subscriptions != null ? subscriptions.size() : "null") + " subscriptions"); + + if (subscriptions != null && !subscriptions.isEmpty()) { + for (SystemSubscription subscription : subscriptions) { + LOG.debug("Handle subscription topic: " + subscription.getEventTopic().getName() + " system " + subscription.getSystem().getName()); + generateReceivingRoute(subscription); + } + } + } + + private void generateReceivingRoute(SystemSubscription subscription) { + if (SubscriptionType.PUSH.equals(subscription.getType())) { + LOG.trace("Generate routes PUSH"); + RouteDefinition definition = from("jms:topic:" + subscription.getEventTopic().getName() + + "?subscriptionName=" + getEventHelper().getClientId(subscription) + "&subscriptionDurable=true&subscriptionShared=true") + .setProperty("topicName").constant(subscription.getEventTopic().getName()) + .to("system:" + subscription.getSystem().getName()) + .errorHandler( + defaultErrorHandler() + .maximumRedeliveries( + propertiesHelper.getInteger(EventHandlerConstant.REDELIVERY_MAXIMUMREDELIVERIES, + EventHandlerConstant.REDELIVERY_MAXIMUMREDELIVERIES_DEFAULT)) + .redeliveryDelay( + propertiesHelper.getInteger(EventHandlerConstant.REDELIVERY_REDELIVERYDELAY, + EventHandlerConstant.REDELIVERY_REDELIVERYDELAY_DEFAULT)) + ); + + routeMap.put(getEventHelper().getClientId(subscription), definition); + + } else if (SubscriptionType.PULL.equals(subscription.getType())) { + //TODO + } + } + + public void deleteRoutes(CamelContext context) throws Exception { + List subsNames = subscriptions.stream() + .map(s -> getEventHelper().getClientId(s)) + .collect(Collectors.toList()); + + LOG.debug("Delete " + subsNames.size() + " receving routes " + String.join(", ", subsNames)); + + + LOG.trace("Routes before delete " + routeMap.size()); + List routeToDelete = routeMap.entrySet().stream() + .filter(x -> subsNames.contains(x.getKey())) + .map(x -> x.getValue()) + .collect(Collectors.toList()); + if (routeToDelete != null && routeToDelete.size() > 0) { +// context.removeRouteDefinitions(routeToDelete); + for (RouteDefinition routeDefinition : routeToDelete) { + context.removeRoute(routeDefinition.getRouteId()); + } + + routeMap = routeMap.entrySet().stream() + .filter(x -> !subsNames.contains(x.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + LOG.trace("Routes after delete " + routeMap.size()); + } + } + + public EventHelper getEventHelper() { + if (eventHelper == null) { + eventHelper = (EventHelper) OSGIUtils.getServiceReference( + FrameworkUtil.getBundle(EventHelper.class).getBundleContext(), + EventHelper.class.getName()); + } + return eventHelper; + } + + public List getSubscriptions() { + return subscriptions; + } + + public void setSubscriptions(List subscriptions) { + this.subscriptions = subscriptions; + } + +} diff --git a/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/EventAdminHelper.java b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/EventAdminHelper.java new file mode 100644 index 00000000..201aea47 --- /dev/null +++ b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/EventAdminHelper.java @@ -0,0 +1,41 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.handler.util; + +import org.osgi.service.event.Event; + +import java.util.HashMap; +import java.util.Map; + +public class EventAdminHelper { + + Map properties = new HashMap<>(); + + public Event createEvent(String eventTopic) { + Event event = new Event(eventTopic, new HashMap<>(properties)); + properties.clear(); + return event; + } + + public void setProperty(String key, Object value) { + properties.put(key, value); + } + +} diff --git a/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/EventHandlerConstant.java b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/EventHandlerConstant.java new file mode 100644 index 00000000..290a274b --- /dev/null +++ b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/EventHandlerConstant.java @@ -0,0 +1,34 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.handler.util; + +public class EventHandlerConstant { + + public static final String CONFIG_FILE = "ru.entaxy.esb.system.event.handler.cfg"; + + public static final String REDELIVERY_MAXIMUMREDELIVERIES = "redelivery.maximumRedeliveries"; + public static final String REDELIVERY_MAXIMUMREDELIVERIES_DEFAULT = "-1"; + public static final String REDELIVERY_REDELIVERYDELAY = "redelivery.redeliveryDelay"; + public static final String REDELIVERY_REDELIVERYDELAY_DEFAULT = "5000"; + + private EventHandlerConstant() { + } + +} diff --git a/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/EventHelper.java b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/EventHelper.java new file mode 100644 index 00000000..00ba0751 --- /dev/null +++ b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/EventHelper.java @@ -0,0 +1,39 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.handler.util; + +import com.google.gson.reflect.TypeToken; +import ru.entaxy.esb.system.core.events.jpa.entity.SystemSubscription; + +import java.util.ArrayList; + +public class EventHelper { + + public static final String CONSUMER_NAME = "consumer"; + + public String getClientId(SystemSubscription subscription) { + return subscription.getSystem().getName() + "_" + subscription.getEventTopic().getName(); + } + + public static java.lang.reflect.Type getType() { + return new TypeToken>() { + }.getType(); + } +} diff --git a/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/GsonDataFormatInitializer.java b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/GsonDataFormatInitializer.java new file mode 100644 index 00000000..79e474cb --- /dev/null +++ b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/GsonDataFormatInitializer.java @@ -0,0 +1,81 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.handler.util; + +import com.google.gson.ExclusionStrategy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import org.apache.camel.component.gson.GsonDataFormat; +import ru.entaxy.esb.system.core.events.jpa.entity.SystemSubscription; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.ArrayList; + +public class GsonDataFormatInitializer extends GsonDataFormat { + + private Gson gson; + + public GsonDataFormatInitializer() { + super(); + Type type = new TypeToken>() { + }.getType(); + setUnmarshalGenericType(type); + } + + @Override + protected void doStart() throws Exception { + if (gson == null) { + GsonBuilder builder = new GsonBuilder(); + if (getExclusionStrategies() != null && !getExclusionStrategies().isEmpty()) { + ExclusionStrategy[] strategies = getExclusionStrategies().toArray(new ExclusionStrategy[getExclusionStrategies().size()]); + builder.setExclusionStrategies(strategies); + } +// if (longSerializationPolicy != null) { +// builder.setLongSerializationPolicy(longSerializationPolicy); +// } + if (getFieldNamingPolicy() != null) { + builder.setFieldNamingPolicy(getFieldNamingPolicy()); + } +// if (fieldNamingStrategy != null) { +// builder.setFieldNamingStrategy(fieldNamingStrategy); +// } +// if (serializeNulls) { +// builder.serializeNulls(); +// } +// if (prettyPrint) { +// builder.setPrettyPrinting(); +// } +// if (dateFormatPattern != null) { +// builder.setDateFormat(dateFormatPattern); +// } + + builder.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY); + + gson = builder.create(); + + Field f1 = this.getClass().getSuperclass().getDeclaredField("gson"); + f1.setAccessible(true); + f1.set(this, gson); + } + } + +} diff --git a/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/HibernateProxyTypeAdapter.java b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/HibernateProxyTypeAdapter.java new file mode 100644 index 00000000..fa7eefce --- /dev/null +++ b/system/core/events/events-handler/src/main/java/ru/entaxy/esb/system/core/events/handler/util/HibernateProxyTypeAdapter.java @@ -0,0 +1,70 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.handler.util; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import org.hibernate.Hibernate; +import org.hibernate.proxy.HibernateProxy; + +import java.io.IOException; + +public class HibernateProxyTypeAdapter extends TypeAdapter { + + public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter) new HibernateProxyTypeAdapter(gson) : null); + } + }; + private final Gson context; + + private HibernateProxyTypeAdapter(Gson context) { + this.context = context; + } + + @Override + public HibernateProxy read(JsonReader in) throws IOException { + throw new UnsupportedOperationException("Not supported"); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Override + public void write(JsonWriter out, HibernateProxy value) throws IOException { + if (value == null) { + out.nullValue(); + return; + } + // Retrieve the original (not proxy) class + Class baseType = Hibernate.getClass(value); + // Get the TypeAdapter of the original class, to delegate the serialization + TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType)); + // Get a filled instance of the original class + Object unproxiedValue = value.getHibernateLazyInitializer() + .getImplementation(); + // Serialize the value + delegate.write(out, unproxiedValue); + } + +} diff --git a/system/core/events/events-handler/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/system/core/events/events-handler/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 00000000..63128866 --- /dev/null +++ b/system/core/events/events-handler/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + entaxy + AUTO + true + + $common{org.quartz.jobStore.driverDelegateClass} + + true + 5000 + org.quartz.impl.jdbcjobstore.JobStoreTX + cache + osgi:service/entaxy.esb.cache + + org.quartz.simpl.SimpleThreadPool + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + ${body} + + + + + + ${exchangeProperty.bodyHolder} + + + + + + + + + + ${body} + + + + + + ${exchangeProperty.bodyHolder} + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${body.getProperty('subscribe')} + + + + ${body.getProperty('subscriptions')} + + + + + + + + + + + ${exchangeProperty.subscribe} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/core/events/events-impl/LICENSE.txt b/system/core/events/events-impl/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/events/events-impl/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/events/events-impl/pom.xml b/system/core/events/events-impl/pom.xml new file mode 100644 index 00000000..b36513fd --- /dev/null +++ b/system/core/events/events-impl/pom.xml @@ -0,0 +1,138 @@ + + + + + ru.entaxy.esb.system.core.events + events + 1.8.0 + ../../events/pom.xml + + + 4.0.0 + + events-impl + SYSTEM :: ENTAXY :: CORE :: EVENTS :: IMPL + bundle + + + + ru.entaxy.esb.system.core.permission.jpa.entity, + ru.entaxy.esb.system.connector.entity, + ru.entaxy.esb.system.management.bundle.jpa.entity, + ru.entaxy.esb.system.common.exception, + javax.xml.bind;version="[2,3)", + javax.xml.bind.annotation;version="[2,3)", + javax.persistence;version="[2,3)", + org.hibernate, + org.hibernate.cfg, + org.hibernate.service, + org.hibernate.jpa, + org.hibernate.proxy, + javassist.util.proxy, + * + + + + + + org.osgi + osgi.core + ${osgi.version} + provided + + + org.eclipse.persistence + javax.persistence + ${jpa.version} + + + javax.transaction + javax.transaction-api + ${javax.transaction.version} + + + javax.interceptor + javax.interceptor-api + ${javax.interceptor.version} + + + + ru.entaxy.esb.system.registry.systems + system-api + ${project.version} + provided + + + ru.entaxy.esb.system.core.events + events-api + ${project.version} + provided + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + ru.entaxy.esb.system.core.events + events-common + ${project.version} + provided + + + ru.entaxy.esb.system.registry.connector + connector-api + ${project.version} + + + + ru.entaxy.esb.system.core.permission + permission-api + ${project.version} + provided + + + + ru.entaxy.esb.system.core.permission + permission-common + ${project.version} + provided + + + + + + + + dev + + + env + dev + + + + true + true + + + + + prod + + + env + !dev + + + + false + false + + + + + diff --git a/system/core/events/events-impl/src/main/java/ru/entaxy/esb/system/core/events/jpa/impl/EventTopicServiceImpl.java b/system/core/events/events-impl/src/main/java/ru/entaxy/esb/system/core/events/jpa/impl/EventTopicServiceImpl.java new file mode 100644 index 00000000..5635e46a --- /dev/null +++ b/system/core/events/events-impl/src/main/java/ru/entaxy/esb/system/core/events/jpa/impl/EventTopicServiceImpl.java @@ -0,0 +1,344 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-impl + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.jpa.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.query.Query; +import ru.entaxy.esb.system.core.events.jpa.EventTopicService; +import ru.entaxy.esb.system.core.events.jpa.SystemSubscriptionService; +import ru.entaxy.esb.system.core.events.jpa.entity.EventTopic; +import ru.entaxy.esb.system.core.permission.common.PermissionConstants; +import ru.entaxy.esb.system.core.permission.jpa.PermissionService; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +public class EventTopicServiceImpl implements EventTopicService { + + private static final Log LOG = LogFactory.getLog(EventTopicServiceImpl.class); + + private SessionFactory sessionFactory; + private PermissionService permissionService; + private SystemSubscriptionService systemSubscriptionService; + + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public Session getSession() { + return sessionFactory.openSession(); + } + + public PermissionService getPermissionService() { + return permissionService; + } + + public void setPermissionService(PermissionService permissionService) { + this.permissionService = permissionService; + } + + public SystemSubscriptionService getSystemSubscriptionService() { + return systemSubscriptionService; + } + + public void setSystemSubscriptionService(SystemSubscriptionService systemSubscriptionService) { + this.systemSubscriptionService = systemSubscriptionService; + } + + @Override + public List list() { + List list; + try (Session s = getSession()) { + s.getTransaction().begin(); + CriteriaQuery cq = s.getCriteriaBuilder().createQuery(EventTopic.class); + cq.from(EventTopic.class); + list = s.createQuery(cq).getResultList(); + s.getTransaction().commit(); + s.close(); + } + + return list; + } + + @Override + public List listByDeleted(boolean deleted) { + List list; + + try (Session s = getSession()) { + s.getTransaction().begin(); + + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery cq = s.getCriteriaBuilder().createQuery(EventTopic.class); + Root root = cq.from(EventTopic.class); + cq.where(builder.equal(root.get("deleted"), deleted)); + + list = s.createQuery(cq).getResultList(); + s.getTransaction().commit(); + s.close(); + } + + return list; + } + + @Override + public EventTopic get(long id) { + EventTopic eventTopic; + try (Session s = getSession()) { + s.getTransaction().begin(); + + Query query = prepareQueryGet(s, id); + eventTopic = query.getSingleResult(); + + s.getTransaction().commit(); + s.close(); + } + return eventTopic; + } + + @Override + public Optional fetch(long id) { + Optional eventTopic; + try (Session s = getSession()) { + s.getTransaction().begin(); + + Query query = prepareQueryGet(s, id); + eventTopic = query.uniqueResultOptional(); + + s.getTransaction().commit(); + s.close(); + } + return eventTopic; + } + + private Query prepareQueryGet(Session s, long id) { + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(EventTopic.class); + Root root = criteriaQuery.from(EventTopic.class); + criteriaQuery.where(builder.equal(root.get("id"), id)); + return s.createQuery(criteriaQuery); + } + + @Override + public EventTopic getByName(String name) { + EventTopic eventTopic; + try (Session s = getSession()) { + s.getTransaction().begin(); + + Query query = prepareQueryGetByName(s, name); + eventTopic = query.getSingleResult(); + + s.getTransaction().commit(); + s.close(); + } + return eventTopic; + } + + @Override + public Optional fetchByName(String name) { + Optional eventTopic; + try (Session s = getSession()) { + s.getTransaction().begin(); + + Query query = prepareQueryGetByName(s, name); + eventTopic = query.uniqueResultOptional(); + + s.getTransaction().commit(); + s.close(); + } + return eventTopic; + } + + private Query prepareQueryGetByName(Session s, String name) { + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(EventTopic.class); + Root root = criteriaQuery.from(EventTopic.class); + criteriaQuery.where(builder.equal(root.get("name"), name)); + return s.createQuery(criteriaQuery); + } + + @Override + public EventTopic getByNameAndDeleted(String name, boolean deleted) { + EventTopic eventTopic; + try (Session s = getSession()) { + s.getTransaction().begin(); + + Query query = prepareQueryGetByNameAndDeleted(s, name, deleted); + eventTopic = query.getSingleResult(); + + s.getTransaction().commit(); + s.close(); + } + return eventTopic; + } + + @Override + public Optional fetchByNameAndDeleted(String name, boolean deleted) { + Optional eventTopic; + try (Session s = getSession()) { + s.getTransaction().begin(); + + Query query = prepareQueryGetByNameAndDeleted(s, name, deleted); + eventTopic = query.uniqueResultOptional(); + + s.getTransaction().commit(); + s.close(); + } + return eventTopic; + } + + private Query prepareQueryGetByNameAndDeleted(Session s, String name, boolean deleted) { + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(EventTopic.class); + Root root = criteriaQuery.from(EventTopic.class); + criteriaQuery.where(builder.and( + builder.equal(root.get("name"), name), + builder.equal(root.get("deleted"), deleted) + )); + return s.createQuery(criteriaQuery); + } + + @Override + public EventTopic add(EventTopic eventTopic) { + try (Session s = getSession()) { + s.getTransaction().begin(); + s.persist(eventTopic); + s.getTransaction().commit(); + s.close(); + } + return eventTopic; + } + + @Override + public EventTopic add(String name, String createdBy) { + EventTopic eventTopic = new EventTopic(); + eventTopic.setName(name); + eventTopic.setCreateDate(new Date()); + eventTopic.setCreatedBy(createdBy); + + return add(eventTopic); + } + + @Override + public EventTopic update(EventTopic eventTopic) { + Optional topicOldOpt = fetch(eventTopic.getId()); + return save(eventTopic, topicOldOpt.isPresent()); + } + + @Override + public EventTopic update(long id, String name, String editedBy) { + EventTopic eventTopic = get(id); + fillModel(eventTopic, name, eventTopic.getCreateDate(), eventTopic.getCreatedBy(), new Date(), editedBy); + return save(eventTopic, true); + } + + private void fillModel(EventTopic eventTopic, String name, Date createDate, + String createdBy, Date editDate, String editedBy) { + eventTopic.setName(name); + eventTopic.setCreateDate(createDate); + eventTopic.setCreatedBy(createdBy); + eventTopic.setEditDate(editDate); + eventTopic.setEditedBy(editedBy); + } + + private EventTopic save(EventTopic topic, boolean isExist) { + try (Session s = getSession()) { + s.getTransaction().begin(); + if (isExist) { + s.update(topic); + } else { + s.persist(topic); + } + s.getTransaction().commit(); + s.close(); + } + return topic; + } + + @Override + public void remove(EventTopic eventTopic) { + try (Session s = getSession()) { + s.getTransaction().begin(); + + processRemove(s, eventTopic); + + s.getTransaction().commit(); + s.close(); + } + + } + + private void processRemove(Session s, EventTopic eventTopic) { + permissionService.removeAll(s, eventTopic.getId(), PermissionConstants.TYPE_EVENT_TOPIC); + s.flush(); + systemSubscriptionService.removeByTopic(s, eventTopic.getId()); + s.flush(); + s.delete(EventTopic.class.getName(), eventTopic); + } + + @Override + public void remove(long id) { + try (Session s = getSession()) { + s.getTransaction().begin(); + + EventTopic eventTopic = get(id); + + processRemove(s, eventTopic); + + s.getTransaction().commit(); + s.close(); + } + } + + @Override + public void markAsDeleted(long id, boolean deleted) { + try (Session s = getSession()) { + s.getTransaction().begin(); + + EventTopic eventTopic = get(id); + + systemSubscriptionService.markAsDeletedByTopic(s, eventTopic.getId(), deleted); + s.flush(); + + eventTopic.setDeleted(deleted); + s.update(eventTopic); + + s.getTransaction().commit(); + s.close(); + } + } + + @Override + public int clean() { + List listToDelete = listByDeleted(true); + + listToDelete.forEach(t -> remove(t)); + + return listToDelete.size(); + } + + +} diff --git a/system/core/events/events-impl/src/main/java/ru/entaxy/esb/system/core/events/jpa/impl/SystemSubscriptionServiceImpl.java b/system/core/events/events-impl/src/main/java/ru/entaxy/esb/system/core/events/jpa/impl/SystemSubscriptionServiceImpl.java new file mode 100644 index 00000000..1f0122db --- /dev/null +++ b/system/core/events/events-impl/src/main/java/ru/entaxy/esb/system/core/events/jpa/impl/SystemSubscriptionServiceImpl.java @@ -0,0 +1,339 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-impl + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.jpa.impl; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import ru.entaxy.esb.system.core.events.common.SubscriptionType; +import ru.entaxy.esb.system.core.events.jpa.SystemSubscriptionService; +import ru.entaxy.esb.system.core.events.jpa.entity.EventTopic; +import ru.entaxy.esb.system.core.events.jpa.entity.SystemSubscription; +import ru.entaxy.esb.system.core.permission.common.PermissionConstants; +import ru.entaxy.esb.system.core.permission.jpa.PermissionService; +import ru.entaxy.esb.system.jpa.entity.System; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.Root; +import java.util.List; + +public class SystemSubscriptionServiceImpl implements SystemSubscriptionService { + + private SessionFactory sessionFactory; + private PermissionService permissionService; + + + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public Session getSession() { + return sessionFactory.openSession(); + } + + public PermissionService getPermissionService() { + return permissionService; + } + + public void setPermissionService(PermissionService permissionService) { + this.permissionService = permissionService; + } + + @Override + public List list() { + List list; + + try (Session s = getSession()) { + s.getTransaction().begin(); + + CriteriaQuery cq = s.getCriteriaBuilder().createQuery(SystemSubscription.class); + cq.from(SystemSubscription.class); + list = s.createQuery(cq).getResultList(); + + s.getTransaction().commit(); + s.close(); + } + + return list; + } + + @Override + public List listByDeleted(boolean deleted) { + List list; + + try (Session s = getSession()) { + s.getTransaction().begin(); + + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(SystemSubscription.class); + Root root = criteriaQuery.from(SystemSubscription.class); + criteriaQuery.where(builder.equal(root.get("deleted"), deleted)); + list = s.createQuery(criteriaQuery).getResultList(); + + s.getTransaction().commit(); + s.close(); + } + + return list; + } + + @Override + public SystemSubscription get(long id) { + SystemSubscription systemSubscriptionRegistry; + + try (Session s = getSession()) { + s.getTransaction().begin(); + + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(SystemSubscription.class); + Root root = criteriaQuery.from(SystemSubscription.class); + criteriaQuery.where(builder.equal(root.get("id"), id)); + systemSubscriptionRegistry = s.createQuery(criteriaQuery).getSingleResult(); + + s.getTransaction().commit(); + s.close(); + } + + return systemSubscriptionRegistry; + } + + @Override + public List getBySystem(long systemId) { + List list; + + try (Session s = getSession()) { + s.getTransaction().begin(); + + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(SystemSubscription.class); + Root root = criteriaQuery.from(SystemSubscription.class); + Join systemJoin = root.join("system"); + criteriaQuery.where(builder.equal(systemJoin.get("id"), systemId)); + list = s.createQuery(criteriaQuery).getResultList(); + + s.getTransaction().commit(); + s.close(); + } + + return list; + } + + @Override + public SystemSubscription getBySystemAndTopic(long systemId, long eventTopicId) { + SystemSubscription systemSubscriptionRegistry; + + try (Session s = getSession()) { + s.getTransaction().begin(); + + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(SystemSubscription.class); + Root root = criteriaQuery.from(SystemSubscription.class); + Join systemJoin = root.join("system"); + Join eventTopicJoin = root.join("eventTopic"); + criteriaQuery.where(builder.and( + builder.equal(systemJoin.get("id"), systemId), + builder.equal(eventTopicJoin.get("id"), eventTopicId))); + systemSubscriptionRegistry = s.createQuery(criteriaQuery).getSingleResult(); + + s.getTransaction().commit(); + s.close(); + } + + return systemSubscriptionRegistry; + } + + @Override + public List getByTopic(long eventTopicId) { + List list; + + try (Session s = getSession()) { + s.getTransaction().begin(); + + list = getByTopic(s, eventTopicId); + + s.getTransaction().commit(); + s.close(); + } + + return list; + } + + @Override + public List getByTopic(Session s, long eventTopicId) { + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(SystemSubscription.class); + Root root = criteriaQuery.from(SystemSubscription.class); + Join eventTopicJoin = root.join("eventTopic"); + criteriaQuery.where(builder.equal(eventTopicJoin.get("id"), eventTopicId)); + return s.createQuery(criteriaQuery).getResultList(); + } + + @Override + public List getByTopicAndType(long eventTopicId, SubscriptionType type) { + List list; + + try (Session s = getSession()) { + s.getTransaction().begin(); + + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(SystemSubscription.class); + Root root = criteriaQuery.from(SystemSubscription.class); + Join eventTopicJoin = root.join("eventTopic"); + criteriaQuery.where(builder.and( + builder.equal(root.get("type"), type), + builder.equal(eventTopicJoin.get("id"), eventTopicId))); + list = s.createQuery(criteriaQuery).getResultList(); + + s.getTransaction().commit(); + s.close(); + } + + return list; + } + + @Override + public List getByType(SubscriptionType type) { + List list; + + try (Session s = getSession()) { + s.getTransaction().begin(); + + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(SystemSubscription.class); + Root root = criteriaQuery.from(SystemSubscription.class); + criteriaQuery.where(builder.equal(root.get("type"), type)); + list = s.createQuery(criteriaQuery).getResultList(); + + s.getTransaction().commit(); + s.close(); + } + + return list; + } + + @Override + public SystemSubscription add(SystemSubscription systemSubscriptionRegistry) throws IllegalAccessException { + try (Session s = getSession()) { + s.getTransaction().begin(); + if (!permissionService.existByAllParameters( + systemSubscriptionRegistry.getEventTopic().getId(), + PermissionConstants.TYPE_EVENT_TOPIC, + String.valueOf(systemSubscriptionRegistry.getSystem().getId()), + PermissionConstants.TYPE_SYSTEM, + PermissionConstants.ACTION_SUBSCRIBE)) { + throw new IllegalAccessException("No permission to subscribe"); + } + + s.persist(systemSubscriptionRegistry); + s.getTransaction().commit(); + s.close(); + } + + return systemSubscriptionRegistry; + } + + @Override + public SystemSubscription add(System system, EventTopic eventTopic, SubscriptionType type) throws IllegalAccessException { + SystemSubscription systemSubscriptionRegistry = new SystemSubscription(); + + systemSubscriptionRegistry.setSystem(system); + systemSubscriptionRegistry.setEventTopic(eventTopic); + systemSubscriptionRegistry.setType(type); + + return add(systemSubscriptionRegistry); + } + + @Override + public SystemSubscription update(SystemSubscription systemSubscriptionRegistry) { + try (Session s = getSession()) { + s.getTransaction().begin(); + s.merge(systemSubscriptionRegistry); + s.getTransaction().commit(); + s.close(); + } + + return systemSubscriptionRegistry; + } + + @Override + public void remove(long id) { + try (Session s = getSession()) { + s.getTransaction().begin(); + + SystemSubscription systemSubscriptionRegistry = get(id); + s.delete(SystemSubscription.class.getName(), systemSubscriptionRegistry); + + s.getTransaction().commit(); + s.close(); + } + } + + @Override + public void removeByTopic(long eventTopicId) { + try (Session s = getSession()) { + s.getTransaction().begin(); + removeByTopic(s, eventTopicId); + s.getTransaction().commit(); + s.close(); + } + } + + @Override + public void removeByTopic(Session s, long eventTopicId) { + List subscriptions = getByTopic(s, eventTopicId); + subscriptions.forEach(s::delete); + } + + @Override + public void markAsDeleted(long id, boolean deleted) { + try (Session s = getSession()) { + SystemSubscription systemSubscription = get(id); + s.getTransaction().begin(); + systemSubscription.setDeleted(deleted); + s.update(systemSubscription); + s.getTransaction().commit(); + s.close(); + } + + } + + @Override + public void markAsDeletedByTopic(long eventTopicId, boolean deleted) { + try (Session s = getSession()) { + s.getTransaction().begin(); + markAsDeletedByTopic(s, eventTopicId, deleted); + s.getTransaction().commit(); + s.close(); + } + } + + @Override + public void markAsDeletedByTopic(Session s, long eventTopicId, boolean deleted) { + List subscriptions = getByTopic(s, eventTopicId); + subscriptions.forEach(subscription -> this.markAsDeletedProc(s, subscription, deleted)); + } + + private void markAsDeletedProc(Session s, SystemSubscription subscription, boolean deleted) { + subscription.setDeleted(deleted); + s.update(subscription); + } + +} diff --git a/system/core/events/events-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/system/core/events/events-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 00000000..0556ae6e --- /dev/null +++ b/system/core/events/events-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${body} != null && ${body.size()} > 0 + + ${body} + + + + + ${body} + + + null + + + + + + + + + + + + ${body.get(0)} + + + + + + + + + + + + + + + + + + + + + + + + + + + + javax.persistence.NoResultException + + + + + + + + + diff --git a/system/core/events/events-impl/src/main/resources/hibernate.cfg.xml b/system/core/events/events-impl/src/main/resources/hibernate.cfg.xml new file mode 100644 index 00000000..0a4a1b58 --- /dev/null +++ b/system/core/events/events-impl/src/main/resources/hibernate.cfg.xml @@ -0,0 +1,48 @@ + + + + + + + + + osgi:service/entaxy.esb.storage + validate + + true + + ${hibernate.show_sql} + ${hibernate.format_sql} + + + + + + + + + + + + + diff --git a/system/core/events/events-rest/LICENSE.txt b/system/core/events/events-rest/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/events/events-rest/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/events/events-rest/README.md b/system/core/events/events-rest/README.md new file mode 100644 index 00000000..287cd7e5 --- /dev/null +++ b/system/core/events/events-rest/README.md @@ -0,0 +1,260 @@ +#SYSTEM :: ENTAXY :: CORE :: EVENTS :: REST + +Рутовый контекст сервиса по умолчанию **topic-management**, +при смене контекста требуется перераздать права на данный сервис + +**Методы:** + + - create - создать топик + Запрос: + POST server:9090/topic-management/create + Тело + } + "topicName": "boomNews", + "possibleSubscribers" : ["systemUuid1", "systemUuid2"], + "possiblePublishers" : ["systemUuid3", "systemUuid4"] + } + + Ответ: + Статус 201 + Тело + { + "title": "Topic created", + "topicName": "", + "subscriberErrors": { + "systemNotFound": [ + "" + ] + }, + "publisherErrors": { + "systemNotFound": [] + } + } + + - update - изменить топик (название не меняется, так как на него завязана сама очередь в брокере) + Запрос: + POST server:9090/topic-management/update + Тело + } + "topicName": "boomNews", + "possibleSubscribers" : ["systemUuid1", "systemUuid2"], + "possiblePublishers" : ["systemUuid3", "systemUuid4"] + } + Ответ: + Статус 201 + Тело + { + "title": "Topic updated", + "topicName": "", + "subscriberErrors": { + "systemNotFound": [ + "" + ] + }, + "publisherErrors": { + "systemNotFound": [] + } + } + + - delete - удалить топик, так же удаляется подписки, права и консьюмеры в брокере + Запрос: + POST server:9090/topic-management/delete + Тело + { + "topicName": "boomNews" + } + + Ответ: + Статус 200 + Тело + { + "title": "Topic deleted", + "topicName": "" + } + + - clean - очистить топики и подписки, помеченные на удаление топики и подписки будут окончательно удалены + Запрос: + POST server:9090/topic-management/clean + + Ответ: + Статус 200 + Тело + { + "title": "Cleaned" + } + + - subscribe - подписаться на топик + Запрос: + POST server:9092/topic-subscription/subscribe + Тело + { + "topicName": "boomNews", + "subscriptionType": "PUSH" + } + + Ответ: + Статус 201 + Тело + { + "title": "Subscription created", + "topicName": "", + "systemName": "", + "subscriptionType": "" + } + + Массовая обработка при наличии права manage для данного сервиса. + Запрос: + POST server:9092/topic-subscription/subscribe + Тело + { + "topicName": "boomNews", + "systemUuids": [ + {"systemUuid": "NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN", "subscriptionType": "PUSH"}, + {"systemUuid": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "subscriptionType": "PULL"}, + {"systemUuid": "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY", "subscriptionType": "PULL"} + ] + } + + Ответ: + Статус 200 + Тело + [ + { + "title": "Internal Server Error", + "detail": "System not found NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN", + "reason": "javax.persistence.NoResultException: No entity found for query" + }, + { + "title": "Subscription created", + "topicName": "ooooo111-ff6e-4219-a878-bff120c495f1", + "systemUUID": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "subscriptionType": "PULL" + }, + { + "title": "Forbidden", + "detail": "No permission to subscribe for system YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY" + } + ] + + + + - unsubscribe - отписаться от топика + Запрос: + POST server:9092/topic-subscription/unsubscribe + Тело + { + "topicName": "boomNews" + } + + Ответ: + Статус 200 + Тело + { + "title": "Subscription deleted", + "topicName": "", + "systemName": "" + } + + Массовая обработка при наличии права manage для данного сервиса. + Запрос: + POST server:9092/topic-subscription/unsubscribe + Тело + { + "topicName": "boomNews", + "systemUuids": [ + {"systemUuid": "NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN", "subscriptionType": "PUSH"}, + {"systemUuid": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "subscriptionType": "PULL"}, + {"systemUuid": "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY", "subscriptionType": "PULL"} + ] + } + + Ответ: + Статус 200 + Тело + [ + { + "title": "Internal Server Error", + "detail": "System not found NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN", + "reason": "javax.persistence.NoResultException: No entity found for query" + }, + { + "title": "Subscription deleted", + "topicName": "ooooo111-ff6e-4219-a878-bff120c495f1", + "systemUUID": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" + }, + { + "title": "Subscription not found", + "topicName": "ooooo111-ff6e-4219-a878-bff120c495f1", + "systemUUID": "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY" + } + ] + + - publish - опубликовать событие + Запрос: + POST server:9092/topic-subscription/publish + Тело + { + "topicName": "boomNews", "message": "messageText2" + } + + Ответ: + Статус 200 + Тело + { + "title": "Message published", + "topicName": "" + } + + **Ответ при ошибке** + + - Передан некорректный JSON или логин не определён + Статус 400 + Тело + { + "title": "Incorrect input parameters", + "detail": "Cannot parse incoming JSON or login/system not defined" + } + + - Подписка не найдена + Статус 404 + Тело + { + "title": "Subscription not found", + "topicName": "${exchangeProperty.topicName}", + "systemUUID": "${header.X-SystemUuid}" + } + + - Топик не зарегистрирован + Статус 400 + Тело + { + "title": "Topic not registered", + "topicName": "${exchangeProperty.topicName}" + } + + - Система не найдена + Статус 500 + Тело + { + "title": "Internal Server Error", + "detail": "System not found ${header.X-SystemUuid}", + "reason": "${exception.stacktrace}" + } + + - Неизвестный тип подписки + Статус 500 + Тело + { + "title": "Internal Server Error", + "detail": "Unknown subscription type ${exchangeProperty.subscriptionType}", + "reason": "${exception.stacktrace}" + } + + - Неизвестная ошибка + Статус 500 + Тело + { + "title": "Internal Server Error", + "detail": "Unknown exception", + "reason": "${exception.stacktrace}" + } diff --git a/system/core/events/events-rest/pom.xml b/system/core/events/events-rest/pom.xml new file mode 100644 index 00000000..b5e09aa8 --- /dev/null +++ b/system/core/events/events-rest/pom.xml @@ -0,0 +1,92 @@ + + + + + ru.entaxy.esb.system.core.events + events + 1.8.0 + ../../events/pom.xml + + + 4.0.0 + + events-rest + SYSTEM :: ENTAXY :: CORE :: EVENTS :: REST + bundle + + + + org.apache.cxf.jaxrs.impl, + org.apache.camel.component.cxf.jaxrs.blueprint, + org.apache.camel.component.cxf.blueprint, + ru.entaxy.esb.system.core.permission.handler, + * + + + + + + + org.apache.activemq + artemis-jms-client + ${activemq.version} + provided + + + + ru.entaxy.esb.system.registry.systems + system-api + ${project.version} + provided + + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + + ru.entaxy.esb.system.core.events + events-api + ${project.version} + provided + + + + ru.entaxy.esb.system.auth.basic.api + basic-auth-api + ${project.version} + provided + + + + ru.entaxy.esb.system.core.events + events-common + ${project.version} + provided + + + + ru.entaxy.esb.system.core.permission + permission-api + ${project.version} + provided + + + + ru.entaxy.esb.system.core.permission + permission-common + ${project.version} + provided + + + org.apache.camel + camel-cxf + + + + diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/ManagementService.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/ManagementService.java new file mode 100644 index 00000000..25532a7c --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/ManagementService.java @@ -0,0 +1,64 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest; + +import org.apache.camel.Body; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +@Path("/") +public class ManagementService { + + @POST + @Path("/create") + @Consumes("application/json") + @Produces("application/json") + public String create(@Body String body) { + return null; + } + + @POST + @Path("/update") + @Consumes("application/json") + @Produces("application/json") + public String update(@Body String body) { + return null; + } + + @POST + @Path("/delete") + @Consumes("application/json") + @Produces("application/json") + public String delete(@Body String body) { + return null; + } + + @POST + @Path("/clean") + @Produces("application/json") + public String clean() { + return null; + } + + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/SubscriptionService.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/SubscriptionService.java new file mode 100644 index 00000000..8d9c8876 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/SubscriptionService.java @@ -0,0 +1,56 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest; + +import org.apache.camel.Body; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; + +@Path("/") +public class SubscriptionService { + + @POST + @Path("/subscribe") + @Consumes("application/json") + @Produces("application/json") + public String subscribe(@Body String body) { + return null; + } + + @POST + @Path("/unsubscribe") + @Consumes("application/json") + @Produces("application/json") + public String unsubscribe(@Body String body) { + return null; + } + + @POST + @Path("/publish") + @Consumes("application/json") + @Produces("application/json") + public String publish(@Body String body) { + return null; + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/TopicProcessor.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/TopicProcessor.java new file mode 100644 index 00000000..3fcbff7f --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/TopicProcessor.java @@ -0,0 +1,389 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest; + +import org.hibernate.exception.ConstraintViolationException; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.system.common.osgi.OSGIUtils; +import ru.entaxy.esb.system.core.events.common.SubscriptionType; +import ru.entaxy.esb.system.core.events.jpa.EventTopicService; +import ru.entaxy.esb.system.core.events.jpa.SystemSubscriptionService; +import ru.entaxy.esb.system.core.events.jpa.entity.EventTopic; +import ru.entaxy.esb.system.core.events.jpa.entity.SystemSubscription; +import ru.entaxy.esb.system.core.events.rest.exception.*; +import ru.entaxy.esb.system.core.events.rest.response.CreateTopicResponse; +import ru.entaxy.esb.system.core.permission.common.PermissionConstants; +import ru.entaxy.esb.system.core.permission.jpa.PermissionService; +import ru.entaxy.esb.system.core.permission.jpa.entity.Permission; +import ru.entaxy.esb.system.jpa.SystemService; +import ru.entaxy.esb.system.jpa.entity.System; + +import javax.persistence.NoResultException; +import javax.persistence.PersistenceException; +import javax.ws.rs.ForbiddenException; +import java.util.*; +import java.util.stream.Collectors; + +public class TopicProcessor { + + private static final Logger LOG = LoggerFactory.getLogger(TopicProcessor.class); + + private SystemService systemService; + private SystemSubscriptionService systemSubscriptionService; + private EventTopicService eventTopicService; + private PermissionService permissionService; + + public CreateTopicResponse registerTopic(String login, String topicName, + List possibleSubscribers, List possiblePublishers) throws TopicAlreadyExist { + CreateTopicResponse response = null; + + try { + Optional topicOpt = getEventTopicService().fetchByName(topicName); + boolean restoring = false; + EventTopic topic = null; + if (topicOpt.isPresent()) { + topic = topicOpt.get(); + if (topic.isDeleted()) { + //restore + restoring = true; + getEventTopicService().markAsDeleted(topic.getId(), false); + } else { + throw new TopicAlreadyExist(); + } + } else { + topic = getEventTopicService().add(topicName, login); + } + + Map> subscriberErrors = registerSystemsPermission(topic, possibleSubscribers, PermissionConstants.ACTION_SUBSCRIBE); + + Map> publisherErrors = registerSystemsPermission(topic, possiblePublishers, PermissionConstants.ACTION_PUBLISH); + + response = new CreateTopicResponse(); + response.setTitle(restoring ? "Topic restored" : "Topic created"); + response.setTopicName(topic.getName()); + response.setSubscriberErrors(subscriberErrors); + response.setPublisherErrors(publisherErrors); + +// if (restoring) { +// throw new TopicDeletedStateException(); +// } + + } catch (PersistenceException e) { + if (e.getCause() instanceof ConstraintViolationException) { + throw new TopicAlreadyExist(e); + } + } + + return response; + } + + public CreateTopicResponse updateTopic(String login, String topicName, + List possibleSubscribers, List possiblePublishers) throws TopicNotFound { + CreateTopicResponse response = null; + try { + EventTopic topic = getEventTopicService().getByName(topicName); + + topic = getEventTopicService().update(topic.getId(), topic.getName(), login); + + Map> subscriberErrors = registerSystemsPermission( + topic, + possibleSubscribers, + PermissionConstants.ACTION_SUBSCRIBE); + + Map> publisherErrors = registerSystemsPermission( + topic, + possiblePublishers, + PermissionConstants.ACTION_PUBLISH); + + response = new CreateTopicResponse(); + response.setTitle(topic.isDeleted() ? "Topic restored" : "Topic updated"); + response.setTopicName(topic.getName()); + response.setSubscriberErrors(subscriberErrors); + response.setPublisherErrors(publisherErrors); + + if (topic.isDeleted()) { + getEventTopicService().markAsDeleted(topic.getId(), false); + } + + } catch (NoResultException e) { + LOG.error("Topic not found", e); + throw new TopicNotFound(e); + } + + return response; + } + + private Map> registerSystemsPermission(EventTopic topic, List systemUuids, String action) { + Map> errorHolder = new HashMap<>(); + + if (systemUuids != null && !systemUuids.isEmpty()) { + List notFoundSystems = new ArrayList<>(); + Map passedSystemMap = new HashMap<>(); + + for (String uuid : systemUuids) { + try { + System system = getSystemService().getByUuid(uuid); + LOG.debug("System " + uuid + " " + (system != null ? system.getName() : "null") + " for " + action); + passedSystemMap.put(system.getId(), system); + } catch (NoResultException e) { + LOG.error(e.getMessage() + " system uuid=" + uuid); + notFoundSystems.add(uuid); + } + } + + List passedSystemIds = new ArrayList(passedSystemMap.keySet()); + + List> systemSubjectsToAdd = new ArrayList<>(); + List permissionToDelete = new ArrayList<>(); + + List permissionsOld = getPermissionService().get(topic.getId(), PermissionConstants.TYPE_EVENT_TOPIC, action); + if (permissionsOld != null && !permissionsOld.isEmpty()) { + for (Permission permission : permissionsOld) { + if (PermissionConstants.TYPE_SYSTEM.equals(permission.getSubjectType()) + && !passedSystemIds.contains(Long.valueOf(permission.getSubjectId()))) { + permissionToDelete.add(permission); + } + } + List currentSystemIdsWithPermission = permissionsOld.stream() + .map(p -> Long.valueOf(p.getSubjectId())) + .collect(Collectors.toList()); + + for (long systemId : passedSystemIds) { + if (!currentSystemIdsWithPermission.contains(systemId)) { + systemSubjectsToAdd.add(Arrays.asList(String.valueOf(systemId), PermissionConstants.TYPE_SYSTEM, action)); + } + } + + } else { + for (long systemId : passedSystemMap.keySet()) { + systemSubjectsToAdd.add(Arrays.asList(String.valueOf(systemId), PermissionConstants.TYPE_SYSTEM, action)); + } + } + + //Add new permissions + List permissions = getPermissionService().addAll(topic.getId(), PermissionConstants.TYPE_EVENT_TOPIC, systemSubjectsToAdd); + + //Delete old permissions + for (Permission permission : permissionToDelete) { + getPermissionService().remove(permission.getId()); + } + + +// List systemsWithPermission = permissions.stream() +// .map(p ->Long.valueOf(p.getSubjectId())) +// .collect(Collectors.toList()); +// List systemsWithoutPermission = passedSystemMap.entrySet().stream() +// .filter(e -> !systemsWithPermission.contains(e.getKey())) +// .map(e -> e.getValue().getUuid()) +// .collect(Collectors.toList()); + if (!notFoundSystems.isEmpty()) { + errorHolder.put("systemNotFound", notFoundSystems); + } +// errorHolder.put("permissionCreateSystemError", systemsWithoutPermission); + } else { + //if not passed remove all permission for current object action + getPermissionService().remove(topic.getId(), PermissionConstants.TYPE_EVENT_TOPIC, action); + } + + return errorHolder; + } + + public void restoreTopic() { + + } + + public void deleteTopic(String topicName) throws TopicNotFound { + EventTopic topic = null; + try { + topic = getEventTopicService().getByNameAndDeleted(topicName, false); + } catch (NoResultException e) { + LOG.error("Topic not found", e); + throw new TopicNotFound(e); + } + + getEventTopicService().markAsDeleted(topic.getId(), true); + + } + + public SystemSubscription getExistingSubscription(String systemUUID, String topicName) throws Exception { + System System = null; + try { + System = getSystemService().getByUuid(systemUUID); + } catch (NoResultException e) { + LOG.error("System not found", e); + throw new SystemNotFound(e); + } + + EventTopic topic = getActualTopic(topicName); + + SystemSubscription systemSubscription = null; + try { + systemSubscription = getSystemSubscriptionService() + .getBySystemAndTopic(System.getId(), topic.getId()); + } catch (NoResultException e) { + /* keep silence */ + } + + return systemSubscription; + } + + public SystemSubscription subscribe(String systemUUID, String topicName, String subscriptionType) throws Exception { + SubscriptionType type = null; + try { + type = SubscriptionType.valueOf(subscriptionType.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new UnknownSubscriptionType(e); + } + + System system = null; + try { + system = getSystemService().getByUuid(systemUUID); + } catch (NoResultException e) { + LOG.error("System not found", e); + throw new SystemNotFound(e); + } + + try { + EventTopic topic = getEventTopicService().getByNameAndDeleted(topicName, false); + + return registerConsumer(topic, system, type); + } catch (NoResultException e) { + LOG.error("Topic not found", e); + throw new TopicNotFound(e); + } catch (IllegalAccessException e) { + LOG.error("No permission to subscribe", e); + throw new ForbiddenException(e); + } + } + + public void restoreSubscription(SystemSubscription subscription) { + getSystemSubscriptionService().markAsDeleted(subscription.getId(), false); + } + + private SystemSubscription registerConsumer(EventTopic topic, System system, SubscriptionType type) throws Exception { + SystemSubscription systemSubscription = null; + try { + systemSubscription = getSystemSubscriptionService() + .getBySystemAndTopic(system.getId(), topic.getId()); + } catch (NoResultException e) { + /* keep silence */ + } + if (systemSubscription != null) { + if (!systemSubscription.getType().equals(type)) { + systemSubscription.setType(type); + getSystemSubscriptionService().update(systemSubscription); +// throw new SubscriptionTypeModificationException(); + } + } else { + systemSubscription = getSystemSubscriptionService().add(system, topic, + type); + } + + return systemSubscription; + } + + public SystemSubscription unsubscribe(String systemUUID, String topicName) throws Exception { + System system = null; + try { + system = getSystemService().getByUuid(systemUUID); + } catch (NoResultException e) { + LOG.error("System not found " + systemUUID, e); + throw new SystemNotFound(e); + } + + EventTopic topic = getActualTopic(topicName); + + if (system != null && topic != null) { + try { + SystemSubscription systemSubscription = getSystemSubscriptionService() + .getBySystemAndTopic(system.getId(), topic.getId()); + getSystemSubscriptionService().markAsDeleted(systemSubscription.getId(), true); + + return systemSubscription; + } catch (NoResultException e) { + LOG.warn("Subscription not found for system=" + systemUUID + " topic=" + topicName, e); + throw new SubscriptionNotFound(); + } + } + + return null; + } + + public EventTopic getTopic(String topicName) throws TopicNotFound { + try { + return getEventTopicService().getByName(topicName); + } catch (NoResultException e) { + LOG.error("Topic not found", e); + throw new TopicNotFound(e); + } + } + + public EventTopic getActualTopic(String topicName) throws TopicNotFound { + try { + return getEventTopicService().getByNameAndDeleted(topicName, false); + } catch (NoResultException e) { + LOG.error("Topic not found", e); + throw new TopicNotFound(e); + } + } + + public List getTopicSubscriptions(EventTopic topic) throws TopicNotFound { + return getSystemSubscriptionService().getByTopic(topic.getId()); + } + + public SystemService getSystemService() { + if (systemService == null) { + systemService = (SystemService) OSGIUtils.getServiceReference( + FrameworkUtil.getBundle(TopicProcessor.class).getBundleContext(), + SystemService.class.getName()); + } + return systemService; + } + + public SystemSubscriptionService getSystemSubscriptionService() { + if (systemSubscriptionService == null) { + systemSubscriptionService = (SystemSubscriptionService) OSGIUtils.getServiceReference( + FrameworkUtil.getBundle(TopicProcessor.class).getBundleContext(), + SystemSubscriptionService.class.getName()); + } + return systemSubscriptionService; + } + + public EventTopicService getEventTopicService() { + if (eventTopicService == null) { + eventTopicService = (EventTopicService) OSGIUtils.getServiceReference( + FrameworkUtil.getBundle(TopicProcessor.class).getBundleContext(), + EventTopicService.class.getName()); + } + return eventTopicService; + } + + public PermissionService getPermissionService() { + if (permissionService == null) { + permissionService = (PermissionService) OSGIUtils.getServiceReference( + FrameworkUtil.getBundle(TopicProcessor.class).getBundleContext(), + PermissionService.class.getName()); + } + return permissionService; + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/aggregation/ResponseAggregator.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/aggregation/ResponseAggregator.java new file mode 100644 index 00000000..ff841df8 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/aggregation/ResponseAggregator.java @@ -0,0 +1,50 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.aggregation; + +import org.apache.camel.AggregationStrategy; +import org.apache.camel.Exchange; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResponseAggregator implements AggregationStrategy { + + private static final Logger LOG = LoggerFactory.getLogger(ResponseAggregator.class); + + @Override + public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { + LOG.debug("oldExchange " + (oldExchange != null)); + LOG.debug("newExchange " + (newExchange != null)); + + if (oldExchange == null) { + oldExchange = newExchange; + oldExchange.getIn().setBody("[" + oldExchange.getIn().getBody(String.class)); + } else if (newExchange != null) { + String oldBody = oldExchange.getIn().getBody(String.class); + String newBody = newExchange.getIn().getBody(String.class); + oldExchange.getIn().setBody(oldBody + "," + newBody); + } + if (newExchange.getProperty("CamelSplitComplete", Boolean.class)) { + oldExchange.getIn().setBody(oldExchange.getIn().getBody(String.class) + "]"); + } + return oldExchange; + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/SubscriptionNotFound.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/SubscriptionNotFound.java new file mode 100644 index 00000000..724dd7a2 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/SubscriptionNotFound.java @@ -0,0 +1,47 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.exception; + +public class SubscriptionNotFound extends Exception { + + private static final long serialVersionUID = 1438059417921228582L; + + public SubscriptionNotFound() { + super(); + } + + public SubscriptionNotFound(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public SubscriptionNotFound(String message, Throwable cause) { + super(message, cause); + } + + public SubscriptionNotFound(String message) { + super(message); + } + + public SubscriptionNotFound(Throwable cause) { + super(cause); + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/SubscriptionTypeModificationException.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/SubscriptionTypeModificationException.java new file mode 100644 index 00000000..7ad874a9 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/SubscriptionTypeModificationException.java @@ -0,0 +1,47 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.exception; + +public class SubscriptionTypeModificationException extends Exception { + + private static final long serialVersionUID = -1621510117561995906L; + + public SubscriptionTypeModificationException() { + super(); + } + + public SubscriptionTypeModificationException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public SubscriptionTypeModificationException(String message, Throwable cause) { + super(message, cause); + } + + public SubscriptionTypeModificationException(String message) { + super(message); + } + + public SubscriptionTypeModificationException(Throwable cause) { + super(cause); + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/SystemNotFound.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/SystemNotFound.java new file mode 100644 index 00000000..33a32a34 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/SystemNotFound.java @@ -0,0 +1,46 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.exception; + +public class SystemNotFound extends Exception { + + private static final long serialVersionUID = -5204253149870905318L; + + public SystemNotFound() { + super(); + } + + public SystemNotFound(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public SystemNotFound(String message, Throwable cause) { + super(message, cause); + } + + public SystemNotFound(String message) { + super(message); + } + + public SystemNotFound(Throwable cause) { + super(cause); + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/TopicAlreadyExist.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/TopicAlreadyExist.java new file mode 100644 index 00000000..97a57b70 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/TopicAlreadyExist.java @@ -0,0 +1,46 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.exception; + +public class TopicAlreadyExist extends Exception { + + private static final long serialVersionUID = -2731202383081783015L; + + public TopicAlreadyExist() { + super(); + } + + public TopicAlreadyExist(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public TopicAlreadyExist(String message, Throwable cause) { + super(message, cause); + } + + public TopicAlreadyExist(String message) { + super(message); + } + + public TopicAlreadyExist(Throwable cause) { + super(cause); + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/TopicNotFound.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/TopicNotFound.java new file mode 100644 index 00000000..cd682579 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/TopicNotFound.java @@ -0,0 +1,46 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.exception; + +public class TopicNotFound extends Exception { + + private static final long serialVersionUID = 5093239116981997713L; + + public TopicNotFound() { + super(); + } + + public TopicNotFound(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public TopicNotFound(String message, Throwable cause) { + super(message, cause); + } + + public TopicNotFound(String message) { + super(message); + } + + public TopicNotFound(Throwable cause) { + super(cause); + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/UnknownSubscriptionType.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/UnknownSubscriptionType.java new file mode 100644 index 00000000..ea515ab5 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/exception/UnknownSubscriptionType.java @@ -0,0 +1,47 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.exception; + +public class UnknownSubscriptionType extends Exception { + + private static final long serialVersionUID = 5233193990834603868L; + + public UnknownSubscriptionType() { + super(); + } + + public UnknownSubscriptionType(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public UnknownSubscriptionType(String message, Throwable cause) { + super(message, cause); + } + + public UnknownSubscriptionType(String message) { + super(message); + } + + public UnknownSubscriptionType(Throwable cause) { + super(cause); + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/CleanResponse.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/CleanResponse.java new file mode 100644 index 00000000..c9a96ac4 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/CleanResponse.java @@ -0,0 +1,42 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.response; + +public class CleanResponse extends Response { + + private int topicDeleted; + + public int getTopicDeleted() { + return topicDeleted; + } + + public void setTopicDeleted(int topicDeleted) { + this.topicDeleted = topicDeleted; + } + + public static CleanResponse getInstance(String title, int topicDeleted) { + CleanResponse response = new CleanResponse(); + + response.setTitle(title); + response.setTopicDeleted(topicDeleted); + + return response; + } +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/CreateTopicResponse.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/CreateTopicResponse.java new file mode 100644 index 00000000..87b88e29 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/CreateTopicResponse.java @@ -0,0 +1,58 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.response; + +import java.util.List; +import java.util.Map; + +public class CreateTopicResponse extends JsonSuccessResponse { + + private Map> subscriberErrors; + private Map> publisherErrors; + + public Map> getSubscriberErrors() { + return subscriberErrors; + } + + public void setSubscriberErrors(Map> subscriberErrors) { + this.subscriberErrors = subscriberErrors; + } + + public Map> getPublisherErrors() { + return publisherErrors; + } + + public void setPublisherErrors(Map> publisherErrors) { + this.publisherErrors = publisherErrors; + } + + public static CreateTopicResponse getInstance(String title, String topicName, + Map> subscriberErrors, Map> publisherErrors) { + CreateTopicResponse response = new CreateTopicResponse(); + + response.setTitle(title); + response.setTopicName(topicName); + response.setSubscriberErrors(subscriberErrors); + response.setPublisherErrors(publisherErrors); + + return response; + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/JsonErrorResponse.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/JsonErrorResponse.java new file mode 100644 index 00000000..e97f63b0 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/JsonErrorResponse.java @@ -0,0 +1,51 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.response; + +public class JsonErrorResponse extends Response { + + private String detail; + private String reason; + + public String getDetail() { + return detail; + } + + public void setDetail(String detail) { + this.detail = detail; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public static JsonErrorResponse getInstance(String title, String detail, String reason) { + JsonErrorResponse response = new JsonErrorResponse(); + response.setTitle(title); + response.setDetail(detail); + response.setReason(reason); + + return response; + } +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/JsonSuccessResponse.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/JsonSuccessResponse.java new file mode 100644 index 00000000..14f970cc --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/JsonSuccessResponse.java @@ -0,0 +1,42 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.response; + +public class JsonSuccessResponse extends Response { + + private String topicName; + + public String getTopicName() { + return topicName; + } + + public void setTopicName(String topicName) { + this.topicName = topicName; + } + + public static JsonSuccessResponse getInstance(String title, String topicName) { + JsonSuccessResponse response = new JsonSuccessResponse(); + response.setTitle(title); + response.setTopicName(topicName); + + return response; + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/Response.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/Response.java new file mode 100644 index 00000000..bab62b94 --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/Response.java @@ -0,0 +1,34 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.response; + +public abstract class Response { + + private String title; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + +} diff --git a/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/SubscriptionResponse.java b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/SubscriptionResponse.java new file mode 100644 index 00000000..d24cd8ce --- /dev/null +++ b/system/core/events/events-rest/src/main/java/ru/entaxy/esb/system/core/events/rest/response/SubscriptionResponse.java @@ -0,0 +1,52 @@ +/*- + * ~~~~~~licensing~~~~~~ + * events-rest + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.events.rest.response; + +public class SubscriptionResponse extends JsonSuccessResponse { + + private String systemUUID; + private String subscriptionType; + + public String getSystemUUID() { + return systemUUID; + } + + public void setSystemUUID(String systemUUID) { + this.systemUUID = systemUUID; + } + + public String getSubscriptionType() { + return subscriptionType; + } + + public void setSubscriptionType(String subscriptionType) { + this.subscriptionType = subscriptionType; + } + + public static SubscriptionResponse getInstance(String title, String topicName, String systemUUID, String subscriptionType) { + SubscriptionResponse response = new SubscriptionResponse(); + response.setTitle(title); + response.setTopicName(topicName); + response.setSystemUUID(systemUUID); + response.setSubscriptionType(subscriptionType); + + return response; + } +} diff --git a/system/core/events/events-rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/system/core/events/events-rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 00000000..ba279cb4 --- /dev/null +++ b/system/core/events/events-rest/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,894 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $.topicName + + + $.possibleSubscribers + + + $.possiblePublishers + + + org.apache.camel.ExpressionEvaluationException + + + + + + + ${exchangeProperty.topicName} != null && ${exchangeProperty.topicName} != "" + && ${header.X-ForwardedUser} != null && ${header.X-ForwardedUser} != "" + + + + + + + + ${exchangeProperty.DELETED} + + + + 200 + + + + + ${body} + + + + null + + + + + ${exchangeProperty.BODY_HOLDER} + + + 201 + + + + + + + + + + ru.entaxy.esb.system.core.events.rest.exception.TopicAlreadyExist + + { "title": "Topic already exists", "topicName": "${exchangeProperty.topicName}" + } + + + + 200 + + + + java.lang.Exception + + + { "title": "Internal Server Error", "detail": "Unknown exception", "reason": + "${exception.message}" } + + + + 500 + + + + + + + + + { "title": "Incorrect input parameters", "detail": "Cannot parse incoming JSON or login + not defined" } + + + + 400 + + + + + + + + + + + + + ${body.deleted} + + + + java.lang.Exception + + + + + + + + + + + + $.topicName + + + $.possibleSubscribers + + + $.possiblePublishers + + + org.apache.camel.ExpressionEvaluationException + + + + + + + ${exchangeProperty.topicName} != null && ${exchangeProperty.topicName} != "" + && ${header.X-ForwardedUser} != null && ${header.X-ForwardedUser} != "" + + + + + + + + ${body.deleted} + + + + + + ${exchangeProperty.DELETED} + + + + + + + + 200 + + + + java.lang.Exception + + + { "title": "Internal Server Error", "detail": "Unknown exception", "reason": + "${exception.message}" } + + + + 500 + + + + + + + + + { "title": "Incorrect input parameters", "detail": "Cannot parse incoming JSON or login + not defined" } + + + + 400 + + + + + + + + + + ${body} + + + + + + + + + ${exchangeProperty.BODY_HOLDER} + + + + + + + + + $.topicName + + + org.apache.camel.ExpressionEvaluationException + + + + + + + ${exchangeProperty.topicName} != null && ${exchangeProperty.topicName} != "" + && ${header.X-ForwardedUser} != null && ${header.X-ForwardedUser} != "" + + + + + + + + + + + + + + + + + + 200 + + + + ru.entaxy.esb.system.core.events.rest.exception.TopicNotFound + + { "title": "Topic not registered", "topicName": "${exchangeProperty.topicName}" + } + + + + 400 + + + + java.lang.Exception + + + { "title": "Internal Server Error", "detail": "Unknown exception", "reason": + "${exception.message}" } + + + + 500 + + + + + + + + + { "title": "Incorrect input parameters", "detail": "Cannot parse incoming JSON or login + not defined" } + + + + 400 + + + + + + + + + + + + + + + + + + + java.lang.Exception + + + { "title": "Internal Server Error", "detail": "Unknown exception", "reason": + "${exception.message}" } + + + + 500 + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + false + + + + + + + + + + + $.systemUuids + + + org.apache.camel.ExpressionEvaluationException + + + + + + $.topicName + + + org.apache.camel.ExpressionEvaluationException + + + + + + + ${exchangeProperty.systemUuids} != null && ${exchangeProperty.systemUuids} != "" + + + + {{service.root.path.subscription}} + + + ${exchangeProperty.serviceName.substring(1)} + + + + + + + bean-fix:permissionChecker?method=check(${headers.X-ForwardedUserId}, 'account', + ${exchangeProperty.serviceName}, 'service', 'manage') + + + + + + + + ${exchangeProperty.permissionCheck} + + + $.systemUuids + + + + + $.systemUuid + + + $.subscriptionType + + + org.apache.camel.ExpressionEvaluationException + + + + + + + + + 200 + + + + + + + + { "title": "Forbidden", "detail": "No MANAGE permission" } + + + 403 + + + + + + + + + + $.subscriptionType + + + org.apache.camel.ExpressionEvaluationException + + + + + + + + + + + + + + + ${exchangeProperty.topicName} != null && ${exchangeProperty.topicName} != "" + && ${header.X-SystemUuid} != null && ${header.X-SystemUuid} != "" + + + + + + + ${exchangeProperty.subscribe} + + + + + + + Subscription created + + + + ${exchangeProperty.ALREADY_EXIST} == false + + + + + ${exchangeProperty.DELETED} + + + + + Subscription restored + + + + + + + + + + + 201 + + + + + + + + + + + + + + 200 + + + + + + ru.entaxy.esb.system.core.events.rest.exception.SubscriptionNotFound + + { "title": "Subscription not found", "topicName": + "${exchangeProperty.topicName}", "systemUUID": "${header.X-SystemUuid}" } + + + + 404 + + + + ru.entaxy.esb.system.core.events.rest.exception.TopicNotFound + + { "title": "Topic not registered", "topicName": "${exchangeProperty.topicName}" + } + + + + 400 + + + + ru.entaxy.esb.system.core.events.rest.exception.SystemNotFound + + + { "title": "Internal Server Error", "detail": "System not found + ${header.X-SystemUuid}", "reason": "${exception.message}" } + + + + 500 + + + + ru.entaxy.esb.system.core.events.rest.exception.UnknownSubscriptionType + + + + { "title": "Internal Server Error", "detail": "Unknown subscription type + ${exchangeProperty.subscriptionType}", "reason": "${exception.message}" } + + + + 500 + + + + javax.ws.rs.ForbiddenException + + + { "title": "Forbidden", "detail": "No permission to subscribe for system + ${header.X-SystemUuid}" } + + + + 403 + + + + java.lang.Exception + + + { "title": "Internal Server Error", "detail": "Unknown exception", "reason": + "${exception.message}" } + + + + 500 + + + + + + + + { "title": "Incorrect input parameters", "detail": "Cannot parse incoming JSON or system + not defined" } + + + + 400 + + + + + + + + + + + false + + + ${body} != null && ${exchangeProperty.subscriptionType} != null + + + ${body.getType().equalsName(${exchangeProperty.subscriptionType})} == false + + + + + true + + + + + + + ${body} != null + + ${body.deleted} + + + + + + + + + + + + + $.topicName + + + $.message + + + org.apache.camel.ExpressionEvaluationException + + + + + + + ${exchangeProperty.topicName} != null && ${exchangeProperty.topicName} != "" + && ${exchangeProperty.message} != null && ${exchangeProperty.message} != "" + && ${header.X-SystemUuid} != null && ${header.X-SystemUuid} != "" + + + + + + + + + + + ${header.X-SystemName} + + + system.name + + + + ${exchangeProperty.message} + + + + + + + + + + + + + 200 + + + + ru.entaxy.esb.system.core.events.rest.exception.TopicNotFound + + { "title": "Topic not registered", "topicName": "${exchangeProperty.topicName}" + } + + + + 400 + + + + java.lang.IllegalAccessException + + + { "title": "Forbidden", "detail": "No permission to publishing" } + + + 403 + + + + java.lang.Exception + + + { "title": "Internal Server Error", "detail": "Unknown exception", "reason": + "${exception.message}" } + + + + 500 + + + + + + + + + { "title": "Incorrect input parameters", "detail": "Cannot parse incoming JSON or system + not defined" } + + + + 400 + + + + + + + + diff --git a/system/core/events/pom.xml b/system/core/events/pom.xml new file mode 100644 index 00000000..bff2d47c --- /dev/null +++ b/system/core/events/pom.xml @@ -0,0 +1,28 @@ + + + + 4.0.0 + + + ru.entaxy.esb.system.core + system-core + 1.8.0 + ../../core/pom.xml + + + ru.entaxy.esb.system.core.events + events + SYSTEM :: ENTAXY :: CORE :: EVENTS + pom + + + events-rest + events-api + events-impl + events-handler + events-common + + + \ No newline at end of file diff --git a/system/core/pom.xml b/system/core/pom.xml new file mode 100644 index 00000000..dc0c30ee --- /dev/null +++ b/system/core/pom.xml @@ -0,0 +1,30 @@ + + + + 4.0.0 + + + ru.entaxy.esb.system + system-parent + 1.8.0 + + + ru.entaxy.esb.system.core + system-core + pom + + SYSTEM :: ENTAXY :: CORE + SYSTEM :: ENTAXY :: CORE + + + events + dispatcher + template + security + error-handler + + + + diff --git a/system/core/security/LICENSE.txt b/system/core/security/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/security/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/security/README.md b/system/core/security/README.md new file mode 100644 index 00000000..ca5424e0 --- /dev/null +++ b/system/core/security/README.md @@ -0,0 +1,16 @@ +# SYSTEM :: ENTAXY :: CORE :: PERMISSION + +**Модули:** + + - permission-api + интерфейс hibernate сервиса и модель Permission + - permission-common + общий модуль, содержит константы Permission + - permission-component + camel компонент для управления и проверки Permission + - permission-handler + osgi сервис для проверки Permission + - permission-impl + реализация hibernate сервисов, интерцептор для проверки права доступа в сервис + - permission-soap + soap сервис для управления и проверки Permission \ No newline at end of file diff --git a/system/core/security/permission-api/LICENSE.txt b/system/core/security/permission-api/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/security/permission-api/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/security/permission-api/pom.xml b/system/core/security/permission-api/pom.xml new file mode 100644 index 00000000..afde4398 --- /dev/null +++ b/system/core/security/permission-api/pom.xml @@ -0,0 +1,55 @@ + + + + + ru.entaxy.esb.system.core.permission + permission + 1.8.0 + ../../security/pom.xml + + + 4.0.0 + + permission-api + SYSTEM :: ENTAXY :: CORE :: PERMISSION :: API + bundle + + + + ru.entaxy.esb.system.core.permission.jpa, + ru.entaxy.esb.system.core.permission.jpa.entity + + + javax.persistence;version="[2,3)", + org.hibernate.proxy, + javassist.util.proxy, + * + + + + + + org.eclipse.persistence + javax.persistence + ${jpa.version} + + + org.hibernate + hibernate-envers + ${hibernate.version} + + + + ru.entaxy.esb.system.core.permission + permission-common + ${project.version} + provided + + + com.sun.xml.bind + jaxb-core + + + diff --git a/system/core/security/permission-api/src/main/java/ru/entaxy/esb/system/core/permission/jpa/PermissionService.java b/system/core/security/permission-api/src/main/java/ru/entaxy/esb/system/core/permission/jpa/PermissionService.java new file mode 100644 index 00000000..5dc18103 --- /dev/null +++ b/system/core/security/permission-api/src/main/java/ru/entaxy/esb/system/core/permission/jpa/PermissionService.java @@ -0,0 +1,89 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.jpa; + +import org.hibernate.Session; +import ru.entaxy.esb.system.core.permission.jpa.entity.Permission; + +import java.util.List; +import java.util.Optional; + +public interface PermissionService { + + List list(); + + Permission get(long id); + + List getAllById(long id, String type); + + List getAllById(Session s, long id, String type); + + Optional fetch(long id); + + List get(long objectId, String objectType, String action); + + List get(Session session, long objectId, String objectType, String action); + + Permission getByAllParameters(long objectId, String objectType, String subjectId, String subjectType, String action); + + Permission getByAllParameters(Session session, long objectId, String objectType, String subjectId, String subjectType, String action); + + Optional fetchByAllParameters(long objectId, String objectType, String subjectId, String subjectType, String action); + + boolean existByAllParameters(long objectId, String objectType, String subjectId, String subjectType, String action); + + Permission add(Permission permission); + + Permission addIfNotExist(long objectId, String objectType, String subjectId, String subjectType, String action); + + Permission add(long objectId, String objectType, String subjectId, String subjectType, String action); + + /** + * Bulk addition of permission + * + * @param objectId + * @param objectType + * @param subject - list of list with parameters siquence 1. subjectId 2.subjectType 3.action + * @return list of permission + */ + List addAll(long objectId, String objectType, List> subjects); + + List addAll(List permissions); + + Permission update(Permission permission); + + Permission update(long permissionId, long objectId, String objectType, String subjectId, String subjectType, String action); + + void remove(long id); + + void remove(long objectId, String objectType, String subjectId, String subjectType, String action); + + void remove(long objectId, String objectType); + + void remove(long objectId, String objectType, String action); + + void remove(String subjectId, String subjectType); + + void remove(String subjectId, String subjectType, String action); + + void removeAll(long objectId, String objectType); + + void removeAll(Session s, long objectId, String objectType); +} diff --git a/system/core/security/permission-api/src/main/java/ru/entaxy/esb/system/core/permission/jpa/entity/Permission.java b/system/core/security/permission-api/src/main/java/ru/entaxy/esb/system/core/permission/jpa/entity/Permission.java new file mode 100644 index 00000000..f370afe9 --- /dev/null +++ b/system/core/security/permission-api/src/main/java/ru/entaxy/esb/system/core/permission/jpa/entity/Permission.java @@ -0,0 +1,126 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-api + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.jpa.entity; + + +import com.sun.istack.NotNull; + +import javax.persistence.*; +import java.util.Objects; + +@Entity +@Table(name = "permission") +public class Permission { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + @NotNull + @Column(name = "object_id") + private long objectId; + @NotNull + @Column(name = "object_type") + private String objectType; + @NotNull + @Column(name = "subject_id") + private String subjectId; + @NotNull + @Column(name = "subject_type") + private String subjectType; + @NotNull + @Column(name = "action") + private String action; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public long getObjectId() { + return objectId; + } + + public void setObjectId(long objectId) { + this.objectId = objectId; + } + + public String getObjectType() { + return objectType; + } + + public void setObjectType(String objectType) { + this.objectType = objectType; + } + + public String getSubjectId() { + return subjectId; + } + + public void setSubjectId(String subjectId) { + this.subjectId = subjectId; + } + + public String getSubjectType() { + return subjectType; + } + + public void setSubjectType(String subjectType) { + this.subjectType = subjectType; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + @Override + public int hashCode() { + return Objects.hash(action, id, objectId, objectType, subjectId, subjectType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Permission other = (Permission) obj; + return Objects.equals(action, other.action) && id == other.id && objectId == other.objectId + && Objects.equals(objectType, other.objectType) && Objects.equals(subjectId, other.subjectId) + && Objects.equals(subjectType, other.subjectType); + } + + @Override + public String toString() { + return "Permission [id=" + id + ", objectId=" + objectId + ", objectType=" + objectType + ", subjectId=" + + subjectId + ", subjectType=" + subjectType + ", action=" + action + "]"; + } + + +} diff --git a/system/core/security/permission-common/LICENSE.txt b/system/core/security/permission-common/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/security/permission-common/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/security/permission-common/pom.xml b/system/core/security/permission-common/pom.xml new file mode 100644 index 00000000..4e3cb017 --- /dev/null +++ b/system/core/security/permission-common/pom.xml @@ -0,0 +1,27 @@ + + + + + ru.entaxy.esb.system.core.permission + permission + 1.8.0 + ../../security/pom.xml + + + 4.0.0 + + permission-common + SYSTEM :: ENTAXY :: CORE :: PERMISSION :: COMMON + bundle + + + + ru.entaxy.esb.system.core.permission.common + + + * + + + diff --git a/system/core/security/permission-common/src/main/java/ru/entaxy/esb/system/core/permission/common/PermissionConstants.java b/system/core/security/permission-common/src/main/java/ru/entaxy/esb/system/core/permission/common/PermissionConstants.java new file mode 100644 index 00000000..e556ab65 --- /dev/null +++ b/system/core/security/permission-common/src/main/java/ru/entaxy/esb/system/core/permission/common/PermissionConstants.java @@ -0,0 +1,45 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-common + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.common; + +public class PermissionConstants { + + public static final String ACTION_CREATE = "create"; + public static final String ACTION_READ = "read"; + public static final String ACTION_UPDATE = "update"; + public static final String ACTION_DELETE = "delete"; + public static final String ACTION_CONNECT = "connect"; + public static final String ACTION_SEND = "send"; + public static final String ACTION_RECEIVE = "receive"; + public static final String ACTION_OCCUPY = "occupy"; + public static final String ACTION_PUBLISH = "publish"; + public static final String ACTION_SUBSCRIBE = "subscribe"; + public static final String ACTION_DEFAULT = "default"; + public static final String ACTION_MANAGE = "manage"; + + public static final String TYPE_SYSTEM = "system"; + public static final String TYPE_SYSTEM_GROUP = "system-group"; + public static final String TYPE_SERVICE = "service"; + public static final String TYPE_ACCOUNT = "account"; + public static final String TYPE_EVENT_TOPIC = "event-topic"; + + private PermissionConstants() { + } +} diff --git a/system/core/security/permission-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/system/core/security/permission-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 00000000..ae03f922 --- /dev/null +++ b/system/core/security/permission-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/system/core/security/permission-component/LICENSE.txt b/system/core/security/permission-component/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/security/permission-component/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/security/permission-component/README.md b/system/core/security/permission-component/README.md new file mode 100644 index 00000000..cee7fa20 --- /dev/null +++ b/system/core/security/permission-component/README.md @@ -0,0 +1,78 @@ +# SYSTEM :: ENTAXY :: CORE :: PERMISSION :: COMPONENT + +Схема компонента: **permission** + +Поддерживаемые операции: + + - check - проверка права, принимает параметры + * objectId (long) - идентификатор объекта, для которого проверяются права + * objectType (String) - тип объекта, данный параметр соответствует проектной терминалогии: system, system-group + * subjectId (String) - идентификатор предмета применяемого права + * subjectType (String) - тип предмета + * action (String, не обязательный)- тип действия, по умолчанию проставляется значение default + Возвращает в тело запроса boolean + + - checkException - проверка права, принимает параметры + * objectId (long) - идентификатор объекта, для которого проверяются права + * objectType (String) - тип объекта, данный параметр соответствует проектной терминалогии: system, system-group + * subjectId (String) - идентификатор предмета применяемого права + * subjectType (String) - тип предмета + * action (String, не обязательный)- тип действия, по умолчанию проставляется значение default + При положительном результате не меняет данных, при отрицательном выбрасывает IllegalAccessException + + - checkSystemAccess - проверка доступа системы к системе, type проставляется по умолчанию system, + принимает параметры + * objectId (long) - идентификатор системы, для которой проверяются права + * subjectId (String) - идентификатор/имя/uuid системы применяемого права + * action (String, не обязательный)- тип действия, по умолчанию проставляется значение default + Возвращает в тело запроса boolean, в случае если система subject не найдена возвращается false + + - checkSystemAccessException - проверка доступа системы к системе, type проставляется по умолчанию system, + принимает параметры + * objectId (long) - идентификатор системы, для которой проверяются права + * subjectId (String) - идентификатор/имя/uuid системы применяемого права + * action (String, не обязательный)- тип действия, по умолчанию проставляется значение default + При положительном результате не меняет данных, при отрицательном выбрасывает IllegalAccessException + + - get - получение объекта permission, принимает параметры + * permissionId (long) - идентификатор объекта permission + Возвращает в тело запроса объект Permission + + - getByAllParams - получение объекта permission, принимает параметры + * objectId + * objectType + * subjectId + * subjectType + * action (не обязательный) + Возвращает в тело запроса объект Permission + + - create - создаёт Permission c заданными параметрами + * objectId + * objectType + * subjectId + * subjectType + * action (не обязательный) + Возвращает в тело запроса объект Permission + + - update - обновляет либо создаёт Permission + * permissionId + * objectId + * objectType + * subjectId + * subjectType + * action (не обязательный) + Возвращает в тело запроса объект Permission + + - delete - удаляет permission + * objectId + * objectType + * subjectId + * subjectType + * action (не обязательный) + Возвращает в тело запроса boolean + +Пример вызова в XML-DSL: + +``` + +``` diff --git a/system/core/security/permission-component/pom.xml b/system/core/security/permission-component/pom.xml new file mode 100644 index 00000000..4e5d4c7a --- /dev/null +++ b/system/core/security/permission-component/pom.xml @@ -0,0 +1,74 @@ + + + + + ru.entaxy.esb.system.core.permission + permission + 1.8.0 + ../../security/pom.xml + + + 4.0.0 + + permission-component + bundle + + SYSTEM :: ENTAXY :: CORE :: PERMISSION :: COMPONENT + SYSTEM :: ENTAXY :: CORE :: PERMISSION :: COMPONENT + + + org.apache.camel.spi.ComponentResolver;component=permission + + + ru.entaxy.esb.system.common.osgi, + ru.entaxy.esb.system.common.osgi.impl, + javax.persistence;version="[2,3)", + * + + + + + + + ru.entaxy.esb.system.registry.systems + system-api + ${project.version} + compile + + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + + ru.entaxy.esb.system.core.permission + permission-api + ${project.version} + provided + + + + ru.entaxy.esb.system.core.permission + permission-common + ${project.version} + provided + + + + + + org.apache.camel + camel-test + test + + + org.apache.camel + camel-core + + + diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/PermissionComponent.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/PermissionComponent.java new file mode 100644 index 00000000..9c02e5e3 --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/PermissionComponent.java @@ -0,0 +1,39 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component; + +import org.apache.camel.Endpoint; +import org.apache.camel.support.DefaultComponent; + +import java.util.Map; + +public class PermissionComponent extends DefaultComponent { + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception { + PermissionEndpoint endpoint = new PermissionEndpoint(uri, this); + + endpoint.setOperation(remaining); + + setProperties(endpoint, parameters); + return endpoint; + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/PermissionEndpoint.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/PermissionEndpoint.java new file mode 100644 index 00000000..2dfb62cf --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/PermissionEndpoint.java @@ -0,0 +1,132 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component; + +import org.apache.camel.Consumer; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.UriEndpoint; +import org.apache.camel.spi.UriParam; +import org.apache.camel.spi.UriPath; +import org.apache.camel.support.DefaultEndpoint; + +@UriEndpoint( + scheme = "permission", + title = "Permission", + syntax = "permission:operation", + label = "custom", + producerOnly = true) +public class PermissionEndpoint extends DefaultEndpoint { + + @UriPath + @Metadata(required = true) + private String operation; + + @UriParam + private long permissionId; + @UriParam + private long objectId; + @UriParam + private String objectType; + @UriParam + private String subjectId; + @UriParam + private String subjectType; + @UriParam + private String action; + + + public PermissionEndpoint() { + } + + public PermissionEndpoint(String uri, PermissionComponent component) { + super(uri, component); + } + + public Producer createProducer() throws Exception { + return new PermissionProducer(this); + } + + public Consumer createConsumer(Processor processor) throws Exception { + return null; + } + + public boolean isSingleton() { + return true; + } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } + + public long getPermissionId() { + return permissionId; + } + + public void setPermissionId(long permissionId) { + this.permissionId = permissionId; + } + + public long getObjectId() { + return objectId; + } + + public void setObjectId(long objectId) { + this.objectId = objectId; + } + + public String getObjectType() { + return objectType; + } + + public void setObjectType(String objectType) { + this.objectType = objectType; + } + + public String getSubjectId() { + return subjectId; + } + + public void setSubjectId(String subjectId) { + this.subjectId = subjectId; + } + + public String getSubjectType() { + return subjectType; + } + + public void setSubjectType(String subjectType) { + this.subjectType = subjectType; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/PermissionProducer.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/PermissionProducer.java new file mode 100644 index 00000000..73cba64a --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/PermissionProducer.java @@ -0,0 +1,47 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component; + +import org.apache.camel.Exchange; +import org.apache.camel.support.DefaultProducer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.system.core.permission.component.operation.OperationFactory; + +public class PermissionProducer extends DefaultProducer { + + private static final Logger LOG = LoggerFactory.getLogger(PermissionProducer.class); + private final PermissionEndpoint endpoint; + + public PermissionProducer(PermissionEndpoint endpoint) { + super(endpoint); + this.endpoint = endpoint; + } + + public void process(Exchange exchange) throws Exception { + String operation = endpoint.getOperation(); + + LOG.debug("In PermissionProducer " + endpoint.getPermissionId() + " " + endpoint.getObjectId() + " " + endpoint.getObjectType() + " " + + endpoint.getSubjectId() + " " + endpoint.getSubjectType() + " " + endpoint.getAction()); + + OperationFactory.getOperation(operation).process(exchange, endpoint); + + } +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/exception/UnknownOperationException.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/exception/UnknownOperationException.java new file mode 100644 index 00000000..cfd745ae --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/exception/UnknownOperationException.java @@ -0,0 +1,47 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.exception; + +public class UnknownOperationException extends Exception { + + private static final long serialVersionUID = 948229285513408917L; + + public UnknownOperationException() { + super(); + } + + public UnknownOperationException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public UnknownOperationException(String message, Throwable cause) { + super(message, cause); + } + + public UnknownOperationException(String message) { + super(message); + } + + public UnknownOperationException(Throwable cause) { + super(cause); + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/BaseOperation.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/BaseOperation.java new file mode 100644 index 00000000..daea3072 --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/BaseOperation.java @@ -0,0 +1,74 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + + +import org.apache.camel.Exchange; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.entaxy.esb.system.common.osgi.OSGIUtils; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; +import ru.entaxy.esb.system.core.permission.component.PermissionProducer; +import ru.entaxy.esb.system.core.permission.jpa.PermissionService; +import ru.entaxy.esb.system.jpa.SystemService; + +public abstract class BaseOperation implements Operation { + + private static final Logger LOG = LoggerFactory.getLogger(BaseOperation.class); + + private PermissionService permissionService; + + private SystemService systemService; + + @Override + public void process(Exchange exchange, PermissionEndpoint endpoint) throws Exception { + doProcess(exchange, endpoint); + } + + protected abstract void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws Exception; + + protected void validateParams(String... parameters) { + for (String parameter : parameters) { + if (parameter == null || "0".equals(parameter) || parameter.isEmpty()) { + throw new IllegalArgumentException("One or more parameters empty!"); + } + } + } + + protected PermissionService getPermissionService() { + if (permissionService == null) { + permissionService = (PermissionService) OSGIUtils.getServiceReference( + FrameworkUtil.getBundle(PermissionProducer.class).getBundleContext(), + PermissionService.class.getName()); + } + return permissionService; + } + + protected SystemService getSystemService() { + if (systemService == null) { + systemService = (SystemService) OSGIUtils.getServiceReference( + FrameworkUtil.getBundle(PermissionProducer.class).getBundleContext(), + SystemService.class.getName()); + } + return systemService; + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/BulkCreate.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/BulkCreate.java new file mode 100644 index 00000000..a7e31cbb --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/BulkCreate.java @@ -0,0 +1,33 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; + +public class BulkCreate extends BaseOperation { + + @Override + protected void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws Exception { + // TODO Auto-generated method stub + + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Check.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Check.java new file mode 100644 index 00000000..449145e3 --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Check.java @@ -0,0 +1,41 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; + +public class Check extends BaseOperation { + + @Override + protected void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws Exception { + validateParams(String.valueOf(endpoint.getObjectId()), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType()); + exchange.getIn().setBody(check(endpoint), Boolean.class); + + } + + protected boolean check(PermissionEndpoint endpoint) { + return getPermissionService().existByAllParameters(endpoint.getObjectId(), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType(), endpoint.getAction()); + } + + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/CheckSystemAccess.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/CheckSystemAccess.java new file mode 100644 index 00000000..b55e1d23 --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/CheckSystemAccess.java @@ -0,0 +1,71 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.common.PermissionConstants; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; +import ru.entaxy.esb.system.jpa.entity.System; + +import javax.persistence.NoResultException; + +public class CheckSystemAccess extends BaseOperation { + + @Override + protected void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws Exception { + validateParams(String.valueOf(endpoint.getObjectId()), endpoint.getSubjectId()); + exchange.getIn().setBody(checkSystemAccessProc(endpoint), Boolean.class); + } + + protected boolean checkSystemAccessProc(PermissionEndpoint endpoint) { + System system = getSystem(endpoint.getSubjectId()); + boolean result = false; + if (system != null) { + result = getPermissionService().existByAllParameters(endpoint.getObjectId(), PermissionConstants.TYPE_SYSTEM, + String.valueOf(system.getId()), PermissionConstants.TYPE_SYSTEM, endpoint.getAction()); + } + return result; + } + + protected System getSystem(String subject) { + try { + long systemId = Long.valueOf(subject); + return getSystemService().get(systemId); + } catch (Exception e) { + /*keep silence*/ + } + System system = null; + try { + system = getSystemService().getByName(subject); + return system; + } catch (NoResultException e) { + /*keep silence*/ + } + + try { + system = getSystemService().getByUuid(subject); + } catch (NoResultException e) { + /*keep silence*/ + } + + return system; + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/CheckSystemAccessWithException.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/CheckSystemAccessWithException.java new file mode 100644 index 00000000..84ca917c --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/CheckSystemAccessWithException.java @@ -0,0 +1,39 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; +import ru.entaxy.esb.system.jpa.entity.System; + +public class CheckSystemAccessWithException extends CheckSystemAccess { + + @Override + protected void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws IllegalAccessException { + validateParams(String.valueOf(endpoint.getObjectId()), endpoint.getSubjectId()); + if (!checkSystemAccessProc(endpoint)) { + if (endpoint.getSubjectId().equals("error")) return; + System system = getSystem(endpoint.getSubjectId()); + if (system.getId() == endpoint.getObjectId()) return; + throw new IllegalAccessException("Connection to system " + endpoint.getSubjectId() + " is not allowed"); + } + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/CheckWithException.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/CheckWithException.java new file mode 100644 index 00000000..16dba40e --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/CheckWithException.java @@ -0,0 +1,34 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; + +public class CheckWithException extends Check { + @Override + protected void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws IllegalAccessException { + validateParams(String.valueOf(endpoint.getObjectId()), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType()); + if (!check(endpoint)) { + throw new IllegalAccessException(); + } + } +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Create.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Create.java new file mode 100644 index 00000000..80012305 --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Create.java @@ -0,0 +1,35 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; + +public class Create extends BaseOperation { + + @Override + protected void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws Exception { + validateParams(String.valueOf(endpoint.getObjectId()), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType()); + exchange.getIn().setBody(getPermissionService().add(endpoint.getObjectId(), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType(), endpoint.getAction())); + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Delete.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Delete.java new file mode 100644 index 00000000..0dff21a3 --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Delete.java @@ -0,0 +1,40 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; + +public class Delete extends BaseOperation { + + @Override + protected void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws Exception { + validateParams(String.valueOf(endpoint.getObjectId()), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType()); + try { + getPermissionService().remove(endpoint.getObjectId(), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType(), endpoint.getAction()); + exchange.getIn().setBody(true, Boolean.class); + } catch (Exception e) { + exchange.getIn().setBody(false, Boolean.class); + } + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Get.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Get.java new file mode 100644 index 00000000..53e1fe82 --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Get.java @@ -0,0 +1,33 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; + +public class Get extends BaseOperation { + + @Override + protected void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws Exception { + validateParams(String.valueOf(endpoint.getPermissionId())); + exchange.getIn().setBody(getPermissionService().get(endpoint.getPermissionId())); + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/GetByAllParams.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/GetByAllParams.java new file mode 100644 index 00000000..7eee6808 --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/GetByAllParams.java @@ -0,0 +1,35 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; + +public class GetByAllParams extends BaseOperation { + + @Override + protected void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws Exception { + validateParams(String.valueOf(endpoint.getObjectId()), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType()); + exchange.getIn().setBody(getPermissionService().getByAllParameters(endpoint.getObjectId(), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType(), endpoint.getAction())); + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Operation.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Operation.java new file mode 100644 index 00000000..c7aa3a83 --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Operation.java @@ -0,0 +1,29 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; + +public interface Operation { + + void process(Exchange exchange, PermissionEndpoint endpoint) throws Exception; + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/OperationFactory.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/OperationFactory.java new file mode 100644 index 00000000..09c1c188 --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/OperationFactory.java @@ -0,0 +1,52 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import ru.entaxy.esb.system.core.permission.component.exception.UnknownOperationException; +import ru.entaxy.esb.system.core.permission.component.util.PermissionComponentConstants; + +import java.util.HashMap; +import java.util.Map; + +public class OperationFactory { + + private static final Map operations; + + static { + operations = new HashMap<>(); + operations.put(PermissionComponentConstants.OPERATION_CHECK, new Check()); + operations.put(PermissionComponentConstants.OPERATION_CHECK_EXCEPTION, new CheckWithException()); + operations.put(PermissionComponentConstants.OPERATION_CHECK_SYSTEM_ACCESS, new CheckSystemAccess()); + operations.put(PermissionComponentConstants.OPERATION_CHECK_SYSTEM_ACCESS_EXCEPTION, new CheckSystemAccessWithException()); + operations.put(PermissionComponentConstants.OPERATION_CREATE, new Create()); + operations.put(PermissionComponentConstants.OPERATION_DELETE, new Delete()); + operations.put(PermissionComponentConstants.OPERATION_GET, new Get()); + operations.put(PermissionComponentConstants.OPERATION_GET_BY_ALL_PARAM, new GetByAllParams()); + operations.put(PermissionComponentConstants.OPERATION_UPDATE, new Update()); + } + + public static final Operation getOperation(String name) throws UnknownOperationException { + if (operations.containsKey(name)) { + return operations.get(name); + } + throw new UnknownOperationException(); + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Update.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Update.java new file mode 100644 index 00000000..589bf71e --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/operation/Update.java @@ -0,0 +1,35 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.operation; + +import org.apache.camel.Exchange; +import ru.entaxy.esb.system.core.permission.component.PermissionEndpoint; + +public class Update extends BaseOperation { + + @Override + protected void doProcess(Exchange exchange, PermissionEndpoint endpoint) throws Exception { + validateParams(String.valueOf(endpoint.getObjectId()), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType()); + exchange.getIn().setBody(getPermissionService().update(endpoint.getPermissionId(), endpoint.getObjectId(), endpoint.getObjectType(), + endpoint.getSubjectId(), endpoint.getSubjectType(), endpoint.getAction())); + } + +} diff --git a/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/util/PermissionComponentConstants.java b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/util/PermissionComponentConstants.java new file mode 100644 index 00000000..8f0c1c5d --- /dev/null +++ b/system/core/security/permission-component/src/main/java/ru/entaxy/esb/system/core/permission/component/util/PermissionComponentConstants.java @@ -0,0 +1,36 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-component + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.component.util; + +public class PermissionComponentConstants { + + public static final String OPERATION_CHECK = "check"; + public static final String OPERATION_CHECK_EXCEPTION = "checkException"; + public static final String OPERATION_CHECK_SYSTEM_ACCESS = "checkSystemAccess"; + public static final String OPERATION_CHECK_SYSTEM_ACCESS_EXCEPTION = "checkSystemAccessException"; + public static final String OPERATION_GET = "get"; + public static final String OPERATION_GET_BY_ALL_PARAM = "getByAllParams"; + public static final String OPERATION_CREATE = "create"; + public static final String OPERATION_UPDATE = "update"; + public static final String OPERATION_DELETE = "delete"; + + private PermissionComponentConstants() { + } +} diff --git a/system/core/security/permission-component/src/main/resources/META-INF/services/org/apache/camel/component/permission b/system/core/security/permission-component/src/main/resources/META-INF/services/org/apache/camel/component/permission new file mode 100644 index 00000000..ad181d87 --- /dev/null +++ b/system/core/security/permission-component/src/main/resources/META-INF/services/org/apache/camel/component/permission @@ -0,0 +1 @@ +class=ru.entaxy.esb.system.core.permission.component.PermissionComponent diff --git a/system/core/security/permission-component/src/main/resources/log4j2.properties b/system/core/security/permission-component/src/main/resources/log4j2.properties new file mode 100644 index 00000000..2be713d2 --- /dev/null +++ b/system/core/security/permission-component/src/main/resources/log4j2.properties @@ -0,0 +1,30 @@ +### +# ~~~~~~licensing~~~~~~ +# permission-component +# ========== +# Copyright (C) 2020 - 2021 EmDev LLC +# ========== +# 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. +# ~~~~~~/licensing~~~~~~ +### +appender.file.type=File +appender.file.name=file +appender.file.fileName=target/camel-test.log +appender.file.layout.type=PatternLayout +appender.file.layout.pattern=%d %-5p %c{1} - %m %n +appender.out.type=Console +appender.out.name=out +appender.out.layout.type=PatternLayout +appender.out.layout.pattern=[%30.30t] %-30.30c{1} %-5p %m%n +rootLogger.level=INFO +rootLogger.appenderRef.out.ref=out diff --git a/system/core/security/permission-handler/LICENSE.txt b/system/core/security/permission-handler/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/security/permission-handler/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/security/permission-handler/pom.xml b/system/core/security/permission-handler/pom.xml new file mode 100644 index 00000000..cbc63630 --- /dev/null +++ b/system/core/security/permission-handler/pom.xml @@ -0,0 +1,64 @@ + + + + + ru.entaxy.esb.system.core.permission + permission + 1.8.0 + ../../security/pom.xml + + + 4.0.0 + + permission-handler + SYSTEM :: ENTAXY :: CORE :: PERMISSION :: HANDLER + bundle + + + + org.apache.camel.component.jms, + * + + + ru.entaxy.esb.system.core.permission.handler + + + + + + org.apache.activemq + artemis-jms-client + ${activemq.version} + provided + + + + ru.entaxy.esb.system.registry.systems + system-api + ${project.version} + provided + + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + + ru.entaxy.esb.system.core.permission + permission-api + ${project.version} + provided + + + ru.entaxy.esb.system.core.permission + permission-common + ${project.version} + provided + + + diff --git a/system/core/security/permission-handler/src/main/java/ru/entaxy/esb/system/core/permission/handler/PermissionChecker.java b/system/core/security/permission-handler/src/main/java/ru/entaxy/esb/system/core/permission/handler/PermissionChecker.java new file mode 100644 index 00000000..c1767013 --- /dev/null +++ b/system/core/security/permission-handler/src/main/java/ru/entaxy/esb/system/core/permission/handler/PermissionChecker.java @@ -0,0 +1,27 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.handler; + +public interface PermissionChecker { + + public boolean check(int objectId, String objectType, String subjectId, String subjectType, String action); + + public boolean check(int objectId, String objectType, String subjectId, String subjectType); +} diff --git a/system/core/security/permission-handler/src/main/java/ru/entaxy/esb/system/core/permission/handler/PermissionCheckerImpl.java b/system/core/security/permission-handler/src/main/java/ru/entaxy/esb/system/core/permission/handler/PermissionCheckerImpl.java new file mode 100644 index 00000000..34742686 --- /dev/null +++ b/system/core/security/permission-handler/src/main/java/ru/entaxy/esb/system/core/permission/handler/PermissionCheckerImpl.java @@ -0,0 +1,43 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-handler + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.handler; + +import ru.entaxy.esb.system.core.permission.jpa.PermissionService; + +public class PermissionCheckerImpl implements PermissionChecker { + + private PermissionService permissionService; + + public PermissionService getPermissionService() { + return permissionService; + } + + public void setPermissionService(PermissionService permissionService) { + this.permissionService = permissionService; + } + + public boolean check(int objectId, String objectType, String subjectId, String subjectType, String action) { + return permissionService.existByAllParameters(objectId, objectType, subjectId, subjectType, action); + } + + public boolean check(int objectId, String objectType, String subjectId, String subjectType) { + return check(objectId, objectType, subjectId, subjectType, null); + } +} diff --git a/system/core/security/permission-handler/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/system/core/security/permission-handler/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 00000000..13a3e8fa --- /dev/null +++ b/system/core/security/permission-handler/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${body} != null + + + + + + + + + + + + java.lang.Exception + + + + + + + + + + + + + + + + + ${body} != null + + + + + + + + + + + ${body} + + + + + + + + + + + ${body} != null + + + + + + + + + + + ${body} + + + + + + + + + + + + ${body} != null + + + + + + + + + + + + + + + + + + ${body} == false + + + + + + + + + + + ${body} == false + + + + + + + + + + + + diff --git a/system/core/security/permission-impl/LICENSE.txt b/system/core/security/permission-impl/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/security/permission-impl/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/security/permission-impl/pom.xml b/system/core/security/permission-impl/pom.xml new file mode 100644 index 00000000..2e59d52a --- /dev/null +++ b/system/core/security/permission-impl/pom.xml @@ -0,0 +1,92 @@ + + + + + ru.entaxy.esb.system.core.permission + permission + 1.8.0 + ../../security/pom.xml + + + 4.0.0 + + permission-impl + SYSTEM :: ENTAXY :: CORE :: PERMISSION :: IMPL + bundle + + + + ru.entaxy.esb.system.core.permission.jpa.entity + + + javax.xml.bind;version="[2,3)", + javax.xml.bind.annotation;version="[2,3)", + javax.persistence;version="[2,3)", + org.hibernate, + org.hibernate.cfg, + org.hibernate.service, + org.hibernate.jpa, + org.hibernate.proxy, + javassist.util.proxy, + * + + + + + + org.osgi + osgi.core + ${osgi.version} + provided + + + org.eclipse.persistence + javax.persistence + ${jpa.version} + + + javax.transaction + javax.transaction-api + ${javax.transaction.version} + + + javax.interceptor + javax.interceptor-api + ${javax.interceptor.version} + + + + + ru.entaxy.esb.system.core.permission + permission-api + ${project.version} + provided + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + provided + + + ru.entaxy.esb.system.core.permission + permission-common + ${project.version} + provided + + + ru.entaxy.esb.system.auth.basic.api + basic-auth-api + ${project.version} + compile + + + org.apache.camel + camel-cxf + + + + + diff --git a/system/core/security/permission-impl/src/main/java/ru/entaxy/esb/system/core/permission/interceptor/ServiceInterceptor.java b/system/core/security/permission-impl/src/main/java/ru/entaxy/esb/system/core/permission/interceptor/ServiceInterceptor.java new file mode 100644 index 00000000..10ed16fc --- /dev/null +++ b/system/core/security/permission-impl/src/main/java/ru/entaxy/esb/system/core/permission/interceptor/ServiceInterceptor.java @@ -0,0 +1,112 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-impl + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.interceptor; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.AbstractPhaseInterceptor; +import org.apache.cxf.phase.Phase; +import org.apache.cxf.transport.http.Headers; +import org.osgi.framework.FrameworkUtil; +import ru.entaxy.esb.system.auth.basic.jpa.api.BasicAuthService; +import ru.entaxy.esb.system.auth.basic.jpa.api.entity.BasicAuthAccount; +import ru.entaxy.esb.system.common.osgi.OSGIUtils; +import ru.entaxy.esb.system.core.permission.common.PermissionConstants; +import ru.entaxy.esb.system.core.permission.jpa.PermissionService; + +import javax.ws.rs.ForbiddenException; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class ServiceInterceptor extends AbstractPhaseInterceptor { + + private static final Log LOG = LogFactory.getLog(ServiceInterceptor.class); + private static final String APACHE_CXF_MESSAGE_MESSAGE_PATH_INFO = "org.apache.cxf.message.Message.PATH_INFO"; + private static final String HEADER_USER_LOGIN = "X-ForwardedUser"; + private static final String CXF = "/cxf/"; + + private PermissionService permissionService; + private BasicAuthService basicAuthService; + + public ServiceInterceptor() { + super(Phase.RECEIVE); + } + + @Override + public void handleMessage(Message message) throws Fault { + Map> headers = Headers.getSetProtocolHeaders(message); + String serviceName = message.get(APACHE_CXF_MESSAGE_MESSAGE_PATH_INFO).toString(); + if (serviceName.contains(CXF)) { + serviceName = serviceName.replace(CXF, ""); + } else { + int firstSlashIndex = serviceName.indexOf("/") + 1; + serviceName = serviceName.substring(firstSlashIndex, serviceName.indexOf("/", firstSlashIndex)); + } + + Optional login = Optional.ofNullable(headers.get(HEADER_USER_LOGIN)) + .orElse(Collections.emptyList()) + .stream().findFirst(); + + Optional basicAuthAccount = Optional.empty(); + if (login.isPresent()) { + basicAuthAccount = getBasicAuthService().get(login.get()); + } + + LOG.trace(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>ServiceInterceptor" + + " <<< serviceName " + serviceName + + " <<< login " + login); + if (!login.isPresent() || !basicAuthAccount.isPresent() || + !getPermissionService().existByAllParameters(basicAuthAccount.get().getId(), PermissionConstants.TYPE_ACCOUNT, + serviceName, PermissionConstants.TYPE_SERVICE, null)) { + throw new ForbiddenException(); + } + } + + public void setPermissionService(PermissionService permissionService) { + this.permissionService = permissionService; + } + + public PermissionService getPermissionService() { + if (permissionService == null) { + permissionService = (PermissionService) OSGIUtils.getServiceReference( + FrameworkUtil.getBundle(ServiceInterceptor.class).getBundleContext(), + PermissionService.class.getName()); + } + return permissionService; + } + + public void setBasicAuthService(BasicAuthService basicAuthService) { + this.basicAuthService = basicAuthService; + } + + public BasicAuthService getBasicAuthService() { + if (basicAuthService == null) { + basicAuthService = (BasicAuthService) OSGIUtils.getServiceReference( + FrameworkUtil.getBundle(ServiceInterceptor.class).getBundleContext(), + BasicAuthService.class.getName()); + } + return basicAuthService; + } + +} diff --git a/system/core/security/permission-impl/src/main/java/ru/entaxy/esb/system/core/permission/jpa/impl/PermissionServiceImpl.java b/system/core/security/permission-impl/src/main/java/ru/entaxy/esb/system/core/permission/jpa/impl/PermissionServiceImpl.java new file mode 100644 index 00000000..2c1a4a23 --- /dev/null +++ b/system/core/security/permission-impl/src/main/java/ru/entaxy/esb/system/core/permission/jpa/impl/PermissionServiceImpl.java @@ -0,0 +1,430 @@ +/*- + * ~~~~~~licensing~~~~~~ + * permission-impl + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.permission.jpa.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.query.Query; +import org.hibernate.type.StringType; +import ru.entaxy.esb.system.core.permission.jpa.PermissionService; +import ru.entaxy.esb.system.core.permission.jpa.entity.Permission; + +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static ru.entaxy.esb.system.core.permission.common.PermissionConstants.ACTION_DEFAULT; + +public class PermissionServiceImpl implements PermissionService { + + private static final Log LOG = LogFactory.getLog(PermissionServiceImpl.class); + + private SessionFactory sessionFactory; + + public void setSessionFactory(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + public Session getSession() { + return sessionFactory.openSession(); + } + + @Override + public List list() { + List list; + try (Session s = getSession()) { + s.getTransaction().begin(); + CriteriaQuery cq = s.getCriteriaBuilder().createQuery(Permission.class); + cq.from(Permission.class); + list = s.createQuery(cq).getResultList(); + s.getTransaction().commit(); + s.close(); + } + + return list; + } + + @Override + public Permission get(long id) { + Permission permission; + try (Session s = getSession()) { + s.getTransaction().begin(); + + Query query = getQuery(s, id); + permission = query.getSingleResult(); + + s.getTransaction().commit(); + s.close(); + } + return permission; + } + + + @Override + public List getAllById(long id, String type) { + List permissionList; + try (Session s = getSession()) { + s.getTransaction().begin(); + permissionList = getAllById(s, id, type); + s.getTransaction().commit(); + s.close(); + } + return permissionList; + } + + @Override + public List getAllById(Session s, long id, String type) { + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(Permission.class); + Root root = criteriaQuery.from(Permission.class); + criteriaQuery.where( + builder.or( + builder.and( + builder.equal(root.get("objectId"), id), + builder.equal(root.get("objectType"), type)), + builder.and( + builder.equal(root.get("subjectId"), String.valueOf(id)), + builder.equal(root.get("objectType"), type)))); + + return s.createQuery(criteriaQuery).getResultList(); + } + + @Override + public Optional fetch(long id) { + Optional permission; + try (Session s = getSession()) { + s.getTransaction().begin(); + + Query query = getQuery(s, id); + permission = query.uniqueResultOptional(); + + s.getTransaction().commit(); + s.close(); + } + return permission; + } + + private Query getQuery(Session session, long id) { + CriteriaBuilder builder = session.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(Permission.class); + Root root = criteriaQuery.from(Permission.class); + criteriaQuery.where(builder.equal(root.get("id"), id)); + return session.createQuery(criteriaQuery); + } + + @Override + public List get(long objectId, String objectType, String action) { + List permissionList; + try (Session s = getSession()) { + s.getTransaction().begin(); + permissionList = get(s, objectId, objectType, action); + s.getTransaction().commit(); + s.close(); + } + return permissionList; + } + + @Override + public List get(Session s, long objectId, String objectType, String action) { + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(Permission.class); + Root root = criteriaQuery.from(Permission.class); + criteriaQuery.where(builder.equal(root.get("objectId"), objectId), + builder.equal(root.get("objectType"), objectType), + builder.equal(root.get("action"), action)); + return s.createQuery(criteriaQuery).getResultList(); + } + + + @Override + public Permission getByAllParameters(long objectId, String objectType, String subjectId, + String subjectType, String action) { + Permission permission; + + try (Session s = getSession()) { + s.getTransaction().begin(); + permission = getByAllParameters(s, objectId, objectType, subjectId, subjectType, action); + s.getTransaction().commit(); + s.close(); + } + + return permission; + } + + @Override + public Permission getByAllParameters(Session session, long objectId, String objectType, String subjectId, + String subjectType, String action) { + Query query = getByAllParametersQuery(session, objectId, objectType, subjectId, subjectType, action); + return query.getSingleResult(); + } + + @Override + public Optional fetchByAllParameters(long objectId, String objectType, String subjectId, + String subjectType, String action) { + Optional permission; + + try (Session s = getSession()) { + s.getTransaction().begin(); + + Query query = getByAllParametersQuery(s, objectId, objectType, subjectId, subjectType, action); + permission = query.uniqueResultOptional(); + + s.getTransaction().commit(); + s.close(); + } + + return permission; + } + + private Query getByAllParametersQuery(Session s, long objectId, String objectType, String subjectId, + String subjectType, String action) { + CriteriaBuilder builder = s.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(Permission.class); + Root root = criteriaQuery.from(Permission.class); + criteriaQuery.select(root).where( + builder.equal(root.get("objectId"), objectId), + builder.equal(root.get("objectType"), objectType), + builder.equal(root.get("subjectId"), subjectId), + builder.equal(root.get("subjectType"), subjectType), + builder.equal(root.get("action"), orElseGet(action)) + ); + return s.createQuery(criteriaQuery); + } + + @Override + public boolean existByAllParameters(long objectId, String objectType, String subjectId, + String subjectType, String action) { + if (objectId < 1) { + return true; + } + boolean exists = false; + try (Session s = getSession()) { + s.getTransaction().begin(); + exists = (s + .createQuery("select 1 from Permission where exists (" + + "select 1 from Permission p where " + + " p.objectId = ?0 " + + " AND p.objectType = ?1 " + + " AND p.subjectId = ?2 " + + " AND p.subjectType = ?3 " + + " AND p.action = ?4" + + ")") + .setParameter(0, objectId) + .setParameter(1, objectType, StringType.INSTANCE) + .setParameter(2, subjectId, StringType.INSTANCE) + .setParameter(3, subjectType, StringType.INSTANCE) + .setParameter(4, orElseGet(action), StringType.INSTANCE) + .uniqueResult() != null); + + s.getTransaction().commit(); + s.close(); + } + return exists; + } + + @Override + public Permission add(Permission permission) { + return save(permission, false); + } + + @Override + public Permission add(long objectId, String objectType, String subjectId, String subjectType, String action) { + Permission permission = new Permission(); + fillModel(permission, objectId, objectType, subjectId, subjectType, action); + return add(permission); + } + + @Override + public Permission addIfNotExist(long objectId, String objectType, String subjectId, String subjectType, String action) { + Optional permission = fetchByAllParameters(objectId, objectType, subjectId, subjectType, action); + return permission.orElseGet(() -> add(objectId, objectType, subjectId, subjectType, action)); + } + + private void fillModel(Permission permission, long objectId, String objectType, String subjectId, + String subjectType, String action) { + permission.setObjectId(objectId); + permission.setObjectType(objectType); + permission.setSubjectId(subjectId); + permission.setSubjectType(subjectType); + permission.setAction(orElseGet(action)); + } + + @Override + public List addAll(long objectId, String objectType, List> subjects) { + List permissions = new ArrayList<>(); + if (subjects != null && !subjects.isEmpty()) { + for (List subject : subjects) { + try { + //TODO:make it in tttttransaction + permissions.add( + addIfNotExist( + objectId, + objectType, + subject.get(0), + subject.get(1), + subject.get(2))); + } catch (Exception e) { + LOG.error("Bulk addition of permission error " + e.getMessage()); + LOG.trace(e); + } + } + } + return permissions; + } + + @Override + public List addAll(List permissionsToCreate) { + List permissions = new ArrayList<>(); + if (permissionsToCreate != null && !permissionsToCreate.isEmpty()) { + for (Permission permission : permissionsToCreate) { + try { + permissions.add( + addIfNotExist( + permission.getObjectId(), + permission.getObjectType(), + permission.getSubjectId(), + permission.getSubjectType(), + permission.getAction())); + } catch (Exception e) { + LOG.error("Bulk addition of permission error " + e.getMessage()); + LOG.trace(e); + } + } + } + return permissions; + } + + @Override + public Permission update(Permission permission) { + Optional permissionOldOpt = fetch(permission.getId()); + + return save(permission, permissionOldOpt.isPresent()); + } + + @Override + public Permission update(long permissionId, long objectId, String objectType, String subjectId, String subjectType, String action) { + Permission permission = get(permissionId); + fillModel(permission, objectId, objectType, subjectId, subjectType, action); + + return save(permission, true); + } + + public Permission save(Permission permission, boolean isExist) { + try (Session s = getSession()) { + s.getTransaction().begin(); + if (isExist) { + s.update(permission); + } else { + s.persist(permission); + } + s.getTransaction().commit(); + s.close(); + } + return permission; + } + + @Override + public void remove(long id) { + try (Session s = getSession()) { + s.getTransaction().begin(); + + Permission permission = get(id); + s.delete(Permission.class.getName(), permission); + + s.getTransaction().commit(); + s.close(); + } + } + + @Override + public void remove(long objectId, String objectType, String subjectId, String subjectType, String action) { + try (Session s = getSession()) { + s.getTransaction().begin(); + + Permission permission = getByAllParameters(s, objectId, objectType, subjectId, subjectType, action); + s.delete(Permission.class.getName(), permission); + + s.getTransaction().commit(); + s.close(); + } + } + + @Override + public void remove(long objectId, String objectType) { + // TODO Auto-generated method stub + + } + + @Override + public void remove(long objectId, String objectType, String action) { + try (Session s = getSession()) { + s.getTransaction().begin(); + + List permission = get(s, objectId, objectType, action); + permission.forEach(s::delete); + + s.getTransaction().commit(); + s.close(); + } + } + + @Override + public void remove(String subjectId, String subjectType) { + // TODO Auto-generated method stub + + } + + @Override + public void remove(String subjectId, String subjectType, String action) { + // TODO Auto-generated method stub + + } + + + @Override + public void removeAll(long objectId, String objectType) { + try (Session s = getSession()) { + s.getTransaction().begin(); + + removeAll(s, objectId, objectType); + + s.getTransaction().commit(); + s.close(); + } + } + + private String orElseGet(String action) { + return action == null || action.isEmpty() ? ACTION_DEFAULT : action; + } + + @Override + public void removeAll(Session s, long objectId, String objectType) { + List permissionList = getAllById(s, objectId, objectType); + for (Permission permission : permissionList) { + s.delete(Permission.class.getName(), permission); + } + } + +} diff --git a/system/core/security/permission-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/system/core/security/permission-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 00000000..466e7686 --- /dev/null +++ b/system/core/security/permission-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/core/security/permission-impl/src/main/resources/hibernate.cfg.xml b/system/core/security/permission-impl/src/main/resources/hibernate.cfg.xml new file mode 100644 index 00000000..32dc589a --- /dev/null +++ b/system/core/security/permission-impl/src/main/resources/hibernate.cfg.xml @@ -0,0 +1,40 @@ + + + + + + + + + osgi:service/entaxy.esb.storage + validate + + true + + ${hibernate.show_sql} + ${hibernate.format_sql} + + + + + diff --git a/system/core/security/permission-soap/LICENSE.txt b/system/core/security/permission-soap/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/security/permission-soap/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/security/permission-soap/pom.xml b/system/core/security/permission-soap/pom.xml new file mode 100644 index 00000000..99df674b --- /dev/null +++ b/system/core/security/permission-soap/pom.xml @@ -0,0 +1,72 @@ + + + 4.0.0 + + + ru.entaxy.esb.system.core.permission + permission + 1.8.0 + + + permission-soap + bundle + + SYSTEM :: ENTAXY :: CORE :: PERMISSION :: SOAP + SYSTEM :: ENTAXY :: CORE :: PERMISSION :: SOAP + + + + * + + + + + + + org.osgi + osgi.core + ${osgi.version} + provided + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + + + + + dev + + + env + dev + + + + true + true + + + + + prod + + + env + !dev + + + + false + false + + + + + diff --git a/system/core/security/permission-soap/src/main/resources/OSGI-INF/blueprint/camel-context.xml b/system/core/security/permission-soap/src/main/resources/OSGI-INF/blueprint/camel-context.xml new file mode 100644 index 00000000..b3cf6683 --- /dev/null +++ b/system/core/security/permission-soap/src/main/resources/OSGI-INF/blueprint/camel-context.xml @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <response xmlns="http://www.entaxy.ru/permission/">${body}</response> + + + java.lang.Exception + + + + <response xmlns="http://www.entaxy.ru/permission/">false</response> + + + + + + + + + + + //p:permissionId + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + //p:permission/p:permissionId + + + //p:permission/p:objectId + + + //p:permission/p:objectType + + + //p:permission/p:subjectId + + + //p:permission/p:subjectType + + + //p:permission/p:action + + + + + + + + + + + + + + + + + + <response xmlns="http://www.entaxy.ru/permission/">true</response> + + + + + + + + ${body.id} + + + ${body.objectId} + + + ${body.objectType} + + + ${body.subjectId} + + + ${body.subjectType} + + + ${body.action} + + + + + + + ${body.id} + + + ${body.objectId} + + + ${body.objectType} + + + ${body.subjectId} + + + ${body.subjectType} + + + ${body.action} + + + + + + + //p:permissionCommon/p:objectId + + + //p:permissionCommon/p:objectType + + + //p:permissionCommon/p:subjectId + + + //p:permissionCommon/p:subjectType + + + //p:permissionCommon/p:action + + + + + + + + + + diff --git a/system/core/security/permission-soap/src/main/resources/ru/entaxy/esb/system/core/permission/template/permission.xsl b/system/core/security/permission-soap/src/main/resources/ru/entaxy/esb/system/core/permission/template/permission.xsl new file mode 100644 index 00000000..843c3ef5 --- /dev/null +++ b/system/core/security/permission-soap/src/main/resources/ru/entaxy/esb/system/core/permission/template/permission.xsl @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/core/security/permission-soap/src/main/resources/types/permission.ftl b/system/core/security/permission-soap/src/main/resources/types/permission.ftl new file mode 100644 index 00000000..dec7a490 --- /dev/null +++ b/system/core/security/permission-soap/src/main/resources/types/permission.ftl @@ -0,0 +1,27 @@ +<#-- + ~~~~~~licensing~~~~~~ + permission-soap + ========== + Copyright (C) 2020 - 2021 EmDev LLC + ========== + 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. + ~~~~~~/licensing~~~~~~ +--> + + ${exchange.properties.permissionId} + ${exchange.properties.objectId} + ${exchange.properties.objectType} + ${exchange.properties.subjectId} + ${exchange.properties.subjectType} + ${exchange.properties.action} + diff --git a/system/core/security/permission-soap/src/main/resources/wsdl/permission-service.wsdl b/system/core/security/permission-soap/src/main/resources/wsdl/permission-service.wsdl new file mode 100644 index 00000000..6b6df580 --- /dev/null +++ b/system/core/security/permission-soap/src/main/resources/wsdl/permission-service.wsdl @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/core/security/pom.xml b/system/core/security/pom.xml new file mode 100644 index 00000000..20efd7d5 --- /dev/null +++ b/system/core/security/pom.xml @@ -0,0 +1,28 @@ + + + + 4.0.0 + + + ru.entaxy.esb.system.core + system-core + 1.8.0 + ../../core/pom.xml + + + ru.entaxy.esb.system.core.permission + permission + SYSTEM :: ENTAXY :: CORE :: PERMISSION + pom + + + permission-api + permission-impl + permission-handler + permission-common + permission-component + permission-soap + + + diff --git a/system/core/template/LICENSE.txt b/system/core/template/LICENSE.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/system/core/template/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + 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. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + 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 + + 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. diff --git a/system/core/template/pom.xml b/system/core/template/pom.xml new file mode 100644 index 00000000..2dff1361 --- /dev/null +++ b/system/core/template/pom.xml @@ -0,0 +1,50 @@ + + + + system-core + ru.entaxy.esb.system.core + 1.8.0 + + 4.0.0 + + template + bundle + + SYSTEM :: ENTAXY :: TEMPLATE + SYSTEM :: ENTAXY :: TEMPLATE + + + + javax.xml.bind;version="[2,3)", + javax.xml.bind.annotation;version="[2,3)", + javax.persistence;version="[2,3)", + org.hibernate, + org.hibernate.cfg, + org.hibernate.service, + org.hibernate.jpa, + org.hibernate.proxy, + javassist.util.proxy, + * + + + ru.entaxy.esb.system.core.template.* + + + + + + org.osgi + osgi.core + ${osgi.version} + provided + + + ru.entaxy.esb.system.commons + system-commons + ${project.version} + + + + \ No newline at end of file diff --git a/system/core/template/src/main/java/ru/entaxy/esb/system/core/template/Template.java b/system/core/template/src/main/java/ru/entaxy/esb/system/core/template/Template.java new file mode 100644 index 00000000..c0dd25a6 --- /dev/null +++ b/system/core/template/src/main/java/ru/entaxy/esb/system/core/template/Template.java @@ -0,0 +1,37 @@ +/*- + * ~~~~~~licensing~~~~~~ + * template + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.template; + +import org.osgi.framework.BundleContext; + +import java.net.URL; +import java.util.Map; + +public interface Template { + String getTemplateName(); + + URL getTemplateLocation(); + + Map getParams(); + + void setBundleContext(BundleContext bundleContext); + + String getTemplateFileName(); +} diff --git a/system/core/template/src/main/java/ru/entaxy/esb/system/core/template/TemplateCollector.java b/system/core/template/src/main/java/ru/entaxy/esb/system/core/template/TemplateCollector.java new file mode 100644 index 00000000..01302e6d --- /dev/null +++ b/system/core/template/src/main/java/ru/entaxy/esb/system/core/template/TemplateCollector.java @@ -0,0 +1,29 @@ +/*- + * ~~~~~~licensing~~~~~~ + * template + * ========== + * Copyright (C) 2020 - 2021 EmDev LLC + * ========== + * 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. + * ~~~~~~/licensing~~~~~~ + */ +package ru.entaxy.esb.system.core.template; + +import ru.entaxy.esb.system.common.osgi.impl.CommonNamedReferenceListener; + +public class TemplateCollector extends CommonNamedReferenceListener