Динамическое программирование ABAP. RFC ФМ для вызова методов произвольного класса.

При интеграциях между системами частенько надо получать данные из смежных систем. Самое простое -  обернуть метод  в RFC ФМ и вызвать его в нужной системе. Это хорошее решение, но что делать если нам нужно вызвать не один метод, а 50 или даже 100. Писать обертку для каждого? Довольно долгое занятие, плюс любое изменение в методе повлечет необходимость дополнительной поддержки этих ФМ. Короче, самое очевидное решение, не всегда самое удобное в конкретном случае. 
Один из альтернативных путей решений - динамическое программирование. Это способ тоже не без недостатков, но он может позволить избежать создании сотен лишних ФМ.  Если надо вызвать один-два метода, я бы не заморачивался и делал все в обертках.

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

Сначала пару слов о динамическом программировании. Вызвать метод или класс динамически проблем не составляет. Для этого просто оборачиваем переменную с названием метода или класса в скобки. Получаем вызов в таком виде CALL METHOD (lv_class)=>(lv_method). Где lv_class и lv_method хранят название класса и метода.
Значения входных и выходных параметров передаются в таблице типа abap_parmbind_tab. Чуть более подробно...

Казалось бы, бери и пользуются. Как всегда есть одно но. Т.к. в рамках текущей задачи нам надо передавать параметры из внешней системы, а поле value типа REF TO.
В версиях ABAP 7.50 и выше можно добавить к трансформации префикс 'heap-or-create' . Префикс можно добавить и в версии 7.40, это даже работает для обычных REF , но у нас REF вложен в структуры, и ABAP 7.40 не может преобразовать корректно.
Доп. информация 1.
Доп информация 2.
Примечание.
Если у вас 7.40 дополнительно надо разобраться с сериализацией данных содержащих вложенные REF TO. Попробуйте статью на Хабре

Примечание:
Можно сериализовать и инстанции классов. Но для этого класс должен наследоваться от интерфейса IF_SERIALIZABLE_OBJECT.

В строке iv_init_parameters передаем значения для метода CONSTRUCTOR объекта. Её же использование при вызове ФМ и будет сигнализировать о том, что инстанцию надо создавать

Теперь код самого ФМ:

Код вызова статического метода:

Код вызова динамического метода.

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

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


Вот ссылка на  подобное решение от другого человека.

 

Добавить комментарий

Ваш адрес email не будет опубликован.