RAD на Java: как устроена
CUBA Platform?
Константин Кривопустов
технический директор
Haulmont
Что в составе платформы
CUBA
Premium
Add-ons
Run time
Eclipse
Plugin
IntelliJ
IDEA
Plugin
Studio
Design time
2
Уровни и блоки
3
Модули
4
Компоненты приложения
5
Пример составных частей приложения
6
Основные части API платформы
Data model
Metadata
Services
DataManager
App Properties
Data stores
ORM
UserSession
VCL
Datasources
Generic UI
Middleware
7
Модель данных
8
Методы сущности
• getId()
• getMetaClass()
• getInstanceName()
• getValue(property) / setValue(property, value)
• addPropertyChangeListener(listener)
9
Метаданные
10
Application Properties
Свойства приложения − именованные значения различных типов,
определяющие конфигурацию и функционирование приложения.
• Конфигурационные параметры - определяют функциональность
приложения, обычно задаются при разработке приложения.
• Параметры развертывания - различные URL для соединения блоков
приложения, тип используемой БД и т.д. Зависят от окружения, в
котором устанавливается данный экземпляр приложения.
• Параметры времени выполнения - активность аудита, параметры
отсылки email и т.д. Могут быть изменены при необходимости во
время работы приложения.
11
Конфигурационные параметры
Пример параметра: springContextConfig – указывает набор конфигурационных
файлов Spring-контейнера данного блока приложения
cuba
springContextConfig = cuba-spring.xml
bpm
springContextConfig = bpm-spring.xml
app
springContextConfig = +com/company/app/spring.xml
Итоговое значение в приложении app:
springContextConfig = cuba-spring.xml bpm-spring.xml com/company/app/spring.xml
12
DataManager
DataManager - универсальный интерфейс для загрузки графов сущностей
из хранилищ, и для сохранения изменений
• load() – загружает экземпляр сущности
• loadList() – загружает список экземпляров
• loadValues() – загружает список KeyValueEntity
• getCount() – возвращает количество экземпляров
• commit() – сохраняет переданные экземпляры и возвращает
сохраненные
13
UserSession & SecurityContext
Объект UserSession ассоциирован с текущим пользователем и содержит
информацию о его правах доступа
• UserSession создается после логина, кэшируется на middleware и
возвращается клиенту
• Клиент с каждым обращением к middleware передает ID сессии
• Поэтому клиент должен либо хранить ID сессии либо всегда выполнять логин
• ID текущей сессии хранится в потоке выполнения и на клиенте и на
middleware в объекте SecurityContext
• При создании новых потоков в них нужно передавать SecurityContext
• На middleware можно использовать «системную аутентификацию»
14
Сервисы middleware
Сервисы – точки входа в middleware для клиентов
15
Data stores
• Данные представляются сущностями, сущности принадлежат
хранилищам
• DataStore – интерфейс хранилищ, повторяющий DataManager
• load(), loadList(), loadValues(), getCount(), commit()
• DataManager делегирует запросы хранилищам и обеспечивает
поддержание ссылок между сущностями
• Стандартная реализация хранилища – RdbmsStore для работы с RDBMS
через ORM. Поддерживает права доступа пользователя к данным и
динамические атрибуты.
• Приложение должно содержать основное хранилище, являющееся
реляционной БД
16
ORM
• Использует EclipseLink
• CUBA EntityManager в основном повторяет JPA EntityManager и добавляет
поддержку:
• soft deletion
• views (представления)
• Собственная реализация entity listeners
• Before[Insert|Update|Delete] – принимают текущий EntityManager
• After[Insert|Update|Delete] – принимают текущий JDBC Connection
• BeforeDetachEntityListener – можно использовать для заполнения неперсистентных
атрибутов перед отправкой клиенту
• BeforeAttachEntityListener – можно использовать для заполнения персистентных
атрибутов перед сохранением в БД
• Criteria API не поддерживается
17
ORM: почему не Hibernate?
Date Customer Service Driver Passengers
25/06/2017 17:10 Smith Regular Jones 2
25/06/2017 17:15 Williams 7-seater Taylor 5
select j.creationDate, [+50 fields],
c.name, [+30 fields],
s.caption, [+35 fields],
d.name, [+ 45 fields]
from Job j
join Customer c on …
join Service s on …
join Driver d on …
Итого загружено: >150 колонок
вместо 12 для каждой строки
18
EclipseLink FetchGroups + CUBA Views
• Задание FetchGroup в EclipseLink позволяет загружать «частичные»
объекты
• CUBA Views: надстройка для удобного управления FetchGroups
• View обязательно передается вместе с запросом в DataManager и
опционально в EntityManager Query
19
Generic UI
20
Универсальный REST API
21
Polymer UI
• Web Components в чистом виде
• Google Polymer
• Vaadin Elements
• Любые другие
• Сборка на Gradle вместе с остальными частями приложения
• CUBA Web Components обеспечивают работу с CUBA REST API
• CUBA Studio умеет генерировать UI по модели данных
22
Варианты развертывания приложений
• Exploded WARs in Tomcat: используется во время разработки
• WAR files по числу используемых блоков приложения:
• app-core.war, app.war, app-portal.war
• Single WAR: middleware & web client в одном WAR
• app.war, каждый блок в своем специальном classloader
• UberJAR files по числу используемых блоков приложения:
• app-core.jar, app.jar, app-portal.jar
• Single UberJAR
• app.jar, каждый блок в своем специальном classloader
23
Масштабирование
24
Масштабирование (продолжение)
25
Обнаружение в кластере
Клиентский блок
connectionUrlList = node1, node2
Service Proxy
Блок среднего слоя
node1
JGroups , TCP stack
TCPPing
initial_hosts=node1,node2
Блок среднего слоя
node2
JGroups , TCP stack
TCPPing
initial_hosts= node1, node2
26
Обнаружение в кластере с аддоном cuba-zk
Клиентский блок
cubazk.connection = node3
Service Proxy
Блок среднего слоя
node1
JGroups, TCP stack
ZkPing
zkping.connection=node3
Блок среднего слоя
node2
JGroups, TCP stack
ZkPing
zkping.connection=node3
ZooKeeper
node3
read topology
reads topology
advertises itselfadvertises itself
27
Встроенная функциональность
• Контроль доступа к данным
• Пользователи
• Роли и разрешения на экраны UI, операции с сущностями (CRUD), атрибуты
сущностей (r/w, r/o, hidden), именованные разрешения
• Группы доступа: ограничения (row-level security), session attributes. Возможно
создание «локальных администраторов».
• Аудит: Журнал изменения сущностей, Снимки сущностей
• Инспектор сущностей
• Назначенные задания
• Профилировщик экранов
• Консоль JMX
28
Настройка роли
29
Ограничения (row-level security)
30
CUBA Studio
• Настройка инфраструктуры проекта
• Описание модели данных
• Генерация UI и шаблонного кода
• Визуальный редактор экранов
• Hot-deploy изменений в коде
• Настройки сборки и развертывания
• Написание кода в Java IDE
• Специфическая навигация, code
completion и подсказки в IntelliJ
IDEA
31
Hot deploy
Foo.java
App Server
conf directory
classpath
JavaClassLoader
Source code project
CUBA Studio
Foo.java
Foo.class
monitors for changes
is copied
checks first
loads if not found in conf
Хабрахабр: Динамическая компиляция Java-кода своими руками
https://habrahabr.ru/company/haulmont/blog/248981
32
Ограничения и известные проблемы
• Предопределенная архитектура
• Набор базовых библиотек (Spring, EclipseLink, Vaadin, etc.)
• Некоторые ограничения в маппинге JPA и расширениях JPQL от
EclipseLink. Criteria API не поддерживается.
• Интеграция сторонних UI компонентов относительно трудоемка
• Стандартный web UI (основанный на Vaadin) – stateful. Репликация
HTTP сессий не поддерживается.
33
Спасибо за внимание!
34

RAD на Java: как устроена CUBA Platform?

  • 1.
    RAD на Java:как устроена CUBA Platform? Константин Кривопустов технический директор Haulmont
  • 2.
    Что в составеплатформы CUBA Premium Add-ons Run time Eclipse Plugin IntelliJ IDEA Plugin Studio Design time 2
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
    Основные части APIплатформы Data model Metadata Services DataManager App Properties Data stores ORM UserSession VCL Datasources Generic UI Middleware 7
  • 8.
  • 9.
    Методы сущности • getId() •getMetaClass() • getInstanceName() • getValue(property) / setValue(property, value) • addPropertyChangeListener(listener) 9
  • 10.
  • 11.
    Application Properties Свойства приложения− именованные значения различных типов, определяющие конфигурацию и функционирование приложения. • Конфигурационные параметры - определяют функциональность приложения, обычно задаются при разработке приложения. • Параметры развертывания - различные URL для соединения блоков приложения, тип используемой БД и т.д. Зависят от окружения, в котором устанавливается данный экземпляр приложения. • Параметры времени выполнения - активность аудита, параметры отсылки email и т.д. Могут быть изменены при необходимости во время работы приложения. 11
  • 12.
    Конфигурационные параметры Пример параметра:springContextConfig – указывает набор конфигурационных файлов Spring-контейнера данного блока приложения cuba springContextConfig = cuba-spring.xml bpm springContextConfig = bpm-spring.xml app springContextConfig = +com/company/app/spring.xml Итоговое значение в приложении app: springContextConfig = cuba-spring.xml bpm-spring.xml com/company/app/spring.xml 12
  • 13.
    DataManager DataManager - универсальныйинтерфейс для загрузки графов сущностей из хранилищ, и для сохранения изменений • load() – загружает экземпляр сущности • loadList() – загружает список экземпляров • loadValues() – загружает список KeyValueEntity • getCount() – возвращает количество экземпляров • commit() – сохраняет переданные экземпляры и возвращает сохраненные 13
  • 14.
    UserSession & SecurityContext ОбъектUserSession ассоциирован с текущим пользователем и содержит информацию о его правах доступа • UserSession создается после логина, кэшируется на middleware и возвращается клиенту • Клиент с каждым обращением к middleware передает ID сессии • Поэтому клиент должен либо хранить ID сессии либо всегда выполнять логин • ID текущей сессии хранится в потоке выполнения и на клиенте и на middleware в объекте SecurityContext • При создании новых потоков в них нужно передавать SecurityContext • На middleware можно использовать «системную аутентификацию» 14
  • 15.
    Сервисы middleware Сервисы –точки входа в middleware для клиентов 15
  • 16.
    Data stores • Данныепредставляются сущностями, сущности принадлежат хранилищам • DataStore – интерфейс хранилищ, повторяющий DataManager • load(), loadList(), loadValues(), getCount(), commit() • DataManager делегирует запросы хранилищам и обеспечивает поддержание ссылок между сущностями • Стандартная реализация хранилища – RdbmsStore для работы с RDBMS через ORM. Поддерживает права доступа пользователя к данным и динамические атрибуты. • Приложение должно содержать основное хранилище, являющееся реляционной БД 16
  • 17.
    ORM • Использует EclipseLink •CUBA EntityManager в основном повторяет JPA EntityManager и добавляет поддержку: • soft deletion • views (представления) • Собственная реализация entity listeners • Before[Insert|Update|Delete] – принимают текущий EntityManager • After[Insert|Update|Delete] – принимают текущий JDBC Connection • BeforeDetachEntityListener – можно использовать для заполнения неперсистентных атрибутов перед отправкой клиенту • BeforeAttachEntityListener – можно использовать для заполнения персистентных атрибутов перед сохранением в БД • Criteria API не поддерживается 17
  • 18.
    ORM: почему неHibernate? Date Customer Service Driver Passengers 25/06/2017 17:10 Smith Regular Jones 2 25/06/2017 17:15 Williams 7-seater Taylor 5 select j.creationDate, [+50 fields], c.name, [+30 fields], s.caption, [+35 fields], d.name, [+ 45 fields] from Job j join Customer c on … join Service s on … join Driver d on … Итого загружено: >150 колонок вместо 12 для каждой строки 18
  • 19.
    EclipseLink FetchGroups +CUBA Views • Задание FetchGroup в EclipseLink позволяет загружать «частичные» объекты • CUBA Views: надстройка для удобного управления FetchGroups • View обязательно передается вместе с запросом в DataManager и опционально в EntityManager Query 19
  • 20.
  • 21.
  • 22.
    Polymer UI • WebComponents в чистом виде • Google Polymer • Vaadin Elements • Любые другие • Сборка на Gradle вместе с остальными частями приложения • CUBA Web Components обеспечивают работу с CUBA REST API • CUBA Studio умеет генерировать UI по модели данных 22
  • 23.
    Варианты развертывания приложений •Exploded WARs in Tomcat: используется во время разработки • WAR files по числу используемых блоков приложения: • app-core.war, app.war, app-portal.war • Single WAR: middleware & web client в одном WAR • app.war, каждый блок в своем специальном classloader • UberJAR files по числу используемых блоков приложения: • app-core.jar, app.jar, app-portal.jar • Single UberJAR • app.jar, каждый блок в своем специальном classloader 23
  • 24.
  • 25.
  • 26.
    Обнаружение в кластере Клиентскийблок connectionUrlList = node1, node2 Service Proxy Блок среднего слоя node1 JGroups , TCP stack TCPPing initial_hosts=node1,node2 Блок среднего слоя node2 JGroups , TCP stack TCPPing initial_hosts= node1, node2 26
  • 27.
    Обнаружение в кластерес аддоном cuba-zk Клиентский блок cubazk.connection = node3 Service Proxy Блок среднего слоя node1 JGroups, TCP stack ZkPing zkping.connection=node3 Блок среднего слоя node2 JGroups, TCP stack ZkPing zkping.connection=node3 ZooKeeper node3 read topology reads topology advertises itselfadvertises itself 27
  • 28.
    Встроенная функциональность • Контрольдоступа к данным • Пользователи • Роли и разрешения на экраны UI, операции с сущностями (CRUD), атрибуты сущностей (r/w, r/o, hidden), именованные разрешения • Группы доступа: ограничения (row-level security), session attributes. Возможно создание «локальных администраторов». • Аудит: Журнал изменения сущностей, Снимки сущностей • Инспектор сущностей • Назначенные задания • Профилировщик экранов • Консоль JMX 28
  • 29.
  • 30.
  • 31.
    CUBA Studio • Настройкаинфраструктуры проекта • Описание модели данных • Генерация UI и шаблонного кода • Визуальный редактор экранов • Hot-deploy изменений в коде • Настройки сборки и развертывания • Написание кода в Java IDE • Специфическая навигация, code completion и подсказки в IntelliJ IDEA 31
  • 32.
    Hot deploy Foo.java App Server confdirectory classpath JavaClassLoader Source code project CUBA Studio Foo.java Foo.class monitors for changes is copied checks first loads if not found in conf Хабрахабр: Динамическая компиляция Java-кода своими руками https://habrahabr.ru/company/haulmont/blog/248981 32
  • 33.
    Ограничения и известныепроблемы • Предопределенная архитектура • Набор базовых библиотек (Spring, EclipseLink, Vaadin, etc.) • Некоторые ограничения в маппинге JPA и расширениях JPQL от EclipseLink. Criteria API не поддерживается. • Интеграция сторонних UI компонентов относительно трудоемка • Стандартный web UI (основанный на Vaadin) – stateful. Репликация HTTP сессий не поддерживается. 33
  • 34.

Editor's Notes

  • #9 Все есть сущности. DTO нет. Сущности бывают персистентные (хранящиеся в РСУБД через ORM) и неперсистентные. Неперсистентные сущности могут быть как in-memory only, так и хранимые в каком-то внешнем источнике. Все сущности имеют ID с момента создания в памяти. Это важно для передачи между уровнями, когда есть сериализация. Есть генераторы числовых ключей, в случае IDENTITY-ключей исполльзуется IdProxy.
  • #10 Все generic-механизмы работают с сущностями через getValue/setValue PropertyChangeListener срабатывает и в случае вызовов сеттеров. Это достигается путем специальной модификации байт-кода сущностей в дополнение к той которую проводит ORM.
  • #11 Источник метаданных – классы и аннотации модели данных. MetaClass.getJavaClass – только Java классы, MetaProperty.getAnnotatedElement – и поля и методы getAnnotations возвращает мэп произвольных пар имя-значение – способ хранить второстепенную информацию о метаданных. Кроме того, позволяет переопределять Java-аннотации.
  • #15 - Текущая пользовательская сессия, всегда доступна при обработке запроса от пользователя. - Кроме прав доступа, содержит также мэп атрибутов – аналог атрибутов HTTP сессии. - Web клиент хранит UserSession в HTTP сессии, Desktop client – понятно что просто в своем объекте, REST – в хранилище, отображающем выданные токены на сессии. - Системная аутентификация позволяет выдать UserSession потоку, выполняющему не запрос от пользователя, а например назначенное задание или JMX-запрос.
  • #16 Клиент может обратиться к среднему слою (и в итоге к БД) только вызвав метод некоторого сервиса. Ну и можно еще написать Spring MVC Controller на среднем слое. Это используется в платформе для передачи файлов, чтобы не загружать их целиком в память, а передавать между потоками ввода-вывода. Структура сервиса, что в каком модуле и слое.
  • #21 - Структура стандартного UI платформы (располагается в модулях gui, web, desktop)
  • #22 REST API доступен в блоках web & portal Можно добавлять свои endpoints путем создания контроллеров Spring MVC в своем проекте
  • #23 Здесь мы ничего не оборачиваем в свой API, все сторонние компоненты используются напрямую.
  • #27 - В Jgroups по умолчанию используется UDP протокол, но мы нигде не используем его в продакшн
  • #34 - QueryDSL