Подсистема Sochi-Server (SSRV) и платформа ActiveFrame 5 (AF5) позволяют получить конфигурацию, которая:
Используется связка открытого ПО: Java EE – сервера приложений JBoss EAP , РСУБД PostgreSQL и платформа AF5
Платформа AF5 обеспечивает базовые операции для:
Подсистема CMJ-Server:
Назначение подсистемы SSRV :
Содержит xml-описания структуры хранимых сущностей (ДОП-ы платформы AF5).
Реализует механизмы преобразования элементов хранения данных платформы AF5 (ДОП) в формат Document и обратно.
Все сущности CMJ-Server сохраняет и читает через объект с интерфейсом lotus.domino.Document из состава Notes Java API . Интерфейс содержит методы для чтения и модификации атрибутов сущности.
При отображении Document в объекты платформы, как правило, задействуется множество разнотипных доменных объектов платформы (ДОП), например, для сохранения множественных значений полей. Т.е. одному типу Document соответствует N типов ДОП, которые связаны между собой в древовидную структуру. Корень дерева будем называть «корневым ДОП» (КДОП).
При сохранении Document, на основании ключевых атрибутов сущности определяется её тип (РКК, КР и т.п.). По имени типа сущности, имени типа и «комплекта» модуля, к которому относится Document, ищется именованный Spring-бин с интерфейсом EntityMapper, описывающий логику конвертации Document в иерархию ДОПи обратно. Если бин не найден, ищется бин по имени типа сущности и типа модуля. Если и такой не найден, ищется по имени типа сущности. Такой подход позволяет иметь единые правила преобразования однотипных сущностей, логически расположенных в разных бизнес-модулях или комплектах.
Компонента EntityMapper названа по имени её ключевого интерфейса. Любой объект EntityMapper выполняет сопоставление поступивших для сохранения данных, с уже хранимыми данными. Модификация ДОП выполняется только если данные изменены. Если хотя бы один ДОП из иерархии изменён, выполняется фиктивная модификация корневого ДОП для того, чтобы изменилась хранимая дата его последней модификации. Дата модификации корневого ДОП используется как дата модификации всей сущности в целом.
При запросе на извлечение сущности из хранилища, ищется её корневой ДОП . Любой КДОП имеет ссылку на модуль, к которому относится сущность. По типу КДОП , типу модуля и «комплекту» модуля ищется EntityMapper, который и выполняет наполнение Document данными.
AF5 отслеживает конкурентную модификацию ДОП. Но не считает конфликтом, если первый поток изменил один ДОП из иерархии сущности, а второй поток изменил другой ДОП той же сущности. Обязательность сохранения КДОП при изменении любого ДОП из иерархии, решает и эту проблему. Когда AF5 фиксирует конфликт модификации КДОП, бросается эксепшен, который приводит к откату транзакции в «проигравшем» потоке, а значит и откату модификаций всех ДОП из иерархии сущности.
AF5 обеспечивает кэширование ДОП в рамках одной транзакции. Транзакция открывается на каждый HTTP-запрос и закрывается после формирования HTTP-ответа.
Для экономии операций конвертации иерархии ДОП в Document, SSRV имеет LFU-кэш считанных из хранилища сущностей. Ключом кэша является идентификатор сущности и идентификатор потока исполнения. Идентификатор потока в ключе предотвращает получение одного java-объекта разными потоками и избавляет от необходимости управления конкурентным доступом к java-объекту на уровне SSRV. Использование пула потоков обеспечивает хорошее кэш-попадание. Конфликты конкурентной модификации ДОП отслеживает AF5.
При развертывании СМ на нескольких серверах приложений с общей БД, возможна модификация ДОП другим экземпляром SSRV. Для обеспечения получения актуальных, не закешированных данных на первом экземпляре SSRV, при считывании сущности всегда извлекается её КДОП и сравнивается дата его модификации с датой в кэше. Если дата совпадает, данные берутся из кэша. Не совпадает – выполняется полное считывание иерархии ДОП из БД и конвертация в Document. Этот принцип обеспечивает и актуальность данных после модификации сущности разными потоками одного экземпляра SSRV.
CMJ-Server применяет подход, когда идентификатор сущности (UNID) генерируется и назначается сущности ещё до её первого сохранения. Платформа AF5 назначает идентификатор только после первого сохранения ДОП. Для установления соответствия сгенерированного UNID идентификатору КДОП, использованы служебные ДОП типа «nunid2punid_map», которые хранят:
При первом сохранении сущности, после сохранения её КДОП, создаётся и ДОП типа «nunid2punid_map». Если CMJ-Server запрашивает сущность по назначенному UNID, по «nunid2punid_map» определяется id её КДОП, и по полученному id уже извлекается КДОП средствами AF5. При поиске сущности не по id, например через коллекции, выполняется обратное преобразование id найденных КДОП в назначенный UNID.
Содержит xml-описания списков хранимых сущностей (коллекции AF5).
Реализует механизм извлечения списков, функционально эквивалентный Notes - View.
Базируется на подсистеме «коллекций» платформы, добавляя возможность преобразования нескольких колонок в одну (виртуальные колонки), группировки по значениям колонок и определения сортировок по-умолчанию.
При запросе на получение именованного списка через CollectionProvider, выполняется поиск коллекции платформы по имени списка, типу модуля и «комплекту» модуля, к которому относится данный CollectionProvider. Если коллекция не найдена, ищется по имени списка и типу модуля. Если не найдено, то только по имени списка. К найденной коллекции применяется фильтр с зарезервированным именем Module, который должен отбирать сущности, приписанные заданному модулю. После нахождения точного имени коллекции, ищется Spring-бин с именем коллекции плюс суффикс «Metadata». Из этого бина с метаданными, CollectionProvider получает правила формирования виртуальных колонок, сортировки и категоризации по-умолчанию. Такой подход позволяет иметь единые описания списков сущностей, логически расположенных в разных модулях или комплектах.
Поля виртуальной колонки вычисляются в отложенном режиме, в момент, когда запрашивается значение виртуального поля. Этим достигается экономия на вычислении значений виртуальных полей в больших списках.
Средствами CollectionProvider моделируются методы получения респонсов Notes API. Для этого у модуля должна быть коллекция с именем « document _responses», которая должна иметь фильтр « parent». Фильтр должен отбирать респонсы первого уровня для заданной родительской сущности.
Для получения локализованных списков, у коллекции должен быть фильтр «byLocale», который отбирает локализованные значения сущностей. CollectionProvider сначала считает все имена локалей, сохраненные БД. Имя таблицы с локализованными значениями и имя колонки с именами локалей берутся из бина с метаданными списка. Затем получает имя локали из настроек браузера пользователя. Среди хранимых локалей находит наиболее подходящую пользовательской локали. Полученное имя локали CollectionProvider подставляет как значение параметра фильтру « byLocale».
СМ-CollectionProvider
Содержит xml-описания кастомных коллекций
Формирует иерархию списков сущностей в формате CMJ, в соответствии с настройками, заданными через CM-AdminGUI и отображаемую в интерфейсе CMJ-WebGUI в виде иерархии папок.
Реализует движок исполнения JavaScript
Формирует контекст исполнения для скриптов
Настраивыемые реквизиты. Настройка полей формы, кнопок и секций.
Каталог. Настройка Web-навигации и представление данных в grid-е
Связи. Настройка связей между сущностями
Конфигурация бизнес-процессов по стандарту BPMN 2.0
Содержит описание типов e-mail уведомлений. Содержит локализованные шаблоны текстов уведомлений
Описывает события, по которым должно отправляться уведомление заданного типа.
Формирует персональные задачи и уведомления, отображаемые в интерфейсе CMJ-WebGUI, отслеживает их статус.
В конфигурации CM на AF5 данные для ПКД поставляются через её API, которое выполняет их сохранение средствами ORM Hibernate , т.е. без использования средств платформы AF5. Интеграция с ПКД в СМ на AF5 выполнена путём создания специального канала уведомлений платформы AF5. Обработчик канала выполняет сопоставление типа уведомления типу PKD-уведомления или PKD-задачи и через API PKD выполняет их создание или обновление.
Реализует полнотекстовый поиск сущностей
Реализует операции по работе со справочниками СО, СпО, СпП
Настройка бизнес-правил для Согласования
Настройка реляций
Выполняет построение отчетов. Реализован с использованием JasperReports компоненты платформы AF5.
Содержит настройки с шаблонами и параметрами отчетов
Реализует запуск фоновых задач по-расписанию или при изменении сущностей
Реализует синхронный запуск именованных CM-агентов.
Реализует бизнес-логику в виде фоновых задач, запускаемых через AgentRunner
Выполняет инициализацию БД значениями по-умолчанию, предоставленными в CSV-формате.
Содержит описание правил предоставления доступа к хранимым сущностям.
Базируется на подсистеме «прав доступа» платформы AF5.
Проверку прав на создание и модификацию сущностей осуществляет CMJ-Server, в соответствии с настройками в профиле пользователя и назначением его на роли. Поэтому компонент AclRoles описывает лишь правила предоставления доступа «на чтение» сущностей. Помимо авторизации, правами также обеспечивается, чтобы в списки попадали только доступные сущности.
AF5, при пересчёте прав, не модифицирует ДОП, а значит пересчет не может привести к неуспешному сохранению пользовательских изменений.
Реализует аутентификацию пользователей в системе. Базируется на JAAS подсистеме Java EE
Реализует программные интерфейсы Notes Java API с использованием подсистем EntityMapper, CollectionProvider, NamedCode, JS, Authentification
Содержит альтернативную имплементацию компонент CMJ, которые задействуют специфичные Domino операции, такие, как поиск по @-формуле, полнотекстовый поиск.
Интерфейсы для абстрагирования от реализации подсистемы хранения
Реализует пользовательский интерфейс для АРМ предметного администратора средствами AF5.
Содержит серверную логику обработки сохранения сущностей через UI