Пример конфигурации: использование узлов типа mail-node

Автор: Виталий Шакуров
Компания: Janet systems

В приведенном примере мы создадим:

  1. Описание бизнес-процесса в формате jPDL, включающего следующие узлы:
    • узел позволяющий делегировать обработку события удалённому janet-модулю;
    • email-узел позволяющий организовать email-рассылку списку получателей.
  2. janet-модуль содержащий бизнес-логику построения отчёта по таблице из СУБД и работу по расписанию, которая создаёт экземпляр бизнес-процесса и запускает его на выполнение через заданные промежутки времени.

Требования к окружению

  1. JDK версии 1.5 или выше можно загрузить по адресу. Рекомендуем использовать последнюю доступную версию JDK. Далее для ссылок на место установки JDK будем использовать следующее обозначение $JAVA_HOME.
  2. ant версии 1.6 или выше доступен по адресу. Рекомендуем использовать последнюю доступную версию ant. Далее для ссылок на место установки ant будем использовать следующее обозначение $ANT_HOME.
  3. Последнюю версию iJaNet Server можно загрузить по адресу (ссылки вида janet-installer-5.x.x.jar). Процесс установки платформы iJaNet рассмотрен в п 3.3 Платформа iJaNet V5. Общее описание. Далее для ссылок на место установки платформы будем использовать следующее обозначение $JANET_HOME.
  4. Создать папку в которую будет помещены создаваемые janet-модули и описание бизнес-процесса. Далее ссылки на эту папку будем обозначать $JANET_PROJECTS.
  5. Последнюю версию iJaNet SDK for java можно загрузить по адресу (ссылки вида janet-sdk-5.x.x.zip).

Постановка задачи

Предположим что у нас есть некоторая система учёта рабочего времени, которая хранит информацию о времени прихода сотрудников на работу в следующей таблице EMPL_CHECK_IN_TIME.

5EMPLOYEE_ID CHECK_IN_DATE_TIME
42 1256276712399
15 1256276947612
63 1256277475091
22 1256278092102
8 1256278890180
78 1256280704341

В первом столбце хранится ID служащего, во втором время, когда он зарегистрировался в системе при проходе через проходную. Формат времени — это то что возвращает метод System.currentTimeMillis() (количество миллисекунд которое прошло с 1го января 1970 г. UTC). Понятно, что в реальной системе таблица будет сложнее. Здесь мы выбрали её максимально упрощённый вариант.

Скрипт (db_script.sql) для создания таблицы и наполнения её данными есть в приложении к статье.

Количество опоздавших можно получить выполнив такой запрос

select count(employee_id)
    from (select employee_id, check_in_date_time
                from empl_check_in_time 
                where check_in_date_time > 1256277600000)

результатом которого является такая таблица

COUNT
3

Описание решения

Сначала мы создадим описание бизнес-процесса(pdtemplate.par). Бизнес-процесс будет содержать в себе всего два узла. Из первого узла (node1) мы обратимся к удалённому модулю. Удалённый модуль (module.ear) будет содержать в себе логику подготовки данных для будущего отчёта и работу по расписанию (Scheduled job), позволяющую запустить на выполнение экземпляр бизнес-процесса в интересующее нас время.

Второй узел (mail-node1) позволит нам сформировать и разослать отчёт списку e-mail адресов.

Подготовка к работе

Перейдите в папку $JANET_PROJECTS

cd $JANET_PROJECTS

Распакуйте содержимое архива SDK в текущую папку.

unzip -o janet-sdk-5.x.x.zip

В результате операции внутри папки $JANET_PROJECTS будет создано следующее дерево каталогов:

$JANET_PROJECTS
|
+--[doc]
|
+--[pdtemplate]
|
+--[template]
|
---LICENSE
|
---README
|
---janet.ear

переименуйте папку template в module

mv template module

отредактируйте файл jbpm.cfg.xml который находится внутри архива janet.ear. Найдите в нём следующую строку:

1 <string name="jbpm.mail.smtp.host" value="localhost" />

и замените значение атрибута value на адрес SMTP сервера, котрый будет использоваться для отправки письма с отчётом, например mail.janetsys.com

затем измените адрес отправителя этого письма

1 <string name="jbpm.mail.from.address" value="jbpm@noreply" />

Если SMTP сервер требует аутентификации используйте следующие параметры

1 <string name="jbpm.mail.user" value="username" />
2 <string name="jbpm.mail.pass" value="password" />

где username и password соответственно имя пользователя и пароль для доступа к SMTP серверу.

Создание и конфигурирование описания бизнес-процесса

Перейдите в папку $JANET_PROJECTS/pdtemplate/src

cd $JANET_PROJECTS/pdtemplate/src

и создайте в ней папку actions

mkdir actions

Скопируйте файл NodeActionHandler.java в созданую папку. Затем отредактируйте файл $JANET_PROJECTS/pdtemplate/src-jpdl/processdefinition.xml. Внутри блока <process-definition> вставьте следующий код:

 1 <start-state name="start-state1">
 2     <transition to="node1" name="to_node1"></transition>
 3 </start-state>
 4 
 5 <mail-node name="mail-node1" to="your@email.com">
 6     <subject>
 7         Отчёт системы учёта рабочего времени
 8       </subject>
 9     <text>Доброе утро,
10 сегодня в системе зарегистрировано #{var1} опоздавших.
11 
12 С уважением, система учёта рабочего времени.
13         </text>
14     <transition to="end-state1" name="to_end-state1"></transition>
15 </mail-node>
16 
17 <node name="node1">
18     <action class="actions.NodeActionHandler" config-type="bean">
19         <remoteName>
20             remotebpm
21         </remoteName>
22         <localName>
23             remotebpm.local
24         </localName>
25         <serviceInterface>
26             janet.services.bpm.IJBPMRemoteHandler
27         </serviceInterface>
28         <transportHttpUrl>
29             http://localhost:8080/module/service
30         </transportHttpUrl>
31     </action>
32     <transition to="mail-node1" name="to_mail-node1"></transition>
33 </node>
34 
35 <end-state name="end-state1"></end-state>

Замечание: атрибут to тега <mail-node> содержит адрес e-mail на который будет выслан отчёт.

которому соответсвует следующая схема процесса

Замечание: для облегчения создания описаний бизнес-процессов рекомендуем использовать бесплатный плагин Graphical Process Designer к среде разработки eclipse. Процесс установки плагина подробно рассмотрен на ссылке.

Выполните сборку созданого описания процесса для чего перейдите в папку $JANET_PROJECTS/pdtemplate

cd $JANET_PROJECTS/pdtemplate

и выполните ant без параметров

$ANT_HOME/bin/ant

Полученый архив с описанием процесса pdtemplate.par необходимо развернуть через интерфейс системы управления бизнес-процессами. Подробнее о работе с интерфейсом системы управления бизнес-процессами см. Руководство пользователя системы управления бизнес-процессами.

Создание и конфигурирование модуля содержащего удалённый обработчик события

Перейдите в папку $JANET_PROJECTS/module/src

cd $JANET_PROJECTS/module/src

и создайте в ней папки actions и jobs

mkdir actions jobs

Скопируйте файлы NodeActionHandlerRemote.java в папку actions, BPStarter.java в папку jobs . Затем отредактируйте файл $JANET_PROJECTS/module/build.xml. Найдите в нём строку:

<target name="build-deploy" depends="build-ear" if="server.deploydir">

и перед ней вставьте

<property name="server.deploydir" value="$JANET_HOME/Server/server/janet/deploy" />

Замечание: здесь и далее все ссылки в конфигурационных файлах на переменные окружения вида $JANET_HOME нужно заменять значениями этих переменных. Так в примере выше значение атрибута value="/path/to/janet/Server/server/janet/deploy"

Далее сконфигурируем настройки транспорта создаваемого удалённого модуля, для этого в файле в файле $JANET_PROJECTS/module/resources/jws-module.xml внутри блока <module-properties> изменим значения параметров

1 <param name="transport.compress" type="boolean">false</param>
2 <param name="transport.encrypt" type="boolean">false</param>

на противоположные

1 <param name="transport.compress" type="boolean">true</param>
2 <param name="transport.encrypt" type="boolean">true</param>

В удалённом модуле нам также необходимо сконфигурировать сервис позволяющий делегировать обработку события возникающего при выполнении бизнес-процесса обработчику находящемуся внутри создаваемого модуля. Для этого в внутри блока <local-services> нужно добавить следущее описание службы remotebpm:

1 <service name="remotebpm" publish="true">
2     <factory-class>jws.core.services.GenericServiceFactory</factory-class>
3     <service-interface>janet.services.bpm.IJBPMRemoteHandler</service-interface>
4     <parameters>
5         <param name="impl.class" type="string">janet.services.bpm.impl.JBPMRemoteHandlerService</param>
6     </parameters>
7 </service>

В этой же секции добавим описание службы data с помощью которой мы будем выполнять SQL запрос к СУБД

 1 <service name="data">
 2     <factory-class>jws.services.data.impl.DataServiceFactory</factory-class>
 3     <service-interface>jws.services.data.IDataService</service-interface>
 4     <parameters>
 5         <param name="datasource" type="jws.services.common.DirectDataSourceConf">
 6             <driver-class>org.firebirdsql.jdbc.FBDriver</driver-class>
 7             <connection-url>jdbc:firebirdsql:localhost:/var/lib/firebird/2.1/data/janet.fdb</connection-url>
 8             <driver-parameters>
 9                 <param name="user" type="string">SYSDBA</param>
10                 <param name="password" type="string">masterkey</param>
11             </driver-parameters>
12         </param>
13     </parameters>
14 </service>

Примечание: в примере используется СУБД Firebird версии 2.1 Полный список СУБД с которыми можно работать с использованием системного сервиса data приведён в документе Платформа iJaNet V5. Общее описание.

и удалим описание службы remoting, которое имеет следующий вид

1 <service name="remoting" publish="true">
2 ..
3 </service>

Т. о. секция <local-services> должна содержать описание двух служб remotebpm и data.

В секции <remote-module-ref> изменим настройки транспорта для обращения к удалённым службам

1 <transport>
2     <transport-name>http</transport-name>
3     <parameters>
4         <param name="transport.http.url" type="string">http://localhost:8080/janet/service</param>
5         <param name="transport.http.timeout" type="int">5000</param>
6     </parameters>
7 </transport>

Удалим блок с описанием прокси-службы remoting

1 <service-proxy remote-name="remoting" local-name="module.remoting">
2     <service-interface>jws.services.remoting.IRemotingService</service-interface>
3 </service-proxy>

и добавим описание прокси-службы для доступа к системе управления бизнес-процессами, которая расположена в системном модуле janet.ear.

1 <service-proxy remote-name="bpm" local-name="bpm">
2     <service-interface>janet.services.bpm.IJBPMService</service-interface>
3 </service-proxy>

Т.о. секция <remote-module-ref> должна содержать описание прокси-службы bpm и транспорта для доступа к этой службе.

В секции <scheduled-jobs> зададим работу по расписанию, которая будет создавать и стартовать экземпляр бизнес-процесса.

1 <job start-delay="3000" interval="86400000">
2     <job-class>jobs.BPStarter</job-class>
3 </job>

Работа по расписанию стартует первый раз через 3 секунды после развёртывания модуля на сервере приложений и после этого каждые 86400000 мс (24 часа).

после чего можно приступать к сборке и развёртыванию модуля, для этого перейдите в папку @$JANET_PROJECTS/module

cd $JANET_PROJECTS/module

и выполните ant без параметров

$ANT_HOME/bin/ant

Старт работы по расписанию, результат работы экземпляра процесса

Перед запуском клиента запустите сервер приложений JBoss в отдельном окне терминала

$JANET_HOME/bin/run.sh

Через 3 секунды после полного запуска сервера в консоли сервера должны появиться следующие строки

19:24:19,990 INFO  [BPStarter] Job started
19:24:19,990 INFO  [BPStarter] Creating and starting process instance for process definition: pdtemplate
19:24:20,269 INFO  [AbstractActionHandler] Entered node1
19:24:20,270 INFO  [NodeActionHandler] Starting local handler
19:24:20,270 INFO  [NodeActionHandler] Trying to invoke remote handler
19:24:20,308 INFO  [NodeActionHandlerRemote] Hello from remote handler
19:24:20,407 INFO  [NodeActionHandlerRemote] Select query returned: 3
19:24:20,459 INFO  [NodeActionHandler] Creating new process variable var1 
19:24:20,459 INFO  [NodeActionHandler] Local handler ended
19:24:20,459 INFO  [AbstractActionHandler] Exiting node1
19:24:20,459 INFO  [AbstractActionHandler] Propagating process execution
19:24:20,545 INFO  [BPStarter] Execution of process instance ended
19:24:20,545 INFO  [BPStarter] Job ended
19:24:20,545 INFO  [BPStarter] Bye!

На почтовый ящик, указанный на этапе создания бизнес-процесса должно прийти письмо-отчёт с темой Отчет системы учёта рабочего времени и следующим содержимым

Доброе утро, сегодня в системе зарегистрировано 3 опоздавших.

С уважением, система учёта рабочего времени.

processimage.jpg (11.7 KB) Виталий Шакуров, 04/29/2010 07:42 pm

db_script.sql (780 Bytes) Виталий Шакуров, 04/29/2010 07:42 pm

solution_diagram.png (55.3 KB) Виталий Шакуров, 04/29/2010 07:42 pm

BPStarter.java (920 Bytes) Виталий Шакуров, 04/30/2010 12:33 pm

NodeActionHandlerRemote.java (1.5 KB) Виталий Шакуров, 04/30/2010 12:33 pm

NodeActionHandler.java (836 Bytes) Виталий Шакуров, 04/30/2010 12:33 pm

Also available in: HTML TXT