Привет, Хабр! Меня зовут Юрий Мишин, я технический директор в департаменте банковского ПО компании R‑Style Softlab. В этой статье я расскажу о масштабном проекте по переводу одного из ключевых продуктов компании 一 автоматизированной банковской системы (АБС) 一 на импортозамещенный стек.
Технологический стек АБС
АБС представляет собой набор модулей для реализации различных направлений деятельности банка: обслуживания клиентов, работы с ценными бумагами и финансовыми инструментами, кредитования и работы с депозитами, выпуска отчетности и других.
АБС не существует сама по себе. Она работает в определенном программно‑аппаратном комплексе. Касаться аппаратной части мы сейчас не будем, тема данной статьи — программная часть.
Ключевыми составляющими программной части являлись:
Операционная система (ОС), в которой работает приложение. Серверная и терминальные части АБС RS-Bank V.6 работали только в MS Windows.
Система управления базами данных (СУБД). АБС использовала СУБД Oracle.
Офисный пакет для вывода и печати различных отчетов. Некоторые отчеты могли выпускаться и отображаться в любых офисных пакетах, но полноценно АБС работала только с MS Office.
Сервер для JEE-приложений. Можно было использовать серверы приложений IBM, Oracle, опенсорсный TomEE или контейнер сервлетов Tomcat.
Среда для выполнения java-приложений.
С последними тремя позициями оказалось проще всего. Можно продолжать работать с опенсорсными Tomcat и свободными сборками OpenJDK. Но если для банка критично использование именно продуктов из реестра РосПО, то мы рекомендуем сервер приложений Libercat и AxiomJDK. В качестве офисного пакета можно использовать любой, умеющий работать с серией форматов файлов OOXML, например, Р7-Офис.
Целевой операционной системой была выбрана ОС Astra Linux. Мы не видим технических ограничений по использованию других российских операционных систем, на некоторых из них мы даже тестировали нашу систему после выполненных доработок, но возможны ограничения со стороны внешних продуктов. Так, например, в формуляре АПК «Валидата Клиент L» указано функционирование только в ОС Astra Linux Special Edition.
В качестве СУБД выбрана Postgres Pro.
Адаптация системы для работы в ОС Linux
В соответствии с частями программного комплекса проект можно разделить на три крупных блока. Первый – это адаптация системы для возможности работы в ОС Linux.
Ядро АБС представляет собой большой монолит. Учитывая сжатые сроки, перевести его на нативный Linux даже отдельными кусками в рамках данного проекта оказалось невозможно. Поэтому было принято решение использовать Wine — ПО, позволяющее запускать приложения Windows в операционных системах семейства Linux. Это свободное ПО, но каждый разработчик российской ОС поставляет вместе с ней и свой вариант Wine. Но в качестве основного продукта мы используем зарегистрированный в РосПО Wine@Etersoft.
Несмотря на заявленную возможность запуска Windows-приложений, мы встретились с некоторыми сложностями. До сих пор Wine мало использовался в корпоративных продуктах, в основном только для запуска относительно простых приложений. Некоторые функции API Windows в Wine не реализованы. В частности, мы столкнулись с тем, что в Wine не реализована функция LogonUser, предназначенная для запуска процесса от имени определенного пользователя. Пришлось переделывать алгоритм запуска процессов.
Заметили также больший расход памяти. При запуске приложения в Wine для него выделяется больше памяти, чем при запуске этого же приложения в Windows. Но при дальнейшей работе эта дельта не изменяется. Анализ показал, что причина в способах загрузки некоторых DLL. В Wine все DLL загружаются как частные, а в Windows системные DLL являются разделяемыми. Из-за этого частный набор памяти процесса в Windows ниже.
Но подавляющая часть кода системы работает в Wine без проблем.
Формирование и печать отчетных форм в офисных пакетах
Второй блок задач был связан с формированием и печатью отчетных форм в офисных пакетах. Старая технология формирования отчетных форм предполагала использование ActiveX-объектов Excel и Word. Работы по замене данной технологии мы начали еще раньше. Вместо ActiveX перешли на использование инструмента Apache POI. В результате чего формирование документов выполнялось без участия объектов Excel и Word.
Сформированный файл передавался с сервера приложений на машину пользователя, и уже в этот момент запускался соответствующий продукт MS Office для отображения документа. К началу работ по импортозамещению еще не все отчеты были переведены на данную технологию. Мы продолжили работы по переводу отчетов на инструмент Apache POI. Но основное изменение состояло в способе открытия сформированного файла. Вместо прямого запуска Excel или Word, теперь идет вызов функции ShellExecute и операционная система стартует приложение, ассоциированное с файлами такого типа. Причем, несмотря на то что АБС работает в Wine, для отчетов запускается линуксовый офисный пакет. В Wine@Etersoft это работает «из коробки», для ванильного Wine требуется сделать дополнительные настройки.
Адаптация системы для возможности работы с СУБД PostgreSQL
Третий блок работ был связан с адаптацией системы для возможности работы с СУБД PostgreSQL. Это был самый сложный, трудоемкий, но и самый интересный блок. RS-Bank V.6 работает с СУБД Oracle с использованием ODBC-драйвера, поэтому внутренние механизмы работы с СУБД дорабатывать не пришлось. Для варианта с PostgreSQL работа с СУБД также идет через функции API ODBC. Но это только немного упростило работу.
Основная сложность состояла в том, что в прикладных местах, где происходит выполнение SQL-запросов, текст запроса мог быть как в ANSI-формате, так и в формате, специфичном для Oracle. Мы разработали конвертер, который в случае необходимости во время выполнения SQL-запроса «на лету» преобразовывает его текст из ораклового формата в формат, понятный PostgreSQL. К сожалению, исчерпывающего списка всех конструкций, требующих конвертирования, на входе не было, о многих из них мы узнавали уже во время работ по адаптации.
В итоге после всех доработок некоторые SQL-запросы стали автоматически работать на PostgreSQL, другие потребовали где-то косметических, где-то более серьезных изменений, чтобы конвертер смог их обработать. Для определенной части SQL-запросов мы пришли к выводу, что дешевле и проще будет их переписать, чем доработать конвертер. В качестве примера можно привести SQL-запросы, которые в PostgreSQL не заработали из-за отсутствия неявных преобразований типов. В них мы добавляли явный вызов функций преобразования соответствующих типов. Но были и такие SQL-запросы, для которых придумать алгоритм автоматического конвертирования было невозможно, или конвертер выдавал неоптимальные SQL-запросы. В таких случаях мы делали отдельную ветку для PostgreSQL.
В итоге оказалось, что всего SQL-запросов, которые пришлось так или иначе править в прикладном коде, было около 20%. Остальные же 80% конвертер преобразовать смог.
Еще интереснее было с хранимыми процедурами. На старте проекта было принято решение, что текст хранимого кода (пакеты, функции, процедуры, триггеры) продолжит храниться в формате PL/SQL. Для PL/SQL-кода мы также разработали конвертер, который при инсталляции системы преобразует код на PL/SQL в код на PL/pgSQL.
Как известно, в PL/pgSQL отсутствуют пакеты. При конвертации для каждого PL/SQL-пакета в БД PostgreSQL конвертер создает схему с таким же именем, процедуры и функции создаются внутри схемы. Это, конечно, не ноу-хау, а общепринятый подход, но он позволяет оставлять без изменения вызывающий их код. Когда наш проект был уже в разгаре, компания Postgres Pro выпустила Postgres Pro Enterprise 15, где появились пакеты. Но мы решили эту функциональность не использовать, чтобы в случае необходимости иметь возможность реализовать работу АБС не только в редакциях, отличных от Enterprise, но и ванильном PostgreSQL.
Различий в PL/SQL и PL/pgSQL намного больше, чем между SQL-диалектами двух СУБД. Помимо различий между SQL-запросами добавились еще существенные различия в возможностях двух языков. Например, во многих наших хранимых процедурах используются коллекции. В PL/pgSQL коллекций нет. Для таких случаев мы делали отдельную реализацию. В начале проекта мы планировали, что сможем сделать конвертер для как можно большего PL/SQL-кода, но быстро выяснилось, что, к сожалению, такая задача близка к невыполнимой, и стали проще относиться к дублированию кода. Но в итоге оказалось, что из 1495 скриптов с хранимым кодом дубли были сделаны для 280 скриптов, те же самые почти 20%.
На этом пока все. Отвечу на ваши вопросы.