ݺߣ

ݺߣShare a Scribd company logo
СИСТЕМА ОБРАБОТКИ
    БИЗНЕС-ЛОГИКИ
SERVER-SIDE ПРИЛОЖЕНИЯ
      НА GROOVY
        Александр Шлянников
                  Digital Zone
Задача
• Возможность изменять бизнес-логику server-side Java
 EE приложения «на лету»:
 • С минимальными обращениями к разработчикам системы
 • Без перекомпиляции
 • Без shutdown/redeploy системы на сервере
 • С защитой от синтаксических и семантических ошибок
Применение
• Биллинговые системы:
  • Операторы связи
  • Такси
• Генерация разнообразных отчетов


• Пример:
  • «Клиенту, сделавшему 3 заказа в прошлом месяце и с днем
    рождения на этой неделе, сделать скидку в 10% после 15-й
    минуты поездки»
Типичные решения
• Фиксированные параметры и настройки логики –
  недостаточно гибко
• Скриптинг:
 • JavaScript (Mozilla Rhino, http://www.mozilla.org/rhino/)
 • Groovy (http://groovy.codehaus.org/)
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 команды:
 • @ScriptMapping("/createOrder")

• Имплементация 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:
  • Все сущности предметной области – @Entity
  • Утилитный Stateless Bean:
    • public interface BaseDAO {
       • <T> List<T> getAll(Class<T> c);
       • <T> List<T> getEntitiesByKey(Class<T> c, String key, Object
         value);
       • <T> T getEntityById(Class<T> c, Object id);
       • <T> T createEntity(T entity);
       • void mergeEntity(Object entity);
       • void removeEntity(Class c, Object id);
    • }

  • Методы Stateless Bean доступны через контекст скрипта
Организация доступа к данным
• Имплементация Stateless Bean, примеры:

 • <T> T createEntity(T entity) {
   • entityManager.persist(entity);
   • return entity;
 • }


 • <T> List<T> getAll(Class<T> c) {
   • Query query = entityManager.createQuery("select c from " +
      c.getName() + " c");
    • return query.getResultList();
 • }
Управление транзакцией
• Работа с транзакцией в Stateless Bean:
 • @TransactionManagement(value =
   TransactionManagementType.CONTAINER)
 • @TransactionManagement(value = TransactionManagementType.BEAN)

• При использовании CMT – аннотации на методах:
 • @TransactionAttribute(TransactionAttributeType.REQUIRED)
 • @TransactionAttribute(TransactionAttributeType.SUPPORTS)
 • …
 • sessionContext.setRollbackOnly();// откат

• В обоих случаях, нельзя:
 • myStatelessBean.startTransaction();
 • doSomething();
 • myStatelessBean.commitTransaction();
Управление транзакцией
• Решение:
  • Специальные методы-обертки в Stateless Bean:
    • //для Read/Write контекста
    • @TransactionAttribute(TransactionAttributeType.REQUIRED)
    • public Object wrapTransactionRequired(ScriptWrapper sw)


    • //для Read-Only контекста
    • @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    • public Object wrapTransactionSupports(ScriptWrapper sw)

  • Вызов метода invoke скрипта-команды и связывание с Stateless
   Bean – внутри методов wrapTransactionRequired и
   wrapTransactionSupports
Многопоточное исполнение
• Исполнение в очереди - ExecutorService:
  • singleThreadExecutor: один поток, контроль времени
    выполнения
  • multiThreadExecutor: несколько потоков, контроль времени
    выполнения
  • debugThreadExecutor: несколько потоков, без контроля
    времени выполнения
• Определение типа команды и таймаута выполнения в
 аннотации к классу скрипта:
  • @Target(ElementType.TYPE)
  • @Retention(RetentionPolicy.RUNTIME)
  • public @interface 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
  • Отключенные команды
Пример
• @ScriptMapping(value = "/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
  • Работа с сущностями предметной области системы
  • Защита от ошибок
  • Возможность расширения на другие платформы
Спасибо за внимание!

More Related Content

What's hot (20)

Инструментация среды исполнения в арсенале тестировщика
Инструментация среды исполнения в арсенале тестировщикаИнструментация среды исполнения в арсенале тестировщика
Инструментация среды исполнения в арсенале тестировщика
SQALab
Автоматизация тестирования многопоточности
Автоматизация тестирования многопоточностиАвтоматизация тестирования многопоточности
Автоматизация тестирования многопоточности
SQALab
Java Core. Lecture# 5. Concurrency.
Java Core. Lecture# 5. Concurrency.Java Core. Lecture# 5. Concurrency.
Java Core. Lecture# 5. Concurrency.
Anton Moiseenko
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.
Igor Shkulipa
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Ontico
Основы и нюансы параллельного тестрования
Основы и нюансы параллельного тестрованияОсновы и нюансы параллельного тестрования
Основы и нюансы параллельного тестрования
bearoff
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Andrey Rebrov
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с MavenКурс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
7bits
C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.
Igor Shkulipa
Опыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервисаОпыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервиса
Ilya Chesnokov
Testing with Selenium
Testing with SeleniumTesting with Selenium
Testing with Selenium
OSLL
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
Омские ИТ-субботники
Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.
Anton Moiseenko
Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.
Anton Moiseenko
C++ STL & Qt. Занятие 03.
C++ STL & Qt. Занятие 03.C++ STL & Qt. Занятие 03.
C++ STL & Qt. Занятие 03.
Igor Shkulipa
Курс Java-2016. Занятие 06. Файлы и ввод-вывод
Курс Java-2016. Занятие 06. Файлы и ввод-выводКурс Java-2016. Занятие 06. Файлы и ввод-вывод
Курс Java-2016. Занятие 06. Файлы и ввод-вывод
7bits
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
Sergey Zubkov
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.
Igor Shkulipa
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
Nikolay Samokhvalov
#noBackend, или Как выжить в эпоху толстеющих клиентов
#noBackend, или Как выжить в эпоху толстеющих клиентов#noBackend, или Как выжить в эпоху толстеющих клиентов
#noBackend, или Как выжить в эпоху толстеющих клиентов
Nikolay Samokhvalov
Инструментация среды исполнения в арсенале тестировщика
Инструментация среды исполнения в арсенале тестировщикаИнструментация среды исполнения в арсенале тестировщика
Инструментация среды исполнения в арсенале тестировщика
SQALab
Автоматизация тестирования многопоточности
Автоматизация тестирования многопоточностиАвтоматизация тестирования многопоточности
Автоматизация тестирования многопоточности
SQALab
Java Core. Lecture# 5. Concurrency.
Java Core. Lecture# 5. Concurrency.Java Core. Lecture# 5. Concurrency.
Java Core. Lecture# 5. Concurrency.
Anton Moiseenko
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.
Igor Shkulipa
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Ontico
Основы и нюансы параллельного тестрования
Основы и нюансы параллельного тестрованияОсновы и нюансы параллельного тестрования
Основы и нюансы параллельного тестрования
bearoff
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Andrey Rebrov
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с MavenКурс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
Курс Java-2016. Занятие 02. Пакеты, сборка проекта с Maven
7bits
C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.C++ STL & Qt. Занятие 09.
C++ STL & Qt. Занятие 09.
Igor Shkulipa
Опыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервисаОпыт разработки и тестирования RESTful JSON сервиса
Опыт разработки и тестирования RESTful JSON сервиса
Ilya Chesnokov
Testing with Selenium
Testing with SeleniumTesting with Selenium
Testing with Selenium
OSLL
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
Омские ИТ-субботники
Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.Java Core. Lecture# 3. Part# 2. Exceptions.
Java Core. Lecture# 3. Part# 2. Exceptions.
Anton Moiseenko
Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.Java Core. Lecture# 3. Part# 3. Multithreading.
Java Core. Lecture# 3. Part# 3. Multithreading.
Anton Moiseenko
C++ STL & Qt. Занятие 03.
C++ STL & Qt. Занятие 03.C++ STL & Qt. Занятие 03.
C++ STL & Qt. Занятие 03.
Igor Shkulipa
Курс Java-2016. Занятие 06. Файлы и ввод-вывод
Курс Java-2016. Занятие 06. Файлы и ввод-выводКурс Java-2016. Занятие 06. Файлы и ввод-вывод
Курс Java-2016. Занятие 06. Файлы и ввод-вывод
7bits
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.
Igor Shkulipa
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6
Nikolay Samokhvalov
#noBackend, или Как выжить в эпоху толстеющих клиентов
#noBackend, или Как выжить в эпоху толстеющих клиентов#noBackend, или Как выжить в эпоху толстеющих клиентов
#noBackend, или Как выжить в эпоху толстеющих клиентов
Nikolay Samokhvalov

Viewers also liked (20)

Grails & Groovy
Grails & GroovyGrails & Groovy
Grails & Groovy
Denys Sosuliev
Быть в 10 раз эффективнее благодаря Groovy
Быть в 10 раз эффективнее благодаря GroovyБыть в 10 раз эффективнее благодаря Groovy
Быть в 10 раз эффективнее благодаря Groovy
Evgeny Kompaniyets
Grails report, JEEConf 2012
Grails report, JEEConf 2012Grails report, JEEConf 2012
Grails report, JEEConf 2012
Sergiy Korzh
Unlocking funding opportunities final
Unlocking funding opportunities finalUnlocking funding opportunities final
Unlocking funding opportunities final
saqib_bsettlement
Sp soft profile (15-may-2012)
Sp soft profile (15-may-2012)Sp soft profile (15-may-2012)
Sp soft profile (15-may-2012)
SP SOFTWARE
แบบโครงร่างโครงงานคอมพิว๶ตอร์
แบบโครงร่างโครงงานคอมพิว๶ตอร์แบบโครงร่างโครงงานคอมพิว๶ตอร์
แบบโครงร่างโครงงานคอมพิว๶ตอร์
Lynnie1177
Office 2010 migration
Office 2010 migrationOffice 2010 migration
Office 2010 migration
david_malmborg
Hindavi Technologies Profile
Hindavi Technologies ProfileHindavi Technologies Profile
Hindavi Technologies Profile
onebhushan
Matlab workshop
Matlab workshopMatlab workshop
Matlab workshop
محمدعبد الحى
แบบโครงร่างโครงงานคอมพิว๶ตอร์
แบบโครงร่างโครงงานคอมพิว๶ตอร์แบบโครงร่างโครงงานคอมพิว๶ตอร์
แบบโครงร่างโครงงานคอมพิว๶ตอร์
Lynnie1177
Montras com livrosMontras com livros
Montras com livros
bibliotecaoureana
Regulamento concursoleituraconcelho ourem_aecoRegulamento concursoleituraconcelho ourem_aeco
Regulamento concursoleituraconcelho ourem_aeco
bibliotecaoureana
ประวัติส่วȨัว
ประวัติส่วȨัวประวัติส่วȨัว
ประวัติส่วȨัว
Lynnie1177
Project Report
Project ReportProject Report
Project Report
harshit1991
Kbox 101 1000 slide
Kbox 101 1000 slideKbox 101 1000 slide
Kbox 101 1000 slide
david_malmborg
Быть в 10 раз эффективнее благодаря Groovy
Быть в 10 раз эффективнее благодаря GroovyБыть в 10 раз эффективнее благодаря Groovy
Быть в 10 раз эффективнее благодаря Groovy
Evgeny Kompaniyets
Grails report, JEEConf 2012
Grails report, JEEConf 2012Grails report, JEEConf 2012
Grails report, JEEConf 2012
Sergiy Korzh
Unlocking funding opportunities final
Unlocking funding opportunities finalUnlocking funding opportunities final
Unlocking funding opportunities final
saqib_bsettlement
Sp soft profile (15-may-2012)
Sp soft profile (15-may-2012)Sp soft profile (15-may-2012)
Sp soft profile (15-may-2012)
SP SOFTWARE
แบบโครงร่างโครงงานคอมพิว๶ตอร์
แบบโครงร่างโครงงานคอมพิว๶ตอร์แบบโครงร่างโครงงานคอมพิว๶ตอร์
แบบโครงร่างโครงงานคอมพิว๶ตอร์
Lynnie1177
Hindavi Technologies Profile
Hindavi Technologies ProfileHindavi Technologies Profile
Hindavi Technologies Profile
onebhushan
แบบโครงร่างโครงงานคอมพิว๶ตอร์
แบบโครงร่างโครงงานคอมพิว๶ตอร์แบบโครงร่างโครงงานคอมพิว๶ตอร์
แบบโครงร่างโครงงานคอมพิว๶ตอร์
Lynnie1177
Montras com livrosMontras com livros
Montras com livros
bibliotecaoureana
Regulamento concursoleituraconcelho ourem_aecoRegulamento concursoleituraconcelho ourem_aeco
Regulamento concursoleituraconcelho ourem_aeco
bibliotecaoureana
ประวัติส่วȨัว
ประวัติส่วȨัวประวัติส่วȨัว
ประวัติส่วȨัว
Lynnie1177

Similar to Система обработки бизнес-логики server-side приложения на Groovy (20)

Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Yandex
Cache2012 administrationbasics
Cache2012 administrationbasicsCache2012 administrationbasics
Cache2012 administrationbasics
Denis Pavlov
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
Timur Shemsedinov
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
Badoo Development
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1
m2rus
RESTful API: Best practices, versioning, design documentation
RESTful API: Best practices, versioning, design documentationRESTful API: Best practices, versioning, design documentation
RESTful API: Best practices, versioning, design documentation
Mikhail Shcherbakov
Использование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестированияИспользование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестирования
SQALab
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Ontico
PostgreSQL performance recipes
PostgreSQL performance recipesPostgreSQL performance recipes
PostgreSQL performance recipes
Alexey Ermakov
Java 9: what is there beyond modularization
Java 9: what is there beyond modularizationJava 9: what is there beyond modularization
Java 9: what is there beyond modularization
Ivan Krylov
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
drupalconf
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
PVasili
PowerShell
PowerShellPowerShell
PowerShell
GetDev.NET
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)
Alexander Gornik
Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?
buranLcme
М. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с CodeceptionМ. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с Codeception
Albina Tiupa
Владимир Кочетков "OWASP TOP 10 для.NET"
Владимир Кочетков  "OWASP TOP 10 для.NET"Владимир Кочетков  "OWASP TOP 10 для.NET"
Владимир Кочетков "OWASP TOP 10 для.NET"
MskDotNet Community
What's new in Visual Studio 2012
What's new in Visual Studio 2012What's new in Visual Studio 2012
What's new in Visual Studio 2012
InTRUEdeR
Building deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayBuilding deployment pipeline - DevOps way
Building deployment pipeline - DevOps way
Andrey Rebrov
Михаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с CodeceptionМихаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с Codeception
Albina Tiupa
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Yandex
Cache2012 administrationbasics
Cache2012 administrationbasicsCache2012 administrationbasics
Cache2012 administrationbasics
Denis Pavlov
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
Timur Shemsedinov
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
Badoo Development
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1
m2rus
RESTful API: Best practices, versioning, design documentation
RESTful API: Best practices, versioning, design documentationRESTful API: Best practices, versioning, design documentation
RESTful API: Best practices, versioning, design documentation
Mikhail Shcherbakov
Использование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестированияИспользование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестирования
SQALab
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Ontico
PostgreSQL performance recipes
PostgreSQL performance recipesPostgreSQL performance recipes
PostgreSQL performance recipes
Alexey Ermakov
Java 9: what is there beyond modularization
Java 9: what is there beyond modularizationJava 9: what is there beyond modularization
Java 9: what is there beyond modularization
Ivan Krylov
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
drupalconf
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
PVasili
разработка бизнес приложений (8)
разработка бизнес приложений (8)разработка бизнес приложений (8)
разработка бизнес приложений (8)
Alexander Gornik
Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?
buranLcme
М. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с CodeceptionМ. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с Codeception
Albina Tiupa
Владимир Кочетков "OWASP TOP 10 для.NET"
Владимир Кочетков  "OWASP TOP 10 для.NET"Владимир Кочетков  "OWASP TOP 10 для.NET"
Владимир Кочетков "OWASP TOP 10 для.NET"
MskDotNet Community
What's new in Visual Studio 2012
What's new in Visual Studio 2012What's new in Visual Studio 2012
What's new in Visual Studio 2012
InTRUEdeR
Building deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayBuilding deployment pipeline - DevOps way
Building deployment pipeline - DevOps way
Andrey Rebrov
Михаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с CodeceptionМихаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с Codeception
Albina Tiupa

Система обработки бизнес-логики server-side приложения на Groovy

  • 1. СИСТЕМА ОБРАБОТКИ БИЗНЕС-ЛОГИКИ SERVER-SIDE ПРИЛОЖЕНИЯ НА GROOVY Александр Шлянников Digital Zone
  • 2. Задача • Возможность изменять бизнес-логику server-side Java EE приложения «на лету»: • С минимальными обращениями к разработчикам системы • Без перекомпиляции • Без shutdown/redeploy системы на сервере • С защитой от синтаксических и семантических ошибок
  • 3. Применение • Биллинговые системы: • Операторы связи • Такси • Генерация разнообразных отчетов • Пример: • «Клиенту, сделавшему 3 заказа в прошлом месяце и с днем рождения на этой неделе, сделать скидку в 10% после 15-й минуты поездки»
  • 4. Типичные решения • Фиксированные параметры и настройки логики – недостаточно гибко • Скриптинг: • JavaScript (Mozilla Rhino, http://www.mozilla.org/rhino/) • Groovy (http://groovy.codehaus.org/)
  • 5. Groovy • Dynamic language for the Java Virtual Machine: • Динамическая типизация • Удобный и краткий синтаксис работы с коллекциями, картами, массивами, строками • Возможность runtime-компиляции в JVM байт-код и работы с другим Java кодом и библиотеками
  • 6. Архитектура • Java EE – JBoss Application Server • ORM – EJB JPA Persistence (Stateless & Entity Beans) • Service MBeans • HTTP/SOAP Client Connectors
  • 7. Сервис команд • Service MBean: • Invoker: • Object invoke(String mapping, Object[] args) • Commands: • Object invoke(Object[] args)
  • 8. Оформление команд • Команда: Groovy Script (класс) • Runtime компиляция в JVM байт-код, создание объектов и хранение в памяти: • GroovyClassLoader loader = new GroovyClassLoader(); • Class groovyClass = loader.parseClass(content); • GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance(); • Файлы исходников команд расположены вне EAR/WAR/SAR-архивов • Мониторинг изменений директории исходников через JBoss Deployer для runtime отслеживания изменений
  • 9. Класс команды • Аннотация на класс – mapping команды: • @ScriptMapping("/createOrder") • Имплементация 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);
  • 10. Базовый контекст выполнения скрипта • Новое выполнение – новый объект (аналогично HttpServletRequest) • Утилитные методы: • Object getAttribute(String key); • void setAttribute(String key, Object value); • Object invoke(String mapping, Object[] args); • void log(String message);
  • 11. Типы команд • Разделение контекстов выполнения команд: • Calculation (базовый): без доступа к Persistence • Read-only: с доступом к Persistence на чтение • Read/Write: с доступом к Persistence на чтение/обновление
  • 12. Организация доступа к данным • EJB JPA Persistence: • Все сущности предметной области – @Entity • Утилитный Stateless Bean: • public interface BaseDAO { • <T> List<T> getAll(Class<T> c); • <T> List<T> getEntitiesByKey(Class<T> c, String key, Object value); • <T> T getEntityById(Class<T> c, Object id); • <T> T createEntity(T entity); • void mergeEntity(Object entity); • void removeEntity(Class c, Object id); • } • Методы Stateless Bean доступны через контекст скрипта
  • 13. Организация доступа к данным • Имплементация Stateless Bean, примеры: • <T> T createEntity(T entity) { • entityManager.persist(entity); • return entity; • } • <T> List<T> getAll(Class<T> c) { • Query query = entityManager.createQuery("select c from " + c.getName() + " c"); • return query.getResultList(); • }
  • 14. Управление транзакцией • Работа с транзакцией в Stateless Bean: • @TransactionManagement(value = TransactionManagementType.CONTAINER) • @TransactionManagement(value = TransactionManagementType.BEAN) • При использовании CMT – аннотации на методах: • @TransactionAttribute(TransactionAttributeType.REQUIRED) • @TransactionAttribute(TransactionAttributeType.SUPPORTS) • … • sessionContext.setRollbackOnly();// откат • В обоих случаях, нельзя: • myStatelessBean.startTransaction(); • doSomething(); • myStatelessBean.commitTransaction();
  • 15. Управление транзакцией • Решение: • Специальные методы-обертки в Stateless Bean: • //для Read/Write контекста • @TransactionAttribute(TransactionAttributeType.REQUIRED) • public Object wrapTransactionRequired(ScriptWrapper sw) • //для Read-Only контекста • @TransactionAttribute(TransactionAttributeType.SUPPORTS) • public Object wrapTransactionSupports(ScriptWrapper sw) • Вызов метода invoke скрипта-команды и связывание с Stateless Bean – внутри методов wrapTransactionRequired и wrapTransactionSupports
  • 16. Многопоточное исполнение • Исполнение в очереди - ExecutorService: • singleThreadExecutor: один поток, контроль времени выполнения • multiThreadExecutor: несколько потоков, контроль времени выполнения • debugThreadExecutor: несколько потоков, без контроля времени выполнения • Определение типа команды и таймаута выполнения в аннотации к классу скрипта: • @Target(ElementType.TYPE) • @Retention(RetentionPolicy.RUNTIME) • public @interface ScriptMapping { • //… • long runTimeout() default -1; • ScriptThreadingType type() default ScriptThreadingType.MULTI; • }
  • 17. Контроль времени выполнения • Два вложенных Callable на выполнение команды: • 1) Внутренний: запуск скрипта • 2) Внешний: контроль времени выполнения через FutureTask.get(timeout) • Внутренний ExecutorService на N+1 поток
  • 18. Контроль времени выполнения • 1) TimeoutException в FutureTask.get(timeout) • 2) Вызов метода onInterrupt() у скрипта команды для предупреждения о завершении • 3) sleep(timeout) • 4) stop() у потока • 5) Запись в журнал ошибок
  • 19. Асинхронный режим • Вызывающий клиент имплементирует Callback для взаимодействия с командой во время выполнения, а получает Future:
  • 20. Контроль ошибок • 1) Проверка синтаксиса при компиляции: • GroovyClassLoader loader = new GroovyClassLoader(); • Class groovyClass = loader.parseClass(content); • - throws CompilationFailedException при синтаксическиой ошибке • 2) Проверка времени исполнения по таймауту • 3) При таймауте скрипта больше K раз – исключение из Invoker
  • 21. Отладка • Поддержка синтаксиса Groovy в IDE • Удаленная отладка (JPDA) из IDE • Выполнение в отдельном потоке без контроля таймаута
  • 22. Интерфейс администрирования • Create, Read, Update, Delete команд • Версионность для отката изменений • Мониторинг: • Количество команд в очереди • Exceptions • Отключенные команды
  • 23. Пример • @ScriptMapping(value = "/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; • } • }
  • 24. Другие платформы • Эквивалентное выполнение скриптов: • .NET - перенос в контекст отличающихся по синтаксису методов: • sqrt, pow, round, equal, etc
  • 25. Выводы • Разработанный сервис: • Глубокая настройка бизнес-логики приложения • Понятный юзерам язык и API • Работа с сущностями предметной области системы • Защита от ошибок • Возможность расширения на другие платформы