Плагины SOWA#
Плагин SOWA — это отдельное jar приложение, которое позволяет создавать отдельные сервисы в рамках профиля SOWA и управляемое конфигуратором Platform V SOWA, но при этом не входящее в ее дистрибутив и разрабатываемое прикладными командами.

Требования к взаимодействию плагина и Platform V SOWA#
Для взаимодействия плагина и Platform V SOWA предъявляются следующие требования:
плагин должен являться отдельным сервисом, он может стоять перед и/или за сервисами Platform V SOWA в рамках профиля, но не может использоваться без сервисов SOWA;
взаимодействие между сервисом плагина и сервисом SOWA происходит по usock;
формат взаимодействия — http.
Ограничения плагина#
ресурсы плагина находятся отдельно от ресурсов SOWA;
сервисы плагина запускаются под пользователем sowactl.
Требования к реализации плагина#
плагин должен поддерживать возможность использования сквозного (с SOWA) id запроса, под которым осуществляется логирование:
заголовок, в котором передается id, должен быть настраиваемым;
имя заголовка должно определяться в схеме сервиса параметром rqUidHeader;
заголовок должен передаваться при каждом запросе на SOWA (при взаимодействии SOWA → Plugin хедер также должен быть сгенерирован плагином);
формат значения заголовка должен соответствовать маске maxLength=32 и pattern=(-|[0-9]|[a-f]|[A-F]){32});
плагин должен реализовывать возможность access и error логов.
Структура плагина и расположение его артефактов#
Каталог с плагином должен иметь префикс «plugin_» и располагаться в директории /sowa/plugins/, например /sowa/plugins/plugin_<plugin_name>/.
В каталоге plugin_<plugin_name> необходимо расположить:
директорию lib, которая будет содержать jar-файлы: непосредственно сам плагин и необходимые для его работы библиотеки;
schema.yml — YAML схема с описанием сервиса, реализуемого плагином (в схеме при описании экземпляра сервиса обязательно указание поля «id» уникального идентификатора экземпляра сервиса в рамках профиля);
_init _.py — класс реализации интерфейса PluginInterface. Реализуемые методы будут вызываться конфигуратором для выполнения стандартных команд;
*.j2 — шаблон(ы) преобразования YAML-конфигурации плагина в конфигурационные файлы (например: файлы характеристик приложения, environment-файлы, а также настройки logger).
Одни плагин реализует один тип сервиса.
В качестве примера плагина приведен plugin_example.
В примере имеется исходный код плагина, а также необходимые артефакты для его сборки. Стоит обратить внимание, что в реальном плагине не рекомендуется хранить исходники.
Для корректной работоспособности плагина из примера необходимо самостоятельно установить следующие библиотеки: junixsocket-common, junixsocket-core, junixsocket-native-common, junixsocket-server, log4j-api, log4j-core, log4j-slf4j-impl, rawhttp-core, slf4j-api.
При конфигурировании профиля создается каталог /sowa/<profile_name>/, где располагается конфигурация всего профиля.
Плагин должен располагать свои артефакты, полученные в результате обработки шаблонов *.j2, в каталоге /sowa/<profile_name>/services/<service_name>_<profile_service_id>.
Внутри каждой директории (для каждого из экземпляров сервиса) должны располагаться:
файл service.properties — конфигурационный файл java приложения;
файл logger.properties — настройки logger приложения;
другие необходимые файлы для настройки экземпляра сервиса.
Логи всего профиля располагаются в /sowalogs/<profile_name>. Подробнее о логировании описано в разделе Системный журнал Руководства администратора.
Плагин должен располагать свои логи в /sowalogs/<profile_name>/services/<service_name>/<profile_service_id>.
Внутри каждой директории всегда есть:
<profile_service_id>_access.log — здесь в одной строке данные об одном запросе;
<profile_service_id>_error.log — подробные логи по всем запросам, например, app.log;
необязательная папка <profile_service_id> для логов evh , в ней:
4 необязательные дочерние папки: client_request, client_response, upstream_request, upstream_response, в каждой из которой файлы <request_id>.log. Подробнее о evh логах описано в разделе Транзакционные логи профиля Руководства по системному администрированию.
Структура логов сервисов плагина и параметры настройки должны соответствовать структуре логов и их настройки совы.
Плагин должен создавать .pid файл после полного запуска java-приложения#
После полного запуска java-процесса ожидается создание .pid файла по пути /sowarun/<profile_name> и соответствующего формату <service_name>_<profile_service_id>.pid, содержащего pid java-процесса.
Плагин должен предоставлять http endpoint, возвращающий статистику сервиса#
Плагин должен иметь http-endpoint с возможностью обращения к нему с использованием UNIX-сокетов. В шаблоне конфигурации сервисов, данный endpoint должен определяться путем объявления параметра statusEndpoint.
statusEndpoint: url
Например,
service_sowa_ipa:
- id: async_usock_kafka
statusEndpoint: http://unix:/sowarun/testProfile/async_usock_kafka/statusEndpoint.sock/status
URL endpoint должен формироваться динамически в момент конфигурирования профиля.
При обращении к данному endpoint должен возвращаться json-объект, содержащий статистику данного сервиса и соответствующий JSON-схеме:
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"active",
"inactive"
],
"description": "Return a current service specific status"
},
"overallStats": {
"$ref": "#/$defs/stats",
"description": "An object contains current service statistic"
},
"backends": {
"type": "array",
"description": "An object contains information about service backends",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of backend such configuration specified"
},
"address": {
"type": "string",
"description": "Address of backend such configuration specified"
},
"status": {
"type": "string",
"description": "A current status of specific backend",
"oneof": [
"active",
"inactive",
"drain"
]
},
"stats": {
"$ref": "#/$defs/stats"
}
},
"required": [
"name",
"address",
"status",
"stats"
]
}
}
},
"$defs": {
"stats": {
"type": "object",
"properties": {
"reqPrcCount": {
"type": "number",
"description": "Total count of processed request"
},
"errorCount": {
"type": "number",
"description": "Total error count of processed request"
},
"latencyWamMs": {
"type": "number",
"description": "A weighted average mean latency request processing throw this point (in milliseconds)"
},
"internalLatencyWamMs": {
"type": "number",
"description": "A weighted average mean latency request processing in this point (in milliseconds), without external communication"
},
"throughputWam": {
"type": "number",
"description": "A weighted average mean throughput request processing throw this point (in request/sec)"
},
"inBytes": {
"type": "number",
"description": "A total income count bytes received by this point"
},
"outBytes": {
"type": "number",
"description": "A total income count bytes returned from this point"
},
"inSpeedWam": {
"type": "number",
"description": "A weighted average mean receiving speed at this point (bytes/sec)"
},
"outSpeed": {
"type": "number",
"description": "A weighted average mean sent speed from this point (bytes/sec)"
},
"errorDistribution": {
"type": "array",
"description": "An error status distribution",
"items": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Status name",
"maxLength": 100
},
"count": {
"type": "number"
}
},
"required": [
"status",
"count"
]
}
}
},
"required": [
"reqPrcCount",
"errorCount",
"latencyWamMs",
"internalLatencyWamMs",
"throughputWam",
"inBytes",
"outBytes",
"inSpeedWam",
"outSpeed"
]
}
},
"required": [
"status",
"overallStats"
],
"additionalProperties": false
}
Описание свойств объекта приведено в таблице ниже:
Свойство |
Тип |
Возможные значения |
Обязательность |
Назначение |
|---|---|---|---|---|
status |
строка |
active/incative |
да |
Определяет текущее состояния - активный (может принимать запросы), неактивный - не может принимать запросы. |
overallStats |
объект |
- |
да |
Объект со статистической информацией. |
backends |
массив объектов |
- |
нет |
Массив элементов backend, содержащий информацию о внешних сервисах, с которыми взаимодействует данный интеграционный сервис. |
Объект overallStats имеет следующую структуру:
Свойство |
Тип |
Возможные значения |
Обязательность |
Назначение |
|---|---|---|---|---|
reqPrcCount |
number |
число большее или равное 0 |
да |
Содержит общее количество запросов, принятых и обработанных данным сервисом нарастающим итогом. Сброс значения в 0 происходит только в результате перезапуска сервиса. |
errorCount |
number |
число большее или равное 0 |
да |
Содержит общее количество ошибок, сгенерированных данным сервисом нарастающим итогом. Сброс значения в 0 происходит только в результате перезапуска сервиса. |
latencyWam |
number |
число большее или равное 0 |
да |
Средневзвешенное значение времени обработки запроса от момента установления соединения до момента отправки ответа. В качестве веса используется количество запросов на единицу времени с дискретизацией 100 мс, длина очереди запросов - 10. |
Методы, которые необходимо реализовать в init.py:
Метод |
Описание параметров |
Есть реализация по умолчанию |
Необходимо реализовать |
Комментарий |
|---|---|---|---|---|
init |
init |
Args: configurator: object: Объект класса configurator для доступа к публичным утилитарным функциям |
да, но только для вызова из потомка |
да |
name |
- |
да |
не обязательно, см. init |
Возвращает название плагина |
service |
- |
да |
не обязательно, см. init |
Возвращает название сервиса, реализуемого плагином |
version |
- |
да |
не обязательно, см. init |
Возвращает версию плагина |
config |
Args: |
нет |
да |
Обработка конфигурации плагина. Вызывается на этапе конфигурирования профиля. |
start_before |
Args: |
нет |
да |
Запуск сервисов плагина при запуске профиля до старта основных сервисов совы |
start_after |
Args: |
нет |
да |
Запуск сервисов плагина при запуске профиля после старта основных сервисов совы |
stop_before |
Args: |
нет |
да |
Остановка сервисов плагина при остановке профиля до остановки сервиса совы |
stop_after |
Args: |
нет |
да |
Остановка сервисов плагина при остановке профиля после остановки сервиса совы |
restart_before |
Args: |
нет |
да |
Рестарт сервисов плагина при рестарте профиля до рестарта сервиса совы |
restart_after |
Args: |
нет |
да |
Рестарт сервисов плагина при рестарте профиля после рестарта сервиса совы |
reload_before |
Args: |
нет |
да |
Релоад сервисов плагина при релоаде профиля до релоада сервиса совы |
reload_after |
Args: |
нет |
да |
Релоад сервисов плагина при релоаде профиля после релоада сервиса совы |
status |
Args: |
нет |
да |
Выполняется при просмотре статуса профиля. Отображение необходимой информации о работе плагина (pid, status, execution time) |
backup |
Args: |
нет |
да, можно pass |
В случае, если необходимы дополнительные действия по backup, помимо стандартного механизма совы, необходимо реализовать данные действия |
restore |
Args: |
нет да, можно pass |
В случае, если используется кастомный backup, необходимо реализовать восстановление из него |
|
status_endponit |
Args: |
нет |
да |
Возвращает endpoint сервиса, на котором располагается Health check + статистика сервиса |
cleanup |
Args: |
нет |
да |
Очистка артефактов сервиса |
getDestConfigDir |
Args: |
да |
нет |
Возвращает абсолютный путь до каталога с конфигурационными артефактами экземпляра сервиса (/sowa/…) |
getDestLogDir |
Args: |
да |
нет |
Возвращает абсолютный путь до каталога с логами экземпляра сервиса (/sowalogs/…) |
getDestTmpDir |
Args: |
да |
нет |
Возвращает абсолютный путь до каталога с временными файлами экземпляра сервиса (/sowarun/…) |
createDirStruct |
Args: |
да |
нет |
Создает в профиле необходимую структуру каталогов для экземпляра сервиса |
cleanPluginServices |
Args: |
нет |
да |
Очищает реестр сервисов плагина в профиле. Обертка над методом cleanPluginServices из класса PluginInterface |
addPluginService |
Args: |
да |
нет |
Добавляет в реестр сервисов профиля информацию об экземпляре сервиса. |
getPluginServices |
Args: |
да |
нет |
Возвращает список сконфигурированных сервисов плагина. Обертка над методом getPluginServices из класса PluginInterface |
getPluginServicesStartBefore |
Args: |
да |
нет |
Возвращает список сконфигурированных сервисов плагина с признаком «start before». Обертка над методом getPluginServicesStartBefore из класса PluginInterface |
getPluginServicesStartAfter |
Args: |
да |
нет |
Возвращает список сконфигурированных сервисов плагина с признаком «start after». Обертка над методом getPluginServicesStartAfter из класса PluginInterface |
getPluginServicesStopBefore |
Args: |
да |
нет |
Возвращает список сконфигурированных сервисов плагина с признаком «stop after». Обертка над методом getPluginServicesStopBefore из класса PluginInterface |
getPluginServicesStopAfter |
Args: |
да |
нет |
Возвращает список сконфигурированных сервисов плагина с признаком «stop after». Обертка над методом getPluginServicesStopAfter из класса PluginInterface |
startService |
Args: |
да |
нет |
Выполняет старт сервиса плагина. Обертка над методом unitAction из класса PluginInterface |
stopService |
Args: |
да нет |
Выполняет остановку сервиса плагина. Обертка над методом unitAction из класса PluginInterface |
|
restartService |
Args: |
да |
нет |
Выполняет рестарт сервиса плагина. Обертка над методами stopService и startService. |
serviceStatus |
Args: |
да |
нет |
Отображает состояние процесса сервиса. Обертка над методом unitAction из класса PluginInterface |
getPluginServiceID |
Args: |
да |
нет |
Возвращает порядковый номер из реестра сервисов, присвоенный при регистрации сервиса. Обертка над методом getPluginServiceID из класса PluginInterface |
addPidFile |
Args: |
да |
нет |
Создает pid-файл экземпляра сервиса по стандартному пути |
delPidFile |
Args: |
да |
нет |
Удаляет pid-файл экземпляра сервиса по стандартному пути |
addUsock |
Args: |
да |
нет |
Создает unix socket файл экземпляра сервиса по стандартному пути |
delUsock |
Args: |
да |
нет |
Удаляет unix socket файл экземпляра сервиса по стандартному пути |
logDebug |
message(str): сообщение в лог |
Добавляет cообщение в лог с определенным уровнем |
- |
|
getDirStruct |
- |
Возвращает объект со структурой директорий профиля и конфигуратора в целом |
- |
|
renderTemplate |
srcTemplate(str): путь к шаблону *.j2 |
Производит шаблонизацию по указанному шаблону |
Обязателен вызов со стороны плагина на этапе конфигурирования профиля |
|
__makedirs |
dirName |
да |
нет |
Функция создания произвольной директории профиля |
Методы для регистрации сервиса и его параметров в профиле
Метод |
Аргументы |
Описание |
Комментарий |
|---|---|---|---|
addPluginService |
profile_name (str): имя профиля |
Регистрирует сервис в реестре для обеспечения возможности управления сервисами на последующих этапах |
Обязателен вызов со стороны плагина на этапе конфигурирования профиля |
cleanPluginServices |
profile_name (str): имя профиля |
Отменяет регистрацию всех сервисов плагина в реестре |
Обязателен вызов со стороны плагина на этапе повторного конфигурирования профиля с последующим вызовом addPluginService. Также необходимы использовать в методе clean интерфейса. |
getPluginServices |
profile_name (str): имя профиля |
Возвращает список сконфигурированных сервисов плагина |
- |
getPluginServicesStartBefore |
profile_name (str): имя профиля |
Возвращает список сконфигурированных сервисов плагина с признаком «start before» |
- |
getPluginServicesStartAfter |
profile_name (str): имя профиля |
Возвращает список сконфигурированных сервисов плагина с признаком «start after» |
- |
getPluginServicesStopBefore |
profile_name (str): имя профиля |
Возвращает список сконфигурированных сервисов плагина с признаком «stop before» |
- |
getPluginServicesStopAfter |
profile_name (str): имя профиля |
Возвращает список сконфигурированных сервисов плагина с признаком «stop after» |
- |
getPluginServiceID |
profile_name (str): имя профиля |
Возвращает порядковый номер из реестра сервисов, присвоенный при регистрации сервиса |
- |
execCMD |
args (list): список аргументов в формате [«one», «two», «etc»] |
Выполнение команды |
Требуется наличие записи в sudoers для выполнения необходимой команды. Согласовывается с КБ. |
unitAction |
action(str): действие systemctl (start, stop, status) |
Выполняет указанное действие с systemctl |
Обязателен вызов со стороны плагина как минимум на этапах запуска и остановки профиля |
addPort |
profile_name(str): имя профиля |
Регистрирует в реестре порт для сервиса плагина в рамках профиля. Необходим для отслеживания и валидации используемых портов. |
Обязателен вызов со стороны плагина на этапе конфигурирования профиля в случае, если сервис плагина принимает входящее соединение на определенном порту |
delPort |
profile_name(str): имя профиля |
Удаляет порт из списка зарегистрированных для профиля в реестре |
Обязателен вызов со стороны плагина на этапе удаления профиля |