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