23.01.19

Camunda Spin и http-connector

25 мин · Обучающие

На протяжении долгого времени информационное взаимодействие бизнеса с органами власти было достаточно громоздким и неуклюжим. Процессы взаимодействия (в большинстве случаев, асинхронные) сводились к выгрузке из корпоративной информационный системы файлов (или формированию SOAP-конвертов), отправку выгруженного в интеграционный шлюз и, спустя N минут, а то и часов - обработку ответного сообщения.

Тем не менее, интерфейсы государственных служб продолжают эволюционировать и в ряде случаев граждане и бизнес могут легко получать интересующую информацию посредством HTTP-запросов и обработки ответов в формате JSON. Большим плюсом в деле автоматизации такого взаимодействия является тот факт, что значительное число современных информационных систем предоставляет необходимый функционал (HTTP-клиент, парсер JSON/XML) «из коробки».

Не стала исключением и Camunda BPM - вызов веб-сервиса и обработка ответа легко реализуются при помощи двух библиотек: HTTP Connector и Spin. Рассмотрим подробнее на примере процесса обработки кассовых чеков, поступающих от подотчетных лиц.

Camunda Service Task implements HTTP Connector

Входные условия:

  • Наличие регистрации в мобильном приложении ФНС Проверка чека (телефон, SMS-пароль). Зарегистрироваться можно также посредством HTTP-запроса (см. статья на Хабре).
  • Сканирование и «получение» чека в мобильном приложении (без этого шага при попытке запросить данные API возвратит «illegal public api usage».
    Приложение Проверка чека ФНС

Маршрут процесса:
Стартовое событие - заполнение веб-формы, содержащей в себе данные чека (либо подстановка в форму информации из считывателя QR-кода): fd (фискальный документ), fn (фискальный номер), fp (фискальный признак документа), логин и пароль (полученные при регистрации).
Start process form
Взаимодействие с API ФНС выполняется сервисной задачей (Service Task) - Get receipt info.

Функции задачи:

  • Кодирование полей Login и Password стартовой формы в Base64 строку
  • HTTP-запрос к API ФНС
  • Обработка ответа (если Status Code == 200), то в дело вступает Camunda Spin (S), помещающий ответ (содержимое чека) в переменную с типом JSON.

Рассмотрим подробнее «начинку» задачи.

General: Implementation: Connector.

Во входных параметрах (input parameters) задачи при помощи скрипта происходит обработка переменных login и password - конкатенация и кодирование в Base64.

Camunda Service Task

Листинг скрипта:

var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9+/=]/g,"");while(f>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/rn/g,"n");var t="";for(var n=0;n127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}};
var credentials = Base64.encode(login + ':' + password);
"Basic " + credentials;

Результат обработки помещается в переменную credentials.

Camunda HTTP Connector использует библиотеку Apache HTTP Client, поддерживая, таким образом, те же самые опции.

Настройки коннектора: Connector Id: http-connector
Методы могут иметь следующие типы:

  • Text (обычный String),
  • List (массив),
  • Map (словарь вида: ключ-значение, аналог java.util.Map),
  • Script (JavaScript или Groovy).

Метод (Input Parameter) Описание Пример
method HTTP-метод (POST/GET/PUT/etc) GET
url URL веб-сервиса https://proverkacheka.nalog.ru:9999/v1/inns/*/kkts/*/fss/${fn}/tickets/${fd}?fiscalSign=${fp}&am...
headers HTTP-заголовки (тип параметра - Map)
  • Content-Type: application/x-www-form-urlencoded
  • Content-Charset: utf-8
  • Device-Id: camunda
  • Device-OS: linux
  • Authorization: ${credentials}
payload Тело запроса
Метод (Output Parameter) Описание Пример
statusCode Код состояния HTTP-ответа 200
headers Заголовки HTTP-ответа 200
response Тело ответа (параметр может быть представлен в виде скрипта, обрабатывающего ответ)
if (statusCode == 200) {
    S(response);
} else {
    connector.setVariable("response",response);
}
Camunda HTTP Connector

Функция S(), используемая в скрипте в output-параметре response вызывает библиотеку Spin, которая выполняет обработку тела ответа, помещая его содержимое в переменную процесса с типом JSON. В дальнейшем, используя синтаксис Spin, можно обработать элементы ответа нужным образом.

Пример ответа API ФНС:

{
  "document": {
    "receipt": {
      "requestNumber": 163,
      "dateTime": "2019-01-14T17:06:00",
      "fiscalSign": 3105244272,
      "items": [
        {
          "sum": 12999,
          "quantity": 1,
          "name": "САЛФЕТКА ГЛОБУС",
          "price": 12999
        }
      ],
      "receiptCode": 3,
      "retailPlaceAddress": "142451, Моск. обл, г. о. Электросталь, Случайный п., массив 1, стр 2",
      "nds18": 28015,
      "ecashTotalSum": 544495,
      "fiscalDriveNumber": "9286000100079803",
      "user": "ООО \"Гиперглобус\"",
      "taxationType": 1,
      "cashTotalSum": 0,
      "rawData": "",
      "operationType": 1,
      "userInn": "7743543761",
      "shiftNumber": 161,
      "nds10": 34221,
      "totalSum": 544495,
      "operator": "СТУДЕНТ714 С.       ",
      "kktRegId": "0000658102021189    ",
      "fiscalDocumentNumber": 36333
    }
  }
}

Для получения значения элемента JSON-дерева необходимо использовать метод .prop("name"). Ниже приведен синтаксис Spin для получения значения элемента totalSum JSON-переменной response при помощи Camunda Spin с типом данных number.

response.prop("document").prop("receipt").prop("totalSum").numberValue() 

Метод #Value определяет возвращаемый тип данных.
Допустимые типы данных:

  • #stringValue()
  • #numberValue()
  • #boolValue()

Подробнее о синтаксисе Camunda Spin и обработке JSON.

Заключительные этапы процесса:

  • Шлюз (Data successfully retrieved?): Проверка кода состояния в ответе на запрос. Если данные успешно извлечены (${statusCode == 200}), выполняется проверка на сумму чека (totalSum). Иначе - создаем пользовательскую задачу Review an error, выводящую пользователю форму с кодом состояния и ответов сервиса для анализа ошибки.
  • Шлюз (Approval needed? (Total > 3000 RUB)): Если сумма чека равняется или превышает 3 тыс. рублей – требуется виза утверждающего лица (создается пользовательская задача Approve receipt). Иначе – создаем запись в учетной системе (сервисная задача Create an entry in ERP).
  • Пользовательская задача Approve receipt: Форма с просмотром содержимого чека (основные реквизиты и отдельные предметы и чекбоксом-подтверждением. Camunda Human Task
  • Исключающий шлюз Approved? Если отмечен чекбокс в форме Approve receipt - выполняется сервисная задача Create an entry in ERP. Иначе – процесс завершается.
  • Сервисная задача (заглушка) Create an entry in ERP, добавляющая информацию о чеке в бухгалтерскую систему.

Примеры использования http-connector в описаниях процессов на GitHub:

Оставляйте Ваши комментарии и вопросы по заметке на нашей странице в Facebook.