release version 1.10.0

This commit is contained in:
2024-12-14 04:07:49 +03:00
parent a5088587f7
commit c6b3d793c4
1916 changed files with 254306 additions and 0 deletions

View File

@ -0,0 +1,175 @@
ЛИЦЕНЗИЯ ОГРАНИЧЕННОГО ПРИМЕНЕНИЯ
Настоящий документ устанавливает для Пользователя условия применения Базовой (некоммерческой)
версии лицензии для пробного использования программного обеспечения ENTAXY, принадлежащего
Правообладателю Обществу с ограниченной ответственностью "ЕМДЕВ" (ОГРН 1057810026658, ИНН
7813313860, юридический адрес: 197022, Россия, г. Санкт-Петербург, ул. Профессора Попова,
д. 23, литера В, помещение 3Н), расположенной в сети Интернет по адресу
https://www.emdev.ru/about (далее - Компания).
Используя или получая доступ к Программному обеспечению, или нажав «Я согласен с Условиями»
(или аналогичную кнопку или флажок) после загрузки или установки Программного обеспечения,
Пользователь выражает свое согласие на обязательность условий и ограничений, изложенных в
настоящем документе, в противном случае, он должен не использовать или не получать доступ
к Программному обеспечению.
1. ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ
a) ПО Программное обеспечение, интеграционная шина «ЭНТАКСИ» (ENTAXY) в любой ее версии
или редакции, исключительные права на которую принадлежат Правообладателю.
b) Правообладатель (Компания) ООО «ЕМДЕВ», ОГРН 1057810026658, ИНН 7813313860, исключительные
права которого подтверждаются Свидетельством о государственной регистрации в Реестре программ
для ЭВМ № 2021610848 от 19.01.2021 года.
c) Пользователь юридическое или физическое лицо, получившее через скачивание с сайта
https://entaxy.ru или иным образом, дистрибутив ПО, пользующееся ПО.
d) ИС интеллектуальная собственность закреплённое законом исключительное право, а также
личные неимущественные права авторов произведений на результат интеллектуальной деятельности.
e) Подписка это коммерческое предложение Правообладателя, состоящее из Лицензии на использование
ПО и доступа к технической поддержке программного обеспечения на срок Подписки. Подписка
включает предоставление Пользователю неисключительного права использования ПО, в том числе
получение обновлений функционала ПО и безопасности ПО, исправление ошибок ПО и получение
патчей с обновлениями и исправлениями программного обеспечения. Подписка приобретается
Пользователем на период времени, указанный в Сертификате. Количество подписок устанавливается
для каждого Пользователя индивидуально в Сертификате.
f) Сертификат документ, выдаваемый Дистрибъютором или Авторизованным партнёром (Партнёром),
подтверждающий факт приобретения физическим или юридическим лицом Подписки на программное
обеспечение в ограниченном объёме и на определённый период времени.
g) Лицензия (простая (неисключительная) совокупность ограниченных прав использования ПО,
предоставленных Пользователю согласно условиям Подписки.
h) Библиотека совокупность подпрограмм и объектов, используемых для разработки программного
обеспечения.
i) Исходный код текст компьютерной программы на каком-либо языке программирования, состоящий
из одного или нескольких файлов, который может быть прочтён человеком.
j) Объектный код файл (часть машинного кода) с промежуточным представлением отдельного модуля
программы, полученный в результате обработки исходного кода, еще не связанный в полную программу.
Это машинный код для одной конкретной библиотеки или модуля, который будет составлять готовый
продукт.
k) Некоммерческое использование индивидуальное личное использование Пользователем программного
обеспечения с целью обучения работе с Программным обеспечением, для оценки или демонстрации
возможностей Программного обеспечения, при котором, Пользователем не извлекается коммерческая
выгода и/или не идёт в доход денежное вознаграждение при использовании Программного обеспечения.
2. ДОПУСТИМЫЕ СПОСОБЫ ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
2.1. Правообладатель предоставляет Пользователю ограниченное право использования Программного
обеспечения на условиях простой (неисключительной) лицензии в объёме, ограниченном правом
воспроизведения полной рабочей версии программного обеспечения, новых версий программного обеспечения
в памяти оборудования и его запуска на оборудовании в соответствии со ст. 1280 ГК РФ.
2.2. Право на использование Программного обеспечения, предоставляемое Пользователю, носит
неисключительный характер.
2.3. Пользователю предоставляется всемирная, неисключительная, не подлежащая сублицензированию,
лицензия на ограниченное использование Программного обеспечения.
2.4. Пользователь, имеющий Базовую (некоммерческую) версию лицензии для пробного использования
имеет право приобрести Подписку на программное обеспечение. В этом случае Пользователь обязан
обратиться в службу поддержки Правообладателя по адресу: https://entaxy.ru/ для изменения
вида лицензии с Базовой бесплатной версии на Подписки.
2.5. Срок использования скачанной Пользователем базовой (некоммерческой) версии лицензии для
пробного использования программного обеспечения не ограничен.
2.6. Использование Пользователем настоящего программного обеспечения в целях разработки,
модификации, обновления другого ПО, принадлежащего третьим лицам, а не Правообладателю,
без разрешения Правообладателя не допускается.
3. АВТОРСКОЕ ПРАВО.
3.1. Все авторские права, все права интеллектуальной собственности на Программное обеспечение
и любые его копии принадлежат Правообладателю.
3.2. Все авторские права, все права интеллектуальной собственности в отношении любого контента,
к которому можно получить доступ с помощью Программного обеспечения, является собственностью
соответствующего владельца контента и защищается применимым законодательством об авторском
праве или другими законами и договорами об интеллектуальной собственности.
3.3. Условия использования Программного обеспечения.
Лицензия, предоставленная Пользователю, действительна только в том случае, если Пользователь
придерживается следующих условий:
3.3.1. Принятие уведомлений об авторских правах. Пользователю запрещается удалять или изменять
какие-либо уведомления об авторских правах или лицензиях, которые появляются при использовании
Программного обеспечения или на нем.
3.3.2. Модификация. Пользователю запрещается модифицировать, изменять, декомпилировать,
расшифровывать, дизассемблировать, переводить или реверсировать, перепроектировать
Программное обеспечение.
3.3.3. Распространение. Пользователю запрещается сублицензировать, передавать право использования
ПО или иным образом распространять или предоставлять Программное обеспечение любой третьей стороне.
3.3.4. SaaS. За исключением случаев, когда это разрешено Правообладателем, Пользователю запрещено
использовать Программное обеспечение в коммерческих целях для оказания услуг третьим лицам.
4. ОТВЕТСТВЕННОСТЬ ПРАВООБЛАДАТЕЛЯ ПРИ НАРУШЕНИИ ПОЛЬЗОВАТЕЛЕМ ПРАВ «ИС»
4.1. Правообладатель не несет никаких обязательств в отношении каких-либо претензий к Пользователю
на предмет нарушения последним прав Интеллектуальной собственности, возникших в связи с
использованием Пользователем:
4.1.1. Любых компонентов программного обеспечения с открытым исходным кодом, включенных в
Программное обеспечение;
4.1.2. Любого нарушения правил использования Программного обеспечения, установленного условиями
настоящего соглашения;
4.1.3. Любого использования Программного обеспечения в сочетании с другими ПО, оборудованием,
или данными, не предоставленными Пользователю Правообладателем;
4.1.4. Любого изменения Программного обеспечения любым третьим лицом, а не Правообладателем.
5. НАСТОЯЩИМ ПРАВООБЛАДАТЕЛЬ ЗАЯВЛЯЕТ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ ПОЛЬЗОВАТЕЛЮ
ПО ПРИНЦИПУ «AS IS» - «КАК ЕСТЬ». НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ ПРАВООБЛАДАТЕЛЬ НЕ ГАРАНТИРУЕТ
И НЕ ОБЕЩАЕТ, ЧТО ПРЕДОСТАВЛЕННОЕ ИМ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ ПОДХОДИТЬ ИЛИ НЕ ПОДХОДИТЬ
ДЛЯ КОНКРЕТНЫХ ЦЕЛЕЙ ПОЛЬЗОВАТЕЛЯ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ ОТВЕЧАТЬ ВСЕМ КОММЕРЧЕСКИМ
И ЛИЧНЫМ СУБЪЕКТИВНЫМ ОЖИДАНИЯМ ПОЛЬЗОВАТЕЛЯ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ РАБОТАТЬ
ИСПРАВНО, БЕЗ ТЕХНИЧЕСКИХ ОШИБОК, БЫСТРО И БЕСПЕРЕБОЙНО.
6. ОГРАНИЧЕНИЕ ОТВЕТСТВЕННОСТИ.
НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ ПРАВООБЛАДАТЕЛЬ ИЛИ ЕГО АФФИЛЛИРОВАННЫЕ ЛИЦА НЕ НЕСУТ ПЕРЕД ПОЛЬЗОВАТЕЛЕМ
ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЯМЫЕ ИЛИ КОСВЕННЫЕ УБЫТКИ ПОЛЬЗОВАТЕЛЯ, ЕГО РАСХОДЫ ИЛИ РЕАЛЬНЫЙ УЩЕРБ,
ВКЛЮЧАЯ, ПОМИМО ПРОЧЕГО, ПРОСТОИ; УТРАТУ БИЗНЕСА; УПУЩЕННУЮ ВЫГОДУ; НЕДОПОЛУЧЕННУЮ ПРИБЫЛЬ;
ПОТЕРЮ ИЛИ ПОВРЕЖДЕНИЕ ДАННЫХ, ИМУЩЕСТВА И ИНОЕ.
ОГРАНИЧЕНИЯ ПРИМЕНЯЮТСЯ НЕЗАВИСИМО ОТ ОСНОВАНИЯ НАСТУПЛЕНИЯ ОТВЕТСТВЕННОСТИ; В ТОМ ЧИСЛЕ ВСЛЕДСТВИЕ
ДЕЙСТВИЯ ИЛИ БЕЗДЕЙСТВИЯ, НЕБРЕЖНОСТИ, УМЫСЛА, ПРЯМОГО ИЛИ КОСВЕННОГО; НЕОСТОРОЖНОСТИ; ЗАБЛУЖДЕНИЯ;
КЛЕВЕТЫ; НАРУШЕНИЯ КОНФИДЕНЦИАЛЬНОСТИ ИЛИ ПРАВА ИНТЕЛЛЕКТУАЛЬНОЙ СОБСТВЕННОСТИ; ИЛИ ЛЮБОЕ ДРУГОЕ
ОСНОВАНИЕ НАСТУПЛЕНИЯ ОТВЕТСТВЕННОСТИ.
7. ОБЯЗАННОСТЬ ПОЛЬЗОВАТЕЛЯ:
Не осуществлять самостоятельно и (или) с привлечением третьих лиц нижеследующие действия
(включая, но не ограничиваясь) по:
-дизассемблированию и (или) декомпилированию (преобразованию объектного кода в исходный код)
Программного обеспечения;
-модификации Программного обеспечения, в том числе вносить изменения в объектный код, исходный
код Программного обеспечения, за исключением тех изменений, которые вносятся средствами,
включёнными в Программное обеспечение и описанными непосредственно в документации к нему;
-созданию условий для использования Программного обеспечения лицами, не имеющими прав на
использование данного Программного обеспечения, включая (но не ограничиваясь) вмешательство
третьих лиц в функционирование Программного обеспечения, предоставление третьим лицам доступа
к исследованию и (или) замене настроек Программного обеспечения, включая его первичную установку;
-распространению Программного обеспечения в целом или в части (включая приложенную к нему документацию).
8. БИБЛИОТЕКА ПО. ИСПОЛЬЗУЕМЫЕ ПРОГРАММНЫЕ СРЕДСТВА.
8.1. Настоящим, Правообладатель заверяет, что Библиотека программного обеспечения состоит из
лицензионных продуктов, используемых на законных основаниях, а
именно https://entaxy.ru/libs/licenses/root-aggregated.deps.
8.2. Любые программные средства, применяемые Пользователем при работе с ПО, должны быть
совместимы с библиотекой ПО, указанной в п.8.1. настоящего соглашения.
8.3. Перечень внешних модулей ПО, указанный в п.8.1 настоящего соглашения, может изменяться
Правообладателем в одностороннем порядке, в зависимости от выпуска релизов программного обеспечения,
содержащих все изменения и дополнения программного обеспечения.
9. ВНЕСЕНИЕ ИЗМЕНЕНИЙ В ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ.
9.1. Программное обеспечение, интеграционная шина «ЭНТАКСИ» (ENTAXY) является свободно распространяемым
программным обеспечением.
9.2. Пользователь имеет право вносить изменения в исходный код программного обеспечения исключительно
с согласия Правообладателя в порядке предложения изменений/правок/дополнений через механизм
«Pull Requests» в открытом репозитории Правообладателя по адресу: https://git.entaxy.ru/entaxy/entaxy-public.
9.3. Любые изменения программного обеспечения, осуществляемые Пользователем без соблюдения условий
пункта 9.2. настоящего документа, являются нарушением авторских и смежных прав Правообладателя,
прав интеллектуальной собственности Правообладателя и влекут применение к Пользователю мер
ответственности в соответствии с условиями настоящей Лицензии, а также применимого законодательства
Российской Федерации.
10. ЗАКЛЮЧИТЕЛЬНЫЕ ПОЛОЖЕНИЯ.
10.1. В случае нарушения Пользователем любого из условий настоящей Лицензии, Правообладатель имеет
право взыскать с Пользователя любые причинённые таким нарушением убытки, реальный ущерб,
недополученную прибыль, упущенную выгоду, а также в случае нарушения Пользователем условий
пункта 9.2 настоящего соглашения, в том числе, взыскать с Пользователя штраф в размере
2 000 000 (Два миллиона) рублей за каждый установленный случай несанкционированного изменения
исходного или объектного кода Программного обеспечения «Энтакси» (Entaxy).
10.2. В рамках исполнения Пользователем обязательств по настоящей Лицензии, применимое
законодательство Российской Федерации.
10.3. Если какое-либо положение настоящей Лицензии будет признано судом недействительным,
остальные положения будут продолжать своё действие, а Пользователь будет обязан продолжать
исполнять свои обязанности в соответствии с этими положениями.

View File

@ -0,0 +1,56 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.entaxy.esb.platform.runtime</groupId>
<artifactId>core</artifactId>
<version>1.10.0</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>artifact-management-extensions</artifactId>
<packaging>bundle</packaging>
<name>ENTAXY :: PLATFORM :: CORE :: ARTIFACT MANAGEMENT EXTENSIONS</name>
<description>ENTAXY :: PLATFORM :: CORE :: ARTIFACT MANAGEMENT EXTENSIONS</description>
<properties>
<bundle.osgi.export.pkg>
ru.entaxy.platform.core.artifact.ext.binary,
ru.entaxy.platform.core.artifact.ext.features,
ru.entaxy.platform.core.artifact.ext.impl,
ru.entaxy.platform.core.artifact.ext
</bundle.osgi.export.pkg>
<bundle.osgi.private.pkg>
ru.entaxy.platform.core.artifact.ext.internal,
ru.entaxy.platform.core.artifact.ext.features.impl
</bundle.osgi.private.pkg>
</properties>
<dependencies>
<dependency>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>artifact-management</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>org.apache.karaf.features.core</artifactId>
<version>${karaf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.cellar</groupId>
<artifactId>org.apache.karaf.cellar.features</artifactId>
<version>${cellar.version}</version>
</dependency>
<dependency>
<groupId>ru.entaxy.esb.platform.runtime.base</groupId>
<artifactId>cellar-extensions</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,33 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext;
public interface ArtifactExtended {
String ARTIFACT_CATEGORY_UNTYPED_BINARY = "UNTYPED_BINARY";
String ARTIFACT_CATEGORY_FEATURE = "FEATURE";
}

View File

@ -0,0 +1,58 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.ext.features.FeatureInstaller;
import ru.entaxy.platform.core.artifact.ext.features.FeaturesInstaller;
import ru.entaxy.platform.core.artifact.ext.features.impl.FeatureInstallerImpl;
import ru.entaxy.platform.core.artifact.ext.features.impl.FeaturesInstallerImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.AbstractTypedInstallerFactory;
import ru.entaxy.platform.core.artifact.installer.builder.typed.TypedInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.typed.TypedInstallerFactoryDescriptor;
@TypedInstallerFactoryDescriptor(supportedClasses = {FeaturesInstaller.class, FeatureInstaller.class},
supportedTypes = {Artifact.ARTIFACT_CATEGORY_FEATURES, ArtifactExtended.ARTIFACT_CATEGORY_FEATURE})
public class ExtTypedInstallerFactory extends AbstractTypedInstallerFactory {
@Override
protected TypedInstaller doCreate(String type) {
if (Artifact.ARTIFACT_CATEGORY_FEATURES.equalsIgnoreCase(type)) {
return new FeaturesInstallerImpl();
}
return null;
}
@Override
protected TypedInstaller doCreate(Class<? extends TypedInstaller> targetClass) {
if (FeaturesInstaller.class.equals(targetClass))
return new FeaturesInstallerImpl();
if (FeatureInstaller.class.equals(targetClass))
return new FeatureInstallerImpl();
return null;
}
}

View File

@ -0,0 +1,32 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext;
public interface SequenceSupport<T> {
T inSequence(String sequenceId);
}

View File

@ -0,0 +1,135 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.binary;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.core.artifact.DefaultArtifact;
/**
* Allowed content types: InputStream, File, byte[]
*/
public abstract class AbstractBinaryArtifact extends DefaultArtifact {
private static final Logger LOG = LoggerFactory.getLogger(AbstractBinaryArtifact.class);
@Override
public void setContent(Object content) {
super.setContent(content);
}
@Override
public void toFile(File destination) {
if (content == null)
return;
if (content instanceof File) {
try {
Files.copy(((File) content).getAbsoluteFile().toPath(), destination.getAbsoluteFile().toPath(),
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
LOG.error("Error saving file", e);
}
return;
}
if (content instanceof InputStream) {
try {
InputStream is = (InputStream) content;
if (is.markSupported()) {
is.mark(0);
}
Files.copy((InputStream) content, destination.getAbsoluteFile().toPath(),
StandardCopyOption.REPLACE_EXISTING);
if (is.markSupported()) {
is.reset();
}
} catch (IOException e) {
LOG.error("Error saving file", e);
}
return;
}
if (content instanceof byte[]) {
try (InputStream is = new ByteArrayInputStream((byte[]) content)) {
Files.copy(is, destination.getAbsoluteFile().toPath(),
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
LOG.error("Error saving file", e);
}
return;
}
super.toFile(destination);
}
@Override
public byte[] asByteArray() {
if (content == null)
return new byte[0];
if (content instanceof byte[])
return (byte[]) content;
if (content instanceof InputStream)
try {
byte[] byteArray;
InputStream is = (InputStream) content;
if (is.markSupported()) {
is.mark(0);
}
byteArray = IOUtils.toByteArray(is);
if (is.markSupported()) {
is.reset();
}
return byteArray;
} catch (IOException e) {
LOG.error("Error getting bytes", e);
return new byte[0];
}
if (content instanceof File)
try (InputStream is = new FileInputStream((File) content)) {
return IOUtils.toByteArray(is);
} catch (Exception e) {
LOG.error("Error getting bytes", e);
return new byte[0];
}
return super.asByteArray();
}
}

View File

@ -0,0 +1,39 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.binary;
import java.io.File;
import java.io.InputStream;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.annotation.ArtifactSupport;
@ArtifactSupport(supportedCategory = Artifact.ARTIFACT_CATEGORY_JAR,
supportedContentClasses = {File.class, InputStream.class, byte[].class},
defaultArtifactType = "jar")
public class JarArtifact extends AbstractBinaryArtifact {
}

View File

@ -0,0 +1,39 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.binary;
import java.io.File;
import java.io.InputStream;
import ru.entaxy.platform.core.artifact.annotation.ArtifactSupport;
import ru.entaxy.platform.core.artifact.ext.ArtifactExtended;
@ArtifactSupport(supportedCategory = ArtifactExtended.ARTIFACT_CATEGORY_UNTYPED_BINARY,
supportedContentClasses = {File.class, InputStream.class, byte[].class},
defaultArtifactType = "jar")
public class UntypedBinaryArtifact extends AbstractBinaryArtifact {
}

View File

@ -0,0 +1,51 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features;
import ru.entaxy.platform.core.artifact.ext.SequenceSupport;
import ru.entaxy.platform.core.artifact.installer.builder.typed.TypedInstaller;
public interface FeatureInstaller extends TypedInstaller, SequenceSupport<FeatureInstaller> {
public interface FeatureInstallDescriptor extends TypedInstaller {
FeatureInstallDescriptor version(String version);
FeatureInstallDescriptor noRefresh();
FeatureInstallDescriptor noStart();
FeatureInstallDescriptor noManage();
FeatureInstallDescriptor upgrade();
FeatureInstallDescriptor feature(String name);
}
FeatureInstallDescriptor feature(String name);
}

View File

@ -0,0 +1,77 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import ru.entaxy.platform.base.support.xml.CommonXMLUtils;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.annotation.ArtifactSupport;
import ru.entaxy.platform.core.artifact.ext.binary.AbstractBinaryArtifact;
@ArtifactSupport(supportedCategory = Artifact.ARTIFACT_CATEGORY_FEATURES,
supportedContentClasses = {File.class, InputStream.class, byte[].class, Document.class, String.class},
defaultArtifactType = "xml")
public class FeaturesArtifact extends AbstractBinaryArtifact {
private static final Logger LOG = LoggerFactory.getLogger(FeaturesArtifact.class);
@Override
public void toFile(File destination) {
if (content == null)
return;
if (content instanceof Document) {
String data = null;
try {
data = CommonXMLUtils.doc2string((Document) content);
} catch (Exception e) {
LOG.error("Error converting Document to String for artifact [" + getCoordinates().toMavenString() + "]",
e);
return;
}
try (InputStream is = new ByteArrayInputStream(data.getBytes())) {
Files.copy(is, destination.getAbsoluteFile().toPath(),
StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
LOG.error("Error saving to file for artifact [" + getCoordinates().toMavenString() + "]", e);
return;
}
return;
}
super.toFile(destination);
}
}

View File

@ -0,0 +1,39 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features;
import ru.entaxy.platform.core.artifact.ext.SequenceSupport;
import ru.entaxy.platform.core.artifact.installer.builder.typed.TypedInstaller;
public interface FeaturesInstaller extends TypedInstaller, SequenceSupport<FeaturesInstaller> {
FeaturesInstaller installAllFeatures();
FeaturesInstaller refresh();
FeaturesInstaller installFeatures(String... features);
}

View File

@ -0,0 +1,121 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features.impl;
import java.util.ArrayList;
import java.util.List;
import org.apache.karaf.cellar.features.management.CellarFeaturesMBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.base.support.osgi.OSGIUtils;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
import ru.entaxy.platform.core.artifact.installer.builder.impl.cluster.ClusterTypedInstallerHelper;
import ru.entaxy.platform.runtime.cellar.sequence.CellarSequenceManager;
public class CellarFeaturesInstallerHelper extends ClusterTypedInstallerHelper
implements FeaturesInstallerConfigurableHelper {
private static final Logger LOG = LoggerFactory.getLogger(CellarFeaturesInstallerHelper.class);
protected FeaturesInstallerHelperConfig config;
public FeaturesInstallerHelperConfig getConfig() {
return config;
}
@Override
public void setConfig(FeaturesInstallerHelperConfig config) {
this.config = config;
}
protected CellarFeaturesMBean getFeaturesService() throws Exception {
if (CommonUtils.isValid(config.getSequenceId())) {
CellarSequenceManager seqManager =
OSGIUtils.services().ofClass(CellarSequenceManager.class).waitService(2000).get();
return seqManager.getSequencedHelper(config.getSequenceId(), CellarFeaturesMBean.class);
}
return OSGIUtils.services().ofClass(CellarFeaturesMBean.class).waitService(2000).get();
}
@Override
public InstallationResultImpl install(InstallationResultImpl installationResult) {
CellarFeaturesMBean featuresService;
try {
featuresService = getFeaturesService();
} catch (Exception e) {
LOG.error("Error getting CellarFeaturesMBean service", e);
return installationResult.failed("Error getting CellarFeaturesMBean service").error(e);
}
List<String> groupsToInstall = new ArrayList<>();
for (String groupName : getGroups())
if (checkGroup(groupName))
if (!groupsToInstall.contains(groupName))
groupsToInstall.add(groupName);
if (groupsToInstall.size() == 0) {
return installationResult.failed("No groups to install to");
}
// TODO decide if we really need several groups
// now we use only the first one
String groupToInstall = groupsToInstall.get(0);
String repositoryUrl = config.getSourceLocation();
if (repositoryUrl.indexOf(':') < 0)
repositoryUrl = "mvn:" + repositoryUrl;
try {
if (featuresService.getRepositories(groupToInstall).contains(repositoryUrl)) {
if (config.isRefresh())
featuresService.refreshRepository(groupToInstall, repositoryUrl);
} else {
featuresService.addRepository(groupToInstall, repositoryUrl, null, config.isInstallAllFetures());
}
if (!config.isInstallAllFetures())
for (String feature : config.getFeaturesToInstall())
featuresService.installFeature(groupToInstall, feature);
return installationResult.installed();
} catch (Exception e) {
LOG.error("Error installing repository [" + repositoryUrl + "]", e);
return installationResult.failed("Error installing repository [" + repositoryUrl + "]").error(e);
}
}
@Override
public InstallationResultImpl uninstall(InstallationResultImpl installationResult) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,192 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features.impl;
import java.util.ArrayList;
import java.util.List;
import org.apache.karaf.cellar.features.management.CellarFeaturesMBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.base.support.osgi.OSGIUtils;
import ru.entaxy.platform.core.artifact.ext.features.impl.FeatureInstallerImpl.FeatureInstallDescriptorImpl;
import ru.entaxy.platform.core.artifact.ext.impl.ClusterTypedConfigurableHelper;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
import ru.entaxy.platform.runtime.cellar.sequence.CellarSequenceManager;
public class FeatureInstallerClusterHelper extends ClusterTypedConfigurableHelper<FeatureInstallerImpl>
implements FeatureInstallerConfigurableHelper {
private static final Logger LOG = LoggerFactory.getLogger(FeatureInstallerClusterHelper.class);
protected CellarFeaturesMBean getFeaturesService() throws Exception {
if (CommonUtils.isValid(config.sequenceId)) {
CellarSequenceManager seqManager =
OSGIUtils.services().ofClass(CellarSequenceManager.class).waitService(2000).get();
return seqManager.getSequencedHelper(config.sequenceId, CellarFeaturesMBean.class);
}
return OSGIUtils.services().ofClass(CellarFeaturesMBean.class).waitService(2000).get();
}
@Override
public InstallationResultImpl install(InstallationResultImpl installationResult) {
CellarFeaturesMBean featuresService;
try {
featuresService = getFeaturesService();
} catch (Exception e) {
LOG.error("Error getting CellarFeaturesMBean service", e);
return installationResult.failed("Error getting CellarFeaturesMBean service").error(e);
}
List<String> groupsToInstall = new ArrayList<>();
for (String groupName : getGroups())
if (checkGroup(groupName))
if (!groupsToInstall.contains(groupName))
groupsToInstall.add(groupName);
if (groupsToInstall.size() == 0) {
return installationResult.failed("No groups to install to");
}
// TODO decide if we really need several groups
// now we use only the first one
String groupToInstall = groupsToInstall.get(0);
boolean hasFailed = false;
boolean hasSuccessfull = false;
for (FeatureInstallDescriptorImpl descriptor : config.descriptors.values()) {
InstallationResultImpl subResult = InstallationResultImpl.create();
subResult.object(descriptor.featureName);
try {
// convert version to OSGI-style version
// mj.mn.p-q -> mj.mn.p.q
String finalFeatureVersion = descriptor.featureVersion;
if (CommonUtils.isValid(finalFeatureVersion)) {
finalFeatureVersion = finalFeatureVersion.replace('-', '.');
}
featuresService.installFeature(groupToInstall, descriptor.featureName,
finalFeatureVersion,
descriptor.noRefresh,
descriptor.noStart,
descriptor.noManage,
descriptor.upgrade);
subResult.installed();
hasSuccessfull = true;
} catch (Exception e) {
LOG.error("Error installing repository [" + descriptor.featureName + "]", e);
subResult.failed("Error installing feature [" + descriptor.featureName + "]").error(e);
hasFailed = true;
}
installationResult.subResult(subResult);
}
if (!hasFailed)
installationResult.installed();
else {
if (hasSuccessfull) {
installationResult.message("HAS FAILED SUBRESULTS");
installationResult.installed();
} else {
installationResult.failed();
}
}
return installationResult;
}
@Override
public InstallationResultImpl uninstall(InstallationResultImpl installationResult) {
CellarFeaturesMBean featuresService;
try {
featuresService = getFeaturesService();
} catch (Exception e) {
LOG.error("Error getting CellarFeaturesMBean service", e);
return installationResult.failed("Error getting CellarFeaturesMBean service").error(e);
}
List<String> groupsToUninstall = new ArrayList<>();
for (String groupName : getGroups())
if (checkGroup(groupName))
if (!groupsToUninstall.contains(groupName))
groupsToUninstall.add(groupName);
if (groupsToUninstall.size() == 0) {
return installationResult.failed("No groups to uninstall from");
}
// TODO decide if we really need several groups
// now we use only the first one
String groupToUninstall = groupsToUninstall.get(0);
boolean hasFailed = false;
boolean hasSuccessfull = false;
for (FeatureInstallDescriptorImpl descriptor : config.descriptors.values()) {
InstallationResultImpl subResult = InstallationResultImpl.create();
subResult.object(descriptor.featureName);
try {
// convert version to OSGI-style version
// mj.mn.p-q -> mj.mn.p.q
String finalFeatureVersion = descriptor.featureVersion;
if (CommonUtils.isValid(finalFeatureVersion)) {
finalFeatureVersion = finalFeatureVersion.replace('-', '.');
}
featuresService.uninstallFeature(groupToUninstall, descriptor.featureName, finalFeatureVersion,
descriptor.noRefresh);
subResult.uninstalled();
hasSuccessfull = true;
} catch (Exception e) {
LOG.error("Error uninstalling repository [" + descriptor.featureName + "]", e);
subResult.failed("Error uninstalling feature [" + descriptor.featureName + "]").error(e);
hasFailed = true;
}
installationResult.subResult(subResult);
}
if (!hasFailed)
installationResult.uninstalled();
else {
if (hasSuccessfull) {
installationResult.message("HAS FAILED SUBRESULTS");
installationResult.uninstalled();
} else {
installationResult.failed();
}
}
return installationResult;
}
}

View File

@ -0,0 +1,36 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features.impl;
import ru.entaxy.platform.core.artifact.ext.impl.InstallerConfigurableHelper;
public interface FeatureInstallerConfigurableHelper extends InstallerConfigurableHelper<FeatureInstallerImpl> {
@Override
default Class<FeatureInstallerImpl> getConfigClass() {
return FeatureInstallerImpl.class;
}
}

View File

@ -0,0 +1,172 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features.impl;
import java.util.HashMap;
import java.util.Map;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
import ru.entaxy.platform.core.artifact.ext.features.FeatureInstaller;
import ru.entaxy.platform.core.artifact.ext.impl.ExtendedTypedInstallerImpl;
import ru.entaxy.platform.core.artifact.installer.builder.InstallationResult;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerHelperImpl;
public class FeatureInstallerImpl
extends ExtendedTypedInstallerImpl<FeatureInstallerConfigurableHelper, FeatureInstallerImpl>
implements FeatureInstaller {
protected static class FeatureInstallDescriptorImpl implements FeatureInstallDescriptor {
FeatureInstallerImpl featureInstaller;
String featureName;
String featureVersion;
boolean noStart = false;
boolean noRefresh = false;
boolean noManage = false;
boolean upgrade = false;
protected FeatureInstallDescriptorImpl(FeatureInstallerImpl featureInstaller, String name) {
this.featureInstaller = featureInstaller;
this.featureName = name;
}
@Override
public void clearInstaller() {
featureInstaller.clearInstaller();
}
@Override
public void setSourceLocation(String sourceLocation) {}
@Override
public String getSourceLocation() {
return featureInstaller.getSourceLocation();
}
@Override
public void setArtifact(DeployedArtifact artifact) {
featureInstaller.setArtifact(artifact);
}
@Override
public DeployedArtifact getArtifact() {
return featureInstaller.getArtifact();
}
@Override
public String getTypedName() {
return featureInstaller.getTypedName();
}
@Override
public void setTypedName(String typedName) {
featureInstaller.setTypedName(typedName);
}
@Override
public InstallationResult install() {
return featureInstaller.install();
}
@Override
public InstallationResult uninstall() {
return featureInstaller.uninstall();
}
@Override
public FeatureInstallDescriptor version(String version) {
this.featureVersion = version;
return this;
}
@Override
public FeatureInstallDescriptor noRefresh() {
this.noRefresh = true;
return this;
}
@Override
public FeatureInstallDescriptor noStart() {
this.noStart = true;
return this;
}
@Override
public FeatureInstallDescriptor noManage() {
this.noManage = true;
return this;
}
@Override
public FeatureInstallDescriptor upgrade() {
this.upgrade = true;
return this;
}
@Override
public FeatureInstallDescriptor feature(String name) {
return featureInstaller.feature(name);
}
}
protected final Map<String, FeatureInstallDescriptorImpl> descriptors = new HashMap<>();
protected String sequenceId = null;
@Override
public FeatureInstaller inSequence(String sequenceId) {
this.sequenceId = sequenceId;
return this;
}
@Override
public FeatureInstallDescriptor feature(String name) {
if (descriptors.containsKey(name))
return descriptors.get(name);
FeatureInstallDescriptorImpl descriptor = new FeatureInstallDescriptorImpl(this, name);
descriptors.put(name, descriptor);
return descriptor;
}
@Override
protected Class<FeatureInstallerConfigurableHelper> getHelperClass() {
return FeatureInstallerConfigurableHelper.class;
}
@Override
protected <H extends TypedInstallerHelperImpl> H createClusterHelper(Class<H> targetClass) {
return (H) new FeatureInstallerClusterHelper();
}
@Override
protected <H extends TypedInstallerHelperImpl> H createLocalHelper(Class<H> targetClass) {
return (H) new FeatureInstallerLocalHelper();
}
}

View File

@ -0,0 +1,46 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features.impl;
import ru.entaxy.platform.core.artifact.ext.impl.LocalTypedConfigurableHelper;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
public class FeatureInstallerLocalHelper extends LocalTypedConfigurableHelper<FeatureInstallerImpl>
implements FeatureInstallerConfigurableHelper {
@Override
public InstallationResultImpl install(InstallationResultImpl installationResult) {
// TODO Auto-generated method stub
return null;
}
@Override
public InstallationResultImpl uninstall(InstallationResultImpl installationResult) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,38 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features.impl;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
public interface FeaturesInstallerConfigurableHelper {
void setConfig(FeaturesInstallerHelperConfig config);
public InstallationResultImpl install(InstallationResultImpl installationResult);
public InstallationResultImpl uninstall(InstallationResultImpl installationResult);
}

View File

@ -0,0 +1,42 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features.impl;
import java.util.List;
public interface FeaturesInstallerHelperConfig {
boolean isRefresh();
boolean isInstallAllFetures();
List<String> getFeaturesToInstall();
String getSourceLocation();
String getSequenceId();
}

View File

@ -0,0 +1,46 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features.impl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerHelperImpl;
public abstract class FeaturesInstallerHelperImpl extends TypedInstallerHelperImpl
implements FeaturesInstallerConfigurableHelper {
protected FeaturesInstallerHelperConfig config;
public FeaturesInstallerHelperConfig getConfig() {
return config;
}
@Override
public void setConfig(FeaturesInstallerHelperConfig config) {
this.config = config;
}
}

View File

@ -0,0 +1,133 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import ru.entaxy.platform.core.artifact.ext.features.FeaturesInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.InstallationResult;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
import ru.entaxy.platform.core.artifact.installer.builder.impl.cluster.ClusterTypedInstallerHelper;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.HelperCreator;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerHelperImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerImpl;
public class FeaturesInstallerImpl extends TypedInstallerImpl
implements FeaturesInstaller, HelperCreator, FeaturesInstallerHelperConfig {
protected boolean isInstallAllFeatures = false;
protected boolean isRefresh = false;
protected List<String> featuresToInstall = new ArrayList<>();
protected FeaturesInstallerConfigurableHelper featuresHelper;
protected String sequenceId = null;
@Override
public FeaturesInstaller inSequence(String sequenceId) {
this.sequenceId = sequenceId;
return this;
}
@Override
public InstallationResult install() {
InstallationResultImpl result = InstallationResultImpl.create();
if (this.featuresHelper == null)
result.failed("HELPER NOT FOUND");
else
this.featuresHelper.install(result);
return result.property("artifact", this.artifact);
}
@Override
public InstallationResult uninstall() {
InstallationResultImpl result = InstallationResultImpl.create();
if (this.featuresHelper == null)
result.failed("HELPER NOT FOUND");
else
this.featuresHelper.uninstall(result);
return result.property("artifact", this.artifact);
}
@Override
public void setHelper(TypedInstallerHelperImpl helper) {
if (helper instanceof FeaturesInstallerConfigurableHelper) {
featuresHelper = (FeaturesInstallerConfigurableHelper) helper;
featuresHelper.setConfig(this);
}
super.setHelper(helper);
}
@Override
public FeaturesInstaller installAllFeatures() {
isInstallAllFeatures = true;
return this;
}
@Override
public FeaturesInstaller installFeatures(String... features) {
if (features != null)
this.featuresToInstall = new ArrayList<>(Arrays.asList(features));
return this;
}
@Override
public <H extends TypedInstallerHelperImpl> H createHelper(Class<H> targetClass) {
if (ClusterTypedInstallerHelper.class.isAssignableFrom(targetClass))
return (H) new CellarFeaturesInstallerHelper();
return (H) new LocalFeaturesInstallerHelper();
}
@Override
public FeaturesInstaller refresh() {
isRefresh = true;
return this;
}
@Override
public boolean isRefresh() {
return isRefresh;
}
@Override
public boolean isInstallAllFetures() {
return isInstallAllFeatures;
}
@Override
public List<String> getFeaturesToInstall() {
return featuresToInstall;
}
@Override
public String getSequenceId() {
return sequenceId;
}
}

View File

@ -0,0 +1,44 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.features.impl;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
public class LocalFeaturesInstallerHelper extends FeaturesInstallerHelperImpl {
@Override
public InstallationResultImpl install(InstallationResultImpl installationResult) {
// TODO Auto-generated method stub
return null;
}
@Override
public InstallationResultImpl uninstall(InstallationResultImpl installationResult) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -0,0 +1,40 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.impl;
import ru.entaxy.platform.core.artifact.installer.builder.impl.cluster.ClusterTypedInstallerHelper;
public abstract class ClusterTypedConfigurableHelper<T> extends ClusterTypedInstallerHelper
implements InstallerConfigurableHelper<T> {
protected T config;
@Override
public void setConfig(T config) {
this.config = config;
}
}

View File

@ -0,0 +1,82 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.impl;
import ru.entaxy.platform.core.artifact.installer.builder.InstallationResult;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
import ru.entaxy.platform.core.artifact.installer.builder.impl.cluster.ClusterTypedInstallerHelper;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.HelperCreator;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerHelperImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerImpl;
public abstract class ExtendedTypedInstallerImpl<S extends InstallerConfigurableHelper<T>, T> extends TypedInstallerImpl
implements HelperCreator {
protected S localTypedHelper;
protected abstract Class<S> getHelperClass();
@Override
public InstallationResult install() {
InstallationResultImpl result = InstallationResultImpl.create();
if (localTypedHelper == null)
result.failed("HELPER NOT FOUND");
else
result = localTypedHelper.install(result);
return result;
}
@Override
public InstallationResult uninstall() {
InstallationResultImpl result = InstallationResultImpl.create();
if (localTypedHelper == null)
result.failed("HELPER NOT FOUND");
else
result = localTypedHelper.uninstall(result);
return result;
}
@Override
public void setHelper(TypedInstallerHelperImpl helper) {
if (getHelperClass().isInstance(helper)) {
this.localTypedHelper = (S) helper;
if (localTypedHelper.getConfigClass().isAssignableFrom(getClass()))
localTypedHelper.setConfig((T) this);
}
super.setHelper(helper);
}
@Override
public <H extends TypedInstallerHelperImpl> H createHelper(Class<H> targetClass) {
if (ClusterTypedInstallerHelper.class.isAssignableFrom(targetClass))
return (H) createClusterHelper(targetClass);
return (H) createLocalHelper(targetClass);
}
protected abstract <H extends TypedInstallerHelperImpl> H createClusterHelper(Class<H> targetClass);
protected abstract <H extends TypedInstallerHelperImpl> H createLocalHelper(Class<H> targetClass);
}

View File

@ -0,0 +1,41 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.impl;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
public interface InstallerConfigurableHelper<T> {
void setConfig(T config);
Class<T> getConfigClass();
public InstallationResultImpl install(InstallationResultImpl installationResult);
public InstallationResultImpl uninstall(InstallationResultImpl installationResult);
}

View File

@ -0,0 +1,40 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.impl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerHelperImpl;
public abstract class LocalTypedConfigurableHelper<T> extends TypedInstallerHelperImpl
implements InstallerConfigurableHelper<T> {
protected T config;
@Override
public void setConfig(T config) {
this.config = config;
}
}

View File

@ -0,0 +1,55 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management-extensions
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.ext.internal;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import ru.entaxy.platform.core.artifact.Artifacts;
import ru.entaxy.platform.core.artifact.ext.ExtTypedInstallerFactory;
import ru.entaxy.platform.core.artifact.ext.binary.JarArtifact;
import ru.entaxy.platform.core.artifact.ext.binary.UntypedBinaryArtifact;
import ru.entaxy.platform.core.artifact.installer.builder.typed.TypedInstallerManager;
import ru.entaxy.platform.core.artifact.service.ArtifactService;
@Component(service = Registrator.class, immediate = true)
public class Registrator {
@Reference(cardinality = ReferenceCardinality.MANDATORY)
ArtifactService artifactService;
@Activate
public void activate() {
Artifacts.registerSupport(JarArtifact.class);
Artifacts.registerSupport(UntypedBinaryArtifact.class);
TypedInstallerManager.register(new ExtTypedInstallerFactory());
}
}

View File

@ -0,0 +1,74 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.installer.builder.typed;
import java.util.Arrays;
import java.util.List;
public abstract class AbstractTypedInstallerFactory implements TypedInstallerFactory {
protected List<Class<? extends TypedInstaller>> supportedClasses;
protected List<String> supportedTypes;
protected AbstractTypedInstallerFactory() {
super();
if (this.getClass().isAnnotationPresent(TypedInstallerFactoryDescriptor.class)) {
TypedInstallerFactoryDescriptor descriptor =
this.getClass().getAnnotation(TypedInstallerFactoryDescriptor.class);
this.supportedClasses = Arrays.asList(descriptor.supportedClasses());
this.supportedTypes = Arrays.asList(descriptor.supportedTypes());
}
}
@Override
public List<Class<? extends TypedInstaller>> getSupportedClasses() {
return supportedClasses;
}
@Override
public List<String> getSupportedTypes() {
return supportedTypes;
}
@Override
public TypedInstaller create(String type) {
if (!supportedTypes.contains(type))
return null;
return doCreate(type);
}
protected abstract TypedInstaller doCreate(String type);
@Override
public TypedInstaller create(Class<? extends TypedInstaller> targetClass) {
if (!supportedClasses.contains(targetClass))
return null;
return doCreate(targetClass);
}
protected abstract TypedInstaller doCreate(Class<? extends TypedInstaller> targetClass);
}

View File

@ -0,0 +1,98 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.installer.builder.typed;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BlueprintInstallerImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BundleInstallerImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.JarInstallerImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerImpl;
@TypedInstallerFactoryDescriptor(supportedTypes = {Artifact.ARTIFACT_CATEGORY_BLUEPRINT,
Artifact.ARTIFACT_CATEGORY_BUNDLE, Artifact.ARTIFACT_CATEGORY_JAR},
supportedClasses = {BlueprintInstaller.class, BundleInstaller.class, JarInstaller.class})
public class DefaultTypedInstallerFactory extends AbstractTypedInstallerFactory {
protected static DefaultTypedInstallerFactory INSTANCE;
public static DefaultTypedInstallerFactory getInstance() {
if (INSTANCE == null)
INSTANCE = new DefaultTypedInstallerFactory();
return INSTANCE;
}
protected static Map<String, Class<? extends TypedInstallerImpl>> typeToClassMap;
protected static Map<Class<? extends TypedInstaller>, Class<? extends TypedInstallerImpl>> classToClassMap;
static {
typeToClassMap = new HashMap<>();
typeToClassMap.put(Artifact.ARTIFACT_CATEGORY_BLUEPRINT, BlueprintInstallerImpl.class);
typeToClassMap.put(Artifact.ARTIFACT_CATEGORY_BUNDLE, BundleInstallerImpl.class);
typeToClassMap.put(Artifact.ARTIFACT_CATEGORY_JAR, JarInstallerImpl.class);
classToClassMap = new HashMap<>();
classToClassMap.put(BlueprintInstaller.class, BlueprintInstallerImpl.class);
classToClassMap.put(BundleInstaller.class, BundleInstallerImpl.class);
classToClassMap.put(JarInstaller.class, JarInstallerImpl.class);
}
protected DefaultTypedInstallerFactory() {
super();
}
@Override
protected TypedInstaller doCreate(String type) {
Class<? extends TypedInstallerImpl> clazz = typeToClassMap.get(type);
if (clazz == null)
return null;
return createOfClass(clazz);
}
@Override
protected TypedInstaller doCreate(Class<? extends TypedInstaller> targetClass) {
Class<? extends TypedInstallerImpl> clazz = classToClassMap.get(targetClass);
if (clazz == null)
return null;
return createOfClass(clazz);
}
protected TypedInstaller createOfClass(Class<? extends TypedInstallerImpl> clazz) {
try {
Constructor<?> constructor = clazz.getConstructor();
return (TypedInstaller) constructor.newInstance();
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
return null;
}
}
}

View File

@ -0,0 +1,40 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.installer.builder.typed;
import java.util.List;
public interface TypedInstallerFactory {
List<Class<? extends TypedInstaller>> getSupportedClasses();
List<String> getSupportedTypes();
TypedInstaller create(String type);
TypedInstaller create(Class<? extends TypedInstaller> targetClass);
}

View File

@ -0,0 +1,42 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.installer.builder.typed;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(TYPE)
public @interface TypedInstallerFactoryDescriptor {
Class<? extends TypedInstaller>[] supportedClasses();
String[] supportedTypes();
}

View File

@ -0,0 +1,192 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.installer.builder.typed;
import java.util.HashMap;
import java.util.Map;
import ru.entaxy.platform.core.artifact.installer.builder.ClusterInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.Installer;
import ru.entaxy.platform.core.artifact.installer.builder.LocalInstaller;
public class TypedInstallerManager {
protected static Map<Class<? extends Installer<?>>, TypedInstallerStorage> storages = new HashMap<>();
protected static TypedInstallerStorage commonStorage = new TypedInstallerStorage();
static {
storages.put(LocalInstaller.class, new TypedInstallerStorage());
storages.put(ClusterInstaller.class, new TypedInstallerStorage());
}
protected static Object storagesLock = new Object();
public static void register(String artifactType,
TypedInstallerFactory factory) {
register(commonStorage, artifactType, factory);
}
public static void register(TypedInstallerFactory factory) {
register(commonStorage, factory);
}
protected static TypedInstallerStorage getOrCreateStorage(Class<? extends Installer<?>> installerClass) {
if (!storages.containsKey(installerClass)) {
synchronized (storagesLock) {
storages.put(installerClass, new TypedInstallerStorage());
}
}
return storages.get(installerClass);
}
public static void register(Class<? extends Installer<?>> installerClass, String artifactType,
TypedInstallerFactory factory) {
register(getOrCreateStorage(installerClass), artifactType, factory);
}
public static void register(Class<? extends Installer<?>> installerClass,
TypedInstallerFactory factory) {
register(getOrCreateStorage(installerClass), factory);
}
protected static void register(TypedInstallerStorage storage, TypedInstallerFactory factory) {
for (String type : factory.getSupportedTypes())
register(storage, type, factory);
}
protected static void register(TypedInstallerStorage storage, String artifactType,
TypedInstallerFactory factory) {
storage.register(artifactType, factory);
}
public static TypedInstaller create(Object owner, String type) {
return create(owner, type, false);
}
public static TypedInstaller create(Object owner, String type, boolean strict) {
for (Class<? extends Installer<?>> installerClass : storages.keySet())
if (installerClass.isInstance(owner))
return create(installerClass, type, strict);
if (strict)
return null;
return create(null, type, strict);
}
public static TypedInstaller create(Class<? extends Installer<?>> installerClass, String type) {
return create(installerClass, type, false);
}
public static TypedInstaller create(Class<? extends Installer<?>> installerClass, String type, boolean strict) {
TypedInstallerStorage storage = installerClass == null ? null : storages.get(installerClass);
TypedInstaller result = null;
if (storage != null) {
result = storage.create(type);
}
if (result != null)
return result;
if (strict)
return null;
else
return commonStorage.create(type);
}
public static TypedInstaller create(Object owner, Class<? extends TypedInstaller> typedClass) {
return create(owner, typedClass, false);
}
public static TypedInstaller create(Object owner, Class<? extends TypedInstaller> typedClass, boolean strict) {
for (Class<? extends Installer<?>> installerClass : storages.keySet())
if (installerClass.isInstance(owner))
return create(installerClass, typedClass, strict);
if (strict)
return null;
return create(null, typedClass, strict);
}
public static TypedInstaller create(Class<? extends Installer<?>> installerClass,
Class<? extends TypedInstaller> typedClass) {
return create(installerClass, typedClass, false);
}
public static TypedInstaller create(Class<? extends Installer<?>> installerClass,
Class<? extends TypedInstaller> typedClass, boolean strict) {
TypedInstallerStorage storage = installerClass == null ? null : storages.get(installerClass);
TypedInstaller result = null;
if (storage != null) {
result = storage.create(typedClass);
}
if (result != null)
return result;
if (strict)
return null;
else
return commonStorage.create(typedClass);
}
protected static class TypedInstallerStorage {
protected Map<String, TypedInstallerFactory> factories = new HashMap<>();
protected Object factoriesLock = new Object();
public void register(String type, TypedInstallerFactory factory) {
synchronized (factoriesLock) {
factories.put(type, factory);
}
}
public TypedInstaller create(String type) {
if (!factories.containsKey(type))
return null;
return factories.get(type).create(type);
}
public TypedInstaller create(Class<? extends TypedInstaller> typedClass) {
TypedInstallerFactory factory = null;
for (TypedInstallerFactory f : factories.values())
if (f.getSupportedClasses().contains(typedClass)) {
factory = f;
break;
}
if (factory == null)
return null;
return factory.create(typedClass);
}
}
}

View File

@ -0,0 +1,32 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.installer.builder.typed.impl;
public interface HelperCreator {
<H extends TypedInstallerHelperImpl> H createHelper(Class<H> targetClass);
}

View File

@ -0,0 +1,34 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.installer.builder.typed.impl;
public interface TypedInstallerHelperAware {
TypedInstallerHelperImpl getHelper();
void setHelper(TypedInstallerHelperImpl helper);
}

View File

@ -0,0 +1,30 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.installer.builder.typed.impl;
public class TypedInstallerHelperImpl {
}

View File

@ -0,0 +1,62 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.repository;
public interface RepositoryDescriptor {
String getName();
String getLocation();
String getUrl();
boolean isProxy();
boolean isMirror();
boolean isSnapshots();
String getRemotes();
boolean isReadOnly();
boolean isCopyOnChange();
boolean isEnabled();
String getUsername();
String getPassword();
String getRemoteHostSuffix();
boolean isSystem();
boolean isLookupEnabled();
}

View File

@ -0,0 +1,35 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.repository;
/*
* Internal interface to collect helpers managed by config files
*/
public interface RepositoryDescriptorCollector {
public void addRepositoryDescriptor(RepositoryDescriptor helper);
public void removeRepositoryDescriptor(RepositoryDescriptor helper);
}

View File

@ -0,0 +1,188 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.repository.impl;
import ru.entaxy.platform.core.artifact.repository.RepositoryDescriptor;
public class RepositoryDescriptorImpl implements RepositoryDescriptor {
protected String name;
String location;
String url;
boolean isProxy;
boolean isMirror;
String remotes;
boolean isReadOnly = false;
boolean copyOnChange;
String username = "";
String password = "";
boolean isSnapshots = false;
boolean isEnabled = true;
String remoteHostSuffix = "";
boolean isSystem = true;
boolean isLookupEnabled = true;
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
@Override
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public boolean isProxy() {
return isProxy;
}
public void setProxy(boolean isProxy) {
this.isProxy = isProxy;
}
@Override
public boolean isMirror() {
return isMirror;
}
public void setMirror(boolean isMirror) {
this.isMirror = isMirror;
}
@Override
public boolean isSnapshots() {
return isSnapshots;
}
public void setSnapshots(boolean isSnapshots) {
this.isSnapshots = isSnapshots;
}
@Override
public String getRemotes() {
return remotes;
}
public void setRemotes(String remotes) {
this.remotes = remotes;
}
@Override
public boolean isReadOnly() {
return isReadOnly;
}
public void setReadOnly(boolean isReadOnly) {
this.isReadOnly = isReadOnly;
}
@Override
public boolean isCopyOnChange() {
return copyOnChange;
}
public void setCopyOnChange(boolean copyOnChange) {
this.copyOnChange = copyOnChange;
}
@Override
public boolean isEnabled() {
return isEnabled;
}
public void setEnabled(boolean isEnabled) {
this.isEnabled = isEnabled;
}
@Override
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String getRemoteHostSuffix() {
return remoteHostSuffix;
}
public void setRemoteHostSuffix(String remoteHostSuffix) {
this.remoteHostSuffix = remoteHostSuffix;
}
@Override
public boolean isSystem() {
return isSystem;
}
public void setSystem(boolean isSystem) {
this.isSystem = isSystem;
}
@Override
public boolean isLookupEnabled() {
return isLookupEnabled;
}
public void setLookupEnabled(boolean isLookupEnabled) {
this.isLookupEnabled = isLookupEnabled;
}
}

View File

@ -0,0 +1,158 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.repository.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.felix.utils.properties.TypedProperties;
import org.apache.karaf.config.core.ConfigRepository;
import org.osgi.framework.InvalidSyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.base.support.osgi.OSGIUtils;
import ru.entaxy.platform.core.artifact.repository.ArtifactRepository;
public class RepositoryRegistrator {
private static final Logger log = LoggerFactory.getLogger(RepositoryRegistrator.class);
public static RepositoryRegistrator INSTANCE = new RepositoryRegistrator();
private static final String REPO_CONFIG_PID = "org.ops4j.pax.url.mvn";
private static final String PROP_ENTAXY_SYSTEM_REPO_LIST = "org.ops4j.pax.url.mvn.repositories.entaxy";
private static final String PROP_ENTAXY_CUSTOM_REPO_LIST = "org.ops4j.pax.url.mvn.repositories.entaxy.custom";
private static final String ENTAXY_PROPERTY_HTTP_PORT = "entaxy.org.osgi.service.http.port";
private static final String URL_PREFIX = "http://localhost:${" + ENTAXY_PROPERTY_HTTP_PORT + "}";
protected Map<String, ArtifactRepository> systemRepos = new HashMap<>();
protected Map<String, ArtifactRepository> customRepos = new HashMap<>();
private RepositoryRegistrator() {
}
public void addRepository(ArtifactRepository repository) {
addRepository(repository, true);
}
public void addRepository(ArtifactRepository repository, boolean httpEnabled) {
Map<String, ArtifactRepository> targetMap;
String propertyName;
if (repository.isSystem()) {
targetMap = systemRepos;
propertyName = PROP_ENTAXY_SYSTEM_REPO_LIST;
// TODO implement for initializer
return;
} else {
targetMap = customRepos;
propertyName = PROP_ENTAXY_CUSTOM_REPO_LIST;
}
targetMap.put(repository.getName(), repository);
String repositoryUrlsResult = calculatePropertyValue(targetMap, httpEnabled);
try {
setPropertyValue(propertyName, repositoryUrlsResult);
return;
} catch (IOException e) {
log.error("Error updating config", e);
} catch (InvalidSyntaxException e) {
log.error("Error updating config", e);
} catch (Exception e) {
log.error("Error updating config", e);
}
targetMap.remove(repository.getName());
}
public void removeRepository(ArtifactRepository repository) {
if (repository.isSystem()) {
systemRepos.remove(repository.getName());
} else {
customRepos.remove(repository.getName());
}
}
protected String calculatePropertyValue(Map<String, ArtifactRepository> repoMap, boolean httpEnabled) {
List<ArtifactRepository> list = new ArrayList<>(repoMap.values());
Collections.sort(list, new Comparator<ArtifactRepository>() {
@Override
public int compare(ArtifactRepository o1, ArtifactRepository o2) {
return o1.getName().compareToIgnoreCase(o2.getName());
}
});
String resultValue = "";
List<String> urlList = new ArrayList<>();
for (ArtifactRepository repo : list) {
String url = URL_PREFIX.concat(repo.getUrl())
.concat("@id=").concat(repo.getName())
.concat("@checksum=ignore")
.concat(repo.isSnapshotsAllowed() ? "@snapshots" : "");
if (!httpEnabled) {
url = url.replace("http:", "https:");
}
urlList.add(url);
}
resultValue = urlList.stream().collect(Collectors.joining(", "));
return resultValue;
}
protected void setPropertyValue(String propertyName, String propertyValue) throws Exception {
ConfigRepository configRepository =
OSGIUtils.services().ofClass(ConfigRepository.class).waitService(20000).get();
TypedProperties properties = configRepository.getConfig(REPO_CONFIG_PID);
String hashKey = propertyName + ".md5";
String newHash = DigestUtils.md5Hex(propertyValue);
String currentHash = properties.getOrDefault(hashKey, "").toString();
// To avoid extra config rewriting
// which may cause config loss while updating
if (!newHash.equals(currentHash)) {
properties.put(propertyName, propertyValue);
properties.put(hashKey, newHash);
configRepository.update(REPO_CONFIG_PID, properties);
}
}
}

View File

@ -0,0 +1,169 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT 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 ru.entaxy.esb.platform.core.cluster.persistence.handler;
import java.util.Map;
import java.util.Properties;
import org.apache.karaf.cellar.config.ClusterConfigurationEvent;
import org.apache.karaf.cellar.config.ConfigurationEventHandler;
import org.apache.karaf.cellar.config.ConfigurationSupport;
import org.apache.karaf.cellar.config.Constants;
import org.apache.karaf.cellar.core.Configurations;
import org.apache.karaf.cellar.core.Group;
import org.apache.karaf.cellar.core.control.BasicSwitch;
import org.apache.karaf.cellar.core.control.Switch;
import org.apache.karaf.cellar.core.control.SwitchStatus;
import org.apache.karaf.cellar.core.event.EventHandler;
import org.apache.karaf.cellar.core.event.EventType;
import org.osgi.service.cm.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.esb.platform.core.cluster.persistence.PersistenceManager;
/**
* LocalConfigurationEventHandler handles received configuration cluster event.
*/
public class LocalConfigurationEventHandler extends ConfigurationSupport
implements EventHandler<ClusterConfigurationEvent> {
private static final transient Logger LOGGER = LoggerFactory.getLogger(LocalConfigurationEventHandler.class);
public static final String SWITCH_ID = "org.apache.karaf.cellar.configuration.handler";
private final Switch eventSwitch = new BasicSwitch(SWITCH_ID);
private PersistenceManager persistenceManager;
@Override
public void handle(ClusterConfigurationEvent event) {
// check if the handler is ON
if (this.getSwitch().getStatus().equals(SwitchStatus.OFF)) {
LOGGER.debug("CELLAR CONFIG: {} switch is OFF, cluster event not handled", SWITCH_ID);
return;
}
if (groupManager == null) {
// in rare cases for example right after installation this happens!
LOGGER.error("CELLAR CONFIG: retrieved event {} while groupManager is not available yet!", event);
return;
}
// check if the group is local
if (!groupManager.isLocalGroup(event.getSourceGroup().getName())) {
LOGGER.debug("CELLAR CONFIG: node is not part of the event cluster group {}",
event.getSourceGroup().getName());
return;
}
// @ENTAXY:SKIP check if it's not a "local" event
//if (event.getLocal() != null && event.getLocal().getId().equalsIgnoreCase(clusterManager.getNode().getId())) {
// LOGGER.trace("CELLAR CONFIG: cluster event is local (coming from local synchronizer or listener)");
// return;
//}
Group group = event.getSourceGroup();
String groupName = group.getName();
Map<String, Properties> clusterConfigurations =
clusterManager.getMap(Constants.CONFIGURATION_MAP + Configurations.SEPARATOR + groupName);
String pid = event.getId();
if (isAllowed(event.getSourceGroup(), Constants.CATEGORY, pid, EventType.INBOUND)) {
try {
// TODO mark cluster state as needed to be saved
LOGGER.debug("-->> WE NEED TO SAVE CLUSTER STATE");
this.persistenceManager.updated();
} catch (Exception ex) {
LOGGER.error("CELLAR CONFIG: failed to read cluster configuration", ex);
}
} else
LOGGER.trace("CELLAR CONFIG: configuration PID {} is marked BLOCKED INBOUND for cluster group {}", pid,
groupName);
}
public void init() {
// nothing to do
}
public void destroy() {
// nothing to do
}
/**
* Get the cluster configuration event handler switch.
*
* @return the cluster configuration event handler switch.
*/
@Override
public Switch getSwitch() {
// load the switch status from the config
try {
Configuration configuration = configurationAdmin.getConfiguration(Configurations.NODE, null);
if (configuration != null) {
Boolean status = new Boolean((String) configuration.getProperties()
.get(Configurations.HANDLER + "." + ConfigurationEventHandler.class.getName()));
if (status) {
eventSwitch.turnOn();
} else {
eventSwitch.turnOff();
}
}
} catch (Exception e) {
// nothing to do
}
return eventSwitch;
}
/**
* Get the cluster event type.
*
* @return the cluster configuration event type.
*/
@Override
public Class<ClusterConfigurationEvent> getType() {
return ClusterConfigurationEvent.class;
}
public void setPersistenceManager(PersistenceManager persistenceManager) {
this.persistenceManager = persistenceManager;
}
}

View File

@ -0,0 +1,174 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT 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 ru.entaxy.esb.platform.core.cluster.persistence.handler;
import org.apache.karaf.cellar.core.Configurations;
import org.apache.karaf.cellar.core.control.BasicSwitch;
import org.apache.karaf.cellar.core.control.Switch;
import org.apache.karaf.cellar.core.control.SwitchStatus;
import org.apache.karaf.cellar.core.event.EventHandler;
import org.apache.karaf.cellar.core.event.EventType;
import org.apache.karaf.cellar.features.ClusterFeaturesEvent;
import org.apache.karaf.cellar.features.Constants;
import org.apache.karaf.cellar.features.FeatureState;
import org.apache.karaf.cellar.features.FeaturesEventHandler;
import org.apache.karaf.cellar.features.FeaturesSupport;
import org.apache.karaf.cellar.features.FeaturesSynchronizer;
import org.apache.karaf.features.FeatureEvent;
import org.osgi.framework.BundleContext;
import org.osgi.service.cm.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.esb.platform.core.cluster.persistence.PersistenceManager;
/**
* Handler for cluster features event.
*/
public class LocalFeaturesEventHandler extends FeaturesSupport implements EventHandler<ClusterFeaturesEvent> {
private static final transient Logger LOGGER = LoggerFactory.getLogger(FeaturesSynchronizer.class);
public static final String SWITCH_ID = "org.apache.karaf.cellar.event.features.handler";
private final Switch eventSwitch = new BasicSwitch(SWITCH_ID);
private PersistenceManager<FeatureState> persistenceManager;
public PersistenceManager<FeatureState> getPersistenceManager() {
return persistenceManager;
}
public void setPersistenceManager(PersistenceManager<FeatureState> persistenceManager) {
this.persistenceManager = persistenceManager;
}
@Override
public void init(BundleContext bundleContext) {
super.init(bundleContext);
}
@Override
public void destroy() {
super.destroy();
}
/**
* Handle a received cluster features event.
*
* @param event the received cluster feature event.
*/
public void handle(ClusterFeaturesEvent event) {
if (this.getSwitch().getStatus().equals(SwitchStatus.OFF)) {
LOGGER.debug("CELLAR FEATURE: {} switch is OFF, cluster event is not handled", SWITCH_ID);
return;
}
if (groupManager == null) {
// in rare cases for example right after installation this happens!
LOGGER.error("CELLAR FEATURE: retrieved event {} while groupManager is not available yet!", event);
return;
}
// check if the group is local
if (!groupManager.isLocalGroup(event.getSourceGroup().getName())) {
LOGGER.debug("CELLAR FEATURE: node is not part of the event cluster group {}",
event.getSourceGroup().getName());
return;
}
// check if it's not a "local" event
if (event.getLocal() != null && event.getLocal().getId().equalsIgnoreCase(clusterManager.getNode().getId())) {
LOGGER.trace("CELLAR FEATURE: cluster event is local (coming from local synchronizer or listener)");
return;
}
String name = event.getName();
String version = event.getVersion();
if (isAllowed(event.getSourceGroup(), Constants.CATEGORY, name, EventType.INBOUND) || event.getForce()) {
FeatureEvent.EventType type = event.getType();
Boolean isInstalled = isFeatureInstalledLocally(name, version);
try {
persistenceManager.updated();
} catch (Exception e) {
LOGGER.error("CELLAR FEATURE: failed to handle cluster feature event", e);
}
} else
LOGGER.trace("CELLAR FEATURE: feature {} is marked BLOCKED INBOUND for cluster group {}", name,
event.getSourceGroup().getName());
}
/**
* Get the event type that this handler is able to handle.
*
* @return the cluster features event type.
*/
@Override
public Class<ClusterFeaturesEvent> getType() {
return ClusterFeaturesEvent.class;
}
/**
* Get the handler switch.
*
* @return the handler switch.
*/
@Override
public Switch getSwitch() {
// load the switch status from the config
try {
Configuration configuration = configurationAdmin.getConfiguration(Configurations.NODE, null);
if (configuration != null) {
Boolean status = new Boolean((String) configuration.getProperties()
.get(Configurations.HANDLER + "." +
FeaturesEventHandler.class.getName()));
if (status) {
eventSwitch.turnOn();
} else {
eventSwitch.turnOff();
}
}
} catch (Exception e) {
// ignore
}
return eventSwitch;
}
}

View File

@ -0,0 +1,135 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT 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 ru.entaxy.esb.platform.core.cluster.persistence.handler;
import org.apache.karaf.cellar.core.control.BasicSwitch;
import org.apache.karaf.cellar.core.control.Switch;
import org.apache.karaf.cellar.core.control.SwitchStatus;
import org.apache.karaf.cellar.core.event.EventHandler;
import org.apache.karaf.cellar.features.ClusterRepositoryEvent;
import org.apache.karaf.cellar.features.FeaturesSupport;
import org.apache.karaf.features.RepositoryEvent;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.esb.platform.core.cluster.persistence.PersistenceManager;
/**
* Handler for cluster features repository event.
*/
public class LocalRepositoryEventHandler extends FeaturesSupport implements EventHandler<ClusterRepositoryEvent> {
private static final transient Logger LOGGER = LoggerFactory.getLogger(LocalRepositoryEventHandler.class);
public static final String SWITCH_ID = "org.apache.karaf.cellar.event.repository.handler";
private final Switch eventSwitch = new BasicSwitch(SWITCH_ID);
private PersistenceManager<String> persistenceManager;
@Override
public void init(BundleContext bundleContext) {
super.init(bundleContext);
}
@Override
public void destroy() {
super.destroy();
}
/**
* Handle cluster features repository event.
*
* @param event the cluster event to handle.
*/
@Override
public void handle(ClusterRepositoryEvent event) {
// check if the handler is ON
if (eventSwitch.getStatus().equals(SwitchStatus.OFF)) {
LOGGER.debug("CELLAR FEATURE: {} switch is OFF, cluster event is not handled", SWITCH_ID);
return;
}
if (groupManager == null) {
// in rare cases for example right after installation this happens!
LOGGER.error("CELLAR FEATURE: retrieved event {} while groupManager is not available yet!", event);
return;
}
// check if the group is local
if (!groupManager.isLocalGroup(event.getSourceGroup().getName())) {
LOGGER.debug("CELLAR FEATURE: node is not part of the event cluster group");
return;
}
// check if the event is not "local"
if (event.getLocal() != null && event.getLocal().getId().equals(clusterManager.getNode().getId())) {
LOGGER.trace("CELLAR FEATURE: event is local (coming from synchronizer or listener)");
return;
}
String uri = event.getId();
RepositoryEvent.EventType type = event.getType();
try {
// TODO mark cluster state as needed to be saved
LOGGER.debug("-->> WE NEED TO SAVE CLUSTER STATE");
this.persistenceManager.updated();
} catch (Exception e) {
LOGGER.error("CELLAR FEATURE: failed to add/remove repository URL {}", uri, e);
}
}
@Override
public Class<ClusterRepositoryEvent> getType() {
return ClusterRepositoryEvent.class;
}
@Override
public Switch getSwitch() {
return eventSwitch;
}
public void setPersistenceManager(PersistenceManager<String> persistenceManager) {
this.persistenceManager = persistenceManager;
}
}

View File

@ -0,0 +1,6 @@
ignite.work.directory.path=data/ignite
ignite.common.cache.name=entaxy
ignite.common.cache.cacheMode=REPLICATED
ignite.common.cache.rebalanceMode=SYNC
ignite.common.cache.atomicityMode=TRANSACTIONAL
ignite.common.cache.backups=2

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<config xmlns="urn:org:jgroups"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd">
<UDP
mcast_port="${jgroups.udp.mcast_port:45588}"
ip_ttl="4"
tos="8"
ucast_recv_buf_size="5M"
ucast_send_buf_size="5M"
mcast_recv_buf_size="5M"
mcast_send_buf_size="5M"
max_bundle_size="64K"
enable_diagnostics="true"
thread_naming_pattern="cl"
thread_pool.min_threads="0"
thread_pool.max_threads="20"
thread_pool.keep_alive_time="30000"
bind_port="45800"
port_range="20"
diagnostics_port="45500"
diagnostics_port_range="20"
diag_enable_udp="false"
diag_enable_tcp="true"
/>
<PING />
<MERGE3 max_interval="30000"
min_interval="10000"/>
<FD_SOCK
client_bind_port="45600"
port_range="20"
start_port="45700"
/>
<FD_ALL/>
<VERIFY_SUSPECT timeout="1500" />
<BARRIER />
<pbcast.NAKACK2 xmit_interval="500"
xmit_table_num_rows="100"
xmit_table_msgs_per_row="2000"
xmit_table_max_compaction_time="30000"
use_mcast_xmit="false"
discard_delivered_msgs="true"/>
<UNICAST3 xmit_interval="500"
xmit_table_num_rows="100"
xmit_table_msgs_per_row="2000"
xmit_table_max_compaction_time="60000"
conn_expiry_timeout="0"/>
<pbcast.STABLE desired_avg_gossip="50000"
max_bytes="4M"/>
<pbcast.GMS print_local_addr="false" join_timeout="2000"
view_bundling="true"/>
<UFC max_credits="2M"
min_threshold="0.4"/>
<MFC max_credits="2M"
min_threshold="0.4"/>
<FRAG2 frag_size="60K" />
<RSVP resend_interval="2000" timeout="10000"/>
<pbcast.STATE_TRANSFER />
<CENTRAL_LOCK use_thread_id_for_lock_owner="false"/>
</config>

View File

@ -0,0 +1,658 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-design
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.design.openapi;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.json.Json;
import javax.json.stream.JsonGenerator;
import org.apache.commons.io.FileUtils;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.Generator;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.serialization.JavaParserJsonSerializer;
import com.github.javaparser.utils.SourceRoot;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.parser.OpenAPIV3Parser;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import javassist.CtClass;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.support.design.classgen.Cu2JaConverter;
@Deprecated(since = "1.10", forRemoval = true)
public class EntaxyOpenApiGeneratorDeprecated {
private static final Logger log = LoggerFactory.getLogger(EntaxyOpenApiGeneratorDeprecated.class);
public enum GENERATION_STATUS {
NONE,
IN_PROGRESS,
OK,
FAILED
}
public enum GENERATION_PHASE {
NONE,
CHECK,
GENERATE_JAVA,
PARSE_JAVA,
GENERATE_CLASSES
}
public enum GENERATION_PHASE_STATE {
PRE_EXECUTE,
IN_PROGRESS,
DONE
}
public static interface GenerationCallback {
public void event(GenerationResult generationResult);
}
public static abstract class AbstractResult {
public GENERATION_STATUS status = GENERATION_STATUS.NONE;
public List<Throwable> exceptions = new ArrayList<>();;
public Map<String, Object> properties = new HashMap<>();
public AbstractResult status(GENERATION_STATUS newStatus) {
this.status = newStatus;
return this;
}
public boolean isOk() {
return GENERATION_STATUS.OK.equals(status);
}
public boolean isFailed() {
return GENERATION_STATUS.FAILED.equals(status);
}
public boolean isInProgress() {
return GENERATION_STATUS.IN_PROGRESS.equals(status);
}
public boolean isFinished() {
return isOk() || isFailed();
}
}
public static class GenerationResult extends AbstractResult {
public GENERATION_PHASE currentPhase = GENERATION_PHASE.NONE;
public Map<GENERATION_PHASE, PhaseResult> phases = new LinkedHashMap<>();
public EntaxyOpenApiGeneratorDeprecated generator;
public GenerationResult phase(GENERATION_PHASE phase) {
return this.phase(phase, new PhaseResult());
}
public GenerationResult phase(GENERATION_PHASE phase, PhaseResult phaseResult) {
phases.put(phase, phaseResult);
currentPhase = phase;
return this;
}
public GenerationResult phaseStatus(GENERATION_STATUS newStatus) {
this.currentPhaseResult().status = newStatus;
this.generator.callback(this);
return this;
}
public GenerationResult phaseInProgress() {
this.currentPhaseResult().state(GENERATION_PHASE_STATE.IN_PROGRESS);
return this.phaseStatus(GENERATION_STATUS.IN_PROGRESS);
}
public GenerationResult phaseOk() {
this.currentPhaseResult().state(GENERATION_PHASE_STATE.DONE);
return this.phaseStatus(GENERATION_STATUS.OK);
}
public GenerationResult phaseFailed() {
this.currentPhaseResult().state(GENERATION_PHASE_STATE.DONE);
return this.phaseStatus(GENERATION_STATUS.FAILED);
}
public PhaseResult currentPhaseResult() {
return this.phases.get(currentPhase);
}
public boolean isCurrentPhaseOk() {
return (currentPhase!=null)
&& currentPhaseResult().status.equals(GENERATION_STATUS.OK);
}
}
public static class PhaseResult extends AbstractResult {
public List<Object> resultObjects = new ArrayList<>();
public GENERATION_PHASE_STATE currentState = GENERATION_PHASE_STATE.PRE_EXECUTE;
public PhaseResult state(GENERATION_PHASE_STATE state) {
this.currentState = state;
return this;
}
}
protected static abstract class PhaseProcessor {
protected EntaxyOpenApiGeneratorDeprecated generator;
protected GenerationResult generationResult;
public void process(EntaxyOpenApiGeneratorDeprecated generator, GenerationResult generationResult) {
this.generator = generator;
this.generationResult = generationResult;
this.generationResult.phase(getPhase());
this.generator.callback(this.generationResult);
execute();
}
protected abstract GENERATION_PHASE getPhase();
protected void execute() {
this.generationResult.currentPhaseResult().state(GENERATION_PHASE_STATE.IN_PROGRESS);
this.generator.callback(this.generationResult);
doExecute();
this.generationResult.currentPhaseResult().state(GENERATION_PHASE_STATE.DONE);
this.generator.callback(this.generationResult);
};
protected abstract void doExecute();
protected void failWithException(Throwable e) {
generationResult.exceptions.add(e);
generationResult.currentPhaseResult().exceptions.add(e);
generationResult.currentPhaseResult().state(GENERATION_PHASE_STATE.DONE);
generationResult.phaseFailed();
generator.callback(generationResult);
}
}
protected static class CheckPhaseProcessor extends PhaseProcessor {
public CheckPhaseProcessor() {
super();
}
@Override
protected GENERATION_PHASE getPhase() {
return GENERATION_PHASE.CHECK;
}
@Override
protected void doExecute() {
this.generationResult.currentPhaseResult().status(GENERATION_STATUS.IN_PROGRESS);
SwaggerParseResult result = (new OpenAPIV3Parser()).readLocation(
this.generator.getUrl()
, null
, null);
OpenAPI api = result.getOpenAPI();
if (api != null) {
this.generationResult.currentPhaseResult().properties.put("api", api);
this.generationResult.properties.put("api", api);
this.generationResult.currentPhaseResult().status(GENERATION_STATUS.OK);
} else {
this.generationResult.currentPhaseResult().status(GENERATION_STATUS.FAILED);
}
}
}
protected static class GenerateJavaPhaseProcessor extends PhaseProcessor {
public GenerateJavaPhaseProcessor() {
super();
}
@Override
protected GENERATION_PHASE getPhase() {
return GENERATION_PHASE.GENERATE_JAVA;
}
@Override
protected void doExecute() {
this.generationResult.generator.initializeRootFolder();
this.generationResult.phaseInProgress();
CodegenConfigurator configurator = new CodegenConfigurator();
Generator codeGenerator;
if (!CommonUtils.isValid(generator.getApiPackage())) {
generator.setApiPackage("entaxy.openapi."
+ generator.apiTitleConverted
+ ".v_" + generator.apiVersionConverted);
}
if (!CommonUtils.isValid(generator.getModelPackage())) {
generator.setModelPackage(generator.apiPackage + ".model");
}
configurator.setApiPackage(generator.apiPackage);
configurator.setModelPackage(generator.modelPackage);
configurator.setGeneratorName("jaxrs-cxf");
configurator.setOutputDir(
Paths.get(generator.targetDir.getAbsolutePath(), "sources")
.toFile()
.getAbsolutePath());
configurator.setInputSpec(generator.getUrl());
try {
final ClientOptInput clientOptInput = configurator.toClientOptInput();
codeGenerator = new DefaultGenerator(false);
codeGenerator.opts(clientOptInput);
codeGenerator.generate();
generationResult.properties.put("generator.java.source.path", "sources/src/gen/java");
generationResult.phaseOk();
} catch (Exception e) {
log.error("openapi-generator finished with exception", e);
failWithException(e);
}
}
}
protected static class ParseJavaPhaseProcessor extends PhaseProcessor {
public ParseJavaPhaseProcessor() {
super();
}
@Override
protected GENERATION_PHASE getPhase() {
return GENERATION_PHASE.PARSE_JAVA;
}
@Override
protected void doExecute() {
List<CompilationUnit> apiCUs;
List<CompilationUnit> modelCUs;
String sourceRootFolder = Paths.get( generator.targetDir.getAbsolutePath()
,generationResult.properties.get("generator.java.source.path")
.toString()).toAbsolutePath().toString();
String apiPackageFolder = generator.apiPackage.replace('.', '/');
String modelPackageFolder = generator.modelPackage.replace('.', '/');
String apiFolder = Paths.get(sourceRootFolder, apiPackageFolder).toAbsolutePath().toString();
String modelFolder = Paths.get(sourceRootFolder, modelPackageFolder).toAbsolutePath().toString();
File apiFolderFile = new File(apiFolder);
File[] apis = apiFolderFile.listFiles((dir, name)->dir.getAbsolutePath().equals(apiFolderFile.getAbsolutePath()) && name.endsWith(".java"));
File modelFolderFile = new File(modelFolder);
File[] models = modelFolderFile.listFiles((dir, name)->dir.getAbsolutePath().equals(modelFolderFile.getAbsolutePath()) && name.endsWith(".java"));
String parsedRootFolder = Paths.get(generator.targetDir.getAbsolutePath(), "parsed").toAbsolutePath().toString();
try {
Files.createDirectories(Paths.get(parsedRootFolder));
Files.createDirectories(Paths.get(parsedRootFolder, "model"));
} catch (IOException e) {
log.error("Error creating directories", e);
}
SourceRoot sourceRoot = new SourceRoot(Paths.get(sourceRootFolder));
JavaParserJsonSerializer serializer = new JavaParserJsonSerializer();
apiCUs = new ArrayList<>();
modelCUs = new ArrayList<>();
for (int i=0; i<apis.length; i++) {
String targetPath = Paths.get(parsedRootFolder, apis[i].getName()+".json").toAbsolutePath().toString();
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
CompilationUnit cu = sourceRoot.parse(generator.apiPackage, apis[i].getName());
apiCUs.add(cu);
JsonGenerator generator = Json.createGeneratorFactory(null).createGenerator(bos);
serializer.serialize(cu, generator);
Files.write(Paths.get(targetPath), bos.toByteArray(), StandardOpenOption.CREATE);
} catch (IOException e) {
log.error("javaparser finished with exception", e);
failWithException(e);
return;
}
}
if (models!=null && models.length>0) {
for (int i=0; i<models.length; i++) {
String targetPath = Paths.get(parsedRootFolder, "model", models[i].getName()+".json").toAbsolutePath().toString();
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
CompilationUnit cu = sourceRoot.parse(generator.modelPackage, models[i].getName());
modelCUs.add(cu);
JsonGenerator generator = Json.createGeneratorFactory(null).createGenerator(bos);
serializer.serialize(cu, generator);
Files.write(Paths.get(targetPath), bos.toByteArray(), StandardOpenOption.CREATE);
} catch (IOException e) {
log.error("javaparser finished with exception", e);
failWithException(e);
return;
}
}
generationResult.properties.put("parser.cu.model", modelCUs);
}
generationResult.properties.put("parser.java.path", parsedRootFolder);
generationResult.properties.put("parser.cu.api", apiCUs);
generationResult.phaseOk();
}
}
protected static class GenerateClassesPhaseProcessor extends PhaseProcessor {
public GenerateClassesPhaseProcessor() {
super();
}
@Override
protected GENERATION_PHASE getPhase() {
return GENERATION_PHASE.GENERATE_CLASSES;
}
@Override
protected void doExecute() {
@SuppressWarnings("unchecked")
List<CompilationUnit> apiCUs = (List<CompilationUnit>)generationResult.properties
.getOrDefault("parser.cu.api", Collections.emptyList());
@SuppressWarnings("unchecked")
List<CompilationUnit> modelCUs = (List<CompilationUnit>)generationResult.properties
.getOrDefault("parser.cu.model", Collections.emptyList());
try {
String classesRootFolder = Paths.get(generator.targetDir.getAbsolutePath(), "classes").toString();
Files.createDirectories(Paths.get(classesRootFolder));
Cu2JaConverter converter = new Cu2JaConverter();
List<String> modelClassesImports = new ArrayList<>();
for (CompilationUnit cu: modelCUs)
modelClassesImports.add(cu.getPackageDeclaration().get().getName().asString()
+ "." + cu.getPrimaryType().get().getNameAsString());
List<CtClass> modelClasses = new ArrayList<>();
List<CtClass> apiClasses = new ArrayList<>();
for (CompilationUnit cu: modelCUs) {
converter.clearImports();
for (String s: modelClassesImports)
converter.addImport(s);
modelClasses.add(converter.convert(cu));
}
for (CompilationUnit cu: apiCUs) {
converter.clearImports();
for (String s: modelClassesImports)
converter.addImport(s);
apiClasses.add(converter.convert(cu));
}
List<String> apiClassesFinal = new ArrayList<>();
List<String> modelClassesFinal = new ArrayList<>();
for (CtClass ctClass: modelClasses) {
if (ctClass == null)
continue;
ctClass.writeFile(classesRootFolder);
modelClassesFinal.add(ctClass.getName());
}
for (CtClass ctClass: apiClasses) {
if (ctClass == null)
continue;
ctClass.writeFile(classesRootFolder);
apiClassesFinal.add(ctClass.getName());
}
generationResult.properties.put("classes.path", classesRootFolder);
generationResult.properties.put("classes.api", apiClassesFinal);
generationResult.properties.put("classes.model", modelClassesFinal);
generationResult.phaseOk();
} catch (Exception e) {
log.error("javassist finished with exception", e);
failWithException(e);
return;
}
}
}
protected static Map<GENERATION_PHASE, Class<? extends PhaseProcessor>> processorMap = new HashMap<>();
protected static List<GENERATION_PHASE> defaultPlan = new LinkedList<>();
static {
processorMap.put(GENERATION_PHASE.CHECK, CheckPhaseProcessor.class);
processorMap.put(GENERATION_PHASE.GENERATE_JAVA, GenerateJavaPhaseProcessor.class);
processorMap.put(GENERATION_PHASE.PARSE_JAVA, ParseJavaPhaseProcessor.class);
processorMap.put(GENERATION_PHASE.GENERATE_CLASSES, GenerateClassesPhaseProcessor.class);
defaultPlan.add(GENERATION_PHASE.CHECK);
defaultPlan.add(GENERATION_PHASE.GENERATE_JAVA);
defaultPlan.add(GENERATION_PHASE.PARSE_JAVA);
defaultPlan.add(GENERATION_PHASE.GENERATE_CLASSES);
}
protected String url;
protected String rootFolder = UUID.randomUUID().toString();
protected SwaggerParseResult parseResult;
protected String apiTitleConverted = "unknown_api";
protected String apiVersionConverted = "1_0_0";
protected String apiPackage;
protected String modelPackage;
protected List<GENERATION_PHASE> executionPlan = defaultPlan;
protected GenerationCallback callback;
protected GenerationResult result = new GenerationResult();
protected File targetDir = null;
public GenerationResult generate() {
result.generator = this;
result.phase(GENERATION_PHASE.NONE).status(GENERATION_STATUS.NONE);
callback(result);
if (executionPlan != null) {
result.status(GENERATION_STATUS.IN_PROGRESS);
callback(result);
for (GENERATION_PHASE phase: executionPlan) {
PhaseProcessor processor = null;
try {
processor = processorMap.get(phase).getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
result.currentPhaseResult().exceptions.add(e);
result.exceptions.add(e);
result.status(GENERATION_STATUS.FAILED);
callback(result);
return result;
}
processor.process(this, result);
if (result.currentPhaseResult().status.equals(GENERATION_STATUS.FAILED))
return result;
}
result.status(GENERATION_STATUS.OK);
callback(result);
}
return result;
}
protected void initializeRootFolder() {
if (this.targetDir != null)
return;
Path target = Paths.get(
System.getProperty("karaf.home")
, "temp"
, rootFolder);
this.targetDir = target.toFile();
if (!this.targetDir.exists())
this.targetDir.mkdirs();
}
public void clean() {
try {
FileUtils.deleteDirectory(targetDir);
} catch (IOException e) {
log.error("Failed deleting [" + targetDir.getAbsolutePath() + "]", e);
}
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getRootFolder() {
return rootFolder;
}
public void setRootFolder(String rootFolder) {
this.rootFolder = rootFolder;
}
public SwaggerParseResult getParseResult() {
return parseResult;
}
public GenerationCallback getCallback() {
return callback;
}
public void setCallback(GenerationCallback callback) {
this.callback = callback;
}
public void callback(GenerationResult generationResult) {
if (callback != null)
callback.event(generationResult);
}
public List<GENERATION_PHASE> getExecutionPlan() {
return executionPlan;
}
public void setExecutionPlan(List<GENERATION_PHASE> executionPlan) {
this.executionPlan = executionPlan;
}
public String getApiTitleConverted() {
return apiTitleConverted;
}
public void setApiTitleConverted(String apiTitleConverted) {
this.apiTitleConverted = apiTitleConverted;
}
public String getApiVersionConverted() {
return apiVersionConverted;
}
public void setApiVersionConverted(String apiVersionConverted) {
this.apiVersionConverted = apiVersionConverted;
}
public String getApiPackage() {
return apiPackage;
}
public void setApiPackage(String apiPackage) {
this.apiPackage = apiPackage;
}
public String getModelPackage() {
return modelPackage;
}
public void setModelPackage(String modelPackage) {
this.modelPackage = modelPackage;
}
public File getTargetDir() {
return targetDir;
}
}

View File

@ -0,0 +1,121 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-design
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.design.openapi.utils;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.StringTokenizer;
public class CompilationUnit implements ICompilationUnit {
public static final int BUFFER_SIZE = 8192;
private final String className;
private final String sourceFile;
private final String ignoredPart;
private static final Logger log = LoggerFactory.getLogger(CompilationUnit.class);
public CompilationUnit(String sourceFile, String className, String ignoredPart) {
this.className = className;
this.sourceFile = sourceFile;
this.ignoredPart = ignoredPart;
}
@Override
public char[] getFileName() {
int i = sourceFile.indexOf(ignoredPart);
String result = sourceFile;
if (i >= 0) {
result = result.substring(i + ignoredPart.length());
}
return result.toCharArray();
}
@Override
public char[] getContents() {
char[] result = null;
try (FileInputStream is = new FileInputStream(sourceFile);
InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
Reader reader = new BufferedReader(isr)) {
char[] chars = new char[BUFFER_SIZE];
StringBuilder source = new StringBuilder();
int count;
while ((count = reader.read(chars, 0, chars.length)) > 0) {
source.append(chars, 0, count);
}
result = new char[source.length()];
source.getChars(0, result.length, result, 0);
} catch (IOException e) {
log.error("Failed to get source file {} contents", sourceFile, e);
}
return result;
}
@Override
public char[] getMainTypeName() {
int dot = className.lastIndexOf('.');
if (dot > 0) {
return className.substring(dot + 1).toCharArray();
}
return className.toCharArray();
}
@Override
public char[][] getPackageName() {
StringTokenizer st = new StringTokenizer(className, ".");
char[][] result = new char[st.countTokens() - 1][];
for (int i = 0; i < result.length; i++) {
String token = st.nextToken();
result[i] = token.toCharArray();
}
return result;
}
public static ICompilationUnit build(Path fullPath, String containingDir) {
Path name = fullPath.getFileName();
String directory = fullPath.toString();
int i = directory.indexOf(containingDir);
if (i != -1) {
String packageDir = directory
.substring(i + containingDir.length())
.replace(name.toString(), "").replace('\\', '/');
String className = name.toString().replaceAll(".java$", "");
if (!packageDir.endsWith("/")) {
packageDir = packageDir + "/";
}
if (packageDir.startsWith("/")) {
packageDir = packageDir.substring(1);
}
return new CompilationUnit(fullPath.toString(), packageDir.replaceAll("/", ".") + className, containingDir);
}
return null;
}
}

View File

@ -0,0 +1,115 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-design
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.design.openapi.utils;
import com.google.common.base.Joiner;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CompilerRequestor implements ICompilerRequestor {
private static final Logger log = LoggerFactory.getLogger(CompilerRequestor.class);
private final Map<String, List<String>> problemList = new HashMap<>();
private final String outputDir;
public CompilerRequestor(String outputDir) {
this.outputDir = outputDir;
}
@Override
public void acceptResult(CompilationResult result) {
if (result.hasProblems()) {
IProblem[] problems = result.getProblems();
for (IProblem problem : problems) {
if (problem.isError()) {
String fileName =
new String(problem.getOriginatingFileName());
List<String> errors = problemList.getOrDefault(fileName, new ArrayList<>());
errors.add(String.format("%s %d: %s", fileName, problem.getSourceLineNumber(), problem.getMessage()));
problemList.put(fileName, errors);
}
}
}
if (problemList.isEmpty()) {
createOutDirIfNotExist(this.outputDir);
ClassFile[] classFiles = result.getClassFiles();
for (ClassFile classFile : classFiles) {
char[][] compoundName =
classFile.getCompoundName();
StringBuilder classFileName = new StringBuilder(outputDir).append('/');
for (int j = 0; j < compoundName.length; j++) {
if (j > 0) {
classFileName.append('/');
}
classFileName.append(compoundName[j]);
if (j == compoundName.length - 2) {
createOutDirIfNotExist(classFileName.toString());
}
}
byte[] bytes = classFile.getBytes();
classFileName.append(".class");
try (FileOutputStream classStream = new FileOutputStream(classFileName.toString());
BufferedOutputStream bos = new BufferedOutputStream(classStream)) {
bos.write(bytes);
} catch (IOException e) {
log.error("Error writing classfile {}", classFileName, e);
}
}
} else {
problemList.forEach((file, errors) -> log.error("Error compiling {}:\n {}", file, Joiner.on("\n\t").join(errors)));
}
}
private void createOutDirIfNotExist(String directory) {
File f = new File(directory);
if (! f.exists()) {
if (! f.mkdirs()) {
throw new RuntimeException("Cannot create output directory " + directory);
}
} else if (! f.isDirectory()) {
throw new RuntimeException("File " + directory + " is not directory");
}
}
public Map<String, List<String>> getProblemList() {
return problemList;
}
}

View File

@ -0,0 +1,155 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-design
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.design.openapi.utils;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class INameEnvironmentImpl implements INameEnvironment {
private static final Logger log = LoggerFactory.getLogger(INameEnvironmentImpl.class);
private final ClassLoader classLoader;
public INameEnvironmentImpl(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
StringBuilder result = new StringBuilder();
for(int i = 0; i < compoundTypeName.length; i++) {
if (i > 0) {
result.append(".");
}
result.append(compoundTypeName[i]);
}
String typeName = result.toString();
log.debug("Searching for any package type {}", typeName);
return findType(typeName);
}
@Override
public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
StringBuilder buffer = new StringBuilder();
int i=0;
for (; i < packageName.length; i++) {
if (i > 0) {
buffer.append('.');
}
buffer.append(packageName[i]);
}
if (i > 0) {
buffer.append('.');
}
buffer.append(typeName);
String result = buffer.toString();
log.debug("Searching for type {} in package {}", new String(typeName), result);
return findType(result);
}
private NameEnvironmentAnswer findType(String className) {
String resourceName = className.replace('.', '/') + ".class";
try (InputStream is = classLoader.getResourceAsStream(resourceName)) {
if (is != null) {
byte[] classBytes;
byte[] buf = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream(buf.length);
int count;
while ((count = is.read(buf, 0, buf.length)) > 0) {
baos.write(buf, 0, count);
}
baos.flush();
classBytes = baos.toByteArray();
char[] fileName = className.toCharArray();
ClassFileReader classFileReader = new ClassFileReader(classBytes, fileName, true);
log.debug("Found type {}", className);
return new NameEnvironmentAnswer(classFileReader, null);
} else {
log.error("Class {} not found ", className);
}
} catch (IOException | ClassFormatException e) {
log.error("Failed to get class {}", className, e);
}
return null;
}
private boolean isPackage(String resource) {
boolean result = false;
String resourceName = resource.replace('.', '/') + ".class";
try (InputStream is = classLoader.getResourceAsStream(resourceName)) {
result = is == null;
} catch (IOException e) {
result = false;
}
log.debug("isPackage({}) result: {}", resource, result);
return result;
}
@Override
public boolean isPackage(char[][] parentPackageName, char[] packageName) {
StringBuilder result = new StringBuilder();
//fast hack: package are seldom start from uppercase
String lp = new String(packageName);
if (lp.matches("^[A-Z].*?") || lp.contains("$")) {
log.debug("Skipping package check for resource {}", packageName);
return false;
}
int i = 0;
if (parentPackageName != null) {
for (; i < parentPackageName.length; i++) {
if (i > 0) {
result.append('.');
}
result.append(parentPackageName[i]);
}
}
if (Character.isUpperCase(packageName[0])) {
if (!isPackage(result.toString())) {
return false;
}
}
if (i > 0) {
result.append('.');
}
result.append(packageName);
return isPackage(result.toString());
}
@Override
public void cleanup() {
}
}

View File

@ -0,0 +1,175 @@
ЛИЦЕНЗИЯ ОГРАНИЧЕННОГО ПРИМЕНЕНИЯ
Настоящий документ устанавливает для Пользователя условия применения Базовой (некоммерческой)
версии лицензии для пробного использования программного обеспечения ENTAXY, принадлежащего
Правообладателю Обществу с ограниченной ответственностью "ЕМДЕВ" (ОГРН 1057810026658, ИНН
7813313860, юридический адрес: 197022, Россия, г. Санкт-Петербург, ул. Профессора Попова,
д. 23, литера В, помещение 3Н), расположенной в сети Интернет по адресу
https://www.emdev.ru/about (далее - Компания).
Используя или получая доступ к Программному обеспечению, или нажав «Я согласен с Условиями»
(или аналогичную кнопку или флажок) после загрузки или установки Программного обеспечения,
Пользователь выражает свое согласие на обязательность условий и ограничений, изложенных в
настоящем документе, в противном случае, он должен не использовать или не получать доступ
к Программному обеспечению.
1. ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ
a) ПО Программное обеспечение, интеграционная шина «ЭНТАКСИ» (ENTAXY) в любой ее версии
или редакции, исключительные права на которую принадлежат Правообладателю.
b) Правообладатель (Компания) ООО «ЕМДЕВ», ОГРН 1057810026658, ИНН 7813313860, исключительные
права которого подтверждаются Свидетельством о государственной регистрации в Реестре программ
для ЭВМ № 2021610848 от 19.01.2021 года.
c) Пользователь юридическое или физическое лицо, получившее через скачивание с сайта
https://entaxy.ru или иным образом, дистрибутив ПО, пользующееся ПО.
d) ИС интеллектуальная собственность закреплённое законом исключительное право, а также
личные неимущественные права авторов произведений на результат интеллектуальной деятельности.
e) Подписка это коммерческое предложение Правообладателя, состоящее из Лицензии на использование
ПО и доступа к технической поддержке программного обеспечения на срок Подписки. Подписка
включает предоставление Пользователю неисключительного права использования ПО, в том числе
получение обновлений функционала ПО и безопасности ПО, исправление ошибок ПО и получение
патчей с обновлениями и исправлениями программного обеспечения. Подписка приобретается
Пользователем на период времени, указанный в Сертификате. Количество подписок устанавливается
для каждого Пользователя индивидуально в Сертификате.
f) Сертификат документ, выдаваемый Дистрибъютором или Авторизованным партнёром (Партнёром),
подтверждающий факт приобретения физическим или юридическим лицом Подписки на программное
обеспечение в ограниченном объёме и на определённый период времени.
g) Лицензия (простая (неисключительная) совокупность ограниченных прав использования ПО,
предоставленных Пользователю согласно условиям Подписки.
h) Библиотека совокупность подпрограмм и объектов, используемых для разработки программного
обеспечения.
i) Исходный код текст компьютерной программы на каком-либо языке программирования, состоящий
из одного или нескольких файлов, который может быть прочтён человеком.
j) Объектный код файл (часть машинного кода) с промежуточным представлением отдельного модуля
программы, полученный в результате обработки исходного кода, еще не связанный в полную программу.
Это машинный код для одной конкретной библиотеки или модуля, который будет составлять готовый
продукт.
k) Некоммерческое использование индивидуальное личное использование Пользователем программного
обеспечения с целью обучения работе с Программным обеспечением, для оценки или демонстрации
возможностей Программного обеспечения, при котором, Пользователем не извлекается коммерческая
выгода и/или не идёт в доход денежное вознаграждение при использовании Программного обеспечения.
2. ДОПУСТИМЫЕ СПОСОБЫ ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
2.1. Правообладатель предоставляет Пользователю ограниченное право использования Программного
обеспечения на условиях простой (неисключительной) лицензии в объёме, ограниченном правом
воспроизведения полной рабочей версии программного обеспечения, новых версий программного обеспечения
в памяти оборудования и его запуска на оборудовании в соответствии со ст. 1280 ГК РФ.
2.2. Право на использование Программного обеспечения, предоставляемое Пользователю, носит
неисключительный характер.
2.3. Пользователю предоставляется всемирная, неисключительная, не подлежащая сублицензированию,
лицензия на ограниченное использование Программного обеспечения.
2.4. Пользователь, имеющий Базовую (некоммерческую) версию лицензии для пробного использования
имеет право приобрести Подписку на программное обеспечение. В этом случае Пользователь обязан
обратиться в службу поддержки Правообладателя по адресу: https://entaxy.ru/ для изменения
вида лицензии с Базовой бесплатной версии на Подписки.
2.5. Срок использования скачанной Пользователем базовой (некоммерческой) версии лицензии для
пробного использования программного обеспечения не ограничен.
2.6. Использование Пользователем настоящего программного обеспечения в целях разработки,
модификации, обновления другого ПО, принадлежащего третьим лицам, а не Правообладателю,
без разрешения Правообладателя не допускается.
3. АВТОРСКОЕ ПРАВО.
3.1. Все авторские права, все права интеллектуальной собственности на Программное обеспечение
и любые его копии принадлежат Правообладателю.
3.2. Все авторские права, все права интеллектуальной собственности в отношении любого контента,
к которому можно получить доступ с помощью Программного обеспечения, является собственностью
соответствующего владельца контента и защищается применимым законодательством об авторском
праве или другими законами и договорами об интеллектуальной собственности.
3.3. Условия использования Программного обеспечения.
Лицензия, предоставленная Пользователю, действительна только в том случае, если Пользователь
придерживается следующих условий:
3.3.1. Принятие уведомлений об авторских правах. Пользователю запрещается удалять или изменять
какие-либо уведомления об авторских правах или лицензиях, которые появляются при использовании
Программного обеспечения или на нем.
3.3.2. Модификация. Пользователю запрещается модифицировать, изменять, декомпилировать,
расшифровывать, дизассемблировать, переводить или реверсировать, перепроектировать
Программное обеспечение.
3.3.3. Распространение. Пользователю запрещается сублицензировать, передавать право использования
ПО или иным образом распространять или предоставлять Программное обеспечение любой третьей стороне.
3.3.4. SaaS. За исключением случаев, когда это разрешено Правообладателем, Пользователю запрещено
использовать Программное обеспечение в коммерческих целях для оказания услуг третьим лицам.
4. ОТВЕТСТВЕННОСТЬ ПРАВООБЛАДАТЕЛЯ ПРИ НАРУШЕНИИ ПОЛЬЗОВАТЕЛЕМ ПРАВ «ИС»
4.1. Правообладатель не несет никаких обязательств в отношении каких-либо претензий к Пользователю
на предмет нарушения последним прав Интеллектуальной собственности, возникших в связи с
использованием Пользователем:
4.1.1. Любых компонентов программного обеспечения с открытым исходным кодом, включенных в
Программное обеспечение;
4.1.2. Любого нарушения правил использования Программного обеспечения, установленного условиями
настоящего соглашения;
4.1.3. Любого использования Программного обеспечения в сочетании с другими ПО, оборудованием,
или данными, не предоставленными Пользователю Правообладателем;
4.1.4. Любого изменения Программного обеспечения любым третьим лицом, а не Правообладателем.
5. НАСТОЯЩИМ ПРАВООБЛАДАТЕЛЬ ЗАЯВЛЯЕТ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ ПОЛЬЗОВАТЕЛЮ
ПО ПРИНЦИПУ «AS IS» - «КАК ЕСТЬ». НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ ПРАВООБЛАДАТЕЛЬ НЕ ГАРАНТИРУЕТ
И НЕ ОБЕЩАЕТ, ЧТО ПРЕДОСТАВЛЕННОЕ ИМ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ ПОДХОДИТЬ ИЛИ НЕ ПОДХОДИТЬ
ДЛЯ КОНКРЕТНЫХ ЦЕЛЕЙ ПОЛЬЗОВАТЕЛЯ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ ОТВЕЧАТЬ ВСЕМ КОММЕРЧЕСКИМ
И ЛИЧНЫМ СУБЪЕКТИВНЫМ ОЖИДАНИЯМ ПОЛЬЗОВАТЕЛЯ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ РАБОТАТЬ
ИСПРАВНО, БЕЗ ТЕХНИЧЕСКИХ ОШИБОК, БЫСТРО И БЕСПЕРЕБОЙНО.
6. ОГРАНИЧЕНИЕ ОТВЕТСТВЕННОСТИ.
НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ ПРАВООБЛАДАТЕЛЬ ИЛИ ЕГО АФФИЛЛИРОВАННЫЕ ЛИЦА НЕ НЕСУТ ПЕРЕД ПОЛЬЗОВАТЕЛЕМ
ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЯМЫЕ ИЛИ КОСВЕННЫЕ УБЫТКИ ПОЛЬЗОВАТЕЛЯ, ЕГО РАСХОДЫ ИЛИ РЕАЛЬНЫЙ УЩЕРБ,
ВКЛЮЧАЯ, ПОМИМО ПРОЧЕГО, ПРОСТОИ; УТРАТУ БИЗНЕСА; УПУЩЕННУЮ ВЫГОДУ; НЕДОПОЛУЧЕННУЮ ПРИБЫЛЬ;
ПОТЕРЮ ИЛИ ПОВРЕЖДЕНИЕ ДАННЫХ, ИМУЩЕСТВА И ИНОЕ.
ОГРАНИЧЕНИЯ ПРИМЕНЯЮТСЯ НЕЗАВИСИМО ОТ ОСНОВАНИЯ НАСТУПЛЕНИЯ ОТВЕТСТВЕННОСТИ; В ТОМ ЧИСЛЕ ВСЛЕДСТВИЕ
ДЕЙСТВИЯ ИЛИ БЕЗДЕЙСТВИЯ, НЕБРЕЖНОСТИ, УМЫСЛА, ПРЯМОГО ИЛИ КОСВЕННОГО; НЕОСТОРОЖНОСТИ; ЗАБЛУЖДЕНИЯ;
КЛЕВЕТЫ; НАРУШЕНИЯ КОНФИДЕНЦИАЛЬНОСТИ ИЛИ ПРАВА ИНТЕЛЛЕКТУАЛЬНОЙ СОБСТВЕННОСТИ; ИЛИ ЛЮБОЕ ДРУГОЕ
ОСНОВАНИЕ НАСТУПЛЕНИЯ ОТВЕТСТВЕННОСТИ.
7. ОБЯЗАННОСТЬ ПОЛЬЗОВАТЕЛЯ:
Не осуществлять самостоятельно и (или) с привлечением третьих лиц нижеследующие действия
(включая, но не ограничиваясь) по:
-дизассемблированию и (или) декомпилированию (преобразованию объектного кода в исходный код)
Программного обеспечения;
-модификации Программного обеспечения, в том числе вносить изменения в объектный код, исходный
код Программного обеспечения, за исключением тех изменений, которые вносятся средствами,
включёнными в Программное обеспечение и описанными непосредственно в документации к нему;
-созданию условий для использования Программного обеспечения лицами, не имеющими прав на
использование данного Программного обеспечения, включая (но не ограничиваясь) вмешательство
третьих лиц в функционирование Программного обеспечения, предоставление третьим лицам доступа
к исследованию и (или) замене настроек Программного обеспечения, включая его первичную установку;
-распространению Программного обеспечения в целом или в части (включая приложенную к нему документацию).
8. БИБЛИОТЕКА ПО. ИСПОЛЬЗУЕМЫЕ ПРОГРАММНЫЕ СРЕДСТВА.
8.1. Настоящим, Правообладатель заверяет, что Библиотека программного обеспечения состоит из
лицензионных продуктов, используемых на законных основаниях, а
именно https://entaxy.ru/libs/licenses/root-aggregated.deps.
8.2. Любые программные средства, применяемые Пользователем при работе с ПО, должны быть
совместимы с библиотекой ПО, указанной в п.8.1. настоящего соглашения.
8.3. Перечень внешних модулей ПО, указанный в п.8.1 настоящего соглашения, может изменяться
Правообладателем в одностороннем порядке, в зависимости от выпуска релизов программного обеспечения,
содержащих все изменения и дополнения программного обеспечения.
9. ВНЕСЕНИЕ ИЗМЕНЕНИЙ В ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ.
9.1. Программное обеспечение, интеграционная шина «ЭНТАКСИ» (ENTAXY) является свободно распространяемым
программным обеспечением.
9.2. Пользователь имеет право вносить изменения в исходный код программного обеспечения исключительно
с согласия Правообладателя в порядке предложения изменений/правок/дополнений через механизм
«Pull Requests» в открытом репозитории Правообладателя по адресу: https://git.entaxy.ru/entaxy/entaxy-public.
9.3. Любые изменения программного обеспечения, осуществляемые Пользователем без соблюдения условий
пункта 9.2. настоящего документа, являются нарушением авторских и смежных прав Правообладателя,
прав интеллектуальной собственности Правообладателя и влекут применение к Пользователю мер
ответственности в соответствии с условиями настоящей Лицензии, а также применимого законодательства
Российской Федерации.
10. ЗАКЛЮЧИТЕЛЬНЫЕ ПОЛОЖЕНИЯ.
10.1. В случае нарушения Пользователем любого из условий настоящей Лицензии, Правообладатель имеет
право взыскать с Пользователя любые причинённые таким нарушением убытки, реальный ущерб,
недополученную прибыль, упущенную выгоду, а также в случае нарушения Пользователем условий
пункта 9.2 настоящего соглашения, в том числе, взыскать с Пользователя штраф в размере
2 000 000 (Два миллиона) рублей за каждый установленный случай несанкционированного изменения
исходного или объектного кода Программного обеспечения «Энтакси» (Entaxy).
10.2. В рамках исполнения Пользователем обязательств по настоящей Лицензии, применимое
законодательство Российской Федерации.
10.3. Если какое-либо положение настоящей Лицензии будет признано судом недействительным,
остальные положения будут продолжать своё действие, а Пользователь будет обязан продолжать
исполнять свои обязанности в соответствии с этими положениями.

View File

@ -0,0 +1,166 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>core-support</artifactId>
<version>1.10.0</version>
</parent>
<artifactId>core-support-runtime-legacy</artifactId>
<packaging>bundle</packaging>
<name>ENTAXY :: PLATFORM :: CORE :: SUPPORT :: RUNTIME LEGACY</name>
<description>ENTAXY :: PLATFORM :: CORE :: SUPPORT :: RUNTIME LEGACY</description>
<properties>
<bundle.osgi.export.pkg>
ru.entaxy.esb.system.common.aggregation,
ru.entaxy.esb.system.common.aggregation.hazelcast,
ru.entaxy.esb.system.common.aggregation.repo,
ru.entaxy.esb.system.common.exception,
ru.entaxy.esb.system.common.interceptor,
ru.entaxy.esb.system.common.util,
ru.entaxy.esb.system.common.validator
</bundle.osgi.export.pkg>
<bundle.osgi.import.pkg>
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,
*
</bundle.osgi.import.pkg>
</properties>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>${xerces.version}</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.cm</artifactId>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>${jpa.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>${javax.transaction.version}</version>
</dependency>
<dependency>
<groupId>javax.interceptor</groupId>
<artifactId>javax.interceptor-api</artifactId>
<version>${javax.interceptor.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-core</artifactId>
<version>${ignite.version}</version>
</dependency>
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-jcl</artifactId>
<version>${ignite.version}</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-sql</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-base</artifactId>
<version>${camel.version}-ENTAXY</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,50 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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<String, Object> oldHeaders = oldExchange.getIn().getHeaders();
Map<String, Object> 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;
}
}

View File

@ -0,0 +1,122 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime-legacy
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.common.aggregation;
import java.util.ArrayList;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.ExtendedExchange;
import org.apache.camel.processor.aggregate.jdbc.ClassLoadingAwareObjectInputStream;
import org.apache.camel.support.DefaultExchange;
import org.apache.camel.support.DefaultExchangeHolder;
import org.apache.camel.util.IOHelper;
/**
* Adapted from HawtDBCamelCodec
*/
public class JdbcCamelCodec {
public byte[] marshallExchange(CamelContext camelContext, Exchange exchange, boolean allowSerializedHeaders) throws IOException {
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
marshallExchange(camelContext, exchange, allowSerializedHeaders, bytesOut);
return bytesOut.toByteArray();
}
public void marshallExchange(CamelContext camelContext, Exchange exchange, boolean allowSerializedHeaders, OutputStream outputStream) throws IOException {
// use DefaultExchangeHolder to marshal to a serialized object
DefaultExchangeHolder pe = DefaultExchangeHolder.marshal(exchange, false, allowSerializedHeaders);
// add the aggregated size and timeout property as the only properties we want to retain
DefaultExchangeHolder.addProperty(pe, Exchange.AGGREGATED_SIZE, exchange.getProperty(Exchange.AGGREGATED_SIZE, Integer.class));
DefaultExchangeHolder.addProperty(pe, Exchange.AGGREGATED_TIMEOUT, exchange.getProperty(Exchange.AGGREGATED_TIMEOUT, Long.class));
// add the aggregated completed by property to retain
DefaultExchangeHolder.addProperty(pe, Exchange.AGGREGATED_COMPLETED_BY, exchange.getProperty(Exchange.AGGREGATED_COMPLETED_BY, String.class));
// add the aggregated correlation key property to retain
DefaultExchangeHolder.addProperty(pe, Exchange.AGGREGATED_CORRELATION_KEY, exchange.getProperty(Exchange.AGGREGATED_CORRELATION_KEY, String.class));
DefaultExchangeHolder.addProperty(pe, Exchange.AGGREGATED_CORRELATION_KEY, exchange.getProperty(Exchange.AGGREGATED_CORRELATION_KEY, String.class));
// and a guard property if using the flexible toolbox aggregator
DefaultExchangeHolder.addProperty(pe, Exchange.AGGREGATED_COLLECTION_GUARD, exchange.getProperty(Exchange.AGGREGATED_COLLECTION_GUARD, String.class));
// @ENTAXY-FIX GROUPED_EXCHANGE isn't marshaling
if (exchange.getProperty(Exchange.GROUPED_EXCHANGE) != null && exchange.getProperty(Exchange.GROUPED_EXCHANGE) instanceof ArrayList) {
DefaultExchangeHolder.addProperty(pe, Exchange.GROUPED_EXCHANGE, exchange.getProperty(Exchange.GROUPED_EXCHANGE, ArrayList.class));
} else if (exchange.getProperty(Exchange.GROUPED_EXCHANGE) != null && exchange.getProperty(Exchange.GROUPED_EXCHANGE) instanceof StringBuffer) {
DefaultExchangeHolder.addProperty(pe, Exchange.GROUPED_EXCHANGE, exchange.getProperty(Exchange.GROUPED_EXCHANGE, StringBuffer.class));
}
// persist the from endpoint as well
if (exchange.getFromEndpoint() != null) {
DefaultExchangeHolder.addProperty(pe, "CamelAggregatedFromEndpoint", exchange.getFromEndpoint().getEndpointUri());
}
encode(pe, outputStream);
}
public Exchange unmarshallExchange(CamelContext camelContext, byte[] buffer) throws IOException, ClassNotFoundException {
return unmarshallExchange(camelContext, new ByteArrayInputStream(buffer));
}
public Exchange unmarshallExchange(CamelContext camelContext, InputStream inputStream) throws IOException, ClassNotFoundException {
DefaultExchangeHolder pe = decode(camelContext, inputStream);
Exchange answer = new DefaultExchange(camelContext);
DefaultExchangeHolder.unmarshal(answer, pe);
// restore the from endpoint
String fromEndpointUri = (String) answer.removeProperty("CamelAggregatedFromEndpoint");
if (fromEndpointUri != null) {
Endpoint fromEndpoint = camelContext.hasEndpoint(fromEndpointUri);
if (fromEndpoint != null) {
answer.adapt(ExtendedExchange.class).setFromEndpoint(fromEndpoint);
}
}
return answer;
}
private void encode(Object object, OutputStream bytesOut) throws IOException {
try (ObjectOutputStream objectOut = new ObjectOutputStream(bytesOut)) {
objectOut.writeObject(object);
}
}
private DefaultExchangeHolder decode(CamelContext camelContext, InputStream bytesIn) throws IOException, ClassNotFoundException {
ObjectInputStream objectIn = null;
Object obj = null;
try {
objectIn = new ClassLoadingAwareObjectInputStream(camelContext, bytesIn);
obj = objectIn.readObject();
} finally {
IOHelper.close(objectIn);
}
return (DefaultExchangeHolder)obj;
}
}

View File

@ -0,0 +1,61 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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));
}
}

View File

@ -0,0 +1,74 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.common.aggregation.hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.MemberAttributeEvent;
import com.hazelcast.core.MembershipEvent;
import com.hazelcast.core.MembershipListener;
import org.apache.camel.CamelContext;
import org.apache.camel.processor.aggregate.AggregateProcessorSetter;
import org.apache.camel.processor.aggregate.EntaxyAggregateProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DisconnectedMembershipListener implements MembershipListener, AggregateProcessorSetter {
protected static final Logger log = LoggerFactory.getLogger(DisconnectedMembershipListener.class);
private CamelContext camelContext;
private EntaxyAggregateProcessor aggregateProcessor;
@Override
public void memberAdded(MembershipEvent membershipEvent) {
}
@Override
public void memberRemoved(MembershipEvent membershipEvent) {
try {
aggregateProcessor.recoverCompletedMessageFromAggregationRepository(camelContext);
aggregateProcessor.restoreTimeoutMapFromAggregationRepository();
} catch (Exception e) {
log.error("Can't restore Timeout from Aggregator. Please restart bundle.", e);
}
}
@Override
public void memberAttributeChanged(MemberAttributeEvent memberAttributeEvent) {
}
@Override
public void setAggregateProcessor(EntaxyAggregateProcessor aggregateProcessor) {
this.aggregateProcessor = aggregateProcessor;
}
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
hazelcastInstance.getCluster().addMembershipListener(this);
}
public void setCamelContext(CamelContext camelContext) {
this.camelContext = camelContext;
}
}

View File

@ -0,0 +1,380 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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.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.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.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder;
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 ru.entaxy.esb.system.common.aggregation.JdbcCamelCodec;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
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 Ignite ignite;
private IgniteTransactions transactions;
private IgniteCache<String, byte[]> aggregationCache;
private CacheConfiguration<String, byte[]> aggregationCfg;
private IgniteCache<String, byte[]> aggregationCompleted;
private CacheConfiguration<String, byte[]> 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, Ignite ignite) {
this.setBundleContext(bundleContext);
this.setIgnite(ignite);
}
@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) {
final String confirmKey = exchange.getExchangeId();
try (Transaction tx = transactions.txStart()) {
insert(camelContext, confirmKey, 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<String> getKeys() {
Set<String> keys = new HashSet<>();
aggregationCache.query(new ScanQuery<>(null)).forEach(entry -> keys.add((String) entry.getKey()));
return keys;
}
@Override
public Set<String> scan(CamelContext camelContext) {
Set<String> 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(ignite, "Ignite");
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);
}
}
private void settingsIgnite() {
aggregationCfg = getCacheConfiguration(AGGREGATION);
aggregationCompletedCfg = getCacheConfiguration(AGGREGATION_COMPLETED);
transactions = ignite.transactions();
aggregationCache = ignite.getOrCreateCache(aggregationCfg);
aggregationCompleted = ignite.getOrCreateCache(aggregationCompletedCfg);
}
@NotNull
private CacheConfiguration<String, byte[]> getCacheConfiguration(String cacheName) {
CacheConfiguration<String, byte[]> 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 TcpDiscoveryMulticastIpFinder());
return spi;
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
public void setBackups(int backups) {
this.backups = backups;
}
public void setIgnite(Ignite ignite) {
this.ignite = ignite;
}
}

View File

@ -0,0 +1,655 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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.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 ru.entaxy.esb.system.common.aggregation.JdbcCamelCodec;
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<String> 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<String, Object> 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<String> getKeys() {
return getKeys(getRepositoryName());
}
@Override
public Set<String> 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<String> getKeys(final String repositoryName) {
return transactionTemplateReadOnly.execute(status -> {
List<String> 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<String> 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<String> 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
}
}

View File

@ -0,0 +1,103 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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");
}
}
}

View File

@ -0,0 +1,50 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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);
}
}

View File

@ -0,0 +1,50 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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);
}
}

View File

@ -0,0 +1,50 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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);
}
}

View File

@ -0,0 +1,52 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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);
}
}

View File

@ -0,0 +1,50 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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);
}
}

View File

@ -0,0 +1,76 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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<String, List<String>> headers = (Map<String, List<String>>) message.get(Message.PROTOCOL_HEADERS);
List<Header> 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<String, List<String>> headers) {
List<String> 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;
}
}

View File

@ -0,0 +1,66 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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;
}
}

View File

@ -0,0 +1,189 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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<String, Object> 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<CustomHeader> 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<CustomHeader> customHeaders = gson.fromJson(headers, new TypeToken<ArrayList<CustomHeader>>() {
}.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;
}
}

View File

@ -0,0 +1,157 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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;
}
}

View File

@ -0,0 +1,56 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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<String> outFilter;
public void setOutFilter(Set<String> 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;
}
}

View File

@ -0,0 +1,38 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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";
public static final String HEADER_IS_DISPLAY_SERVICE_SERVICE = "NTX_IsDisplayServiceSchema";
private SystemHeadersConstants() {
}
}

View File

@ -0,0 +1,126 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.common.validator;
import java.io.IOException;
import java.util.List;
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 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;
@Deprecated(since = "1.10", forRemoval = true)
public class ValidateInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
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<Node> 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;
}
}

View File

@ -0,0 +1,56 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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<Node> 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<Node> getNotNullNodes(NodeList nodeList) {
List<Node> 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;
}
}

View File

@ -0,0 +1,59 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.camel.aggregation;
import org.apache.camel.Exchange;
import org.apache.camel.component.jms.JmsMessage;
import org.apache.camel.processor.aggregate.AggregateExtension;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.jms.JMSException;
import javax.jms.Session;
public class JmsCamelAggregateExtension implements AggregateExtension {
private static final Log LOG = LogFactory.getLog(JmsCamelAggregateExtension.class);
@Override
public boolean checkExtension(Exchange exchange) {
return exchange instanceof JmsMessage;
}
@Override
public Exchange doExtension(Exchange exchange) {
JmsMessage jms = exchange.getIn(JmsMessage.class);
Session session = jms.getJmsSession();
try {
if (session != null && Session.CLIENT_ACKNOWLEDGE == session.getAcknowledgeMode()) {
jms.getJmsMessage().acknowledge();
}
} catch (JMSException e) {
LOG.error("Error in CLIENT_ACKNOWLEDGE.", e);
}
return exchange;
}
}

View File

@ -0,0 +1,109 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.cluster;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apache.karaf.cellar.bundle.BundleState;
import org.apache.karaf.cellar.bundle.Constants;
import org.apache.karaf.cellar.core.ClusterManager;
import org.apache.karaf.cellar.core.Configurations;
import org.apache.karaf.cellar.core.GroupManager;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(service = ClusterBundleDataProvider.class, immediate = true)
public class ClusterBundleDataProvider {
protected static ClusterBundleDataProvider INSTANCE = null;
private static final Logger LOG = LoggerFactory.getLogger(ClusterBundleDataProvider.class);
protected BundleContext bundleContext;
@Reference(cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC,
policyOption = ReferencePolicyOption.GREEDY)
volatile protected ClusterManager clusterManager;
@Reference(cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC,
policyOption = ReferencePolicyOption.GREEDY)
volatile protected GroupManager groupManager;
@Activate
public void activate(ComponentContext componentContext) {
this.bundleContext = componentContext.getBundleContext();
INSTANCE = this;
}
public List<String> getGroups(Bundle bundle) {
List<String> result = new ArrayList<>();
String symbolicName = bundle.getSymbolicName();
// Изменено, потому что bundle.getVersion() съедает ведущие нули
String version = bundle.getHeaders().get(org.osgi.framework.Constants.BUNDLE_VERSION);
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
try {
Set<String> groupNames = groupManager.listGroupNames(groupManager.getNode());
for (String groupName : groupNames) {
@SuppressWarnings("unchecked")
Map<String, BundleState> clusterBundles =
clusterManager.getMap(Constants.BUNDLE_MAP + Configurations.SEPARATOR + groupName);
Optional<BundleState> bundleState = clusterBundles.values().stream()
.filter(state -> state.getSymbolicName().equals(symbolicName))
.filter(state -> state.getVersion().equals(version)).findFirst();
if (bundleState.isPresent()) {
result.add(groupName);
} else {
Optional<BundleState> bundleStateWithoutVersionFiltering = clusterBundles.values().stream()
.filter(state -> state.getSymbolicName().equals(symbolicName)).findFirst();
if (bundleStateWithoutVersionFiltering.isPresent()) {
result.add("?" + groupName);
}
}
}
} catch (Exception e) {
LOG.error(String.format("Error getting groups for bundle [%s/%s]", symbolicName, version), e);
}
return result;
}
}

View File

@ -0,0 +1,169 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.cluster;
import java.util.concurrent.TimeUnit;
import org.apache.camel.cluster.CamelClusterView;
import org.apache.camel.support.cluster.AbstractCamelClusterService;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
@Deprecated(since = "1.10")
public class HazelcastLockClusterService extends AbstractCamelClusterService<CamelClusterView> {
private static final String DEFAULT_CACHE_NAME = "entaxy";
private static final String DEFAULT_ID = "entaxy";
private HazelcastInstance hazelcastInstance;
private IMap<String,Object> cache;
private String cacheName;
private long acquireLockDelay = 1;
private TimeUnit acquireLockDelayUnit = TimeUnit.SECONDS;
private long acquireLockInterval = 10;
private TimeUnit acquireLockIntervalUnit = TimeUnit.SECONDS;
private long healthInterval = 60;
private TimeUnit healthIntervalUnit = TimeUnit.SECONDS;
public HazelcastLockClusterService(HazelcastInstance hazelcastInstance) {
this(hazelcastInstance, DEFAULT_CACHE_NAME);
}
public HazelcastLockClusterService(HazelcastInstance hazelcastInstance, String cacheName) {
this.hazelcastInstance = hazelcastInstance;
this.cacheName = cacheName;
this.cache = hazelcastInstance.getMap(cacheName);
setId(DEFAULT_ID);
}
@Override
protected CamelClusterView createView(String namespace) throws Exception {
return new HazelcastValueLockClusterView(this, namespace);
}
public String getCacheName() {
return cacheName;
}
public void setCacheName(String cacheName) {
this.cacheName = cacheName;
}
public HazelcastInstance getHazelcastInstance() {
return hazelcastInstance;
}
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
this.hazelcastInstance = hazelcastInstance;
}
public IMap<String, Object> getCache() {
return cache;
}
public void setCache(IMap<String, Object> cache) {
this.cache = cache;
}
public long getAcquireLockDelay() {
return acquireLockDelay;
}
/**
* The time to wait before starting to try to acquire lock, default 1.
*/
public void setAcquireLockDelay(long acquireLockDelay) {
this.acquireLockDelay = acquireLockDelay;
}
public void setAcquireLockDelay(long pollDelay, TimeUnit pollDelayUnit) {
setAcquireLockDelay(pollDelay);
setAcquireLockDelayUnit(pollDelayUnit);
}
public TimeUnit getAcquireLockDelayUnit() {
return acquireLockDelayUnit;
}
/**
* The time unit of the acquireLockDelay, default to TimeUnit.SECONDS.
*/
public void setAcquireLockDelayUnit(TimeUnit acquireLockDelayUnit) {
this.acquireLockDelayUnit = acquireLockDelayUnit;
}
public long getAcquireLockInterval() {
return acquireLockInterval;
}
/**
* The time to wait between attempts to try to acquire lock, default 10.
*/
public void setAcquireLockInterval(long acquireLockInterval) {
this.acquireLockInterval = acquireLockInterval;
}
public void setAcquireLockInterval(long pollInterval, TimeUnit pollIntervalUnit) {
setAcquireLockInterval(pollInterval);
setAcquireLockIntervalUnit(pollIntervalUnit);
}
public TimeUnit getAcquireLockIntervalUnit() {
return acquireLockIntervalUnit;
}
/**
* The time unit of the acquireLockInterval, default to TimeUnit.SECONDS.
*/
public void setAcquireLockIntervalUnit(TimeUnit acquireLockIntervalUnit) {
this.acquireLockIntervalUnit = acquireLockIntervalUnit;
}
public long getHealthInterval() {
return healthInterval;
}
/**
* The time between current timestamp and leader's last visit, should be greater then acquireLockDelay+acquireLockInterval, default 60.
*/
public void setHealthInterval(long healthInterval) {
this.healthInterval = healthInterval;
}
public TimeUnit getHealthIntervalUnit() {
return healthIntervalUnit;
}
/**
* The time unit of the healthInterval, default to TimeUnit.SECONDS.
*/
public void setHealthIntervalUnit(TimeUnit healthIntervalUnit) {
this.healthIntervalUnit = healthIntervalUnit;
}
}

View File

@ -0,0 +1,271 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.cluster;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.apache.camel.CamelContext;
import org.apache.camel.cluster.CamelClusterMember;
import org.apache.camel.support.cluster.AbstractCamelClusterView;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
@Deprecated(since = "1.10")
public class HazelcastValueLockClusterView extends AbstractCamelClusterView {
private static final transient Logger LOG = LoggerFactory.getLogger(HazelcastValueLockClusterView.class);
private static final String LOCK_VALUE_DELIMITER = "_";
private HazelcastInstance hazelcastInstance;
private IMap<String,Object> cache;
private long healthInterval;
private TimeUnit healthIntervalUnit;
private String lockName;
private final ClusterMember localMember;
private ScheduledExecutorService executor;
private ScheduledFuture<?> task;
private long currentId;
private volatile boolean leader;
protected HazelcastValueLockClusterView(HazelcastLockClusterService cluster, String namespace) {
super(cluster, namespace);
this.hazelcastInstance = cluster.getHazelcastInstance();
this.cache = cluster.getCache();
this.healthInterval = cluster.getHealthInterval();
this.healthIntervalUnit = cluster.getHealthIntervalUnit();
this.currentId = hazelcastInstance.getAtomicLong(cluster.getCacheName()).getAndIncrement();
this.localMember = new ClusterMember();
this.lockName = namespace;
}
@Override
public Optional<CamelClusterMember> getLeader() {
return this.localMember.isLeader() ? Optional.of(this.localMember) : Optional.empty();
}
@Override
public CamelClusterMember getLocalMember() {
return this.localMember;
}
@Override
public List<CamelClusterMember> getMembers() {
return new ArrayList<CamelClusterMember>() {{ add(localMember); }};
}
@Override
protected void doStart() throws Exception {
HazelcastLockClusterService service = getClusterService().unwrap(HazelcastLockClusterService.class);
executor = getExecutor();
task = executor.scheduleAtFixedRate(this::tryLock,
TimeUnit.MILLISECONDS.convert(service.getAcquireLockDelay(), service.getAcquireLockDelayUnit()),
TimeUnit.MILLISECONDS.convert(service.getAcquireLockInterval(), service.getAcquireLockIntervalUnit()),
TimeUnit.MILLISECONDS);
}
protected ScheduledExecutorService getExecutor() {
if (executor == null) {
HazelcastLockClusterService service = getClusterService().unwrap(HazelcastLockClusterService.class);
// Camel context should be set at this stage.
final CamelContext context = ObjectHelper.notNull(getCamelContext(), "CamelContext");
executor = context.getExecutorServiceManager().newSingleThreadScheduledExecutor(this, "HazelcastLockClusterService-" + service.getId());
}
return executor;
}
protected void tryLock() {
if (isStarting() || isStarted()) {
if (localMember.isLeader()) {
leaderHealth();
} else if (!isLeaderHealthy()) {
tryLockProc();
} else {
LOG.trace("The leader is healthy, but the jackals are on alert! Key {}", lockName);
}
}
}
protected void leaderHealthWrite() {
cache.put(lockName, getLockValueNext());
LOG.trace("Leader health refresh on lock {}", lockName);
}
protected void leaderHealth() {
if (getLockOwnerId() == currentId) {
leaderHealthWrite();
LOG.trace("Holding the lock on key {}", lockName);
} else {
LOG.error("Inconsistent lock on key {}. Leadership is reset!", lockName);
leader = false;
fireLeadershipChangedEvent(Optional.empty());
}
}
protected boolean isLeaderHealthy() {
boolean health = false;
if (cache.containsKey(lockName)) {
long leaderHealthCheck = getLockMilliseconds();
long difference = healthIntervalUnit.convert(System.currentTimeMillis() - leaderHealthCheck, TimeUnit.MILLISECONDS);
health = difference < healthInterval;
} else {
LOG.warn("Empty leader's health key {}", lockName);
}
return health;
}
protected void tryLockProc() {
LOG.debug("Try to acquire a lock on key {}", lockName);
if (cache.tryLock(lockName)) {
leaderHealthWrite();
if (getLockOwnerId() == currentId) {
leader = true;
fireLeadershipChangedEvent(Optional.ofNullable(localMember));
LOG.info("Lock on key {} acquired", lockName);
}
cache.unlock(lockName);
}
if (!localMember.isLeader()) {
LOG.debug("Lock on key {} NOT acquired", lockName);
leader = false;
fireLeadershipChangedEvent(Optional.empty());
}
}
protected String getLockValueNext() {
return String.valueOf(currentId) + LOCK_VALUE_DELIMITER + System.currentTimeMillis();
}
protected long getLockOwnerId() {
return getLockPart(cache.get(lockName), 0);
}
protected long getLockMilliseconds() {
return getLockPart(cache.get(lockName), 1);
}
protected long getLockPart(Object lockValue, int i) {
if (lockValue != null && lockValue instanceof String) {
String[] values = ((String)lockValue).split(LOCK_VALUE_DELIMITER);
if (values.length == 2) {
return Long.parseLong(values[i]);
} else {
throw new IllegalArgumentException("Lock value = " + lockValue + " in unknown format");
}
}
return 0L;
}
@Override
protected void doStop() throws Exception {
leader = false;
fireLeadershipChangedEvent(Optional.empty());
closeInternal();
shutdownExecutors();
}
protected void closeInternal() {
if (task != null) {
task.cancel(true);
}
tryUnlock();
}
protected void shutdownExecutors() {
CamelContext context = getCamelContext();
if (executor != null) {
if (context != null) {
context.getExecutorServiceManager().shutdown(executor);
} else {
executor.shutdown();
}
executor = null;
}
}
protected void tryUnlock() {
LOG.debug("Unlock key {}", lockName);
try {
if (getLockOwnerId() == currentId && cache.tryLock(lockName)) {
try {
cache.delete(lockName);
LOG.trace("Leader lock {} is cleared", lockName);
} finally {
cache.unlock(lockName);
}
LOG.info("Unlocked key {}", lockName);
} else {
LOG.debug("Current thread is not owner of lock {}", lockName);
}
} catch (IllegalMonitorStateException e) {
LOG.trace("Unlock error", e);
}
}
public boolean isLeader() {
return leader;
}
public void setLeader(boolean leader) {
this.leader = leader;
}
private final class ClusterMember implements CamelClusterMember {
@Override
public boolean isLeader() {
return leader;
}
@Override
public boolean isLocal() {
return true;
}
@Override
public String getId() {
return getClusterService().getId();
}
}
}

View File

@ -0,0 +1,84 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.cluster;
import java.util.concurrent.TimeUnit;
import org.apache.camel.support.cluster.AbstractCamelClusterService;
import org.jgroups.blocks.locking.LockService;
import ru.entaxy.platform.core.support.runtime.service.ServiceHolder;
public class JGroupsLockClusterService extends AbstractCamelClusterService<JGroupsLockClusterView> {
private LockService lockService;
private long acquireLockDelay = 1;
private TimeUnit acquireLockDelayUnit = TimeUnit.SECONDS;
public JGroupsLockClusterService(ServiceHolder<LockService> lockService) throws Exception {
this.lockService = lockService.getService();
}
@Override
protected JGroupsLockClusterView createView(String namespace) throws Exception {
return new JGroupsLockClusterView(this, namespace);
}
public LockService getLockService() throws Exception {
return lockService;
}
public void setLockService(LockService lockService) {
this.lockService = lockService;
}
public long getAcquireLockDelay() {
return acquireLockDelay;
}
/**
* The time to wait before starting to try to acquire lock, default 1.
*/
public void setAcquireLockDelay(long acquireLockDelay) {
this.acquireLockDelay = acquireLockDelay;
}
public void setAcquireLockDelay(long pollDelay, TimeUnit pollDelayUnit) {
setAcquireLockDelay(pollDelay);
setAcquireLockDelayUnit(pollDelayUnit);
}
public TimeUnit getAcquireLockDelayUnit() {
return acquireLockDelayUnit;
}
/**
* The time unit of the acquireLockDelay, default to TimeUnit.SECONDS.
*/
public void setAcquireLockDelayUnit(TimeUnit acquireLockDelayUnit) {
this.acquireLockDelayUnit = acquireLockDelayUnit;
}
}

View File

@ -0,0 +1,159 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.cluster;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.locks.Lock;
import org.apache.camel.CamelContext;
import org.apache.camel.cluster.CamelClusterMember;
import org.apache.camel.cluster.CamelClusterService;
import org.apache.camel.support.cluster.AbstractCamelClusterView;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JGroupsLockClusterView extends AbstractCamelClusterView {
private static final transient Logger LOG = LoggerFactory.getLogger(JGroupsLockClusterView.class);
private final CamelClusterMember localMember = new JGroupsLocalMember();
private String lockName;
private Lock lock;
private ScheduledExecutorService executor;
private volatile boolean isMaster;
protected JGroupsLockClusterView(CamelClusterService cluster, String namespace) {
super(cluster, namespace);
lockName = namespace;
}
@Override
public Optional<CamelClusterMember> getLeader() {
if (isMaster) {
return Optional.of(localMember);
} else {
return Optional.empty();
}
}
@Override
public CamelClusterMember getLocalMember() {
return localMember;
}
@Override
public List<CamelClusterMember> getMembers() {
return new ArrayList<CamelClusterMember>() {{ add(localMember); }};
}
@Override
protected void doStart() throws Exception {
if (lock != null) {
lock.unlock();
lock = null;
}
JGroupsLockClusterService service = getClusterService().unwrap(JGroupsLockClusterService.class);
lock = service.getLockService().getLock(lockName);
// Camel context should be set at this stage.
final CamelContext context = ObjectHelper.notNull(getCamelContext(), "CamelContext");
executor = context.getExecutorServiceManager().newSingleThreadScheduledExecutor(this, "JGroupsLockClusterView-" + getClusterService().getId() + "-" + lockName);
executor.schedule(new Runnable() {
@Override
public void run() {
LOG.info("Attempting to become master acquiring the lock for group: " + lockName + " in JGroups cluster");
lock.lock();
isMaster = true;
fireLeadershipChangedEvent(Optional.ofNullable(localMember));
LOG.info("Became master by acquiring the lock for group: " + lockName + " in JGroups cluster");
}
},
service.getAcquireLockDelay(),
service.getAcquireLockDelayUnit());
}
@Override
protected void doStop() throws Exception {
LOG.trace("doStop: " + lockName);
stopProcess();
}
@Override
protected void doShutdown() throws Exception {
LOG.trace("doShutdown: " + lockName);
stopProcess();
}
protected void stopProcess() throws Exception {
shutdownExecutor();
fireLeadershipChangedEvent(Optional.empty());
clearLock();
isMaster = false;
}
private void clearLock() throws Exception {
if (lock != null && isMaster) {
LOG.trace("tryUnlock: " + lockName);
JGroupsLockClusterService service = getClusterService().unwrap(JGroupsLockClusterService.class);
service.getLockService().unlockForce(lockName);
LOG.debug("unlocked: " + lockName);
lock = null;
}
}
private void shutdownExecutor() {
CamelContext context = getCamelContext();
if (executor != null) {
if (context != null) {
context.getExecutorServiceManager().shutdown(executor);
} else {
executor.shutdown();
}
executor = null;
}
}
private final class JGroupsLocalMember implements CamelClusterMember {
@Override
public boolean isLeader() {
return isMaster;
}
@Override
public boolean isLocal() {
return true;
}
@Override
public String getId() {
return getClusterService().getId();
}
}
}

View File

@ -0,0 +1,73 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.cxf;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.common.util.Base64Utility;
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 java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class BasicAuthenticationInterceptor extends AbstractPhaseInterceptor<Message> {
private static final Log LOG = LogFactory.getLog(BasicAuthenticationInterceptor.class);
private String login;
private String password;
private static final String BASIC = "Basic ";
private static final String AUTHORIZATION = "Authorization";
public BasicAuthenticationInterceptor() {
super(Phase.SETUP);
}
@Override
public void handleMessage(Message message) throws Fault {
String authorization = login + ":" + password;
String encodeAuthorization = Base64Utility.encode(authorization.getBytes());
Map<String, List<String>> headers = Headers.getSetProtocolHeaders(message);
List<String> auth = new ArrayList<>();
auth.add(BASIC + encodeAuthorization);
headers.put(AUTHORIZATION, auth);
}
public void setLogin(String login) {
this.login = login;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -0,0 +1,110 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.cxf;
import org.apache.cxf.common.security.SimpleGroup;
import org.apache.cxf.common.security.SimplePrincipal;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.rs.security.jose.jwt.JwtToken;
import org.apache.cxf.rt.security.claims.Claim;
import org.apache.cxf.rt.security.claims.ClaimCollection;
import org.apache.cxf.rt.security.claims.ClaimsSecurityContext;
import javax.security.auth.Subject;
import java.security.Principal;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ExtJwtTokenSecurityContext implements ClaimsSecurityContext {
private final JwtToken token;
private final Principal principal;
private final Set<Principal> roles;
private final ClaimCollection claims = new ClaimCollection();
public ExtJwtTokenSecurityContext(JwtToken jwt, String roleClaim, String regexp) {
principal = new SimplePrincipal(jwt.getClaims().getSubject());
this.token = jwt;
if (roleClaim != null && jwt.getClaims().containsProperty(roleClaim)) {
roles = new HashSet<>();
String role = jwt.getClaims().getStringProperty(roleClaim).trim();
//TODO Think to remove regexp cz it is heavy operation
for (String r : role.split(regexp)) {
roles.add(new SimpleGroup(r));
}
} else {
roles = Collections.emptySet();
}
// Parse JwtToken into ClaimCollection
jwt.getClaims().asMap().forEach((String name, Object values) -> {
Claim claim = new Claim();
claim.setClaimType(name);
if (values instanceof List<?>) {
claim.setValues(CastUtils.cast((List<?>)values));
} else {
claim.setValues(Collections.singletonList(values));
}
claims.add(claim);
});
}
public JwtToken getToken() {
return token;
}
@Override
public Subject getSubject() {
return null;
}
@Override
public Set<Principal> getUserRoles() {
return Collections.unmodifiableSet(roles);
}
@Override
public Principal getUserPrincipal() {
return principal;
}
@Override
public boolean isUserInRole(String role) {
for (Principal principalRole : roles) {
if (principalRole != principal && principalRole.getName().equals(role)) {
return true;
}
}
return false;
}
@Override
public ClaimCollection getClaims() {
return claims;
}
}

View File

@ -0,0 +1,109 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.cxf.jose;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.rs.security.jose.common.JoseConstants;
import org.apache.cxf.rs.security.jose.common.JoseException;
import org.apache.cxf.rs.security.jose.jaxrs.JwtAuthenticationFilter;
import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
import org.apache.cxf.rs.security.jose.jwt.JwtToken;
import org.apache.cxf.security.SecurityContext;
import ru.entaxy.platform.core.support.runtime.cxf.ExtJwtTokenSecurityContext;
import ru.entaxy.platform.core.support.runtime.cxf.security.AnonymousSecurityContext;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.HttpHeaders;
import java.io.IOException;
import java.util.List;
public class ExtJwtAuthenticationFilter extends JwtAuthenticationFilter {
private static final String DEFAULT_AUTH_SCHEME = "JWT";
private String expectedAuthScheme = DEFAULT_AUTH_SCHEME;
public static final String HEADER_IS_DISPLAY_SERVICE_SERVICE = "NTX_IsDisplayServiceSchema";
private String regexp;
protected String getEncodedJwtToken(ContainerRequestContext requestContext) {
String auth = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
String[] parts = auth == null ? null : auth.split(" ");
if (parts == null || !expectedAuthScheme.equals(parts[0]) || parts.length != 2) {
throw new JoseException(expectedAuthScheme + " scheme is expected");
}
return parts[1];
}
public void filter(ContainerRequestContext requestContext) throws IOException {
if (!(requestContext.getSecurityContext() instanceof AnonymousSecurityContext) && !getHeaderDisplayServiceSchema(requestContext)) {
String encodedJwtToken = this.getEncodedJwtToken(requestContext);
JwtToken token = super.getJwtToken(encodedJwtToken);
SecurityContext securityContext = this.configureSecurityContext(token);
if (securityContext != null) {
JAXRSUtils.getCurrentMessage().put(SecurityContext.class, securityContext);
}
}
}
private boolean getHeaderDisplayServiceSchema(ContainerRequestContext context) {
List<String> ntxIsDisplayServiceSchema = context.getHeaders().get(AnonymousSecurityContext.HEADER_IS_DISPLAY_SERVICE_SERVICE);
if (ntxIsDisplayServiceSchema != null && !ntxIsDisplayServiceSchema.isEmpty())
return Boolean.parseBoolean(ntxIsDisplayServiceSchema.get(0));
return false;
}
public void setExpectedAuthScheme(String expectedAuthScheme) {
this.expectedAuthScheme = expectedAuthScheme;
}
protected SecurityContext configureSecurityContext(JwtToken jwt) {
Message m = JAXRSUtils.getCurrentMessage();
boolean enableUnsignedJwt =
MessageUtils.getContextualBoolean(m, JoseConstants.ENABLE_UNSIGNED_JWT_PRINCIPAL, false);
// The token must be signed/verified with a public key to set up the security context,
// unless we directly configure otherwise
if (jwt.getClaims().getSubject() != null
&& (isVerifiedWithAPublicKey(jwt) || enableUnsignedJwt)) {
return new ExtJwtTokenSecurityContext(jwt, getRoleClaim(), regexp);
}
return null;
}
private boolean isVerifiedWithAPublicKey(JwtToken jwt) {
if (isJwsRequired()) {
String alg = (String)jwt.getJwsHeader(JoseConstants.HEADER_ALGORITHM);
SignatureAlgorithm sigAlg = SignatureAlgorithm.getAlgorithm(alg);
return SignatureAlgorithm.isPublicKeyAlgorithm(sigAlg);
}
return false;
}
public void setRegexp(String regexp) {
this.regexp = regexp;
}
}

View File

@ -0,0 +1,50 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.cxf.security;
import org.apache.cxf.security.SecurityContext;
import org.apache.karaf.jaas.boot.principal.UserPrincipal;
import java.security.Principal;
public class AnonymousSecurityContext implements SecurityContext {
public static final String HEADER_IS_DISPLAY_SERVICE_SERVICE = "NTX_IsDisplayServiceSchema";
public static final String ANONYMOUS_USER_NAME = "anonymous";
protected static Principal ANONYMOUS_USER = new UserPrincipal(ANONYMOUS_USER_NAME);
@Override
public Principal getUserPrincipal() {
return ANONYMOUS_USER;
}
@Override
public boolean isUserInRole(String role) {
return false;
}
}

View File

@ -0,0 +1,60 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.cxf.security.oauth2.filters;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter;
import ru.entaxy.platform.core.support.runtime.cxf.security.AnonymousSecurityContext;
import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.ext.Provider;
import java.util.List;
@Provider
@PreMatching
// Priorities.AUTHORIZATION also works
@Priority(Priorities.AUTHENTICATION)
public class DisplaySchemaOAuthRequestFilter extends OAuthRequestFilter {
@Override
public void filter(ContainerRequestContext context) {
if (!(context.getSecurityContext() instanceof AnonymousSecurityContext)
&& !getHeaderDisplayServiceSchema(context)) {
validateRequest(JAXRSUtils.getCurrentMessage());
}
}
private boolean getHeaderDisplayServiceSchema(ContainerRequestContext context) {
List<String> ntxIsDisplayServiceSchema = context.getHeaders().get(AnonymousSecurityContext.HEADER_IS_DISPLAY_SERVICE_SERVICE);
if (ntxIsDisplayServiceSchema != null && !ntxIsDisplayServiceSchema.isEmpty())
return Boolean.parseBoolean(ntxIsDisplayServiceSchema.get(0));
return false;
}
}

View File

@ -0,0 +1,194 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.ignite;
import static org.apache.ignite.IgniteSystemProperties.IGNITE_QUIET;
import java.io.File;
import org.apache.camel.util.ObjectHelper;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
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.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.multicast.TcpDiscoveryMulticastIpFinder;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IgniteInstanceIgniter {
private static final Logger LOG = LoggerFactory.getLogger(IgniteInstanceIgniter.class);
private BundleContext bundleContext;
private String workDirectory;
private String cacheName;
private String rebalanceMode;
private String cacheMode;
private String atomicityMode;
private int backups;
private Ignite ignite;
private IgniteCache<String, Object> systemCache;
CacheConfiguration<String, Object> cacheCfg;
public IgniteInstanceIgniter() {}
public void start() throws Exception {
ObjectHelper.notNull(bundleContext, "bundleContext");
ObjectHelper.notNull(workDirectory, "workDirectory");
IgniteConfiguration cfg = createConfig();
LOG.info("IgniteConfiguration created for workDirectory {}", workDirectory);
cacheCfg = createCacheConfig(cacheName);
cfg.setCacheConfiguration(cacheCfg);
LOG.info("Common CacheConfiguration inited for cacheName {}", cacheName);
System.setProperty(IGNITE_QUIET, "false");
ignite = Ignition.getOrStart(cfg);
ignite.cluster().active(true);
systemCache = ignite.getOrCreateCache(cacheCfg);
ignite.cluster().baselineAutoAdjustEnabled(true);
//default timeout 300s
// ignite.cluster().baselineAutoAdjustTimeout(30000);
LOG.info("Ignite instance initialized");
bundleContext.registerService(Ignite.class, ignite, null);
LOG.info("Ignite service published");
}
public void stop() throws Exception {
if (ignite != null) {
ignite.close();
}
}
protected CacheConfiguration<String, Object> createCacheConfig(String cacheName) {
CacheConfiguration<String, Object> cacheCfg = new CacheConfiguration<>();
cacheCfg.setName(cacheName);
cacheCfg.setRebalanceMode(CacheRebalanceMode.valueOf(rebalanceMode));
cacheCfg.setCacheMode(CacheMode.valueOf(cacheMode));
cacheCfg.setAtomicityMode(CacheAtomicityMode.valueOf(atomicityMode));
cacheCfg.setBackups(backups);
return cacheCfg;
}
protected IgniteConfiguration createConfig() {
IgniteConfiguration cfg = new IgniteConfiguration();
// cfg.setConsistentId();
TcpDiscoverySpi spi = new TcpDiscoverySpi();
// spi.setIpFinder(new TcpDiscoverySharedFsIpFinder() {{setPath(workDirectory + "/addresses");}});
spi.setIpFinder(new TcpDiscoveryMulticastIpFinder());
cfg.setDiscoverySpi(spi);
cfg.setGridLogger(new JclLogger());
cfg.setTransactionConfiguration(new TransactionConfiguration());
//Persistence
DataStorageConfiguration storageCfg = new DataStorageConfiguration();
storageCfg.getDefaultDataRegionConfiguration().setPersistenceEnabled(true);
cfg.setWorkDirectory(workDirectory);
cfg.setIgniteHome(workDirectory);
cfg.setDataStorageConfiguration(storageCfg);
return cfg;
}
public BundleContext getBundleContext() {
return bundleContext;
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
public String getWorkDirectory() {
return workDirectory;
}
public void setWorkDirectory(String workDirectory) {
if (workDirectory != null &&
!workDirectory.startsWith(File.separator) && !workDirectory.contains(":")) {
workDirectory = System.getProperty("karaf.home", "/opt/karaf") + File.separator + workDirectory;
}
this.workDirectory = workDirectory;
}
public String getCacheName() {
return cacheName;
}
public void setCacheName(String cacheName) {
this.cacheName = cacheName;
}
public String getRebalanceMode() {
return rebalanceMode;
}
public void setRebalanceMode(String rebalanceMode) {
this.rebalanceMode = rebalanceMode;
}
public String getCacheMode() {
return cacheMode;
}
public void setCacheMode(String cacheMode) {
this.cacheMode = cacheMode;
}
public String getAtomicityMode() {
return atomicityMode;
}
public void setAtomicityMode(String atomicityMode) {
this.atomicityMode = atomicityMode;
}
public int getBackups() {
return backups;
}
public void setBackups(int backups) {
this.backups = backups;
}
}

View File

@ -0,0 +1,55 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.jackson;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.DefaultDeserializationContext;
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
import com.fasterxml.jackson.datatype.joda.JodaModule;
public class EntaxyObjectMapper extends ObjectMapper {
public EntaxyObjectMapper() {
super();
this.registerModule(new JodaModule());
}
public EntaxyObjectMapper(JsonFactory jf) {
super(jf);
this.registerModule(new JodaModule());
}
public EntaxyObjectMapper(ObjectMapper src) {
super(src);
this.registerModule(new JodaModule());
}
public EntaxyObjectMapper(JsonFactory jf, DefaultSerializerProvider sp, DefaultDeserializationContext dc) {
super(jf, sp, dc);
this.registerModule(new JodaModule());
}
}

View File

@ -0,0 +1,71 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.jackson;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import javax.ws.rs.core.MediaType;
public class JacksonJsonProviderFactory {
private boolean acceptSingleValueAsArray;
private boolean failOnUnknownProperties;
private boolean addJodaModule;
public JacksonJsonProvider create() {
JacksonJsonProvider provider = new JacksonJsonProvider();
if (acceptSingleValueAsArray)
provider.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
if (!failOnUnknownProperties)
provider.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
if (addJodaModule) {
ObjectMapper mapper = provider.locateMapper(ObjectMapper.class, MediaType.APPLICATION_JSON_TYPE);
mapper.registerModule(new JodaModule());
}
return provider;
}
public void setAcceptSingleValueAsArray(boolean acceptSingleValueAsArray) {
this.acceptSingleValueAsArray = acceptSingleValueAsArray;
}
public void setFailOnUnknownProperties(boolean failOnUnknownProperties) {
this.failOnUnknownProperties = failOnUnknownProperties;
}
public void setAddJodaModule(boolean addJodaModule) {
this.addJodaModule = addJodaModule;
}
}

View File

@ -0,0 +1,108 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.jgroups;
import org.apache.camel.util.ObjectHelper;
import org.jgroups.JChannel;
import org.jgroups.blocks.locking.LockService;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.core.support.runtime.service.ServiceHolderHelper;
@Component(service = JGroupsLockServiceIgniter.class, immediate = true)
public class JGroupsLockServiceIgniter extends ServiceHolderHelper<LockService> {
private static final Logger LOG = LoggerFactory.getLogger(JGroupsLockServiceIgniter.class);
private static final String DEFAULT_JGROUPS_CONFIG = "etc/jgroups.locking.xml";
private static final String DEFAULT_JGROUPS_CLUSTERNAME = "jgroups-master";
private String jgroupsConfig;
private String jgroupsClusterName;
private JChannel channel;
private LockService lockService;
private BundleContext bundleContext;
@Activate
public JGroupsLockServiceIgniter(BundleContext bundleContext) {
this(DEFAULT_JGROUPS_CONFIG, DEFAULT_JGROUPS_CLUSTERNAME, bundleContext);
}
public JGroupsLockServiceIgniter(String jgroupsConfig, String jgroupsClusterName, BundleContext bundleContext) {
this.jgroupsConfig = jgroupsConfig;
this.jgroupsClusterName = jgroupsClusterName;
this.bundleContext = bundleContext;
}
@Activate
public void start() throws Exception {
ObjectHelper.notNull(jgroupsConfig, "jgroupsConfig");
ObjectHelper.notNull(jgroupsClusterName, "jgroupsClusterName");
ObjectHelper.notNull(bundleContext, "bundleContext");
init();
publish();
LOG.info("JGroups ServiceHolder published");
}
protected void init() throws Exception {
channel = new JChannel(jgroupsConfig);
lockService = new LockService(channel);
channel.connect(jgroupsClusterName);
LOG.info("JGroups LockService instance initialized");
}
public void stop() throws Exception {
if (channel != null) {
channel.disconnect();
channel.close();
channel = null;
}
}
@Override
public LockService getService() throws Exception {
return lockService;
}
@Override
protected Class<LockService> getGenericType() {
return LockService.class;
}
@Override
public BundleContext getBundleContext() {
return bundleContext;
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
}

View File

@ -0,0 +1,34 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.service;
public interface ServiceHolder<T> {
public static final String PROP_INTERNAL_TYPE = "internalType";
T getService() throws Exception;
}

View File

@ -0,0 +1,49 @@
/*-
* ~~~~~~licensing~~~~~~
* core-support-runtime
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.support.runtime.service;
import java.util.Dictionary;
import java.util.Hashtable;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class ServiceHolderHelper<T> implements ServiceHolder<T> {
private static final Logger LOG = LoggerFactory.getLogger(ServiceHolderHelper.class);
public abstract BundleContext getBundleContext();
protected abstract Class<T> getGenericType();
protected void publish() {
Dictionary<String, String> props = new Hashtable<>();
props.put(PROP_INTERNAL_TYPE, getGenericType().getName());
getBundleContext().registerService(ServiceHolder.class, this, props);
LOG.debug("ServiceHolder published: " + getGenericType().getName());
}
}

View File

@ -0,0 +1,30 @@
<!--
~~~~~~licensing~~~~~~
core-support
==========
Copyright (C) 2020 - 2024 EmDev LLC
==========
You may not use this file except in accordance with the License Terms of the Copyright
Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
rights to the Software and any copies are the property of the Copyright Holder. Unless
it is explicitly allowed the Copyright Holder, the User is prohibited from using the
Software for commercial purposes to provide services to third parties.
The Copyright Holder hereby declares that the Software is provided on an "AS IS".
Under no circumstances does the Copyright Holder guarantee or promise that the
Software provided by him will be suitable or not suitable for the specific purposes
of the User, that the Software will meet all commercial and personal subjective
expectations of the User, that the Software will work properly, without technical
errors, quickly and uninterruptedly.
Under no circumstances shall the Copyright Holder or its Affiliates is not liable
to the User for any direct or indirect losses of the User, his expenses or actual
damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
or damage to data, property, etc.
~~~~~~/licensing~~~~~~
-->
<!-- -->
<configfile finalname="etc/ignite.cfg" override="true">
mvn:ru.entaxy.esb.platform.runtime.core/core-support/1.11.0-SNAPSHOT/cfg/ignite
</configfile>
<!-- -->

View File

@ -0,0 +1,175 @@
ЛИЦЕНЗИЯ ОГРАНИЧЕННОГО ПРИМЕНЕНИЯ
Настоящий документ устанавливает для Пользователя условия применения Базовой (некоммерческой)
версии лицензии для пробного использования программного обеспечения ENTAXY, принадлежащего
Правообладателю Обществу с ограниченной ответственностью "ЕМДЕВ" (ОГРН 1057810026658, ИНН
7813313860, юридический адрес: 197022, Россия, г. Санкт-Петербург, ул. Профессора Попова,
д. 23, литера В, помещение 3Н), расположенной в сети Интернет по адресу
https://www.emdev.ru/about (далее - Компания).
Используя или получая доступ к Программному обеспечению, или нажав «Я согласен с Условиями»
(или аналогичную кнопку или флажок) после загрузки или установки Программного обеспечения,
Пользователь выражает свое согласие на обязательность условий и ограничений, изложенных в
настоящем документе, в противном случае, он должен не использовать или не получать доступ
к Программному обеспечению.
1. ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ
a) ПО Программное обеспечение, интеграционная шина «ЭНТАКСИ» (ENTAXY) в любой ее версии
или редакции, исключительные права на которую принадлежат Правообладателю.
b) Правообладатель (Компания) ООО «ЕМДЕВ», ОГРН 1057810026658, ИНН 7813313860, исключительные
права которого подтверждаются Свидетельством о государственной регистрации в Реестре программ
для ЭВМ № 2021610848 от 19.01.2021 года.
c) Пользователь юридическое или физическое лицо, получившее через скачивание с сайта
https://entaxy.ru или иным образом, дистрибутив ПО, пользующееся ПО.
d) ИС интеллектуальная собственность закреплённое законом исключительное право, а также
личные неимущественные права авторов произведений на результат интеллектуальной деятельности.
e) Подписка это коммерческое предложение Правообладателя, состоящее из Лицензии на использование
ПО и доступа к технической поддержке программного обеспечения на срок Подписки. Подписка
включает предоставление Пользователю неисключительного права использования ПО, в том числе
получение обновлений функционала ПО и безопасности ПО, исправление ошибок ПО и получение
патчей с обновлениями и исправлениями программного обеспечения. Подписка приобретается
Пользователем на период времени, указанный в Сертификате. Количество подписок устанавливается
для каждого Пользователя индивидуально в Сертификате.
f) Сертификат документ, выдаваемый Дистрибъютором или Авторизованным партнёром (Партнёром),
подтверждающий факт приобретения физическим или юридическим лицом Подписки на программное
обеспечение в ограниченном объёме и на определённый период времени.
g) Лицензия (простая (неисключительная) совокупность ограниченных прав использования ПО,
предоставленных Пользователю согласно условиям Подписки.
h) Библиотека совокупность подпрограмм и объектов, используемых для разработки программного
обеспечения.
i) Исходный код текст компьютерной программы на каком-либо языке программирования, состоящий
из одного или нескольких файлов, который может быть прочтён человеком.
j) Объектный код файл (часть машинного кода) с промежуточным представлением отдельного модуля
программы, полученный в результате обработки исходного кода, еще не связанный в полную программу.
Это машинный код для одной конкретной библиотеки или модуля, который будет составлять готовый
продукт.
k) Некоммерческое использование индивидуальное личное использование Пользователем программного
обеспечения с целью обучения работе с Программным обеспечением, для оценки или демонстрации
возможностей Программного обеспечения, при котором, Пользователем не извлекается коммерческая
выгода и/или не идёт в доход денежное вознаграждение при использовании Программного обеспечения.
2. ДОПУСТИМЫЕ СПОСОБЫ ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
2.1. Правообладатель предоставляет Пользователю ограниченное право использования Программного
обеспечения на условиях простой (неисключительной) лицензии в объёме, ограниченном правом
воспроизведения полной рабочей версии программного обеспечения, новых версий программного обеспечения
в памяти оборудования и его запуска на оборудовании в соответствии со ст. 1280 ГК РФ.
2.2. Право на использование Программного обеспечения, предоставляемое Пользователю, носит
неисключительный характер.
2.3. Пользователю предоставляется всемирная, неисключительная, не подлежащая сублицензированию,
лицензия на ограниченное использование Программного обеспечения.
2.4. Пользователь, имеющий Базовую (некоммерческую) версию лицензии для пробного использования
имеет право приобрести Подписку на программное обеспечение. В этом случае Пользователь обязан
обратиться в службу поддержки Правообладателя по адресу: https://entaxy.ru/ для изменения
вида лицензии с Базовой бесплатной версии на Подписки.
2.5. Срок использования скачанной Пользователем базовой (некоммерческой) версии лицензии для
пробного использования программного обеспечения не ограничен.
2.6. Использование Пользователем настоящего программного обеспечения в целях разработки,
модификации, обновления другого ПО, принадлежащего третьим лицам, а не Правообладателю,
без разрешения Правообладателя не допускается.
3. АВТОРСКОЕ ПРАВО.
3.1. Все авторские права, все права интеллектуальной собственности на Программное обеспечение
и любые его копии принадлежат Правообладателю.
3.2. Все авторские права, все права интеллектуальной собственности в отношении любого контента,
к которому можно получить доступ с помощью Программного обеспечения, является собственностью
соответствующего владельца контента и защищается применимым законодательством об авторском
праве или другими законами и договорами об интеллектуальной собственности.
3.3. Условия использования Программного обеспечения.
Лицензия, предоставленная Пользователю, действительна только в том случае, если Пользователь
придерживается следующих условий:
3.3.1. Принятие уведомлений об авторских правах. Пользователю запрещается удалять или изменять
какие-либо уведомления об авторских правах или лицензиях, которые появляются при использовании
Программного обеспечения или на нем.
3.3.2. Модификация. Пользователю запрещается модифицировать, изменять, декомпилировать,
расшифровывать, дизассемблировать, переводить или реверсировать, перепроектировать
Программное обеспечение.
3.3.3. Распространение. Пользователю запрещается сублицензировать, передавать право использования
ПО или иным образом распространять или предоставлять Программное обеспечение любой третьей стороне.
3.3.4. SaaS. За исключением случаев, когда это разрешено Правообладателем, Пользователю запрещено
использовать Программное обеспечение в коммерческих целях для оказания услуг третьим лицам.
4. ОТВЕТСТВЕННОСТЬ ПРАВООБЛАДАТЕЛЯ ПРИ НАРУШЕНИИ ПОЛЬЗОВАТЕЛЕМ ПРАВ «ИС»
4.1. Правообладатель не несет никаких обязательств в отношении каких-либо претензий к Пользователю
на предмет нарушения последним прав Интеллектуальной собственности, возникших в связи с
использованием Пользователем:
4.1.1. Любых компонентов программного обеспечения с открытым исходным кодом, включенных в
Программное обеспечение;
4.1.2. Любого нарушения правил использования Программного обеспечения, установленного условиями
настоящего соглашения;
4.1.3. Любого использования Программного обеспечения в сочетании с другими ПО, оборудованием,
или данными, не предоставленными Пользователю Правообладателем;
4.1.4. Любого изменения Программного обеспечения любым третьим лицом, а не Правообладателем.
5. НАСТОЯЩИМ ПРАВООБЛАДАТЕЛЬ ЗАЯВЛЯЕТ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ ПОЛЬЗОВАТЕЛЮ
ПО ПРИНЦИПУ «AS IS» - «КАК ЕСТЬ». НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ ПРАВООБЛАДАТЕЛЬ НЕ ГАРАНТИРУЕТ
И НЕ ОБЕЩАЕТ, ЧТО ПРЕДОСТАВЛЕННОЕ ИМ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ ПОДХОДИТЬ ИЛИ НЕ ПОДХОДИТЬ
ДЛЯ КОНКРЕТНЫХ ЦЕЛЕЙ ПОЛЬЗОВАТЕЛЯ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ ОТВЕЧАТЬ ВСЕМ КОММЕРЧЕСКИМ
И ЛИЧНЫМ СУБЪЕКТИВНЫМ ОЖИДАНИЯМ ПОЛЬЗОВАТЕЛЯ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ РАБОТАТЬ
ИСПРАВНО, БЕЗ ТЕХНИЧЕСКИХ ОШИБОК, БЫСТРО И БЕСПЕРЕБОЙНО.
6. ОГРАНИЧЕНИЕ ОТВЕТСТВЕННОСТИ.
НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ ПРАВООБЛАДАТЕЛЬ ИЛИ ЕГО АФФИЛЛИРОВАННЫЕ ЛИЦА НЕ НЕСУТ ПЕРЕД ПОЛЬЗОВАТЕЛЕМ
ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЯМЫЕ ИЛИ КОСВЕННЫЕ УБЫТКИ ПОЛЬЗОВАТЕЛЯ, ЕГО РАСХОДЫ ИЛИ РЕАЛЬНЫЙ УЩЕРБ,
ВКЛЮЧАЯ, ПОМИМО ПРОЧЕГО, ПРОСТОИ; УТРАТУ БИЗНЕСА; УПУЩЕННУЮ ВЫГОДУ; НЕДОПОЛУЧЕННУЮ ПРИБЫЛЬ;
ПОТЕРЮ ИЛИ ПОВРЕЖДЕНИЕ ДАННЫХ, ИМУЩЕСТВА И ИНОЕ.
ОГРАНИЧЕНИЯ ПРИМЕНЯЮТСЯ НЕЗАВИСИМО ОТ ОСНОВАНИЯ НАСТУПЛЕНИЯ ОТВЕТСТВЕННОСТИ; В ТОМ ЧИСЛЕ ВСЛЕДСТВИЕ
ДЕЙСТВИЯ ИЛИ БЕЗДЕЙСТВИЯ, НЕБРЕЖНОСТИ, УМЫСЛА, ПРЯМОГО ИЛИ КОСВЕННОГО; НЕОСТОРОЖНОСТИ; ЗАБЛУЖДЕНИЯ;
КЛЕВЕТЫ; НАРУШЕНИЯ КОНФИДЕНЦИАЛЬНОСТИ ИЛИ ПРАВА ИНТЕЛЛЕКТУАЛЬНОЙ СОБСТВЕННОСТИ; ИЛИ ЛЮБОЕ ДРУГОЕ
ОСНОВАНИЕ НАСТУПЛЕНИЯ ОТВЕТСТВЕННОСТИ.
7. ОБЯЗАННОСТЬ ПОЛЬЗОВАТЕЛЯ:
Не осуществлять самостоятельно и (или) с привлечением третьих лиц нижеследующие действия
(включая, но не ограничиваясь) по:
-дизассемблированию и (или) декомпилированию (преобразованию объектного кода в исходный код)
Программного обеспечения;
-модификации Программного обеспечения, в том числе вносить изменения в объектный код, исходный
код Программного обеспечения, за исключением тех изменений, которые вносятся средствами,
включёнными в Программное обеспечение и описанными непосредственно в документации к нему;
-созданию условий для использования Программного обеспечения лицами, не имеющими прав на
использование данного Программного обеспечения, включая (но не ограничиваясь) вмешательство
третьих лиц в функционирование Программного обеспечения, предоставление третьим лицам доступа
к исследованию и (или) замене настроек Программного обеспечения, включая его первичную установку;
-распространению Программного обеспечения в целом или в части (включая приложенную к нему документацию).
8. БИБЛИОТЕКА ПО. ИСПОЛЬЗУЕМЫЕ ПРОГРАММНЫЕ СРЕДСТВА.
8.1. Настоящим, Правообладатель заверяет, что Библиотека программного обеспечения состоит из
лицензионных продуктов, используемых на законных основаниях, а
именно https://entaxy.ru/libs/licenses/root-aggregated.deps.
8.2. Любые программные средства, применяемые Пользователем при работе с ПО, должны быть
совместимы с библиотекой ПО, указанной в п.8.1. настоящего соглашения.
8.3. Перечень внешних модулей ПО, указанный в п.8.1 настоящего соглашения, может изменяться
Правообладателем в одностороннем порядке, в зависимости от выпуска релизов программного обеспечения,
содержащих все изменения и дополнения программного обеспечения.
9. ВНЕСЕНИЕ ИЗМЕНЕНИЙ В ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ.
9.1. Программное обеспечение, интеграционная шина «ЭНТАКСИ» (ENTAXY) является свободно распространяемым
программным обеспечением.
9.2. Пользователь имеет право вносить изменения в исходный код программного обеспечения исключительно
с согласия Правообладателя в порядке предложения изменений/правок/дополнений через механизм
«Pull Requests» в открытом репозитории Правообладателя по адресу: https://git.entaxy.ru/entaxy/entaxy-public.
9.3. Любые изменения программного обеспечения, осуществляемые Пользователем без соблюдения условий
пункта 9.2. настоящего документа, являются нарушением авторских и смежных прав Правообладателя,
прав интеллектуальной собственности Правообладателя и влекут применение к Пользователю мер
ответственности в соответствии с условиями настоящей Лицензии, а также применимого законодательства
Российской Федерации.
10. ЗАКЛЮЧИТЕЛЬНЫЕ ПОЛОЖЕНИЯ.
10.1. В случае нарушения Пользователем любого из условий настоящей Лицензии, Правообладатель имеет
право взыскать с Пользователя любые причинённые таким нарушением убытки, реальный ущерб,
недополученную прибыль, упущенную выгоду, а также в случае нарушения Пользователем условий
пункта 9.2 настоящего соглашения, в том числе, взыскать с Пользователя штраф в размере
2 000 000 (Два миллиона) рублей за каждый установленный случай несанкционированного изменения
исходного или объектного кода Программного обеспечения «Энтакси» (Entaxy).
10.2. В рамках исполнения Пользователем обязательств по настоящей Лицензии, применимое
законодательство Российской Федерации.
10.3. Если какое-либо положение настоящей Лицензии будет признано судом недействительным,
остальные положения будут продолжать своё действие, а Пользователь будет обязан продолжать
исполнять свои обязанности в соответствии с этими положениями.

View File

@ -0,0 +1,175 @@
ЛИЦЕНЗИЯ ОГРАНИЧЕННОГО ПРИМЕНЕНИЯ
Настоящий документ устанавливает для Пользователя условия применения Базовой (некоммерческой)
версии лицензии для пробного использования программного обеспечения ENTAXY, принадлежащего
Правообладателю Обществу с ограниченной ответственностью "ЕМДЕВ" (ОГРН 1057810026658, ИНН
7813313860, юридический адрес: 197022, Россия, г. Санкт-Петербург, ул. Профессора Попова,
д. 23, литера В, помещение 3Н), расположенной в сети Интернет по адресу
https://www.emdev.ru/about (далее - Компания).
Используя или получая доступ к Программному обеспечению, или нажав «Я согласен с Условиями»
(или аналогичную кнопку или флажок) после загрузки или установки Программного обеспечения,
Пользователь выражает свое согласие на обязательность условий и ограничений, изложенных в
настоящем документе, в противном случае, он должен не использовать или не получать доступ
к Программному обеспечению.
1. ТЕРМИНЫ И ОПРЕДЕЛЕНИЯ
a) ПО Программное обеспечение, интеграционная шина «ЭНТАКСИ» (ENTAXY) в любой ее версии
или редакции, исключительные права на которую принадлежат Правообладателю.
b) Правообладатель (Компания) ООО «ЕМДЕВ», ОГРН 1057810026658, ИНН 7813313860, исключительные
права которого подтверждаются Свидетельством о государственной регистрации в Реестре программ
для ЭВМ № 2021610848 от 19.01.2021 года.
c) Пользователь юридическое или физическое лицо, получившее через скачивание с сайта
https://entaxy.ru или иным образом, дистрибутив ПО, пользующееся ПО.
d) ИС интеллектуальная собственность закреплённое законом исключительное право, а также
личные неимущественные права авторов произведений на результат интеллектуальной деятельности.
e) Подписка это коммерческое предложение Правообладателя, состоящее из Лицензии на использование
ПО и доступа к технической поддержке программного обеспечения на срок Подписки. Подписка
включает предоставление Пользователю неисключительного права использования ПО, в том числе
получение обновлений функционала ПО и безопасности ПО, исправление ошибок ПО и получение
патчей с обновлениями и исправлениями программного обеспечения. Подписка приобретается
Пользователем на период времени, указанный в Сертификате. Количество подписок устанавливается
для каждого Пользователя индивидуально в Сертификате.
f) Сертификат документ, выдаваемый Дистрибъютором или Авторизованным партнёром (Партнёром),
подтверждающий факт приобретения физическим или юридическим лицом Подписки на программное
обеспечение в ограниченном объёме и на определённый период времени.
g) Лицензия (простая (неисключительная) совокупность ограниченных прав использования ПО,
предоставленных Пользователю согласно условиям Подписки.
h) Библиотека совокупность подпрограмм и объектов, используемых для разработки программного
обеспечения.
i) Исходный код текст компьютерной программы на каком-либо языке программирования, состоящий
из одного или нескольких файлов, который может быть прочтён человеком.
j) Объектный код файл (часть машинного кода) с промежуточным представлением отдельного модуля
программы, полученный в результате обработки исходного кода, еще не связанный в полную программу.
Это машинный код для одной конкретной библиотеки или модуля, который будет составлять готовый
продукт.
k) Некоммерческое использование индивидуальное личное использование Пользователем программного
обеспечения с целью обучения работе с Программным обеспечением, для оценки или демонстрации
возможностей Программного обеспечения, при котором, Пользователем не извлекается коммерческая
выгода и/или не идёт в доход денежное вознаграждение при использовании Программного обеспечения.
2. ДОПУСТИМЫЕ СПОСОБЫ ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
2.1. Правообладатель предоставляет Пользователю ограниченное право использования Программного
обеспечения на условиях простой (неисключительной) лицензии в объёме, ограниченном правом
воспроизведения полной рабочей версии программного обеспечения, новых версий программного обеспечения
в памяти оборудования и его запуска на оборудовании в соответствии со ст. 1280 ГК РФ.
2.2. Право на использование Программного обеспечения, предоставляемое Пользователю, носит
неисключительный характер.
2.3. Пользователю предоставляется всемирная, неисключительная, не подлежащая сублицензированию,
лицензия на ограниченное использование Программного обеспечения.
2.4. Пользователь, имеющий Базовую (некоммерческую) версию лицензии для пробного использования
имеет право приобрести Подписку на программное обеспечение. В этом случае Пользователь обязан
обратиться в службу поддержки Правообладателя по адресу: https://entaxy.ru/ для изменения
вида лицензии с Базовой бесплатной версии на Подписки.
2.5. Срок использования скачанной Пользователем базовой (некоммерческой) версии лицензии для
пробного использования программного обеспечения не ограничен.
2.6. Использование Пользователем настоящего программного обеспечения в целях разработки,
модификации, обновления другого ПО, принадлежащего третьим лицам, а не Правообладателю,
без разрешения Правообладателя не допускается.
3. АВТОРСКОЕ ПРАВО.
3.1. Все авторские права, все права интеллектуальной собственности на Программное обеспечение
и любые его копии принадлежат Правообладателю.
3.2. Все авторские права, все права интеллектуальной собственности в отношении любого контента,
к которому можно получить доступ с помощью Программного обеспечения, является собственностью
соответствующего владельца контента и защищается применимым законодательством об авторском
праве или другими законами и договорами об интеллектуальной собственности.
3.3. Условия использования Программного обеспечения.
Лицензия, предоставленная Пользователю, действительна только в том случае, если Пользователь
придерживается следующих условий:
3.3.1. Принятие уведомлений об авторских правах. Пользователю запрещается удалять или изменять
какие-либо уведомления об авторских правах или лицензиях, которые появляются при использовании
Программного обеспечения или на нем.
3.3.2. Модификация. Пользователю запрещается модифицировать, изменять, декомпилировать,
расшифровывать, дизассемблировать, переводить или реверсировать, перепроектировать
Программное обеспечение.
3.3.3. Распространение. Пользователю запрещается сублицензировать, передавать право использования
ПО или иным образом распространять или предоставлять Программное обеспечение любой третьей стороне.
3.3.4. SaaS. За исключением случаев, когда это разрешено Правообладателем, Пользователю запрещено
использовать Программное обеспечение в коммерческих целях для оказания услуг третьим лицам.
4. ОТВЕТСТВЕННОСТЬ ПРАВООБЛАДАТЕЛЯ ПРИ НАРУШЕНИИ ПОЛЬЗОВАТЕЛЕМ ПРАВ «ИС»
4.1. Правообладатель не несет никаких обязательств в отношении каких-либо претензий к Пользователю
на предмет нарушения последним прав Интеллектуальной собственности, возникших в связи с
использованием Пользователем:
4.1.1. Любых компонентов программного обеспечения с открытым исходным кодом, включенных в
Программное обеспечение;
4.1.2. Любого нарушения правил использования Программного обеспечения, установленного условиями
настоящего соглашения;
4.1.3. Любого использования Программного обеспечения в сочетании с другими ПО, оборудованием,
или данными, не предоставленными Пользователю Правообладателем;
4.1.4. Любого изменения Программного обеспечения любым третьим лицом, а не Правообладателем.
5. НАСТОЯЩИМ ПРАВООБЛАДАТЕЛЬ ЗАЯВЛЯЕТ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ ПОЛЬЗОВАТЕЛЮ
ПО ПРИНЦИПУ «AS IS» - «КАК ЕСТЬ». НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ ПРАВООБЛАДАТЕЛЬ НЕ ГАРАНТИРУЕТ
И НЕ ОБЕЩАЕТ, ЧТО ПРЕДОСТАВЛЕННОЕ ИМ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ ПОДХОДИТЬ ИЛИ НЕ ПОДХОДИТЬ
ДЛЯ КОНКРЕТНЫХ ЦЕЛЕЙ ПОЛЬЗОВАТЕЛЯ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ ОТВЕЧАТЬ ВСЕМ КОММЕРЧЕСКИМ
И ЛИЧНЫМ СУБЪЕКТИВНЫМ ОЖИДАНИЯМ ПОЛЬЗОВАТЕЛЯ, ЧТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ БУДЕТ РАБОТАТЬ
ИСПРАВНО, БЕЗ ТЕХНИЧЕСКИХ ОШИБОК, БЫСТРО И БЕСПЕРЕБОЙНО.
6. ОГРАНИЧЕНИЕ ОТВЕТСТВЕННОСТИ.
НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ ПРАВООБЛАДАТЕЛЬ ИЛИ ЕГО АФФИЛЛИРОВАННЫЕ ЛИЦА НЕ НЕСУТ ПЕРЕД ПОЛЬЗОВАТЕЛЕМ
ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЯМЫЕ ИЛИ КОСВЕННЫЕ УБЫТКИ ПОЛЬЗОВАТЕЛЯ, ЕГО РАСХОДЫ ИЛИ РЕАЛЬНЫЙ УЩЕРБ,
ВКЛЮЧАЯ, ПОМИМО ПРОЧЕГО, ПРОСТОИ; УТРАТУ БИЗНЕСА; УПУЩЕННУЮ ВЫГОДУ; НЕДОПОЛУЧЕННУЮ ПРИБЫЛЬ;
ПОТЕРЮ ИЛИ ПОВРЕЖДЕНИЕ ДАННЫХ, ИМУЩЕСТВА И ИНОЕ.
ОГРАНИЧЕНИЯ ПРИМЕНЯЮТСЯ НЕЗАВИСИМО ОТ ОСНОВАНИЯ НАСТУПЛЕНИЯ ОТВЕТСТВЕННОСТИ; В ТОМ ЧИСЛЕ ВСЛЕДСТВИЕ
ДЕЙСТВИЯ ИЛИ БЕЗДЕЙСТВИЯ, НЕБРЕЖНОСТИ, УМЫСЛА, ПРЯМОГО ИЛИ КОСВЕННОГО; НЕОСТОРОЖНОСТИ; ЗАБЛУЖДЕНИЯ;
КЛЕВЕТЫ; НАРУШЕНИЯ КОНФИДЕНЦИАЛЬНОСТИ ИЛИ ПРАВА ИНТЕЛЛЕКТУАЛЬНОЙ СОБСТВЕННОСТИ; ИЛИ ЛЮБОЕ ДРУГОЕ
ОСНОВАНИЕ НАСТУПЛЕНИЯ ОТВЕТСТВЕННОСТИ.
7. ОБЯЗАННОСТЬ ПОЛЬЗОВАТЕЛЯ:
Не осуществлять самостоятельно и (или) с привлечением третьих лиц нижеследующие действия
(включая, но не ограничиваясь) по:
-дизассемблированию и (или) декомпилированию (преобразованию объектного кода в исходный код)
Программного обеспечения;
-модификации Программного обеспечения, в том числе вносить изменения в объектный код, исходный
код Программного обеспечения, за исключением тех изменений, которые вносятся средствами,
включёнными в Программное обеспечение и описанными непосредственно в документации к нему;
-созданию условий для использования Программного обеспечения лицами, не имеющими прав на
использование данного Программного обеспечения, включая (но не ограничиваясь) вмешательство
третьих лиц в функционирование Программного обеспечения, предоставление третьим лицам доступа
к исследованию и (или) замене настроек Программного обеспечения, включая его первичную установку;
-распространению Программного обеспечения в целом или в части (включая приложенную к нему документацию).
8. БИБЛИОТЕКА ПО. ИСПОЛЬЗУЕМЫЕ ПРОГРАММНЫЕ СРЕДСТВА.
8.1. Настоящим, Правообладатель заверяет, что Библиотека программного обеспечения состоит из
лицензионных продуктов, используемых на законных основаниях, а
именно https://entaxy.ru/libs/licenses/root-aggregated.deps.
8.2. Любые программные средства, применяемые Пользователем при работе с ПО, должны быть
совместимы с библиотекой ПО, указанной в п.8.1. настоящего соглашения.
8.3. Перечень внешних модулей ПО, указанный в п.8.1 настоящего соглашения, может изменяться
Правообладателем в одностороннем порядке, в зависимости от выпуска релизов программного обеспечения,
содержащих все изменения и дополнения программного обеспечения.
9. ВНЕСЕНИЕ ИЗМЕНЕНИЙ В ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ.
9.1. Программное обеспечение, интеграционная шина «ЭНТАКСИ» (ENTAXY) является свободно распространяемым
программным обеспечением.
9.2. Пользователь имеет право вносить изменения в исходный код программного обеспечения исключительно
с согласия Правообладателя в порядке предложения изменений/правок/дополнений через механизм
«Pull Requests» в открытом репозитории Правообладателя по адресу: https://git.entaxy.ru/entaxy/entaxy-public.
9.3. Любые изменения программного обеспечения, осуществляемые Пользователем без соблюдения условий
пункта 9.2. настоящего документа, являются нарушением авторских и смежных прав Правообладателя,
прав интеллектуальной собственности Правообладателя и влекут применение к Пользователю мер
ответственности в соответствии с условиями настоящей Лицензии, а также применимого законодательства
Российской Федерации.
10. ЗАКЛЮЧИТЕЛЬНЫЕ ПОЛОЖЕНИЯ.
10.1. В случае нарушения Пользователем любого из условий настоящей Лицензии, Правообладатель имеет
право взыскать с Пользователя любые причинённые таким нарушением убытки, реальный ущерб,
недополученную прибыль, упущенную выгоду, а также в случае нарушения Пользователем условий
пункта 9.2 настоящего соглашения, в том числе, взыскать с Пользователя штраф в размере
2 000 000 (Два миллиона) рублей за каждый установленный случай несанкционированного изменения
исходного или объектного кода Программного обеспечения «Энтакси» (Entaxy).
10.2. В рамках исполнения Пользователем обязательств по настоящей Лицензии, применимое
законодательство Российской Федерации.
10.3. Если какое-либо положение настоящей Лицензии будет признано судом недействительным,
остальные положения будут продолжать своё действие, а Пользователь будет обязан продолжать
исполнять свои обязанности в соответствии с этими положениями.

View File

@ -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
<camelContext id="soap-service-endpoints-camel-context"
xmlns="http://camel.apache.org/schema/blueprint"
errorHandlerRef="commonErrorHandler" handleFault="true">
<errorHandler id="commonErrorHandler" redeliveryPolicyRef="noRedelivery"
type="DeadLetterChannel" deadLetterUri="direct-vm:commonErrorEndpoint"/>
<redeliveryPolicyProfile id="noRedelivery" disableRedelivery="true" />
<!-- any content -->
</camelContext>
```
Для контекстов, содержащих конечные точки cxf, необходимо:
- через `pom.xml` импортировать интерцептор для перехвата ошибок (SoapFault)
```xml
<bundle.osgi.import.pkg>
ru.entaxy.esb.system.core.common.error.handler.interceptor,
...
</bundle.osgi.import.pkg>
```
- добавить интерцептор в `cxfEndpoint` и bean с указанием в первом аргументе идентификатора `camelContext`
```xml
<camelcxf:cxfEndpoint id="soap-proxy" .../>
<!-- any properties and interceptors -->
<camelcxf:outFaultInterceptors>
<ref component-id="handleOutFaultInterceptor"/>
</camelcxf:outFaultInterceptors>
</camelcxf:cxfEndpoint>
<bean id="handleOutFaultInterceptor" class="ru.entaxy.esb.system.core.common.error.handler.interceptor.HandleOutFaultInterceptor">
<argument ref="soap-service-endpoints-camel-context"/>
<argument value="direct:error_from_cxf"/>
</bean>
```
- в `camelContext` добавить маршрут
```xml
<route id="error_from_cxf">
<from uri="direct:error_from_cxf"/>
<log message="cxf message: ${body}" loggingLevel="DEBUG"/>
<log message="headers: ${headers}\n" loggingLevel="DEBUG"/>
<to uri="direct-vm:cxfErrorEndpoint"/>
</route>
```

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.entaxy.platform.core</groupId>
<artifactId>error-handling</artifactId>
<version>1.10.0</version>
</parent>
<groupId>ru.entaxy.platform.core.error-handling</groupId>
<artifactId>error-handler</artifactId>
<packaging>bundle</packaging>
<name>ENTAXY :: PLATFORM :: CORE :: ERROR HANDLER</name>
<description>ENTAXY :: PLATFORM :: CORE :: ERROR HANDLER</description>
<properties>
<bundle.osgi.export.pkg>
ru.entaxy.esb.system.core.common.error.handler.interceptor
</bundle.osgi.export.pkg>
<bundle.osgi.import.pkg>
org.apache.commons.lang3.exception,
*
</bundle.osgi.import.pkg>
<!-- bundle.osgi.private.pkg>{local-packages}</bundle.osgi.private.pkg -->
<!--ru.entaxy.esb.system.core.common.error.handler.processor,
ru.entaxy.esb.system.core.common.error.handler.util-->
</properties>
<dependencies>
<dependency>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>core-support-runtime-legacy</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,13 @@
<!-- -->
<configfile finalname="etc/ru.entaxy.esb.error.cfg" override="true">
mvn:ru.entaxy.platform.core.error-handling/error-handler/1.10.0/cfg/ru.entaxy.esb.error
</configfile>
<!-- --><!-- -->
<configfile finalname="etc/ru.entaxy.esb.error.code.cfg" override="true">
mvn:ru.entaxy.platform.core.error-handling/error-handler/1.10.0/cfg/ru.entaxy.esb.error.code
</configfile>
<!-- --><!-- -->
<configfile finalname="etc/ru.entaxy.esb.error.text.cfg" override="true">
mvn:ru.entaxy.platform.core.error-handling/error-handler/1.10.0/cfg/ru.entaxy.esb.error.text
</configfile>
<!-- -->

View File

@ -0,0 +1,49 @@
###
# ~~~~~~licensing~~~~~~
# karaf-features
# ==========
# Copyright (C) 2020 - 2024 EmDev LLC
# ==========
# You may not use this file except in accordance with the License Terms of the Copyright
# Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
# rights to the Software and any copies are the property of the Copyright Holder. Unless
# it is explicitly allowed the Copyright Holder, the User is prohibited from using the
# Software for commercial purposes to provide services to third parties.
#
# The Copyright Holder hereby declares that the Software is provided on an "AS IS".
# Under no circumstances does the Copyright Holder guarantee or promise that the
# Software provided by him will be suitable or not suitable for the specific purposes
# of the User, that the Software will meet all commercial and personal subjective
# expectations of the User, that the Software will work properly, without technical
# errors, quickly and uninterruptedly.
#
# Under no circumstances shall the Copyright Holder or its Affiliates is not liable
# to the User for any direct or indirect losses of the User, his expenses or actual
# damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
# or damage to data, property, etc.
# ~~~~~~/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.asynch.stacktrace.show=true
# false - включает в синхронный ответ с ошибкой весь stacktrace исключения
error.synch.stacktrace.show=false
# свойство автоматического запуска тестового маршрута, который при старте модуля бросает исключение java.lang.IllegalArgumentException: Test exception thrown
error.test-route.startup=false

View File

@ -0,0 +1,48 @@
###
# ~~~~~~licensing~~~~~~
# karaf-features
# ==========
# Copyright (C) 2020 - 2024 EmDev LLC
# ==========
# You may not use this file except in accordance with the License Terms of the Copyright
# Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
# rights to the Software and any copies are the property of the Copyright Holder. Unless
# it is explicitly allowed the Copyright Holder, the User is prohibited from using the
# Software for commercial purposes to provide services to third parties.
#
# The Copyright Holder hereby declares that the Software is provided on an "AS IS".
# Under no circumstances does the Copyright Holder guarantee or promise that the
# Software provided by him will be suitable or not suitable for the specific purposes
# of the User, that the Software will meet all commercial and personal subjective
# expectations of the User, that the Software will work properly, without technical
# errors, quickly and uninterruptedly.
#
# Under no circumstances shall the Copyright Holder or its Affiliates is not liable
# to the User for any direct or indirect losses of the User, his expenses or actual
# damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
# or damage to data, property, etc.
# ~~~~~~/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.cxf.interceptor.security.AccessDeniedException=403
org.apache.camel.language.bean.RuntimeBeanExpressionException=500
ConnectorNotFound=424
ru.entaxy.esb.system.common.exception.DefaultException=520
ProfileNotFound=424
java.io.FileNotFoundException=404

View File

@ -0,0 +1,39 @@
###
# ~~~~~~licensing~~~~~~
# karaf-features
# ==========
# Copyright (C) 2020 - 2024 EmDev LLC
# ==========
# You may not use this file except in accordance with the License Terms of the Copyright
# Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
# rights to the Software and any copies are the property of the Copyright Holder. Unless
# it is explicitly allowed the Copyright Holder, the User is prohibited from using the
# Software for commercial purposes to provide services to third parties.
#
# The Copyright Holder hereby declares that the Software is provided on an "AS IS".
# Under no circumstances does the Copyright Holder guarantee or promise that the
# Software provided by him will be suitable or not suitable for the specific purposes
# of the User, that the Software will meet all commercial and personal subjective
# expectations of the User, that the Software will work properly, without technical
# errors, quickly and uninterruptedly.
#
# Under no circumstances shall the Copyright Holder or its Affiliates is not liable
# to the User for any direct or indirect losses of the User, his expenses or actual
# damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
# or damage to data, property, etc.
# ~~~~~~/licensing~~~~~~
###
# 1xx: Informational
# 2xx: Success
200=OK
# 3xx: Redirection
# 4xx: Client Error
400=Bad Request
401=Unauthorized
403=Forbidden
418=Im a teapot
424=Failed Dependency
# 5xx: Server Error
520=Unknown Error

View File

@ -0,0 +1,214 @@
/*-
* ~~~~~~licensing~~~~~~
* error-handler
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.core.common.error.handler.interceptor;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
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;
/**
*
* Prepare soap response and send back to calling system.
* Body can be simple string.
*
* Example:
*
* <bean id="handleOutFaultInterceptor" class="ru.entaxy.esb.system.core.common.error.handler.interceptor.EntaxyCxfFaultInterceptor">
* <argument ref="current-context-id"/>
* <argument value="direct:error_from_cxf"/>
* <property name="wrap" value="true"/>
* <property name="log" value="true"/>
* </bean>
*
* append bean to cxf service description
*
* <camelcxf:outFaultInterceptors>
* <ref component-id="handleOutFaultInterceptor"/>
* </camelcxf:outFaultInterceptors>
*
*/
public class EntaxyCxfFaultInterceptor extends AbstractSoapInterceptor {
private static final Log LOG = LogFactory.getLog(EntaxyCxfFaultInterceptor.class);
private final ProducerTemplate template;
/**
* endpoint to custom error handler route for
* preparing soap response
*/
private final String endpointUri;
/**
* wrap with soap envelope
*/
private boolean wrap = false;
/**
* wrapper endpoint, can be custom
*/
private String wrapEndpoint = "direct-vm:soap-wrap";
/**
* 1 line logging:
* <loggingKey> <errorMessage>
*/
private boolean log = false;
/**
* use service logging key
*/
private boolean loggingKeyUse = false;
/**
* default header with logging key
*/
private String loggingKeyHeader = "NTX_loggingKey";
public EntaxyCxfFaultInterceptor(CamelContext camelContext, String endpointUri) {
super(Phase.POST_PROTOCOL);
this.template = camelContext.createProducerTemplate();
this.endpointUri = endpointUri;
}
public void handleMessage(SoapMessage message) {
LOG.debug("EntaxyCxfFaultInterceptor.handleMessage invocation");
Map<String, Object> headers = prepareHeaders(message);
logging(headers);
String response = template.requestBodyAndHeaders(this.endpointUri, "", headers, String.class);
if (wrap) {
response = template.requestBodyAndHeaders(this.wrapEndpoint, response, headers, String.class);
}
LOG.debug("EntaxyCxfFaultInterceptor.handleMessage result from camel: \n" + response);
sendErrorResponse(message, 200, response, headers);
}
protected void logging(Map<String, Object> headers) {
if (log) {
Fault fault = (Fault) headers.get("NTX_ERROR_HANDLER_SoapFault");
StringBuilder errorMessage = new StringBuilder();
if (loggingKeyUse && headers.get(loggingKeyHeader) != null) {
errorMessage.append(headers.get(loggingKeyHeader));
errorMessage.append(" ");
}
errorMessage.append(fault.getCause().getMessage());
LOG.error(errorMessage);
}
}
protected Map<String, Object> prepareHeaders(SoapMessage message) {
Map<String, List<String>> inHeaders = Headers.getSetProtocolHeaders(message);
Map<String, Object> headers = new HashMap<>();
Object value;
for (Map.Entry<String, List<String>> e : inHeaders.entrySet()) {
if (e.getValue() != null && e.getValue().size() == 1 && e.getValue().get(0) instanceof String) {
value = e.getValue().get(0);
} else {
value = e.getValue();
}
headers.put(e.getKey(), value);
}
Fault fault = (Fault) message.getContent(Exception.class);
headers.put("NTX_ERROR_HANDLER_SoapFault", fault);
return headers;
}
protected void sendErrorResponse(Message message, int responseCode, String ret, Map<String, Object> headers) {
Message outMessage = getOutMessage(message);
outMessage.put(Message.ENCODING, StandardCharsets.UTF_8.name());
outMessage.put(Message.RESPONSE_CODE, responseCode);
// Clear the response headers
@SuppressWarnings("rawtypes")
Map responseHeaders = (Map) outMessage.get(Message.PROTOCOL_HEADERS);
if (responseHeaders != null) {
responseHeaders.clear();
}
message.getInterceptorChain().abort();
try {
getConduit(message).prepare(outMessage);
write(outMessage, ret);
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
}
}
protected 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;
}
protected Conduit getConduit(Message inMessage) throws IOException {
Exchange exchange = inMessage.getExchange();
Conduit conduit = exchange.getDestination().getBackChannel(inMessage);
exchange.setConduit(conduit);
return conduit;
}
protected void write(Message outMessage, String ret) throws IOException {
try (OutputStream os = outMessage.getContent(OutputStream.class);) {
os.write(ret.getBytes(StandardCharsets.UTF_8));
os.flush();
}
}
public void setWrap(boolean wrap) {
this.wrap = wrap;
}
public void setWrapEndpoint(String wrapEndpoint) {
this.wrapEndpoint = wrapEndpoint;
}
public void setLog(boolean log) {
this.log = log;
}
public void setLoggingKeyUse(boolean loggingKeyUse) {
this.loggingKeyUse = loggingKeyUse;
}
public void setLoggingKeyHeader(String loggingKeyHeader) {
this.loggingKeyHeader = loggingKeyHeader;
}
}

View File

@ -0,0 +1,155 @@
/*-
* ~~~~~~licensing~~~~~~
* error-handler
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.core.common.error.handler.interceptor;
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;
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;
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<String, List<String>> 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();
}
}

View File

@ -0,0 +1,45 @@
/*-
* ~~~~~~licensing~~~~~~
* error-handler
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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);
}
}

View File

@ -0,0 +1,36 @@
/*-
* ~~~~~~licensing~~~~~~
* error-handler
* ==========
* Copyright (C) 2020 - 2024 EmDev LLC
* ==========
* You may not use this file except in accordance with the License Terms of the Copyright
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
* rights to the Software and any copies are the property of the Copyright Holder. Unless
* it is explicitly allowed the Copyright Holder, the User is prohibited from using the
* Software for commercial purposes to provide services to third parties.
*
* The Copyright Holder hereby declares that the Software is provided on an "AS IS".
* Under no circumstances does the Copyright Holder guarantee or promise that the
* Software provided by him will be suitable or not suitable for the specific purposes
* of the User, that the Software will meet all commercial and personal subjective
* expectations of the User, that the Software will work properly, without technical
* errors, quickly and uninterruptedly.
*
* Under no circumstances shall the Copyright Holder or its Affiliates is not liable
* to the User for any direct or indirect losses of the User, his expenses or actual
* damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
* or damage to data, property, etc.
* ~~~~~~/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);
}
}

View File

@ -0,0 +1,482 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~~~~~~licensing~~~~~~
error-handler
==========
Copyright (C) 2020 - 2024 EmDev LLC
==========
You may not use this file except in accordance with the License Terms of the Copyright
Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
rights to the Software and any copies are the property of the Copyright Holder. Unless
it is explicitly allowed the Copyright Holder, the User is prohibited from using the
Software for commercial purposes to provide services to third parties.
The Copyright Holder hereby declares that the Software is provided on an "AS IS".
Under no circumstances does the Copyright Holder guarantee or promise that the
Software provided by him will be suitable or not suitable for the specific purposes
of the User, that the Software will meet all commercial and personal subjective
expectations of the User, that the Software will work properly, without technical
errors, quickly and uninterruptedly.
Under no circumstances shall the Copyright Holder or its Affiliates is not liable
to the User for any direct or indirect losses of the User, his expenses or actual
damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
or damage to data, property, etc.
~~~~~~/licensing~~~~~~
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
">
<cm:property-placeholder persistent-id="ru.entaxy.esb.error" update-strategy="reload">
<cm:default-properties>
<cm:property name="error.bus.system.id" value="-1"/>
<cm:property name="error.bus.system.name" value="esb"/>
<cm:property name="error.bus.always_at_source" value="false"/>
<cm:property name="error.description.exception_message" value="true"/>
<cm:property name="error.queue.name" value="error"/>
<cm:property name="error.system.name" value="error"/>
<cm:property name="error.asynch.stacktrace.show" value="true"/>
<cm:property name="error.synch.stacktrace.show" value="false"/>
<cm:property name="error.test-route.startup" value="false"/>
</cm:default-properties>
</cm:property-placeholder>
<cm:property-placeholder persistent-id="ru.entaxy.esb.error.code" update-strategy="reload"
placeholder-prefix="$errorCode{">
<cm:default-properties>
<cm:property name="ru.entaxy.esb.system.common.exception.DefaultException" value="520"/>
</cm:default-properties>
</cm:property-placeholder>
<cm:property-placeholder persistent-id="ru.entaxy.esb.error.text" update-strategy="reload"
placeholder-prefix="$errorText{">
<cm:default-properties>
<cm:property name="http-520" value="Unknown Error"/>
</cm:default-properties>
</cm:property-placeholder>
<cm:property-placeholder persistent-id="ru.entaxy.esb.error.severity" update-strategy="reload"
placeholder-prefix="$errorSeverity{">
<cm:default-properties>
<cm:property name="FATAL" value="1"/>
<cm:property name="ERROR" value="2"/>
<cm:property name="WARN" value="3"/>
<cm:property name="INFO" value="4"/>
</cm:default-properties>
</cm:property-placeholder>
<bean id="uuidGenerator" class="java.util.UUID" scope="prototype" factory-method="randomUUID"/>
<bean id="timestamp" class="ru.entaxy.esb.system.core.common.error.handler.util.Timestamp"/>
<reference id="entaxy-broker" interface="org.apache.camel.Component"
filter="(connection.name=entaxy-broker)"/>
<!-- <bean id="errorProcessor" class="ErrorProcessor"/>-->
<camelContext id="common-error-handler-context" errorHandlerRef="errorHandlerFailed"
xmlns="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint-3.4.5.xsd">
<!-- <errorHandler id="synchronousErrorHandler" redeliveryPolicyRef="noRedelivery"-->
<!-- onPrepareFailureRef="errorProcessor"-->
<!-- type="DeadLetterChannel" deadLetterUri="direct:syncErrorHandlerEndpoint" />-->
<errorHandler id="commonErrorHandler" redeliveryPolicyRef="noRedelivery"
type="DeadLetterChannel" deadLetterUri="direct-vm:commonErrorEndpoint"/>
<errorHandler id="errorHandlerFailed" redeliveryPolicyRef="noRedelivery"
type="DeadLetterChannel" deadLetterUri="direct:errorHandlerFailedEndpoint"/>
<errorHandler id="loggingErrorHandler" redeliveryPolicyRef="noRedelivery"/>
<!-- type="LoggingErrorHandler" logName="errorHandlerCrash"/>-->
<redeliveryPolicyProfile id="noRedelivery" disableRedelivery="true"/>
<route id="error-handler-test-route" errorHandlerRef="commonErrorHandler"
autoStartup="{{error.test-route.startup}}">
<from uri="timer:test-route?repeatCount=1"/>
<log message="error handler test route started successfully\n\n" loggingLevel="INFO"/>
<setBody>
<simple>
<![CDATA[<packet xmlns="http://www.entaxy.ru/ExchangeTypes/1.0"><content>Oops... some test error occurred</content></packet>]]>
</simple>
</setBody>
<throwException exceptionType="java.lang.IllegalArgumentException" message="Test exception thrown"/>
</route>
<!-- the route is designed to handle errors that occurred in other routes of this context -->
<route id="error-handler-failed-route" errorHandlerRef="loggingErrorHandler">
<from uri="direct:errorHandlerFailedEndpoint"/>
<log message="Exception handled by ${routeId}: ${exception}
${messageHistory}${exception.stacktrace}" loggingLevel="ERROR"/>
<!-- TODO connect to alarm or monitoring system (send email, sms, etc) -->
</route>
<route id="cxf-error-handler-route">
<from uri="direct-vm:cxfErrorEndpoint"/>
<log message="Exception handled by ${routeId}: ${header.NTX_ERROR_HANDLER_SoapFault}" loggingLevel="ERROR"/>
<doTry>
<to uri="direct-vm:commonErrorEndpoint"/>
<doFinally>
<to uri="xslt:xslt/WrapSoapEnvelope.xsl"/>
</doFinally>
</doTry>
</route>
<route id="common-error-handler-route">
<from uri="direct-vm:commonErrorEndpoint"/>
<log message="Exception handled by ${routeId}: ${exception}
on message ${headers.ENTAXY_MessageUUID}
${messageHistory}${exception.stacktrace}" loggingLevel="ERROR"/>
<setBody>
<constant><![CDATA[<empty/>]]></constant>
</setBody>
<to uri="xslt:xslt/DefaultResponse.xsl"/>
<to uri="direct:prepareResponseCodeAndTextEndpoint"/>
<wireTap uri="direct:asynchronousErrorEndpoint"/>
<choice>
<when>
<simple>${headers.NTX_ERROR_HANDLER_GenerateResponseEndpoint} != null</simple>
<toD uri="direct-vm:${headers.NTX_ERROR_HANDLER_GenerateResponseEndpoint}"/>
</when>
<when>
<simple>${headers.NTX_ERROR_HANDLER_SYNC_TYPE} == "application/json"</simple>
<to uri="direct:synchronousJSONErrorEndpoint"/>
</when>
<otherwise>
<to uri="direct:synchronousErrorEndpoint"/>
</otherwise>
</choice>
<!-- Remove headers before response -->
<removeHeaders pattern="*"/>
</route>
<route id="prepare-response-code-and-text-route">
<from uri="direct:prepareResponseCodeAndTextEndpoint"/>
<setHeader name="NTX_ERROR_HANDLER_asynch_Stacktrace">
<simple>${properties:error.asynch.stacktrace.show}</simple>
</setHeader>
<setHeader name="NTX_ERROR_HANDLER_synch_Stacktrace">
<simple>${properties:error.synch.stacktrace.show}</simple>
</setHeader>
<choice>
<when>
<simple>${exception} != null</simple>
<setHeader name="NTX_ERROR_HANDLER_ExceptionClass">
<simple resultType="String">${exception.class.name}</simple>
</setHeader>
<setHeader name="NTX_ERROR_HANDLER_ExceptionMessage">
<simple resultType="String">${exception.message}</simple>
</setHeader>
<when>
<simple>
${header.NTX_ERROR_HANDLER_asynch_Stacktrace} == "true" || ${header.NTX_ERROR_HANDLER_synch_Stacktrace} == "true"
</simple>
<setHeader name="NTX_ERROR_HANDLER_Stacktrace">
<simple>${exception.stacktrace}</simple>
</setHeader>
</when>
</when>
<when>
<simple>${header.NTX_ERROR_HANDLER_SoapFault} != null</simple>
<setHeader name="NTX_ERROR_HANDLER_ExceptionClass">
<simple resultType="String">${header.NTX_ERROR_HANDLER_SoapFault.cause.class.name}</simple>
</setHeader>
<setHeader name="NTX_ERROR_HANDLER_ExceptionMessage">
<simple resultType="String">${header.NTX_ERROR_HANDLER_SoapFault.cause.message}</simple>
</setHeader>
<when>
<simple>
${header.NTX_ERROR_HANDLER_asynch_Stacktrace} == "true" || ${header.NTX_ERROR_HANDLER_synch_Stacktrace} == "true"
</simple>
<setProperty name="bodyHolder">
<simple>${body}</simple>
</setProperty>
<bean beanType="org.apache.commons.lang3.exception.ExceptionUtils" method="getStackTrace(${header.NTX_ERROR_HANDLER_SoapFault.cause})"/>
<setHeader name="NTX_ERROR_HANDLER_Stacktrace">
<simple>${body}</simple>
</setHeader>
<setBody>
<simple>${exchangeProperty.bodyHolder}</simple>
</setBody>
</when>
</when>
<otherwise>
<setHeader name="NTX_ERROR_HANDLER_ExceptionClass">
<simple resultType="String">ru.entaxy.esb.system.common.exception.DefaultException</simple>
</setHeader>
<setHeader name="NTX_ERROR_HANDLER_ExceptionMessage">
<simple resultType="String">Something wrong</simple>
</setHeader>
</otherwise>
</choice>
<choice>
<when>
<simple>${header.NTX_ERROR_HANDLER_ExceptionClass}</simple>
<doTry>
<setHeader name="NTX_ERROR_HANDLER_ResponseCode">
<simple>${properties:${header.NTX_ERROR_HANDLER_ExceptionClass}}</simple>
</setHeader>
<doCatch>
<exception>java.lang.Exception</exception>
<log message="Exception code not set for class: ${header.NTX_ERROR_HANDLER_ExceptionClass}" loggingLevel="WARN"/>
<setHeader name="NTX_ERROR_HANDLER_ResponseCode">
<simple>${properties:ru.entaxy.esb.system.common.exception.DefaultException}</simple>
</setHeader>
</doCatch>
</doTry>
</when>
</choice>
<choice>
<when>
<simple>${properties:error.description.exception_message} == "true"</simple>
<setHeader name="NTX_ERROR_HANDLER_ResponseText">
<simple>${header.NTX_ERROR_HANDLER_ExceptionMessage}</simple>
</setHeader>
</when>
<otherwise>
<setHeader name="NTX_ERROR_HANDLER_ResponseText">
<simple>${properties:${header.NTX_ERROR_HANDLER_ResponseCode}}</simple>
</setHeader>
</otherwise>
</choice>
<log message="${exchangeProperty.CamelExceptionCaught}\n" loggingLevel="DEBUG"/>
<log message="${routeId}: \n
${header.NTX_ERROR_HANDLER_ExceptionClass} \n
${header.NTX_ERROR_HANDLER_ResponseCode} ${header.NTX_ERROR_HANDLER_ResponseText}"
loggingLevel="DEBUG"/>
</route>
<route id="asynchronous-error-handler-route">
<from uri="direct:asynchronousErrorEndpoint"/>
<log message="${routeId}" loggingLevel="DEBUG"/>
<to uri="direct:prepareErrorPacketEndpoint"/>
<removeHeaders pattern="NTX_ERROR_HANDLER_.+"/>
<!-- Send error packet to central error handling system -->
<doTry>
<toD uri="system:${properties:error.system.name}?exchangePattern=InOnly"/>
<doCatch>
<exception>java.lang.Exception</exception>
<log message="${exception.message}" loggingLevel="DEBUG"/>
<log message="${exception.stacktrace}" loggingLevel="TRACE"/>
<toD uri="entaxy-broker:queue:entaxy.${properties:error.queue.name}?exchangePattern=InOnly"/>
</doCatch>
</doTry>
<!-- Send error packet back to the calling system -->
<choice>
<when>
<simple>${headers.X-SystemName} != "esb"</simple>
<doTry>
<toD uri="system:${headers.X-SystemName}?exchangePattern=InOnly"/>
<doCatch>
<exception>java.lang.Exception</exception>
<log message="Can't deliver error packet to system: ${headers.X-SystemName}"
loggingLevel="DEBUG"/>
<log message="${exception.message}" loggingLevel="ERROR"/>
<log message="${exception.stacktrace}" loggingLevel="DEBUG"/>
</doCatch>
</doTry>
</when>
</choice>
</route>
<route id="prepare-error-packet-route">
<from uri="direct:prepareErrorPacketEndpoint"/>
<log message="${routeId}" loggingLevel="DEBUG"/>
<to uri="direct:prepareErrorPacketHeadersEndpoint"/>
<setHeader name="ENTAXY_Source">
<constant>esb</constant>
</setHeader>
<log message="Before transformation \n${body}" loggingLevel="DEBUG"/>
<to uri="xslt:xslt/UniversalErrorPacket.xsl"/>
<log message="After transformation \n${body}" loggingLevel="DEBUG"/>
<setHeader name="ENTAXY_MessageUUID">
<simple>${bean:uuidGenerator.toString}</simple>
</setHeader>
<setHeader name="ENTAXY_MessageType">
<constant>ВыгрузкаДанныхКаноническийФормат</constant>
</setHeader>
<setHeader name="ENTAXY_ContentType">
<constant>application/xml</constant>
</setHeader>
<setHeader name="CamelJms_IntMessageType">
<constant>String</constant>
</setHeader>
<setHeader name="CamelJms_IntContentXsiType">
<constant>xs:string</constant>
</setHeader>
</route>
<route id="prepare-error-packet-headers-route">
<from uri="direct:prepareErrorPacketHeadersEndpoint"/>
<setHeader name="NTX_ERROR_HANDLER_CentralIntegrationDB">
<simple>${properties:error.system.name}</simple>
</setHeader>
<choice>
<when>
<simple>${headers.ENTAXY_Source} != null &amp;&amp; ${headers.ENTAXY_Source} != ""
</simple>
<setHeader name="NTX_ERROR_HANDLER_Source">
<simple>${headers.ENTAXY_Source}</simple>
</setHeader>
<setHeader name="NTX_ERROR_HANDLER_Destination">
<simple>${headers.ENTAXY_Source}</simple>
</setHeader>
</when>
<when>
<simple>${headers.NTX_SystemId} != null &amp;&amp; ${headers.NTX_SystemId} != ""</simple>
<setHeader name="NTX_ERROR_HANDLER_Source">
<simple>${headers.NTX_SystemId}</simple>
</setHeader>
<setHeader name="NTX_ERROR_HANDLER_Destination">
<simple>${headers.NTX_SystemId}</simple>
</setHeader>
</when>
<when>
<simple>${headers.X-SystemName} != null &amp;&amp; ${headers.X-SystemName} != ""</simple>
<setHeader name="NTX_ERROR_HANDLER_Source">
<simple>${headers.X-SystemName}</simple>
</setHeader>
<setHeader name="NTX_ERROR_HANDLER_Destination">
<simple>${headers.X-SystemName}</simple>
</setHeader>
</when>
<otherwise>
<setHeader name="NTX_ERROR_HANDLER_Source">
<constant>esb</constant>
</setHeader>
<setHeader name="X-SystemName">
<constant>esb</constant>
</setHeader>
</otherwise>
</choice>
<choice>
<when>
<simple>${headers.X-SystemName} == null || ${headers.X-SystemName} == ""</simple>
<setHeader name="X-SystemName">
<constant>esb</constant>
</setHeader>
</when>
</choice>
<choice>
<when>
<simple>${headers.X-SystemId} == null || ${headers.X-SystemId} == ""</simple>
<setHeader name="X-SystemId">
<constant>-1</constant>
</setHeader>
</when>
</choice>
<choice>
<when>
<simple>${properties:error.bus.always_at_source} == "true"</simple>
<setHeader name="NTX_ERROR_HANDLER_Source">
<constant>esb</constant>
</setHeader>
<setHeader name="X-SystemName">
<constant>esb</constant>
</setHeader>
<setHeader name="X-SystemId">
<constant>-1</constant>
</setHeader>
</when>
</choice>
<setHeader name="NTX_ERROR_HANDLER_ErrorUUID">
<simple>${bean:uuidGenerator.toString}</simple>
</setHeader>
<log message="Prepare error packet with eventUUID: ${headers.NTX_ERROR_HANDLER_ErrorUUID}"
loggingLevel="ERROR"/>
<setHeader name="NTX_ERROR_HANDLER_Timestamp">
<simple>${bean:timestamp?method=currentTimeMillis}</simple>
</setHeader>
<when>
<simple>${headers.NTX_ERROR_HANDLER_SeverityLevel} == null</simple>
<setHeader name="NTX_ERROR_HANDLER_SeverityLevel">
<constant>ERROR</constant>
</setHeader>
</when>
</route>
<route id="synchronous-error-handler-route">
<from uri="direct:synchronousErrorEndpoint"/>
<setBody>
<constant><![CDATA[<root/>]]></constant>
</setBody>
<choice>
<when>
<simple>${headers.operationName}</simple>
<doTry>
<toD uri="xslt:xslt/operation/${header.operationName}.xsl"/>
<doCatch>
<exception>java.lang.Exception</exception>
<log message="${exception}" loggingLevel="TRACE"/>
<to uri="xslt:xslt/DefaultResponse.xsl"/>
</doCatch>
</doTry>
</when>
<otherwise>
<to uri="xslt:xslt/DefaultResponse.xsl"/>
</otherwise>
</choice>
</route>
<route id="synchronous-json-error-handler-route">
<from uri="direct:synchronousJSONErrorEndpoint"/>
<choice>
<when>
<simple>${headers.operationName}</simple>
<doTry>
<toD uri="freemarker:ftl/${header.operationName}.ftl?interpolationSyntax=22&amp;tagSyntax=2"/>
<doCatch>
<exception>java.lang.Exception</exception>
<log message="${exception}" loggingLevel="TRACE"/>
<to uri="freemarker:ftl/DefaultResponse.ftl?contentCache=true&amp;interpolationSyntax=22&amp;tagSyntax=2"/>
</doCatch>
</doTry>
</when>
<otherwise>
<to uri="freemarker:ftl/DefaultResponse.ftl?allowContextMapAll=true&amp;contentCache=true"/>
</otherwise>
</choice>
</route>
<route id="soap-wrap-route">
<from uri="direct-vm:soap-wrap"/>
<log loggingLevel="TRACE" message="wrap: ${body.class.name}\n${body}"/>
<doTry>
<convertBodyTo type="org.w3c.dom.Document"/>
<doCatch>
<exception>java.lang.Exception</exception>
<!--keep silence-->
</doCatch>
</doTry>
<setProperty name="message">
<simple>${body}</simple>
</setProperty>
<setBody>
<simple>${null}</simple>
</setBody>
<to uri="xslt:xslt/soapWrap.xsl?failOnNullBody=false"/>
</route>
</camelContext>
</blueprint>

Some files were not shown because too many files have changed in this diff Show More