Конвертация приложений, написанных на 4GL (языках четвертого поколения), считается одной из самых непростых задач в работе с унаследованными системами. Часто единственный способ вообще увидеть, как такое приложение работает, это генерация тестовых данных с помощью ИИ, потому что реальных данных заказчика у исполнителя, как правило, нет.

Такие приложения часто создавались десятилетия назад и годами дорабатывались разными командами. Они могут остаться практически единственным источником знаний о том, как реально устроена бизнес-логика компании.

Прежде чем переносить такое приложение на новую платформу, нужно понять, как оно работает на самом деле, а не как это описано (или не описано) в документации. Именно здесь конвертация 4GL-систем упирается в две связанные, но разные по своей природе проблемы.

В Конвертум мы регулярно сталкиваемся с этими проблемами на проектах конвертации унаследованного кода. В этой статье разберем обе проблемы и покажем на реальном примере, как их можно обойти без доступа к производственным данным заказчика, за счет автоматического анализа кода и ИИ-моделей, развернутых на собственной инфраструктуре.

Проблема 1. Dynamic SQL как слепая зона статического анализа

SQL-запросы в 4GL-коде бывают двух типов.

Тип запроса

Как попадает в программу

Что видит статический анализ

Embedded SQL

Прописан в коде явно и целиком

Таблицы и столбцы определяются точно

Dynamic SQL

Собирается во время выполнения из переменных, условий, пользовательского ввода

Систематически дает сбои

Статический анализ, то есть просто чтение и разбор текста программы без ее запуска, хорошо работает только с первым типом.

Исследователи, изучавшие эту проблему на примере Java-систем, отмечают, что статический анализатор не способен разрешить логические условия в коде (тогда как динамический анализ справился бы лучше). Из-за этого при попытке восстановить все возможные варианты SQL-запроса возникают ложные срабатывания [1].

“Чтобы понять, какие таблицы задействует динамический запрос, теоретического разбора кода недостаточно. Нужно наблюдать за поведением программы в момент ее реальной работы.”

Эрнест Келин, Конвертум

Полноценная трассировка кода во время выполнения, то есть динамический анализ, сама по себе задача не тривиальная. Исследование по реинжинирингу унаследованных JEE-приложений отмечает, что динамический анализ обычно сложен в настройке и применим только к относительно небольшим и простым системам.

Например, в клиент-серверной архитектуре нужно трассировать одновременно и клиент, и сервер. Если они работают на разных машинах, собрать и сопоставить трассировки становится непросто [2]. Именно поэтому для полного понимания системы часто нужен запуск приложения целиком, а не выборочная трассировка отдельных модулей.

Проблема 2. Отсутствие документации

Вторая системная проблема конвертации 4GL-приложений: практически полное отсутствие актуальной документации. Это не редкое исключение, а типичная черта унаследованных систем в принципе.

Исследователи, работавшие над задачей реверс-инжиниринга технической документации унаследованных систем, описывают это так: такие системы редко представляют собой просто набор старых файлов с кодом. В них годами накапливаются бизнес-правила, архитектурные решения, эксплуатационные исключения, соглашения о данных и сценарии использования.

Часть этого знания отражена в именах функций, SQL-запросах, проверках или конфигурационных файлах. Другая часть остается неявной: в паттернах реализации, истории изменений и неописаном знании сотрудников [3].

Схожий вывод делают и авторы работы о совмещении статического и динамического анализа кода. Понимание того, что реализует программная система, особенно затруднено, когда исходный код остается единственным надежным источником информации, документация устарела или сохранилась лишь фрагментарно, а первоначальные разработчики системы уже недоступны [4].

Масштаб проблемы подтверждают и авторы исследования MITRE. Унаследованные системы, написанные на устаревших языках, создают сложности сразу по нескольким направлениям [5]:

  • эффективность работы;
  • обслуживание;
  • поиск кадров, способных их поддерживать;
  • безопасность.

Это не единичное наблюдение, а иллюстрация того, насколько глубоко закапывается проблема отсутствия документации в реальных, годами эксплуатируемых системах.

Почему обе проблемы упираются в одно и то же

Dynamic SQL и отсутствие документации возникают по разным причинам. Но решаются они, по сути, одним и тем же способом: приложение нужно запустить и понаблюдать за его реальным поведением.

Только так можно увидеть, какие таблицы реально задействует динамически формируемый запрос. И только так можно восстановить бизнес-логику, которая нигде не описана: увидеть ее можно лишь через то, что программа реально показывает на экране и записывает в базу.

Но здесь возникает практическое препятствие: чтобы запустить унаследованное приложение и что-то в нем увидеть, нужны данные. Пустая база данных не покажет ни одного заполненного экрана, ни одного отчета. Сравнивать будет не с чем, анализировать нечего.

Именно в этой точке многие проекты конвертации 4GL-систем упираются в дополнительное препятствие: чаще всего это конфиденциальность и защита персональных данных, заказчик по объективным причинам не может передать исполнителю реальные производственные данные.

Обойти это препятствие можно единственным способом: наполнить базу данными, которых нет. Вручную это нереалистично, речь о сотнях связанных между собой таблиц. Поэтому задача естественно ложится на ИИ: модель, получившая структуру таблиц и описание бизнес-контекста, способна собрать наполнение, с которым приложение начинает вести себя как настоящее.

Как в Конвертум устроена генерация данных для тестирования унаследованного приложения

Именно с такой ситуацией наша команда столкнулась в одном из проектов. Заказчик передал:

  • исходный код унаследованного приложения на 4GL, около сотни скриптов;
  • полное структурное описание (DDL) двух схем базы данных: столбцы, типы данных, ключи и связи между таблицами.

Всего в схемах насчитывалось около двух тысяч таблиц. Сами данные заказчик не передал: по условиям проекта работать нужно было исключительно со структурой, без доступа к производственной информации.

Задача звучала так: обеспечить возможность тестирования и демонстрации приложения без реальных данных. Единственный выход состоял в том, чтобы автоматически сгенерировать правдоподобные тестовые данные, которые позволят приложению запуститься и показать реальное поведение.

Ручной путь решения этой задачи выглядел крайне трудозатратным. Разобрать вручную около сотни файлов кода и порядка двух тысяч таблиц, чтобы понять зависимости между ними и корректно сгенерировать данные, было бы не только долгим, но и подверженным ошибкам процессом.

Этап 1. Извлечение SQL-запросов из кода

Первым шагом мы построили автоматизированный пайплайн, который анализировал все файлы кода и извлекал из них все SQL-запросы: как Embedded, так и Dynamic SQL.

В результате было извлечено более 1500 запросов, примерно шестая часть которых относилась именно к Dynamic SQL.

Важно, что оба типа запросов обрабатывались в одном пайплайне. Без отдельного, целенаправленного разбора Dynamic SQL значительная часть запросов осталась бы той самой "слепой зоной", о которой шла речь выше, и часть реально используемых таблиц осталась бы незамеченной.

Этап 2. Анализ зависимостей и определение реально используемых таблиц

Второй пайплайн сопоставил каждую таблицу из схемы БД с найденными в запросах упоминаниями.

Итог оказался показательным: из почти двух тысяч таблиц реально задействованной приложением оказалась лишь малая часть, меньше 300 таблиц. Это разница почти в 85%.

При ручном или "на всякий случай" подходе пришлось бы готовить тестовые данные для более чем полутора тысяч таблиц, которые приложение вообще не использует. Именно сопоставление кода со структурой БД, то есть закрытие того самого пробела, который создает Dynamic SQL и отсутствие документации, позволило сфокусировать усилия только на реально нужных таблицах.

Этап 3. ИИ-генерация тестовых данных с учетом бизнес-контекста

На финальном этапе DDL-описания отобранных таблиц вместе с информацией о бизнес-контексте задачи были переданы нескольким независимым ИИ-моделям.

Все модели развернуты на собственной инфраструктуре Конвертум. По сути, это внутренний ИИ-сервер для генерации тестовых данных, за пределы которого не уходит ни строчки из переданных заказчиком схем. Когда речь идет о структуре продакшн-базы, это условие не менее важно, чем сам результат.

Использование двух независимых моделей позволило подстраховаться: получить запасной набор данных на случай ошибок при загрузке основного.

Ключевым здесь было не просто заполнить таблицы случайными значениями, а сгенерировать данные, правдоподобные именно для этой структуры таблиц и этого типа бизнеса. Этим ИИ и отличается от обычного генератора случайных значений: модель опирается на смысл названий таблиц и столбцов и на бизнес-контекст, а не только на типы данных. Иначе приложение технически бы запустилось, но показывало бы бессмысленные, нерелевантные записи, непригодные ни для тестирования логики, ни для демонстрации заказчику.

Результаты

Приложение заказчика было успешно запущено на синтетических тестовых данных и впервые продемонстрировало реальную работу с данными: до этого момента добиться этого не удавалось.

Показатель

Значение

Таблиц в переданных схемах

около 2000

Извлечено SQL-запросов из кода

более 1500

Доля Dynamic SQL среди них

примерно шестая часть

Таблиц, реально используемых приложением

менее 300

Длительность всего цикла работ

около недели

При этом построенные автоматизированные пайплайны переиспользуемы. Аналогичную задачу в будущих проектах команда Конвертум оценивает уже в несколько раз быстрее, а значит первоначальные затраты на автоматизацию окупаются уже на втором подобном проекте.

Что автоматизация тестирования с ИИ дает проектам конвертации 4GL

Этот кейс автоматизации тестирования показывает, что типичные проблемы конвертации 4GL-приложений, непрозрачный Dynamic SQL и отсутствие документации, не обязательно решать вручную, строчка за строчкой.

Оба препятствия связаны общей природой: без запуска и наблюдения за реальным поведением системы их не преодолеть, а без данных запуск невозможен.

Именно ИИ оказывается тем недостающим звеном, которое снимает это ограничение. Тестовые данные для приложений, у которых нет ни документации, ни доступной базы, больше не нужно собирать руками.

Генерация тестовых данных перестает быть подготовительной рутиной и превращается в рабочий инструмент самой конвертации.

Эрнест Келин, Конвертум

Есть и дополнительный эффект. На запущенном приложении становится возможной генерация тестовой документации: сценарии и ожидаемое поведение фиксируются по тому, что система реально показывает на экране, а не по устаревшим описаниям. А сами наборы данных дальше переиспользуются в QA-автоматизации, на них удобно сверять поведение старого и нового приложения после конвертации.

Подход при этом не завязан на конкретную среду. Генерация данных для Informix-схем или для другой 4GL-платформы строится по одной и той же логике: анализ кода, анализ структуры БД, ИИ-генерация. Именно такое сочетание команда Конвертум применяет и развивает на проектах перевода 4GL-систем на современные платформы.

Источники

  1. Static Analysis of Dynamic Database Usage in Java Systems (CAISE 2016): loupmeurice.github.io/publications/CAISE2016.pdf
  2. Service-Oriented Re-engineering of Legacy JEE Applications: Issues and Research Directions: arxiv.org/pdf/1906.00937
  3. Reversa: A Reverse Documentation Engineering Framework for Converting Legacy Software into Operational Specifications for AI Agents: arxiv.org/pdf/2605.18684
  4. Integration of Static and Dynamic Code Analysis for Understanding Legacy Source Code (IEEE): ieeexplore.ieee.org/document/7816507
  5. Leveraging LLMs for Legacy Code Modernization: Challenges and Opportunities for LLM-Generated Documentation (MITRE Corporation): arxiv.org/pdf/2411.14971

Обсудите ваш проект

Получите экспертные рекомендации по миграции данных, баз данных и приложений для вашей системы.

→ Обсудить проект