СИСТЕМА ОБРАБОТКИ БИЗНЕС-ЛОГИКИ SERVER-SIDE ПРИЛОЖЕНИЯ НА GROOVY Александр Шлянников Digital Zone.

Презентация:



Advertisements
Похожие презентации
Рассматриваемые темы Технология EJB Типы EJB Вызов EJB Сборка и развертывание EJB- приложения 2-1.
Advertisements

Платформа J2EE Сервис: Java Naming Directory (JNDI) – универсальный сервис хранения объектов в иерархической структуре имен (аналогично файловой системе)
Платформа J2EE Сервис: Java Naming Directory (JNDI) – универсальный сервис хранения объектов в иерархической структуре имен (аналогично файловой системе)
EJB Local Interface Кряжев Василий
Исключения в EJB Кряжев Василий
ENTERPRISE JAVABEANS 3.0 STATEFUL & STATLESS SESSION BEANS.
Interceptors Василий Кряжев
Язык JavaScript Скриптовый язык для выполнения на html-страницах.
Hibernate cashe. Part 4 Для студентов старших курсов университетов Ст.преподаватель Дудник О.А.
Рассматриваемые темы EJB Timer сервис Создание таймера Отмена и сохранение таймера Получение информации о таймере Транзакции и таймеры 11-1.
Saint Petersburg, 2011 Java Lecture #06 Exceptions.
©Павловская Т.А. (СПбГУ ИТМО) Курс «С#. Программирование на языке высокого уровня» Павловская Т.А.
Эффективная разработка отчётов на платформе.NET Александр Федяшов Fast Reports Inc.
1 Введение Информационные системы Альтернативы задачи доступа к данным Стандарт JPA и коммерческие ORM имплементации Определение ORM Проблемы полного преобразования.
Автоматическая генерация схемы реляционной базы данных на основе объектной схемы данных Богданов Алексей.
Java: современные технологии разработки ПО Вашенков О.Е. ООО «РСС», разработчик ПО.
Наследование Наследование – это отношение является между классами. class Person { string first_name; int birth_year;... } class Student : Person { float.
АССОЦИАТИВНЫЕ КОЛЛЕКЦИИ Лекция 6 1. Отличие от последовательных 2 В последовательной коллекции каждый элемент ассоциируется с номером, начиная с 0. В.
Учебный курс Объектно-ориентированный анализ и программирование Лекция 7 Методы как средство реализации операций Лекции читает кандидат технических наук.
Session beans Василий Кряжев
Транксрипт:

СИСТЕМА ОБРАБОТКИ БИЗНЕС-ЛОГИКИ SERVER-SIDE ПРИЛОЖЕНИЯ НА GROOVY Александр Шлянников Digital Zone

Задача Возможность изменять бизнес-логику server-side Java EE приложения «на лету»: С минимальными обращениями к разработчикам системы Без перекомпиляции Без shutdown/redeploy системы на сервере С защитой от синтаксических и семантических ошибок

Применение Биллинговые системы: Операторы связи Такси Генерация разнообразных отчетов Пример: «Клиенту, сделавшему 3 заказа в прошлом месяце и с днем рождения на этой неделе, сделать скидку в 10% после 15-й минуты поездки»

Типичные решения Фиксированные параметры и настройки логики – недостаточно гибко Скриптинг: JavaScript (Mozilla Rhino, Groovy (

Groovy Dynamic language for the Java Virtual Machine: Динамическая типизация Удобный и краткий синтаксис работы с коллекциями, картами, массивами, строками Возможность runtime-компиляции в JVM байт-код и работы с другим Java кодом и библиотеками

Архитектура Java EE – JBoss Application Server ORM – EJB JPA Persistence (Stateless & Entity Beans) Service MBeans HTTP/SOAP Client Connectors

Сервис команд Service MBean: Invoker: Object invoke(String mapping, Object[] args) Commands: Object invoke(Object[] args)

Оформление команд Команда: Groovy Script (класс) Runtime компиляция в JVM байт-код, создание объектов и хранение в памяти: GroovyClassLoader loader = new GroovyClassLoader(); Class groovyClass = loader.parseClass(content); GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance(); Файлы исходников команд расположены вне EAR/WAR/SAR-архивов Мониторинг изменений директории исходников через JBoss Deployer для runtime отслеживания изменений

Класс команды Аннотация на класс – mapping Имплементация Java интерфейса: public interface GenericScript { void init(Object... args); Object invoke(Object... args); void onInterrupt(Object... args); } Хранение скомпилированных объектов в сервисе в виде ассоциативного массива [Mapping -> Object] Выполнение прямым вызовом метода invoke без использования Reflections: GenericScript s = scripts.get(mapping); s.invoke(args);

Базовый контекст выполнения скрипта Новое выполнение – новый объект (аналогично HttpServletRequest ) Утилитные методы: Object getAttribute(String key); void setAttribute(String key, Object value); Object invoke(String mapping, Object[] args); void log(String message);

Типы команд Разделение контекстов выполнения команд: Calculation (базовый): без доступа к Persistence Read-only: с доступом к Persistence на чтение Read/Write: с доступом к Persistence на чтение/обновление

Организация доступа к данным EJB JPA Persistence: Все сущности предметной области Утилитный Stateless Bean: public interface BaseDAO { List getAll(Class c); List getEntitiesByKey(Class c, String key, Object value); T getEntityById(Class c, Object id); T createEntity(T entity); void mergeEntity(Object entity); void removeEntity(Class c, Object id); } Методы Stateless Bean доступны через контекст скрипта

Организация доступа к данным Имплементация Stateless Bean, примеры: T createEntity(T entity) { entityManager.persist(entity); return entity; } List getAll(Class c) { Query query = entityManager.createQuery("select c from " + c.getName() + " c"); return query.getResultList(); }

Управление транзакцией Работа с транзакцией в Stateless = = TransactionManagementType.BEAN) При использовании CMT – аннотации … sessionContext.setRollbackOnly();// откат В обоих случаях, нельзя: myStatelessBean.startTransaction(); doSomething(); myStatelessBean.commitTransaction();

Управление транзакцией Решение: Специальные методы-обертки в Stateless Bean: //для Read/Write public Object wrapTransactionRequired(ScriptWrapper sw) //для Read-Only public Object wrapTransactionSupports(ScriptWrapper sw) Вызов метода invoke скрипта-команды и связывание с Stateless Bean – внутри методов wrapTransactionRequired и wrapTransactionSupports

Многопоточное исполнение Исполнение в очереди - ExecutorService: singleThreadExecutor: один поток, контроль времени выполнения multiThreadExecutor: несколько потоков, контроль времени выполнения debugThreadExecutor: несколько потоков, без контроля времени выполнения Определение типа команды и таймаута выполнения в аннотации к ScriptMapping { //… long runTimeout() default -1; ScriptThreadingType type() default ScriptThreadingType.MULTI; }

Контроль времени выполнения Два вложенных Callable на выполнение команды: 1) Внутренний: запуск скрипта 2) Внешний: контроль времени выполнения через FutureTask.get(timeout) Внутренний ExecutorService на N+1 поток

Контроль времени выполнения 1) TimeoutException в FutureTask.get(timeout) 2) Вызов метода onInterrupt() у скрипта команды для предупреждения о завершении 3) sleep(timeout) 4) stop() у потока 5) Запись в журнал ошибок

Асинхронный режим Вызывающий клиент имплементирует Callback для взаимодействия с командой во время выполнения, а получает Future:

Контроль ошибок 1) Проверка синтаксиса при компиляции: GroovyClassLoader loader = new GroovyClassLoader(); Class groovyClass = loader.parseClass(content); - throws CompilationFailedException при синтаксическиой ошибке 2) Проверка времени исполнения по таймауту 3) При таймауте скрипта больше K раз – исключение из Invoker

Отладка Поддержка синтаксиса Groovy в IDE Удаленная отладка (JPDA) из IDE Выполнение в отдельном потоке без контроля таймаута

Интерфейс администрирования Create, Read, Update, Delete команд Версионность для отката изменений Мониторинг: Количество команд в очереди Exceptions Отключенные команды

= "/SetOrderToBoard", runTimeout = 10000L) class SetOrderToBoard extends ReadWriteScript { def invoke(context, orderUuid, boardUuid) { def success = false; def order = context.findByKey("Order", "uuid", orderUuid); def boards = context.findAll("Board"); for (board in boards) { if (board.status == "free") { board.currentOrder = order; order.board = board; if (new Date().getTime() - order.creationTime > 10*60* 1000) { order.discount += 10; } context.update(board); context.update(order); success = true; break; } return success; }

Другие платформы Эквивалентное выполнение скриптов:.NET - перенос в контекст отличающихся по синтаксису методов: sqrt, pow, round, equal, etc

Выводы Разработанный сервис: Глубокая настройка бизнес-логики приложения Понятный юзерам язык и API Работа с сущностями предметной области системы Защита от ошибок Возможность расширения на другие платформы

Спасибо за внимание!