Обработчик управления устройством

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

Uptime и обнаружение перезагрузки устройства

На текущий момент главной функцией обработчика является получение текущего uptime устройства. Uptime необходим для определения перезагрузки устройства, чтобы при наступлении такого события Access мог синхронизировать заново все сервисы на этом устройстве.

В конфигурации типа устройства (или в самом устройстве) можно задать параметры выполнения команд:

# Пауза между выполнением команды после ошибки
#manage.error.pause=5
# Пауза между получением uptime
#manage.uptime.pause=120
# Пауза после ошибки, возникшей при получении uptime
#manage.uptime.error.pause=120

С модулем Inet поставляется динамический класс ru.bitel.bgbilling.modules.inet.dyn.device.snmp.SnmpDeviceManager, у него реализован метод uptime, который по SNMP у устройства получает его текущий uptime в секундах.

# Хост для отправки SNMP-запросов (по умолчанию хост, заданный в параметрах устройства Хост/порт)
#snmp.host=
# Порт для отправки SNMP-запросов (по умолчанию 161)
#snmp.port=
# Версия SNMP (по умолчанию 1)
#snmp.version=
# Сommunity (по умолчанию из параметра устройства Сommunity/Secret)
#snmp.community=public
# SNMP OID, из которого извлекается значение uptime (1.3.6.1.2.1.1.3.0)
#snmp.uptimeOid=1.3.6.1.2.1.1.3.0

После привязки обработчика управления устройством с реализованным методом uptime, все устройства с периодичностью manage.uptime.pause будут опрашиваться на время работы после перезагрузки. Для того, чтобы при определении очередной перезагрузки устройства Access выполнил синхронизацию сервисов, в конфигурации типа устройства (или в устройстве) необходимо прописать:

# Синхронизировать ли сервисы при обнаружении перезагрузки, 0 - не синхронизировать (по умолчанию), 1 - синхронизировать
# (для обнаружения перезагрузки в типе устройства должен быть установлен обработчик управления устройством)
#sa.device.sync.onReboot=1
# Вызывать ли при синхронизации для каждого сервиса, 0 - только serviceCreate или 1 (по умолчанию) -
# сначала serviceCancel, а затем serviceCreate
#sa.device.sync.cancelBeforeCreate=1

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

Также еще ест специальный метод, который вызывается при перезагрузке:

/**
* Метод вызывается при обнаружении перезагрузки устройства.
* @param e
* @return
* @throws Exception
*/
public Object onReboot( InetDeviceManageEvent e )
{
return null;
}

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

Выполнение команд

В контекстном меню дерева устройств доступен пункт выполнить команду. Данный пункт вызывает метод у Обработчика управления устройством (DeviceManager), указанном в типе устройства. Таким методом, в том числе, является uptime() из ru.bitel.bgbilling.modules.inet.dyn.device.snmp.SnmpDeviceManager, хотя нужен он не для ручного вызова из контекстного меню.

@Override
public Object uptime()
throws Exception
{
return snmpClient.get( uptimeOid, -1, Long.class );
}

Команды-методы можно именовать с помощью аннотации ru.bitel.oss.systems.inventory.resource.server.DeviceManagerMethod, в этом случае они будут сразу доступны в контекстном меню:

import ru.bitel.oss.systems.inventory.resource.server.DeviceManagerMethod;
 
@DeviceManagerMethod(title = "Перезагрузить")
public Object reboot()
throws Exception
{
return return snmpClient.set( new AsnObjectId( "1.2.3.4.5.6.7.8.9" ).getOid(), -1, Long.class );
}

После или вместо выполнения можно вернуть строку определенного вида, чтобы клиент биллинга попытался открыть браузер с указанным URL:

@DeviceManagerMethod(title = "Статус")
public Object status()
throws Exception
{
return "browse:http://google.ru";
}

Или окно с подключением по telnet:

@DeviceManagerMethod(title = "Telnet")
public Object telnet()
throws Exception
{
return "telnet:google.ru 80";
}

Как аргумент в методе можно указать ru.bitel.bgbilling.modules.inet.access.manage.event.InetDeviceManageEvent, чтобы узнать, например, userId пользователя, выполняющего команду:

import ru.bitel.bgbilling.modules.inet.access.manage.event.InetDeviceManageEvent;
 
@DeviceManagerMethod(title = "Telnet")
public Object telnet2( InetDeviceManageEvent e )
throws Exception
{
logger.info( e.getUserId() );
return "telnet:google.ru 80";
}

Пример:

package ru.provider.bgbilling.modules.inet.dyn.device;
 
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.ParameterMap;
import ru.bitel.oss.systems.inventory.resource.common.DeviceManagerMethodType;
import ru.bitel.oss.systems.inventory.resource.common.bean.Device;
import ru.bitel.oss.systems.inventory.resource.common.bean.DeviceType;
import ru.bitel.oss.systems.inventory.resource.server.DeviceManagerMethod;
 
public class SnmpDeviceManager
extends ru.bitel.bgbilling.modules.inet.dyn.device.snmp.SnmpDeviceManager
{
protected ParameterMap deviceConfig;
 
@Override
public Object init( Setup setup, int moduleId, Device<?, ?> device, DeviceType deviceType, ParameterMap deviceConfig )
{
super.init( setup, moduleId, device, deviceType, deviceConfig );
 
this.deviceConfig = deviceConfig;
 
return null;
}
 
@DeviceManagerMethod(title = "Монитор", types = { DeviceManagerMethodType.DEVICE, DeviceManagerMethodType.ACCOUNT })
public Object monitor()
{
return "browse:" + deviceConfig.get( "monitor.url", "http://zabbix.intranet.provider.ru/latest.php?hostid=$monitorHostId" )
.replaceAll( "\\$monitorHostId", deviceConfig.get( "monitor.hostId", "" ) );
}
 
@DeviceManagerMethod(title = "Telnet")
public Object telnet()
{
return "telnet:" + deviceConfig.get( "telnet.host", this.host ) + " " + deviceConfig.getInt( "telnet.port", 23 );
}
}

Без SNMP/uptime:

package ru.provider.bgbilling.modules.inet.dyn.device;
 
import java.util.List;
 
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.ParameterMap;
import ru.bitel.oss.systems.inventory.resource.common.DeviceManagerMethodType;
import ru.bitel.oss.systems.inventory.resource.common.bean.Device;
import ru.bitel.oss.systems.inventory.resource.common.bean.DeviceType;
import ru.bitel.oss.systems.inventory.resource.server.DeviceManagerAdapter;
import ru.bitel.oss.systems.inventory.resource.server.DeviceManagerMethod;
 
public class DeviceManager
extends DeviceManagerAdapter
implements ru.bitel.oss.systems.inventory.resource.server.DeviceManager
{
protected ParameterMap deviceConfig;
 
protected String host;
 
@Override
public Object init( Setup setup, int moduleId, Device<?, ?> device, DeviceType deviceType, ParameterMap deviceConfig )
throws Exception
{
super.init( setup, moduleId, device, deviceType, deviceConfig );
 
this.deviceConfig = deviceConfig;
 
final List<String[]> hosts = device.getHostsAsString();
final String[] host = (hosts != null && hosts.size() > 0) ? hosts.get( 0 ) : null;
 
this.host = deviceConfig.get( "snmp.host", host != null ? host[0] : device.getHost() );
 
return null;
}
 
@DeviceManagerMethod(title = "Монитор", types = { DeviceManagerMethodType.DEVICE, DeviceManagerMethodType.ACCOUNT })
public Object monitor()
{
return "browse:" + deviceConfig.get( "monitor.url", "http://zabbix.intranet.provider.ru/latest.php?hostid=$monitorHostId" )
.replaceAll( "\\$monitorHostId", deviceConfig.get( "monitor.hostId", "" ) );
}
 
@DeviceManagerMethod(title = "Telnet")
public Object telnet()
{
return "telnet:" + deviceConfig.get( "telnet.host", this.host ) + " " + deviceConfig.getInt( "telnet.port", 23 );
}
}

DeviceManagerMethodType.ACCOUNT в types означает, что пункт будет доступен на вкладке сервисов договора, в контестном меню сервиса, если сервис привязан к устройству данного типа.