# MQTT to Zabbix Bridge

**MQTT to Zabbix Bridge** — это легковесное Java-приложение, которое подписывается на MQTT-топики, обрабатывает входящие сообщения и отправляет данные в Zabbix через протокол Trapper (используя утилиту `zabbix_sender`). Программа поддерживает гибкий маппинг топиков на элементы данных Zabbix, автоматическое переподключение к MQTT-брокеру, мониторинг собственного состояния и может быть запущена как systemd-сервис.

## Возможности

- **MQTT-подписка** — подписка на один или несколько топиков (поддерживаются wildcard-шаблоны `+` и `#`).
- **Гибкий маппинг** — сопоставление входящих топиков с хостами и ключами Zabbix с помощью регулярных выражений и подстановок (`$1`, `$2`…).
- **Извлечение значений** — из JSON-полей (по имени поля) или использование всего payload как значения.
- **Подписка на конкретные топики** — можно указать для каждого правила отдельный топик для подписки (если не указан, используется глобальный).
- **Автоматическое переподключение к MQTT** — при потере соединения выполняется повторное подключение с экспоненциальной задержкой.
- **Повторные попытки отправки в Zabbix** — при ошибках отправки данные повторяются до указанного числа раз с экспоненциальной задержкой.
- **Мониторинг работы программы** — каждые N секунд в Zabbix отправляются метрики: количество обработанных сообщений, ошибок, повторных попыток и размер очереди.
- **Валидация конфигурации при старте** — проверяются наличие `zabbix_sender`, обязательные параметры и корректность правил маппинга.
- **Блокировка двойного запуска** — предотвращает одновременный запуск нескольких экземпляров.
- **Поддержка systemd** — готовый unit-файл для запуска как сервиса с автоматическим перезапуском.
- **Внешняя конфигурация** — файлы `config.properties` и `mapping.json` могут лежать рядом с JAR-файлом или внутри него (для удобства изменения без пересборки).

## Требования

- **Java 11** или выше.
- **Maven** (для сборки).
- **Утилита `zabbix_sender`** должна быть установлена и доступна в `PATH` (обычно входит в пакет `zabbix-sender`). Используется для отправки данных.
- **MQTT-брокер** (например, Mosquitto, EMQX и др.).
- **Zabbix-сервер** (с настроенным trapper-портом, по умолчанию 10051).

## Установка и сборка

### 1. Клонирование репозитория

```bash
git clone https://gitbucket.mfnd.ru/git/y.varenkov/MQTT-to-Zabbix-Bridge.git
cd mqtt-to-zabbix
```

### 2. Сборка проекта

```bash
mvn clean package
```

В каталоге `target/` появится файл `mqtt-to-zabbix-1.0-SNAPSHOT-jar-with-dependencies.jar` — это самодостаточный JAR со всеми зависимостями.

### 3. Установка (опционально)

Скопируйте JAR и файлы конфигурации в рабочую директорию:

```bash
sudo mkdir -p /opt/mqtt-to-zabbix
sudo cp target/mqtt-to-zabbix-1.0-SNAPSHOT-jar-with-dependencies.jar /opt/mqtt-to-zabbix/
sudo cp src/main/resources/config.properties /opt/mqtt-to-zabbix/
sudo cp src/main/resources/mapping.json /opt/mqtt-to-zabbix/
```

Убедитесь, что `zabbix_sender` установлен:

```bash
sudo apt install zabbix-sender   # для Debian/Ubuntu
sudo yum install zabbix-sender   # для RHEL/CentOS
```

## Настройка

### Файл `config.properties`

Основные настройки приложения:

```properties
# MQTT Broker
mqtt.broker=tcp://localhost:1883
mqtt.topic=#                     # глобальный топик для подписки (используется, если не указан subscribeTopic в маппинге)
mqtt.user=
mqtt.password=

# Zabbix Trapper
zabbix.server=127.0.0.1
zabbix.port=10051

# Пул потоков
thread.pool.core=2
thread.pool.max=4
thread.pool.queue=1000

# Повторные попытки
retry.max.attempts=3
retry.initial.delay.ms=1000
retry.backoff.multiplier=2.0

# Мониторинг
metrics.host=MQTT-Bridge          # хост в Zabbix для метрик самой программы
metrics.interval=60               # интервал отправки метрик (секунд)
```

### Файл `mapping.json`

Определяет правила преобразования топиков в элементы Zabbix. Формат:

```json
[
  {
    "topicPattern": "sensors/temperature",
    "host": "Server1",
    "key": "temperature",
    "valueField": null,
    "subscribeTopic": "sensors/temperature"
  },
  {
    "topicPattern": "devices/([^/]+)/status",
    "host": "$1",
    "key": "status",
    "valueField": "state",
    "subscribeTopic": "devices/+/status"
  },
  {
    "topicPattern": "metrics/([^/]+)/([^/]+)",
    "host": "$1",
    "key": "$2",
    "valueField": "value"
  }
]
```

**Поля:**

- `topicPattern` — регулярное выражение для сопоставления с входящим MQTT-топиком. Может содержать группы, которые затем используются в `$1`, `$2`...
- `host` — имя хоста в Zabbix. Может содержать подстановки `$1`, `$2` из групп регулярного выражения.
- `key` — ключ элемента данных Zabbix. Аналогично поддерживает подстановки.
- `valueField` — имя поля в JSON, из которого берётся значение. Если `null` или отсутствует, используется весь payload как строка.
- `subscribeTopic` — (опционально) MQTT-топик для подписки. Если не указан, используется глобальный `mqtt.topic` из `config.properties` (или `#`). Можно указывать wildcard-символы `+` и `#`.

### Настройка элементов данных в Zabbix

Для каждого ключа, указанного в маппинге, необходимо создать элемент данных типа **Zabbix trapper** на соответствующем хосте. В поле **Разрешенные хосты** укажите IP-адрес, с которого будут приходить данные (например, `127.0.0.1`).

Для метрик мониторинга создайте хост `MQTT-Bridge` (или измените `metrics.host`) и элементы с ключами:

- `mqtt.bridge.processed` — количество обработанных сообщений (целое)
- `mqtt.bridge.errors` — количество ошибок обработки (целое)
- `mqtt.bridge.retries` — количество повторных попыток отправки (целое)
- `mqtt.bridge.queue_size` — текущий размер очереди задач (целое)

## Запуск

### Ручной запуск

```bash
java -jar /opt/mqtt-to-zabbix/mqtt-to-zabbix-1.0-SNAPSHOT-jar-with-dependencies.jar
```

Если файлы конфигурации лежат рядом с JAR, они будут загружены из файловой системы. Если нет — будут использованы встроенные (из classpath).

### systemd (рекомендуется для продакшена)

Создайте unit-файл `/etc/systemd/system/mqtt-to-zabbix.service`:

```ini
[Unit]
Description=MQTT to Zabbix Bridge
After=network.target zabbix-server.service
Wants=zabbix-server.service

[Service]
Type=simple
User=zabbix
Group=zabbix
WorkingDirectory=/opt/mqtt-to-zabbix
ExecStart=/usr/bin/java -jar /opt/mqtt-to-zabbix/mqtt-to-zabbix-1.0-SNAPSHOT-jar-with-dependencies.jar
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=mqtt-to-zabbix

[Install]
WantedBy=multi-user.target
```

После создания выполните:

```bash
sudo systemctl daemon-reload
sudo systemctl enable mqtt-to-zabbix
sudo systemctl start mqtt-to-zabbix
```

Проверьте статус:

```bash
sudo systemctl status mqtt-to-zabbix
```

Логи можно просматривать через:

```bash
sudo journalctl -u mqtt-to-zabbix -f
```

## Примеры работы

### Пример MQTT-сообщения (JSON)

**Топик:** `devices/room1/temperature`  
**Payload:** `{"value":23.5, "timestamp":"2026-07-10T14:30:00Z"}`

**Правило:**
```json
{
  "topicPattern": "devices/([^/]+)/temperature",
  "host": "$1",
  "key": "temperature",
  "valueField": "value",
  "subscribeTopic": "devices/+/temperature"
}
```

**Результат:** В Zabbix для хоста `room1` элемент с ключом `temperature` получит значение `23.5`.

### Пример MQTT-сообщения (просто число)

**Топик:** `sensors/temperature`  
**Payload:** `20`

**Правило:**
```json
{
  "topicPattern": "sensors/temperature",
  "host": "Server1",
  "key": "temp",
  "valueField": null,
  "subscribeTopic": "sensors/temperature"
}
```

**Результат:** В Zabbix для хоста `Server1` элемент `temp` получит значение `20`.

## Логирование и диагностика

Программа выводит подробные логи в консоль (или `journalctl` при использовании systemd). Основные события:

- Получение MQTT-сообщения
- Обработка по правилу или legacy-режим
- Отправка через `zabbix_sender`
- Повторные попытки и ошибки
- Отправка метрик мониторинга

## Архитектура и принцип работы

1. **Загрузка конфигурации** — читается `config.properties` и `mapping.json`.
2. **Валидация** — проверяется наличие `zabbix_sender`, корректность параметров.
3. **Подключение к MQTT** — устанавливается соединение с брокером, подписка на топики (из маппинга или глобальный).
4. **Обработка сообщений** — каждое сообщение обрабатывается в отдельном потоке из пула. Поиск подходящего правила, извлечение host, key и value, отправка в Zabbix с повторными попытками.
5. **Переподключение** — при разрыве соединения запускается фоновый поток, который пытается восстановить связь с экспоненциальной задержкой.
6. **Мониторинг** — периодически отправляются метрики работы в Zabbix.
7. **Завершение** — при остановке программы (Ctrl+C или systemd) корректно закрываются все ресурсы.

## Лицензия

Этот проект распространяется под лицензией MIT. Подробнее см. файл LICENSE.

