Commit 114faad7 authored by Valentin Skripnikov's avatar Valentin Skripnikov

-

parent b7d703c8
...@@ -128,3 +128,211 @@ ARTA Synergy генерирует событие в случае, ...@@ -128,3 +128,211 @@ ARTA Synergy генерирует событие в случае,
:numbered: :numbered:
integration/events integration/events
Блокирующий процесс
-------------------
Блокирующий процесс предназначен для того,
чтобы предоставить возможность
в маршрут активации/изменения/удаления реестра
вставить асинхронный вызов внешнего модуля.
Основное отличие блокирующего процесса от `события реестра`_
заключается в том, что:
* при использовании блокирующего процесса маршрут реестра
дожидается ответа о результате выполнения операции внешним модулем
* блокирующий процесс может завершиться положительно или отрицательно,
что повлияет на дальнейшую работу маршрута
(Если блокирующий процесс завершится отрицательно
процесс остановится, если положительно то продолжит работу дальше)
Модуль, реализующий блокирующий процесс, должен представлять собой отдельное приложение,
задеплоенное на jboss в соответствии с правилами,
описанными в разделе `Как задеплоить интеграционное приложение`_.
Запускается код модуля блокирующего процесса через очередь.
При старте этапа маршрута, содержащего блокирующий процесс,
в очередь добавляется сообщение, которое должен обработать модуль.
Конфигурация блокирующего процесса
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Для того, чтобы добавить блокирующий процесс,
необходимо выполнить следующие действия:
1. Добавить процесс с в маршрут реестра в конфигураторе:
.. figure:: ../_static/img/integration/blocking-add.png
:scale: 68%
Название процесса должно начинаться с ``event.blocking.``
и далее строка, характеризующая суть блокирующего процесса.
2. Создать очередь JMS для блокирующего процесса.
Для этого необходимо в конфигурационный файл
(в стандартной установке это ``/opt/synergy/jboss/standalone/configuration/standalone-onesynergy.xml``)
в секцию ``<subsystem xmlns="urn:jboss:domain:messaging:1.2">`` добавить:
.. code-block:: xml
<jms-queue name="ExampleQueue">
<entry name="java:jboss/queues/Integration/ExampleQueue"/>
<durable>true</durable>
</jms-queue>
3. Связать очередь и процесс через конфигурационный файл
``{$jboss.home}/standalone/configuration/arta/api-observation-configuration.xml``,
добавив в него следующее:
.. code-block:: xml
<listener>
<queue>java:jboss/queues/Integration/ExampleQueue</queue>
<event>event.blocking.example</event>
</listener>
Обратите внимание, что название блокирующего процесса,
указанное в маршруте в конфигураторе должно быть
равно значению тега в конфигурационном файле
``api-observation-configuration.xml`` (в данном примере: ``event.blocking.example``)
и название очереди должно совпадать со значением тега
``queue`` конфигурационного файла
``api-observation-configuration.xml`` (в данном примере: ``java:jboss/queues/Integration/ExampleQueue``)
Сообщение, передаваемое в очередь, является экземпляром ``TextMessage``.
Содержимым сообщения является объект JSON с полями:
1. dataUUID идентификатор данных по форме записи реестра
2. executionID идентификатор блокирующего процесса
3. documentID идентификатор документа реестра
После того, как модуль обратится к внешней системе
и выполнит необходимые действия, он должен вызвать метод API Synergy
для того, чтобы возвратить результат выполнения процесса и продолжить работу маршрута.
Для того, чтобы это сделать, необходимо вызвать метод API
``rest/api/processes/signal``.
.. note:: Сигнал блокирующему процессу для его разблокировки/блокировки
нужно отправлять после того, как этот процесс был запущен, то есть после того как
транзакция с запуском процесса была завершена. Для этого, перед отправкой сигнала,
проверяйте на наличие такого процесса в БД. В противном случае, блокирующий процесс
может завершиться в транзакции, но в маршруте нет.
В примере кода ниже разблокировка маршрута осуществляется в методе ``onMessage``.
Если время выполнения действия значительно или зависит от внешних факторов
(например, доступность интегрируемой системы,
или необходимость ввода пользователем данных в интегрируемой системе),
то разблокировка маршрута может произойти позже,
в любой другой момент времени из другого метода,
а сам метод onMessage должен завершиться без ошибок, «запомнив» переданные параметры.
.. code-block:: java
package kz.arta.synergy.samples.processes.blocking;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* <p><Пример блокирующего процесса</p>
*/
public class BlockingQueueListener implements MessageListener {
public void onMessage(Message message) {
String dataUUID = null;
String executionID = null;
String documentID = null;
if (!(message instanceof TextMessage)){
return;
}
try {
JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createJsonParser(((TextMessage) message).getText());
JsonToken token = null;
while ((token = parser.nextToken()) != null) {
if (token == JsonToken.FIELD_NAME) {
String fieldName = parser.getText();
parser.nextToken();
String value = parser.getText();
if (fieldName.equals("dataUUID")){
dataUUID = value;
} else if (fieldName.equals("executionID")){
executionID = value;
} else if (fieldName.equals("documentID")){
documentID = value;
}
}
}
//Выполнение каких-либо действий
.......
//Разблокировка маршрута
String address = "http://127.0.0.1:8080/Synergy";
String login = "1";
String password = "1";
String signal = "got_agree";
boolean isSuccess = false;
try {
URL url = new URL(address + "/rest/api/processes/signal?signal=" + signal + "&executionID=" + executionID + "&param1=resolution&value1=signal_is_" + signal);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json; charset=utf-8");
String encoded = Base64.encode((login + ":" + password).getBytes());
conn.setRequestProperty("Authorization", "Basic " + encoded);
String output;
StringBuffer result = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
while ((output = br.readLine()) != null) {
result.append(output);
}
conn.disconnect();
JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createJsonParser(result.toString());
JsonToken token = null;
while ((token = parser.nextToken()) != null) {
if (token == JsonToken.FIELD_NAME) {
String fieldName = parser.getText();
token = parser.nextToken();
if (fieldName.equals("errorCode") && parser.getText().equals("0")){
isSuccess = true;
}
}
}
} catch (Exception exc){
logger.error(exc.getMessage(), exc);
}
} catch (Exception exc){
logger.error(exc.getMessage(), exc);
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment