Высокоуровневая архитектура Backend

Предупреждение

Начиная с версии 6.13 доступна новая публичная документация разработчика SDK и интерактивные руководства по кастомизации интерфейса и бизнес-логики. Объем нового SDK руководства будет меньше, поскольку большая часть предыдущих руководств либо устарела, либо стала непубличной. Если вы используете старые SDK руководства в своей работе, то найти вы их можете в предыдущих версиях документации. В версии 6.15 старые SDK более не будут поддерживаться и будут удалены из дистрибутива.

В этой статье описано, как устроена backend-платформа: от архитектурных решений до инструментов для разработчиков. Статья включает в себя ключевые компоненты, модульную структуру, аутентификацию и интеграцию, для эффективного использования или адаптации платформы под свои задачи.

Платформа реализована как Modular Monolith — гибридный подход, который объединяет преимущества микросервисов (масштабируемость, независимость модулей) и монолита (простота развертывания). Платформа поддерживает OAuth2, Kerberos и другие протоколы аутентификации, а модульная структура позволяет гибко настраивать зависимости и порядок инициализации компонентов.

В основе стека — Spring (каркас для enterprise-приложений), Hazelcast (распределенное кэширование) и Camunda (оркестрация бизнес-процессов).

SDK платформы предоставляет инструменты для расширения функциональности, а диаграммы взаимодействия (C1, C2, C3) помогают визуализировать связи между модулями.

Общая схема взаимодействия пользователей с платформой

Диаграмма уровня С1

Рисунок 1 – Диаграмма уровня С1

Как видно на диаграмме уровня C1, платформа поддерживает аутентификацию, авторизацию и профили пользователей, как ведущихся в самой платформе, так и внешних, приходящих через разные механизмы SSO (Single Sign On).

Практически сейчас поддерживаются Kerberos, OAuth2 и системный протоколы. В будущем могут появится и другие. Источники данных безопасности разных протоколов предоставляют возможность интегратором встраиваться в процесс аутентификации / авторизации / получения профиля для переопределения системных свойств конкретного протокола (местонахождение внешнего токена, URI для переходов на эндпоинт Identity Provider и т. п.). После успешной аутентификации по любому из поддерживаемых протоколов в качестве токена всегда используется собственная схема платформы bearer token. Токен ходит в HTTP заголовке Authorization:.

Обзор контейнеров

Диаграмма уровня С2

Рисунок 2 – Диаграмма уровня С2

Обзор контейнеров сделан в виде диаграммы C2. Как видно из диаграммы, платформа использует ограниченное число базовых технологий. Backend системы запускается на стандартном контейнере сервлетов, удовлетворяющем JavaEE v.8 (напр. Tomcat 9.x). Для сборки и запуска требуется Java 11 (standard VM). Также к числу базовых контейнеров нужно отнести OpenSearch (текущая версия) и PostgreSQL (от версии 15.х). Для backend платформы есть Docker образы, а также возможность деплоя на K8s.

Стек технологий

Базовыми технологиями компонент бэкенда являются Spring (Context, JDBC, Security, Batch, Integration), распределенный кэш Hazelcast, Apache Camel, Quartz scheduler, FasterXML Jackson, CXF, Apache POI, Apache Commons, Camunda BPMN Engine.

Модульная инфраструктура

Backend платформы Universe это решение вокруг MDM, DG, DQ и Matching сценариев. Он задуман и реализован, как набор модулей в стиле Modular Monolith для построения специализированных сценариев использования и сборок с возможностью переиспользования функциональности.

Технически для любого продукта backend представляет собой набор модулей, реализованных в виде jar файлов и снабженных метаданными. С помощью метаданных модули экспортируют информацию о себе, своих расширениях, конфигурационных переменных, ресурсах и т. п. Модули ведут отдельные схемы в БД. Модули могут ссылаться на другие модули и это также отражается в их метаданных. При старте, на основе метаданных модулей загрузчик выстраивает граф зависимостей и определяет очередность инициализации. В процессе модуль выглядит, как отдельный Spring контекст, имеющий видимость вниз по стеку (чем раньше инициализация, тем ниже место в стеке). Таким образом модули "видят" типы из других модулей, от которых они зависят.

Модули и сервисы

Диаграмма уровня С3

Рисунок 3 – Диаграмма уровня С3

На диаграмме C3 представлен список модулей предоставляющих Internal API (Сервисы, используемые внутренними разработчиками для реализации бизнес логики продукта) и SDK (Классы и интерфейсы используемые для расширения бизнес логики сторонними разработчиками).

Шаблон для начала работы

Для разработки SDK можно использовать шаблон работы с SDK.

OAuth2

При помощи SDK возможно расширить аутентификацию в платформе собственными провайдерами OAuth 2.0.

HPE

В системе существует операция деперсонализации данных. По аналогии с функциями для правил качества, реализации обфускаторов могут быть пользовательскими. Для этого нужно реализовать интерфейс org.unidata.mdm.core.type.model.source.obfuscate.ObfuscatingFunction, либо расширить класс org.unidata.mdm.core.type.model.source.obfuscate.impl.AbstractSimpleObfuscatingFunction, который уже включает в себя базовую логику для обфускаторов, обрабатывающих простые атрибуты. Деперсенификация - это часть HPE, в то время как создание абфускаторов является частью деперсенефикации вынесенной в SDK. Таким образом HPE в SDK представлено в виде инструментария для создания пользовательского абфускатора.

   public class HashSalted extends AbstractSimpleObfuscatingFunction {

   /**
    * SimpleDataType обфусцирующего атрибута
    */
   @Override
   public SimpleDataType getSimpleDataType() {
       return SimpleDataType.STRING;
   }

   /**
    * Отображаемое имя обфусцирующей функции
    */
   @Override
   public String getDisplayName() {
       return "Отображаемое имя обфусцирующей функции";
   }

   /**
    * Описание обфусцирующей функции
    */
   @Override
   public String getDescription() {
       return "Описание обфусцирующей функции";
   }

   /**
    * Реализация обфусцирующей функции
    */
   @Override
   public Object obfuscate(final ObfuscateAttributeValueContext ctx) {
       // Получаем значение атрибута
       final Object input = ctx.getValueToObfuscate();

       // Проверяем, соответствует ли тип значения атрибута
       // обфусцируемому типу
       if (!isCorrectInput(input, String.class)) {
           return input;
       }

       // Получаем обфусцирующий атрибут требуемого типа
       final String currentValue = (String) input;

       // Логика обфускации значения
       return BCrypt.hashpw(currentValue, BCrypt.gensalt());
   }
}

Затем нужно собрать проект в .jar файл и загрузить результат в систему, через вкладку библиотеки. Если обфускатор корректно идентифицировался, то библиотека будет иметь тип Obfuscating function.

../../../../_images/theoryimage050.png

После успешного импорта библиотеки выбор реализованных обфускаторов будет доступен в селекторе для атрибутов с соответствующим типом, при включенном checkbox Security sensitive.

../../../../_images/theoryimage051.png

Интеграция

Система не предоставляет возможности интеграции, а только инструменты для частичной ее организации. Например, одно из функциональных расширений Messaging, либо возможность написания задач по регулярной выгрузке. Это обусловлено тем, что возможностей интеграции огромное множество и заранее покрыть их нельзя, так и тем, что у разных продуктов способы получения данных принципиально разнятся. Юниверс MDM является принимающей стороной, передающей данные далее.

Подробнее об инструментах интеграции см. в статье.

../../../../_images/theoryimage052.png