Загрузка справочника БИК с сайта ЦБ России с помощью SAP PI
В этой статье мы разберём способ извлечения справочника БИК с сайта ЦБ, используя исключительно SAP PI 7.40 (Java Stack) без применения BPM-функциональности.
Проекты внедрения SAP ERP включают процессы ведения НСИ, в частности справочник кредитных организаций с информацией, достаточной для составления платёжных поручений.
Обычно процесс ведения такого справочника осуществляется в ручном или полуавтоматическом режиме. При ручном ведении информация по новым кредитным организациям и изменениям вводятся через транзакции SAP ERP. При полуавтоматическом режиме осуществляется импорт файлов-справочников, предоставляемых обслуживающим банком-корреспондентом или ЦБ РФ.
Справочник кредитных организаций также доступен на сайте ЦБ России в виде справочника БИК. Информация о кредитных организациях публикуется в виде единого ZIP-архива, состоящего из множества файлов-таблиц формата dBASE IV. Каждая новая версия справочника публикуется под новым именем (соответствующим дате публикации файла). Для автоматизации доступа к списку версий справочника доступен каталог версий справочника в виде XML-документа, где указан URL-адрес каждой версии размещённого справочника.
В этой статье мы разберём способ извлечения справочника БИК с сайта ЦБ, используя исключительно SAP PI 7.40 (Java Stack) без применения BPM-функциональности. Обработка данных справочника на стороне системы-приёмника выходит за рамками данной статьи и не будет описан.
Проблемы интеграции с использованием SAP PI
Процесс загрузки справочника состоит из следующих четырёх шагов:
- Определение местоположения (URL) актуальной версии справочника;
- Скачивание соответствующего файла с сайта ЦБ;
- Распаковка части файлов из архива;
- Перекодировка dBASE-файлов в XML-формат.
Реализация интерфейса «в лоб» с применением SAP PI невозможна.
Первым камнем преткновения станет особенность HTTP-адаптеров SAP PI, которая не позволяет указывать динамически URL к файлу-источнику. Все опубликованные способы динамической подстановки адреса в адаптере сводятся к применению устаревшего Axis-адаптера и непрозрачных манипуляций с заголовками сообщений, что сводит управляемость интеграционного решения к нулю.
Второй трудностью является обработка архива с файлами в формате dBASE. Для расширения функциональности продукта SAP PI отсутствует специализированный публично доступный конвертор для dBASE-формата, имеются только Java-библиотеки общего назначения. Предоставляемая общими Java-библиотеками функциональность перегружена: реализован либо полноценный JDBC-интерфейс, либо библиотека предоставляется доступ не только на чтение, но и на запись. К тому же работа со сжатыми данными для этих библиотек невозможна, так как требуется доступ к файловой системе, куда соответствующие файлы-таблицы должны быть предварительно распакованы.
Описанное ниже решение позволяет обойти эти ограничения, не задействуя файловую систему, а также в этом решении, по возможности, применяется потоковая обработка файлов для уменьшения используемой памяти системы в процессе работы интерфейса.
Шаг 1. Определение местоположения актуальной версии справочника
Информация о размещаемых файлах справочника и их версиях опубликована на сайте ЦБР. Первичная настройка интерфейса в SAP PI осуществляется в виде запроса к этому файлу. На Рис.1: содержимое файла, где жёлтым цветом выделены ключевые для интерфейса данные.
Рис.1 Каталог опубликованных версий справочника БИК
Первичная настройка коммуникационного канала SAP PI осуществляется следующим образом:
Рис. 2 Конфигурация коммуникационного канала (Communication Channel) в SAP PI
Дополнительного конфигурирования адаптера не осуществляется. Для этого сценария мы выполняем настройку в качестве синхронного интерфейса (запуск по запросу из SAP-системы), хотя допустимо применение любого другого HTTP-адаптера, в том числе в режиме периодического опроса сайта ЦБР.
Получаемый XML-файл должен быть обработан для выявления актуальной версии справочника. Де-факто, последняя запись в XML-файле является актуальной, ей и воспользуемся.
Для обработки запрошенных данных запустим SAP PI Service Builder, где создадим объект Operation Mapping, который назначим этому интерфейсу.
Для обработки XML-файла создадим объект Message mapping с именем “GetLastFileVersionURL”, внутри которого напишем UDF-функцию. Воспользуемся методом transform(TransformationInput,TransformationOutput), который позволяет изменить выходной поток данных соответственно входным данным. Применяемая функция указана ниже (листинг 1). Обратите внимание, что обработка ошибок во всём коде этой статьи минимальна или отсутствует вовсе, так как программа предназначена для ознакомления с подходом реализации и основными принципами работы алгоритма. Важные участки исходного кода выделены жирным шрифтом.
package com.sap.xi.tf;
import com.sap.aii.mapping.api.*;
import com.sap.aii.mapping.lookup.*;
import com.sap.aii.mappingtool.tf7.rt.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import com.sap.ide.esr.tools.mapping.core.Init;
import com.sap.ide.esr.tools.mapping.core.Cleanup;
// дополнительные (зависимые модули)
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class _GetURLFromCatalog_ {
public void transform(TransformationInput in,TransformationOutput out) throws StreamTransformationException
{
InputStream instream = in.getInputPayload().getInputStream();
// базовый адрес
String outURL = "http://www.cbr.ru";
try{
// инициализация парсера XML
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
// парсинг XML
Document doc = builder.parse(instream);
// получение базового URL
outURL += doc.getDocumentElement().getAttribute("Base");
// получение имени файла (последний элемент типа <item>)
NodeList items = doc.getDocumentElement().getElementsByTagName("item");
outURL += items.item(items.getLength() - 1).getAttributes().getNamedItem("file").getNodeValue();
// возращение как результат трансформации полный URL в файлу-справочнику (без XML тегов)
out.getOutputPayload().getOutputStream().write(outURL.getBytes());
}
catch(Exception e1){
throw new StreamTransformationException(e1.getMessage());
}
}
}
Листинг 1. Получение адреса файла из каталога опубликованных версий справочника
Результатом трансформации будет, например:
http://www.cbr.ru/mcirabis/BIK/bik_db_25112014.zip
Шаг 2. Скачивание справочника с сайта ЦБ
Получив ссылку на актуальный файл-справочник, необходимо его скачать. Для этого требуется выполнить ещё один HTTP-запрос к сайту, URL файла при этом поступает на вход функции. Создадим ещё один Message mapping под именем “GetFileFromURL”, для которого зададим следующую UDF-функцию. Для запроса к файлу будем использовать стандартные Java-модули доступа к HTTP-протоколу (URL и URLConnection). (см. Листинг 2)
package com.sap.xi.tf;
import com.sap.aii.mapping.api.*;
import com.sap.aii.mapping.lookup.*;
import com.sap.aii.mappingtool.tf7.rt.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import com.sap.ide.esr.tools.mapping.core.Init;
import com.sap.ide.esr.tools.mapping.core.Cleanup;
// дополнительные модули
import java.net.URL;
import java.net.URLConnection;
public class _GetFileFromURL_ {
// локальная функция-помощник для копирования из InputStream в OutputStream
private void copyStream(InputStream is, OutputStream out) throws Exception {
byte[] buffer = new byte[4096];
Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland
ЗарегистрироватьсяУ вас уже есть учетная запись?
Войти
Обсуждения 5
Комментарий от
Дмитрий Волков
| 18 января 2015, 00:50
Исходный код zip_dbf_to_xml.java не доступен для скачивания.
С уважением,
Дмитрий
Комментарий от
Admin SAPLand
| 20 января 2015, 15:15
Дмитрий Волков 18 января 2015, 00:50
Добрый день, Марат,
Исходный код zip_dbf_to_xml.java не доступен для скачивания.
С уважением,
Дмитрий
Ссылку исправили. Теперь Вы можете скачать код.
Комментарий от
Илья Кузнецов
| 29 января 2015, 10:22
Комментарий от
Алексей Полтев
| 29 января 2015, 12:08
Комментарий от
Марат Бареев
| 30 января 2015, 17:42
Илья Кузнецов 29 января 2015, 10:22
Нехорошо из меппинга куда попало (=недокументировано) соединения устанавливать! Правильно передавать канал как параметр меппинга, а URL через динамическую конфигурацию подсовывать. Да и параметры прокси для интернета, мониторинг общения с ЦБР и поиск ошибок можно будет делать через PIMON.
согласен с тем, что второй этап маппинга (получение итогового файла по ссылке) можно было реализовать через Communication Channel, но я не хотел усложнять схему работы.
Основной упор делается на динамическое получение итоговой ссылки на файл и конверсию DBF-файлов "на лету".