Статья содержит инструкции и рекомендации по написанию плагинов для BILLmanager. Плагин — программный компонент, который добавляет определённую функциональность или изменяет поведение основной системы.
Модификации BILLmanager
BILLmanager позволяет добавить следующие модификации:
- модули — крупные и самостоятельные компоненты системы, которые выполняют определённую функцию или набор функций. Например, расширяют функциональность за счёт интеграции со сторонней системой. Модули:
- обычно имеют свои зависимости и могут включать в себя несколько плагинов;
- не предназначены для динамического изменения поведения системы в реальном времени;
- могут требовать изменений в основной архитектуре системы;
- по функциональности разделяются на:
- обработчики услуг;
- методы оплаты;
- шлюзы сообщений;
- онлайн-кассы;
- модули документооборота;
- модули для координации со сторонними системами — LDAP, Omni, amoCRM и т.д.
О существующих модулях системы см. статью Интеграции.
- плагины — обычно более простые программные компоненты, которые добавляют определённую функциональность или изменяют поведение основной системы. Плагины позволяют:
- интегрировать новые функции без изменения исходного кода;
- перехватывать внутренние события;
- добавлять новые элементы интерфейса;
- выполнять фоновые задачи через триггеры на определённые события;
- адаптировать систему под конкретные потребности.
Виды плагинов
Плагины по функциональности разделяются на:
- плагины, изменяющие поведение платформы;
- плагины, расширяющие функциональность платформы;
- плагины, выполняющие фоновые задачи.
Плагины, изменяющие поведение, позволяют перехватывать внутренние события и модифицировать их. Например, добавить дополнительные поля в карточку клиента и заполнить их нужными значениями. Либо добавить новую логику для существующих действий. Подробнее см. статью документации COREmanager Изменение поведения системы через обработчики событий.
Плагины, расширяющие функциональность, добавляют:
- новые элементы — настраиваемые таблицы и формы, необходимые для решения конкретных задач;
- новые действия и сценарии работы с платформой.
Плагины, которые выполняют фоновые задачи:
- добавляют триггеры на определённые события в платформе;
- позволяют запускать в фоне “тяжёлые” задачи, которые не должны влиять на работу с платформой в интерфейсе. Например, выполнение фоновых задач на основе событий.
Подробнее см. статью документации COREmanager Фоновые плагины.
Чтобы написать собственный плагин для BILLmanager:
- выберите язык программирования;
- подготовьте окружение;
- определитесь со структурой плагина.
Выбор языка программирования
Для разработки плагинов для BILLmanager вы можете использовать любой язык программирования, как скриптовый, так и компилируемый. Рекомендуем:
- Python 3 — предпочтительный выбор. ISPsystem предоставляет SDK (Software Development Kit), упрощающий работу с:
- XML-данными;
- сессиями и параметрами запросов;
- базой данных;
- обработкой ошибок;
-
C++ — следует выбирать для задач, требующих:
- интеграции с ядром биллинга;
- работы в рамках одной транзакции с БД;
- использования API биллинга;
- высокой производительности.
При написании плагина на C++ вы можете использовать публичные заголовки платформы, что расширяет возможности функциональности.
Подготовка окружения
Чтобы подготовить окружение для создания плагина:
- Проверьте, что сервер соответствует требованиям к установке BILLmanager. Подробнее см. статью Требования к серверу.
- Установите платформу BILLmanager. Подробнее см. статью Процесс установки.
- Установите dev-пакеты в зависимости от используемой ОС:
Сервер с AlmaLinux 9sudo dnf install coremanager-devel billmanager-corporate-devel clangСервер с ОС Ubuntu, Astra Linuxsudo apt install coremanager-dev billmanager-corporate-devapt clang
Для комфортной работы с кодом рекомендуем настроить IDE. Например, для настройки Visual Studio Code (VS Code):
- Установите плагин Remote - SSH для удалённой разработки.
- Для Python: установите расширения Python и Pylance. Подробнее о настройках расширений см. в документации VS Code.
- Для C++: установите расширения:
- C/C++. Подробнее о настройках расширения см. в документации VS Code ;
- clangd. Подробнее см. документацию clangd .
- Настройте подключение к серверу с BILLmanager.
Структура плагина. Исходный код
Все плагины разрабатываются и хранятся в директории /usr/local/mgr5/src/. Используется система сборки на основе isp.mk, которая предоставляет:
- автоматическую установку файлов
make install; - очистку временных файлов
make clean; - автоматическую перезагрузку BILLmanager.
/usr/local/mgr5/src/<my_plugin>/
├── Makefile
├── README.md
├── dist/ (опционально, для SQL-скриптов и конфигурационных файлов)
├── xml/
│ └── <my_plugin>.xml
└── addon/ (для Python) или src/ (для C++)
└── <main_script_file>.py или <main_script_file>.cppГде:
Makefile— обязательный файл, который позволяет установить плагин с помощью команды:
make install
Команда make install автоматически копирует файлы в нужные директории:
-
- /usr/local/mgr5/addon/
- /usr/local/mgr5/lib/
- /usr/local/mgr5/xml/
и перезагружает BILLmanager;
dist— директория, содержащая файлы плагина. Например, SQL-скрипты или конфигурационные файлы;- <
my_plugin>.xml— название XML-файла, содержащего описание плагина. XML-файл описывает метаданные плагина и его взаимодействие с BILLmanager; - <
main_script_file> — название файла плагина. Например, myplugin.py или myplugin.cpp
Структура директории исходного кода плагина представлена далее на примерах для языков Python 3 и C++.
Makefile для Python-плагина
MGR=billmgr
PLUGIN=myplugin
dist-prepare: $(DISTDIR)/addon/myplugin.py
$(DISTDIR)/addon/myplugin.py: $(shell pwd)/myplugin.py
@echo "myplugin: copy script"
@mkdir -p $(DISTDIR)/addon/ && \
cp -rf $(shell pwd)/myplugin.py $(DISTDIR)/addon/myplugin.py && chmod 744 $(DISTDIR)/addon/myplugin.py
BASE ?= /usr/local/mgr5
include $(BASE)/src/isp.mkMakefile для C++-плагина
MGR=billmgr
PLUGIN=myplugin
LIB += libmyplugin
libmyplugin_LDADD = -lmgrdb -lispapi
libmyplugin_SOURCES = src/myplugin.cpp
BASE ?= /usr/local/mgr5
include $(BASE)/src/isp.mkОписание плагина в XML
Описание плагина хранится в XML-файле /usr/local/mgr5/xml/billmgr_mod_mypluginname.xml, где billmgr_mod_mypluginname.xml — название XML-файла, содержащего описание плагина.
<mgrdata>
<handler name="<myplugin>.py">
<event name="employee.edit" after="yes" type="xml" ignoreerrors="yes"/>
</handler>
<messages name="employee.edit">
<msg name="mood">Настроение</msg>
<msg name="mood_good">Хорошее</msg>
<!-- ... другие сообщения ... -->
</messages>
<form>
<field name="mood" type="select" after="name">
<option value="good">mood_good</option>
<!-- ... -->
</field>
</form>
</mgrdata>?xml version="1.0" encoding="UTF-8"?>
<mgrdata>
<library name="libmyplugin"/>
<metadata name="employee.edit" type="form">
<form title="name">
<page name="basic">
<field name="mood" before="name">
<select name="mood"/>
</field>
<field name="msg_to_boss" remove_if="new">
<textarea name="msg_to_boss" rows="5" wrap="on"/>
</field>
<field name="employee_active" remove_if="new">
<input name="employee_active" type="checkbox"/>
</field>
</page>
</form>
</metadata>
<lang name="ru">
<messages name="employee.edit">
<msg name="mood">Настроение</msg>
<msg name="mood_good">Хорошее</msg>
<!-- ... другие сообщения ... -->
</messages>
</lang>
</mgrdata>Особенности плагинов Python 3
Требования
Требования к плагинам на Python 3:
- плагин должен быть исполняемым;
- в ответ на вызов от BILLmanager плагин должен возвращать XML. Чтобы вывести XML в stdout, выполните:
result = ET.tostring(xml, encoding="unicode") print(result)
Значение поля type
Для Python SDK в BILLmanager не имеет значения, что указано в поле type, так как получение параметров всегда будет происходить одинаково. Однако, в зависимости от ваших целей, вы можете выбрать:
- если необходимо работать с метаданными действия —
type="xml"; - если требуется модифицировать данные —
type="cgi".
Независимо от type, параметры запроса доступны через:
func = session.get_query_param("func")
elid = session.get_query_param("elid")
sok = session.get_query_param("sok")Корректность ссылок
Используйте шебанг, чтобы гарантировать корректный запуск скрипта независимо от расположения интерпретатора Python в системе
#!/usr/bin/env python3 Порядок импортов
Придерживайтесь следующего порядка импортов:
- Модули, входящие в стандартную библиотеку Python или установленные глобально в системе (например, через pip): Пример импорта стандартных модулей
import xml.etree.ElementTree as ET import requests - Модуль
sysи добавление пути к SDK:Где /usr/local/mgr5/lib/python — путь к локального SDK биллинга. Необходим, чтобы были доступны последующие импорты из billmgr.import sys sys.path.insert(0, "/usr/local/mgr5/lib/python") - Импорты из SDK биллинга (billmgr.*) Пример импорта модулей SDK BILLmanager
import billmgr.logger as logging import billmgr.exception as exception import billmgr.session as session import billmgr.db as db import billmgr.misc as misc
Библиотеки модулей из SDK предоставляют функциональность для логирования, обработки ошибок, работы с XML-сессиями, базой данных и вспомогательными утилитами (например, mgrctl).
Инициализация логирования
Выполните инициализацию логирования:
logging.init_logging("myplugin")
logger = logging.get_logger("main")Лог будет доступен в файле /usr/local/mg5/var/myplugin.log.
Чтобы вывести в лог все параметры запроса (func, elid, sok и т.д), выполните команду:
session.debug_session(xml)Валидация XML
Чтобы BILLmanager всегда получал валидный XML, выполняйте основную логику в контексте блока try/except:
if __name__ == "__main__":
try:
result = process_event()
print(result)
except exception.XmlException as exc:
logger.backtrace()
print(exc.as_xml())
except Exception as exc:
logger.backtrace()
print(exception.XmlException("unknown", "what", str(exc)).as_xml())BILLmanager формирует XML-документ, описывающий форму, данные, метаданные и т.д. Документ передаётся плагину через стандартный ввод stdin. Чтобы его прочитать и распарсить, используйте:
xml = session.get_input_xml(True)Чтобы вывести в лог все параметры запроса (func, elid, sok и т.д), выполните команду:
session.debug_session(xml)Особенности плагинов C++
Порядок импортов
Придерживайтесь следующего порядка импортов:
- Заголовки стандартной библиотеки C++: Пример импорта стандартных заголовков
#include <sstream> - Заголовки внутренней платформы или фреймворка: общие модули api, mgr: Где:
#include <api/action.h> #include <mgr/mgrlog.h> #include <mgr/mgrdb_struct.h> #include <mgr/mgrrpc.h>api/action.h— определяет базовые классы для обработки событий в плагине, включаяEventиSession;mgr/mgrlog.h— предоставляет средства логирования через макросы. Например,Debug,WarningиSTrace;mgr/mgrdb_struct.h— содержит инструменты, которые описывают структуру таблиц базы данных. Такие сущности, как IdTable, StringField, ReferenceField позволяют связывать C++-классы с таблицами и полями в БД без написания SQL-запросов;mgr/mgrrpc.h— включает классHttpQuery, предназначенный для выполнения HTTP-запросов к внешним сервисам.
- Заголовки модулей биллинга (billmgr): Пример импорта заголовков модулей
#include <billmgr/db.h> #include <billmgr/util/http/status.h>
В примере выше заголовки модулей биллинга предоставляют доступ к базе данных, утилитам для проверки HTTP-статусов и др.
Инициализация плагина
Выполните инициализацию плагина, чтобы настроить логирование:
MODULE("myplugin");Лог сохранится в /usr/local/mgr5/var/billmgr.log. Уровень логирования для модуля можно настроить в файле /usr/local/mgr5/etc/debug.conf либо через интерфейс платформы. Подробнее о настройке логирования см. статью Логирование в BILLmanager.
Если плагину нужно хранить данные, опишите таблицу как C++-класс, наследуемый от mgr_db::IdTable:
class EmployeeMoodTable : public mgr_db::IdTable {
public:
mgr_db::ReferenceField User;
mgr_db::StringField Mood;
EmployeeMoodTable()
: mgr_db::IdTable("employee_mood")
, User(this, "user", mgr_db::rtCascade)
, Mood(this, "mood")
{
AddIndex(mgr_db::itIndex, Mood);
}
};В секции MODULE_INIT зарегистрируйте всё, что нужно при запуске:
MODULE_INIT(myplugincpp, "mgr:last") {
db->Register<plugin_table::EmployeeMoodTable>(); // Регистрация таблицы
isp_api::RegisterHandler<eEmployeeEdit>(); // Регистрация события
}Логирование
Рекомендуем использовать логирование на всех этапах разработки. Чтобы получать полный лог из плагина:
- Добавьте в файл /usr/local/mgr5/etc/debug.conf строку:
- при написании плагина на Python — billmgr.pluginname.* 9
- при написании плагина на C++ — billmgr. pluginname 9,
Где:
-
- pluginname — название плагина. Например, pluginname.py или pluginname.cpp
- 9 или *9 — максимальный уровень логирования. Чем выше уровень логирования, тем более подробная информация пишется в лог. Подробнее о настройке логирования см. статью Логирование в BILLmanager.
- Добавьте в плагин библиотеку для логирования с помощью одной из команд: Python
import billmgr.logger as loggingС++#include <mgr/mgrlog.h>
Связанные статьи:
Документация BILLmanager
Документация COREmanager