Конвертер: шлюзы(в устройства INET), ip-реcурсы, типы правил(в опции INET), привязку договоров к шлюзам(в сервисы Inet).Схема dhcp-mikrotik-dlink/mirotik
Материал из BiTel WiKi
Stark (Обсуждение | вклад) (Новая страница: «Было такая схема шлюзов в IPN. 1) DHCP-Папка-Dlink 2) Просто шлюз mikrotik На самом деле папка это факти…») |
Simpl3x (Обсуждение | вклад) |
||
(10 промежуточных версий не показаны.) | |||
Строка 1: | Строка 1: | ||
+ | == Схема подключения в IPN == | ||
Было такая схема шлюзов в IPN. | Было такая схема шлюзов в IPN. | ||
- | |||
- | |||
- | + | 1) Иерархия шлюзов: | |
- | + | DHCP-Папка-Dlink и отдельный Mikrotik(без родителя). | |
- | + | ||
- | + | ||
+ | На самом деле папка это фактически по иерархии является шлюзом mikrotik(папка - это район город, а на район приходится один Mikrotik) , но в случае dhcp Dlink такую иерархию не получалось выстроить в IPN .Поэтому Mikrotik был ванесен отдельно. На каждый договор подключался шлюз Mikrotik , чтобы управлять доступом клиента (добавлять/удалять ip на mikrotik) и управлять скоростью . И Dlink чтобы управлять портом клиента и выдавать Ip по dhcp на порту по option 82. На договоре добавлен адрес(как часть диапазон), он выбран на mikrotik , для него хранится привязка к порту на dlink-е. | ||
+ | 2) Просто шлюз mikrotik(без родителя). Т.е некоторые абоненты были просто напрямую подключены к mikrotik. | ||
- | + | На договор добавлен диапазон адресов, он привязан mikrotik. | |
- | + | ||
- | + | ||
+ | == Схема подключения в Inet == | ||
+ | При переносе этой схемы в Inet получилось: | ||
- | + | 1) Иерархия устройств: | |
+ | Access+Accounting-mikrotik-Dlink | ||
- | + | На договор добавлен сервис Dlink, его привязывают устройству Dlink, и заводят на нем ip-адрес и порт. | |
- | + | 2) Иерархия устройств: | |
+ | Access+Accounting-mikrotik | ||
+ | На договор добавлен сервис Mikrotik, его привязывают устройству mikrotik и заводят на нем диапазон адресов. | ||
+ | |||
+ | == Управление оборудованием == | ||
+ | Изначально для Шлюза mikrotik использовался скрипт подобный вот этому : | ||
+ | http://wiki.bgbilling.ru/index.php/%D0%A8%D0%BB%D1%8E%D0%B7_Mikrotik,_%D0%BE%D1%82%D1%80%D0%B0%D0%B1%D0%B0%D1%82%D1%8B%D0%B2%D0%B0%D1%8E%D1%89%D0%B8%D0%B9_%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB_%D0%BD%D0%B0_%D0%B4%D0%BE%D0%B3%D0%BE%D0%B2%D0%BE%D1%80%D0%B5 | ||
+ | |||
+ | |||
+ | Для него в inet получился вот такой обработчик активации сервисов: | ||
+ | |||
+ | http://wiki.bgbilling.ru/index.php/%D0%9E%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%87%D0%B8%D0%BA_%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%B0%D1%86%D0%B8%D0%B8_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B4%D0%BB%D1%8F_Mikrotik_c_%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8_%D1%81%D0%BA%D0%BE%D1%80%D0%BE%D1%81%D1%82%D0%B8 | ||
+ | |||
+ | |||
+ | Для Шлюза Dlink использовался скрипт подобный вот этому: | ||
+ | http://wiki.bgbilling.ru/index.php/%D0%A0%D0%B5%D0%B0%D0%BB%D0%B8%D0%B0%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B2%D0%B3%D0%BE_%D1%88%D0%BB%D1%8E%D0%B7%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BC%D1%83%D1%82%D0%B0%D1%82%D0%BE%D1%80%D0%BE%D0%B2_DES-3526,_DES-3550,_DES-3828,_DES-3852,_DGS-3200-10_%D0%B8_%D0%B8%D0%BC_%D0%BF%D0%BE%D0%B4%D0%BE%D0%B1%D0%BD%D1%8B%D1%85 | ||
+ | |||
+ | Для него в inet получился вот такой обработчик активации сервисов: | ||
+ | |||
+ | http://wiki.bgbilling.ru/index.php/%D0%A0%D0%B5%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D0%BE%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%87%D0%B8%D0%BA%D0%B0_%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%B0%D1%86%D0%B8%D0%B8_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D0%BE%D0%B2_%D0%B4%D0%BB%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BC%D1%83%D1%82%D0%B0%D1%82%D0%BE%D1%80%D0%BE%D0%B2_DES-3526,_DES-3550,_DES-3828,_DES-3852,_DGS-3200-10_%D0%B8_%D0%B8%D0%BC_%D0%BF%D0%BE%D0%B4%D0%BE%D0%B1%D0%BD%D1%8B%D1%85 | ||
+ | |||
+ | |||
+ | == Настройка == | ||
+ | |||
+ | 1) Создаем тип сервиса Dlink | ||
+ | |||
+ | <source lang="bash"> | ||
+ | Тип инициации : по сигналу | ||
+ | тип адреса: статический адрес | ||
+ | привязка типов трафика : <Некоторая привязка, которую нужно создать > | ||
+ | Интрерфейс:Да | ||
+ | Устройство:Да | ||
+ | Интерфейс персонален:Да | ||
+ | </source> | ||
+ | |||
+ | Конфигурация: | ||
+ | <source lang="java"> | ||
+ | # Шаблон имени сервиса | ||
+ | title.pattern=интернет : (${addressRange}) : (${interfaceId}) | ||
+ | </source> | ||
+ | |||
+ | |||
+ | |||
+ | 2) Создаем тип сервиса Mikrotik | ||
+ | <source lang="bash"> | ||
+ | Тип инициации : по трафику | ||
+ | тип адреса: статический диапазон | ||
+ | привязка типов трафика : <Некоторая привязка, которую нужно создать > | ||
+ | Устройство:Да | ||
+ | Интерфейс персонален:Да | ||
+ | </source> | ||
+ | |||
+ | Конфигурация: | ||
+ | <source lang="java"> | ||
+ | # Шаблон имени сервиса | ||
+ | title.pattern=интернет : (${addressRange}) : (${interfaceId}) | ||
+ | </source> | ||
+ | |||
+ | |||
+ | 3) Создаем тип устройства Dlink | ||
+ | |||
+ | Конфигурация : | ||
+ | |||
+ | <source lang="bash"> | ||
+ | dhcp.deviceSearchMode=2 | ||
+ | dhcp.servSearchMode=1 | ||
+ | # Код субопции 82, содержащей интерфейс, позиция и длина в субопции | ||
+ | dhcp.option82.interfaceId.code=1 | ||
+ | dhcp.option82.interfaceId.position=5 | ||
+ | dhcp.option82.interfaceId.length=1 | ||
+ | dhcp.disable.mode=1 | ||
+ | #Uplink - порты uplink-и, используются в Обработчике активации сервисов. | ||
+ | uplink=25,26,27,28 | ||
+ | #Открытый адрес при закрытом договоре, например адрес сервера статистики. | ||
+ | open.address=172.31.0.254 | ||
+ | |||
+ | dhcp.option.serverIdentifier=172.31.0.254 | ||
+ | dhcp.option.leaseTime=43200 | ||
+ | ###Сети | ||
+ | dhcp.net.option.172.168.184.0:255.255.0.0.gate=172.168.184.253 | ||
+ | dhcp.net.option.172.168.185.0:255.255.0.0.dns=172.168.184.253 | ||
+ | dhcp.net.option.1172.168.184.0:255.255.0.0.subnetMask=255.255.0.0 | ||
+ | dhcp.net.option.172.168.184.0:255.255.0.0.domainName=example.info | ||
+ | |||
+ | </source> | ||
+ | |||
+ | 4) Создаем тип устройства Mikrotik | ||
+ | |||
+ | Конфигурация : | ||
+ | |||
+ | <source lang="bash"> | ||
+ | flow.agent.type=netflow | ||
+ | flow.agent.link={@deviceId}:-1 | ||
+ | </source> | ||
+ | |||
+ | 5) Создаем тип устройства Access+Accounting | ||
+ | |||
+ | Конфигурация : | ||
+ | |||
+ | <source lang="bash"> | ||
+ | dhcp.relay.deviceTypeIds=3 | ||
+ | dhcp.xid=0 | ||
+ | |||
+ | # Количество потоков на worker'а | ||
+ | dhcp.xid=0 | ||
+ | accounting.worker.1.thread.count=1 | ||
+ | # Тарификатор: | ||
+ | # минимальная сумма трафика, при которой тарифицировать соединение | ||
+ | accounting.worker.1.tariffication.1.minDeltaAmount=0 | ||
+ | # пауза между заданиями тарификации | ||
+ | accounting.worker.1.tariffication.1.delay=10 | ||
+ | # максимальное количество тарифицируемых соединений за задание | ||
+ | accounting.worker.1.tariffication.1.batchSize=100 | ||
+ | # Трекер (обработка сессий без наработки): | ||
+ | # пауза между заданиями трекинга | ||
+ | accounting.worker.1.tracking.1.delay=20 | ||
+ | # максимальное количество проверенных соединений за задание | ||
+ | accounting.worker.1.tracking.1.batchSize=100 | ||
+ | |||
+ | # Количество потоков на worker'а | ||
+ | accounting.worker.2.thread.count=1 | ||
+ | # Сброс в базу трафиков и наработки: | ||
+ | # минимальная наработка, при которой сбрасывать соединение в базу | ||
+ | accounting.worker.2.flushing.1.minDeltaAccount=0 | ||
+ | # минимальная сумма трафика, при которой сбрасывать соединение в базу | ||
+ | accounting.worker.2.flushing.1.minDeltaAmount=0 | ||
+ | # пауза между заданиями сброса в базу | ||
+ | accounting.worker.2.flushing.1.delay=20 | ||
+ | # максимальное количество сброшенных соединений в базу за задание | ||
+ | accounting.worker.2.flushing.1.batchSize=500 | ||
+ | |||
+ | # Количество потоков на worker'а | ||
+ | accounting.worker.3.thread.count=1 | ||
+ | # Завершатель соединений: | ||
+ | # пауза между заданиями | ||
+ | accounting.worker.3.finishing.1.delay=20 | ||
+ | # максимальное количество сброшенных соединений в базу за задание | ||
+ | accounting.worker.3.finishing.1.batchSize=500 | ||
+ | # При выдаче access-accept добавлять запись в базу; | ||
+ | # необходимо, если используется reject-to-accept и по старт пакету нельзя определить в каком состоянии соединение | ||
+ | #connection.start.fromAccept=0 | ||
+ | # При создании сессии по update пакету, 0 - не создавать сессии без старт пакета, 1 - создать сессию от текущего момента, | ||
+ | # 2 - создавать сессию от реального времени начала, если время сессии не больше connection.close.timeout | ||
+ | #connection.start.fromUpdate=1 | ||
+ | |||
+ | # Таймаут перевода соединения в статус suspended при остутствии радиус пакетов | ||
+ | connection.suspend.timeout=900 | ||
+ | # Таймаут перевода соединения в статус suspended при остутствии радиус пакетов для сессии в состоянии отключен | ||
+ | # (по умолчанию используется значение connection.suspend.timeout) | ||
+ | connection.disable.suspend.timeout=900 | ||
+ | # Таймаут закрытия соединения при остутствии радиус-пакетов или, для сессий, создаваемых по наличии трафика, при отсутствии flow пакетов | ||
+ | # (не складывается с connection.suspend.timeout) | ||
+ | connection.close.timeout=1300 | ||
+ | # Таймаут закрытия соединения при остутствии радиус-пакетов или, для сессий, создаваемых по наличии трафика, при отсутствии flow пакетов, | ||
+ | # в состоянии отключен (не складывается с connection.disable.suspend.timeout, по умолчанию используется значение connection.close.timeout) | ||
+ | connection.disable.close.timeout=1300 | ||
+ | # Таймаут завершения закрытой сессии | ||
+ | connection.finish.timeout=5 | ||
+ | |||
+ | # Нужно ли логически разрывать сессию при переключении состояния | ||
+ | session.split.onDeviceState=0 | ||
+ | # Нужно ли логически разрывать сессию при активации или деактивации тарифной опции | ||
+ | session.split.onTariffOption=1 | ||
+ | </source> | ||
+ | |||
+ | 6) Создаем Головное устройство Access+Accounting в дереве устройства | ||
+ | |||
+ | 7) Далее запуск конвертера (после его настройки т.п ) создаст иерархию устройств | ||
+ | |||
+ | Access+Accounting ->Mikrotik->Dlink | ||
+ | |||
+ | в дереве устройств. | ||
+ | |||
+ | Для шлюза mikrotik будет указан хост/порт в формате хост:порт, логин, пароль . В конфигурации будет проставлена настройка вида: | ||
+ | |||
+ | <source lang="bash"> | ||
+ | ip.resource.categoryId=14,21,3,2 | ||
+ | </source> | ||
+ | |||
+ | Для шлюза dlink будет указан хост/порт в формате хост:порт, логин, пароль,секрет . | ||
+ | |||
+ | == Конвертация данных == | ||
Конвертер это глобальный скрипт поведения . Он работает так | Конвертер это глобальный скрипт поведения . Он работает так | ||
1) Для каждого шлюза IPN в inet ищется устройство с таким же ip, если на найдено, то создается новое. Параметры устройства обновляются. | 1) Для каждого шлюза IPN в inet ищется устройство с таким же ip, если на найдено, то создается новое. Параметры устройства обновляются. | ||
+ | |||
2) Для каждой категории ip-ресурсов IPN ищется категория с таким-же именем в INET. Если не найдена, то создается. Потом в ней удаляются все ресурсы и добавляются заново. | 2) Для каждой категории ip-ресурсов IPN ищется категория с таким-же именем в INET. Если не найдена, то создается. Потом в ней удаляются все ресурсы и добавляются заново. | ||
+ | |||
3) Для каждого типа правила в IPN ищется опция с таким-же именем в INET. Если не найдена, то создается. | 3) Для каждого типа правила в IPN ищется опция с таким-же именем в INET. Если не найдена, то создается. | ||
+ | |||
4) Удаляются все сервисы с договоров (кроме исключающих групп договоров) . | 4) Удаляются все сервисы с договоров (кроме исключающих групп договоров) . | ||
- | 5) На каждом договоре берутся все действующие ip из IPN(диапазон дробится ) и для каждого ip, ищется порт в настройках dlink и для каждого найденного порта создается сервис Dlink с этим ip и портом. Если ip не привязан к | + | |
+ | 5) На каждом договоре берутся все действующие ip из IPN(диапазон дробится ) и для каждого ip, ищется порт в настройках шлюза dlink и для каждого найденного порта создается сервис Dlink с этим ip и портом. Если ip не привязан к dlink, то ищется привязка к шлюзу mikrotik и если найдена ,то создается сервис mikrotik. Если что-то не нашло (dlink/порт и mikrotik) , то ругается в лог и не создает сервис. | ||
+ | |||
+ | Код конвертера: | ||
+ | <source lang="java"> | ||
+ | package ru.gigacom.inet.dyn.convert; | ||
+ | |||
+ | import java.sql.Connection; | ||
+ | import java.sql.PreparedStatement; | ||
+ | import java.sql.ResultSet; | ||
+ | import java.sql.SQLException; | ||
+ | import java.util.ArrayList; | ||
+ | import java.util.Collection; | ||
+ | import java.util.Collections; | ||
+ | import java.util.Date; | ||
+ | import java.util.HashMap; | ||
+ | import java.util.HashSet; | ||
+ | import java.util.List; | ||
+ | import java.util.Map; | ||
+ | import java.util.Set; | ||
+ | |||
+ | import org.apache.log4j.Logger; | ||
+ | |||
+ | import ru.bitel.bgbilling.common.BGException; | ||
+ | import ru.bitel.bgbilling.kernel.container.managed.ServerContext; | ||
+ | import ru.bitel.bgbilling.kernel.contract.api.common.event.ContractModifiedEvent; | ||
+ | import ru.bitel.bgbilling.kernel.event.EventProcessor; | ||
+ | import ru.bitel.bgbilling.kernel.module.common.bean.User; | ||
+ | import ru.bitel.bgbilling.kernel.script.server.dev.GlobalScriptBase; | ||
+ | import ru.bitel.bgbilling.modules.inet.api.common.bean.InetDevice; | ||
+ | import ru.bitel.bgbilling.modules.inet.api.common.bean.InetDeviceType; | ||
+ | import ru.bitel.bgbilling.modules.inet.api.common.bean.InetOption; | ||
+ | import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServ; | ||
+ | import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServOption; | ||
+ | import ru.bitel.bgbilling.modules.inet.api.common.service.InetDeviceService; | ||
+ | import ru.bitel.bgbilling.modules.inet.api.common.service.InetServService; | ||
+ | import ru.bitel.bgbilling.modules.ipn.common.bean.AddressRange; | ||
+ | import ru.bitel.bgbilling.modules.ipn.server.bean.AddressRangeManager; | ||
+ | import ru.bitel.bgbilling.modules.ipn.server.bean.GateFilter; | ||
+ | import ru.bitel.bgbilling.server.util.ModuleSetup; | ||
+ | import ru.bitel.bgbilling.server.util.Setup; | ||
+ | import ru.bitel.common.Preferences; | ||
+ | import ru.bitel.common.Utils; | ||
+ | import ru.bitel.common.sql.ConnectionSet; | ||
+ | import ru.bitel.oss.systems.inventory.resource.common.ResourceService; | ||
+ | import ru.bitel.oss.systems.inventory.resource.common.bean.Device; | ||
+ | import ru.bitel.oss.systems.inventory.resource.common.bean.IpCategory; | ||
+ | import ru.bitel.oss.systems.inventory.resource.common.bean.IpResource; | ||
+ | import bitel.billing.common.IPUtils; | ||
+ | import bitel.billing.common.TimeUtils; | ||
+ | import bitel.billing.common.module.ipn.IPNContractStatus; | ||
+ | import bitel.billing.server.admin.resource.bean.IPResourceCategory; | ||
+ | import bitel.billing.server.admin.resource.bean.IPResourceCategoryManager; | ||
+ | import bitel.billing.server.admin.resource.bean.ip.IPResourceRange; | ||
+ | import bitel.billing.server.contract.bean.ContractModuleManager; | ||
+ | import bitel.billing.server.ipn.bean.Gate; | ||
+ | import bitel.billing.server.ipn.bean.GateManager; | ||
+ | import bitel.billing.server.ipn.bean.IPNContractStatusManager; | ||
+ | import bitel.billing.server.ipn.bean.IPNResourceManager; | ||
+ | import bitel.billing.server.ipn.bean.RuleType; | ||
+ | import bitel.billing.server.ipn.bean.RuleTypeManager; | ||
+ | import bitel.billing.server.ipn.bean.UserGateRule; | ||
+ | import bitel.billing.server.ipn.bean.UserGateRuleManager; | ||
+ | |||
+ | |||
+ | public class ConvertFromIPNToInet | ||
+ | extends GlobalScriptBase | ||
+ | { | ||
+ | |||
+ | //код модуля IPN | ||
+ | private static int IPN_MODULE_ID = 1; | ||
+ | //тип шлюза микротик в IPN | ||
+ | private static int IPN_MIKROTIK_GATE_TYPE_ID = 3; | ||
+ | //тип шлюза dlink в IPN | ||
+ | private static int IPN_DLINK_GATE_TYPE_ID = 10; | ||
+ | |||
+ | //код модуля Inet | ||
+ | private static int INET_MODULE_ID = 20; | ||
+ | |||
+ | //код модуля Inet | ||
+ | private static int INET_DLINK_DEVICE_TYPE_ID = 3; | ||
+ | |||
+ | //код модуля Inet | ||
+ | private static int INET_MIKROTIK_DEVICE_TYPE_ID = 2; | ||
+ | //код корня дерева устройств (устойство access+accountig в модуле Inet) | ||
+ | private static int INET_ROOT_DEVICE_ID = 1; | ||
+ | |||
+ | //код родительской опции в модуле Inet | ||
+ | private static int INET_OPTION_ROOT_ID = 1; | ||
+ | |||
+ | //код типа сервиса dlink модуля Inet | ||
+ | private static int INET_SERV_TYPE_DLINK_ID = 1; | ||
+ | //код типа сервиса mikrotik модуля Inet | ||
+ | private static int INET_SERV_TYPE_MIKROTIK_ID = 2; | ||
+ | |||
+ | //код универсальной категории белых Ip в модуле Inet | ||
+ | public static int INET_IP_CATEGORY_WHITE_UNIVERSAL_ID = 3; | ||
+ | //код универсальной категории серых Ip в модуле Inet | ||
+ | public static int INET_IP_CATEGORY_GREY_UNIVERSAL_ID = 2; | ||
+ | |||
+ | |||
+ | //коды неиспользуемых групп | ||
+ | private static Set<Integer> unusedGroups = new HashSet<Integer>(); | ||
+ | { | ||
+ | unusedGroups.add( 5 ); | ||
+ | unusedGroups.add( 10 ); | ||
+ | unusedGroups.add( 11 ); | ||
+ | |||
+ | |||
+ | } | ||
+ | //коды неиспользуемых категорий ресурсов | ||
+ | private static Set<Integer> unusedResources = new HashSet<Integer>(); | ||
+ | { | ||
+ | |||
+ | unusedResources.add( 13 ); | ||
+ | unusedResources.add( 14 ); | ||
+ | } | ||
+ | |||
+ | //коды неиспользуемых шлюзов IPN | ||
+ | private static Set<Integer> unusedGates = new HashSet<Integer>(); | ||
+ | { | ||
+ | unusedGates.add( 171 ); | ||
+ | unusedGates.add( 172 ); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | //связка кодов шлюзов папок со шлюзами микротик | ||
+ | private static Map<Integer, Integer> mikrotikFolderMap = new HashMap<Integer, Integer>(); | ||
+ | |||
+ | { | ||
+ | //заря | ||
+ | mikrotikFolderMap.put( 49, 7 ); | ||
+ | //бугорок | ||
+ | mikrotikFolderMap.put( 240, 239 ); | ||
+ | //гальчино | ||
+ | mikrotikFolderMap.put( 43, 52 ); | ||
+ | //городок | ||
+ | mikrotikFolderMap.put( 121, 143 ); | ||
+ | //ильнское | ||
+ | mikrotikFolderMap.put( 91, 89 ); | ||
+ | //малино | ||
+ | mikrotikFolderMap.put( 173, 172 ); | ||
+ | //троицое | ||
+ | mikrotikFolderMap.put( 219, 220 ); | ||
+ | //харино | ||
+ | mikrotikFolderMap.put( 174, 171 ); | ||
+ | //цос | ||
+ | mikrotikFolderMap.put( 65, 64 ); | ||
+ | //южное | ||
+ | mikrotikFolderMap.put( 131, 140 ); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | private InetDeviceService wsDevice = null;; | ||
+ | private ResourceService wsResource = null; | ||
+ | private InetServService wsServ = null; | ||
+ | |||
+ | |||
+ | Logger logger = Logger.getLogger( ConvertFromIPNToInet.class ); | ||
+ | |||
+ | @Override | ||
+ | public void execute( Setup setup, ConnectionSet connectionSet ) | ||
+ | throws Exception | ||
+ | { | ||
+ | print ( "connectionSet.getAutoCommit()=" + connectionSet.getAutoCommit() ); | ||
+ | |||
+ | ServerContext context = ServerContext.get(); ; | ||
+ | wsDevice = context.getService( InetDeviceService.class, INET_MODULE_ID ); | ||
+ | wsResource = context.getService( ResourceService.class, INET_MODULE_ID ); | ||
+ | wsServ = context.getService( InetServService.class, INET_MODULE_ID ); | ||
+ | |||
+ | Map<Integer, Integer> mapIpnInetCategories = new HashMap<Integer, Integer>(); | ||
+ | |||
+ | //Map<Integer, Gate> dlinkGateMap = new HashMap<Integer, Gate>(); | ||
+ | Map<Integer, InetDevice> dlinkIpnInetMap = new HashMap<Integer, InetDevice>(); | ||
+ | Map<Integer, Gate> mikrotikGateMap = new HashMap<Integer, Gate>(); | ||
+ | |||
+ | Map<Integer, InetOption > ipnInetOptionMap = new HashMap<Integer, InetOption>(); | ||
+ | |||
+ | createIpResources( connectionSet, mapIpnInetCategories ); | ||
+ | connectionSet.commit(); | ||
+ | |||
+ | Map<Integer, InetDevice> mikrotikIpnInetMap = new HashMap<Integer, InetDevice>(); | ||
+ | |||
+ | |||
+ | createDevices( connectionSet, mapIpnInetCategories, dlinkIpnInetMap, mikrotikGateMap, mikrotikIpnInetMap ); | ||
+ | connectionSet.commit(); | ||
+ | |||
+ | createOptions( connectionSet, ipnInetOptionMap ); | ||
+ | connectionSet.commit(); | ||
+ | |||
+ | createServices( connectionSet, dlinkIpnInetMap, ipnInetOptionMap, mikrotikGateMap, mikrotikIpnInetMap ); | ||
+ | |||
+ | |||
+ | print ( "Ok" ); | ||
+ | } | ||
+ | private void createOptions( ConnectionSet connectionSet, Map<Integer, InetOption > ipnInetOptionMap ) | ||
+ | throws BGException | ||
+ | { | ||
+ | Connection con = connectionSet.getConnection(); | ||
+ | |||
+ | List<InetOption> list = wsServ.inetOptionList(); | ||
+ | Map<String, InetOption> optMap = new HashMap<String, InetOption>(); | ||
+ | for ( InetOption option : list ) | ||
+ | { | ||
+ | optMap.put( option.getTitle(), option ); | ||
+ | } | ||
+ | RuleTypeManager rtMan = new RuleTypeManager( con, IPN_MODULE_ID ); | ||
+ | |||
+ | for( RuleType type : rtMan.getTypeList( ) ) | ||
+ | { | ||
+ | InetOption option = optMap.get( type.getTitle() ); | ||
+ | if ( option == null ) | ||
+ | { | ||
+ | option = new InetOption(); | ||
+ | } | ||
+ | option.setTitle( type.getTitle() ); | ||
+ | option.setComment( type.getComment() ); | ||
+ | option.setParentId( INET_OPTION_ROOT_ID ); | ||
+ | option.setConfig( type.getData() ); | ||
+ | int id = wsServ.inetOptionUpdate( option ); | ||
+ | if ( option.getId() <= 0 ) | ||
+ | { | ||
+ | option.setId( id ); | ||
+ | } | ||
+ | |||
+ | ipnInetOptionMap.put( type.getId(), option ); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | private void createIpResources( ConnectionSet connectionSet, Map<Integer, Integer> mapIpnInetCategories ) | ||
+ | throws BGException | ||
+ | { | ||
+ | List<IpCategory> categoryList = wsResource.ipCategoryList(); | ||
+ | Map<String, IpCategory> categoryMap = new HashMap<String, IpCategory>(); | ||
+ | |||
+ | for ( IpCategory cat : categoryList ) | ||
+ | { | ||
+ | categoryMap.put( cat.getTitle(), cat ); | ||
+ | } | ||
+ | |||
+ | Connection con = connectionSet.getConnection(); | ||
+ | |||
+ | |||
+ | List<IPResourceCategory> topLevelList = new IPResourceCategoryManager( con, IPN_MODULE_ID ).getCategoryTree(); | ||
+ | |||
+ | |||
+ | |||
+ | for( IPResourceCategory category : topLevelList ) | ||
+ | { | ||
+ | if ( !unusedResources.contains( category.getId() ) ) | ||
+ | { | ||
+ | addSubcategories( category, wsResource.ipCategoryRoot(), categoryMap, con, mapIpnInetCategories ); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | } | ||
+ | private void addSubcategories( IPResourceCategory categoryIPN, IpCategory categoryParent, Map<String, IpCategory> categoryMap, Connection con, Map<Integer, Integer> mapIpnInetCategories ) | ||
+ | throws BGException | ||
+ | { | ||
+ | IpCategory cat = categoryMap.get( categoryIPN.getTitle() ); | ||
+ | if ( cat == null ) | ||
+ | { | ||
+ | cat = new IpCategory(); | ||
+ | categoryMap.put( categoryIPN.getTitle(), cat ); | ||
+ | } | ||
+ | |||
+ | cat.setTitle( categoryIPN.getTitle() ); | ||
+ | cat.setParentId( categoryParent.getId() ); | ||
+ | int id = wsResource.ipCategoryUpdate( cat ); | ||
+ | if ( cat.getId() <= 0 ) | ||
+ | { | ||
+ | cat.setId( id ); | ||
+ | } | ||
+ | |||
+ | mapIpnInetCategories.put( categoryIPN.getId(), cat.getId() ); | ||
+ | |||
+ | //print( "cat.id = " + cat.getId() ); | ||
+ | |||
+ | IPNResourceManager resourceManager = new IPNResourceManager( con, IPN_MODULE_ID ); | ||
+ | Iterable<IPResourceRange> resourceList = resourceManager.getResourceIterator( categoryIPN.getId(), 0, 0, false ); | ||
+ | |||
+ | |||
+ | //удаляем все | ||
+ | Set<Integer> cats = new HashSet<Integer>(); | ||
+ | cats.add( cat.getId() ); | ||
+ | |||
+ | for ( IpResource res : wsResource.ipResourceList( cats ) ) | ||
+ | { | ||
+ | wsResource.ipResourceDelete( res.getId() ); | ||
+ | } | ||
+ | |||
+ | |||
+ | for( IPResourceRange resource : resourceList ) | ||
+ | { | ||
+ | IpResource res = new IpResource(); | ||
+ | res.setDateFrom( resource.getDateFrom() ); | ||
+ | res.setDateTo( resource.getDateTo() ); | ||
+ | res.setAddressFrom( Utils.convertIntToBytes( (int) resource.getIp1() ) ); | ||
+ | res.setAddressTo( Utils.convertIntToBytes( (int) resource.getIp2() ) ); | ||
+ | res.setCategoryId( cat.getId() ); | ||
+ | res.setComment( "" ); | ||
+ | |||
+ | wsResource.ipResourceUpdate( res ); | ||
+ | } | ||
+ | |||
+ | List<IPResourceCategory> subCategories = categoryIPN.getSubCategories(); | ||
+ | if( subCategories != null ) | ||
+ | { | ||
+ | for( int index = 0; index < subCategories.size(); index++ ) | ||
+ | { | ||
+ | addSubcategories( subCategories.get( index ), cat, categoryMap, con, mapIpnInetCategories ); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | private void createServices( ConnectionSet connectionSet, | ||
+ | Map<Integer, InetDevice> dlinkIpnInetMap, | ||
+ | Map<Integer, InetOption > ipnInetOptionMap, | ||
+ | Map<Integer, Gate> mikrotikGateMap, | ||
+ | Map<Integer, InetDevice> mikrotikIpnInetMap ) | ||
+ | throws SQLException, BGException | ||
+ | { | ||
+ | Connection con = connectionSet.getConnection(); | ||
+ | |||
+ | String query = "SELECT * FROM contract " + | ||
+ | " LEFT JOIN contract_module as cm ON contract.id = cm.cid " + | ||
+ | " WHERE cm.mid = " + IPN_MODULE_ID ; | ||
+ | |||
+ | for ( Integer gr : unusedGroups ) | ||
+ | { | ||
+ | query += " AND contract.gr & (1 << " + gr + ") = 0"; | ||
+ | } | ||
+ | |||
+ | PreparedStatement ps = con.prepareStatement( query ); | ||
+ | ResultSet rs = ps.executeQuery(); | ||
+ | |||
+ | ContractModuleManager cmm = new ContractModuleManager( con ); | ||
+ | |||
+ | AddressRangeManager adrRangeMan = new AddressRangeManager( con, IPN_MODULE_ID ); | ||
+ | UserGateRuleManager userGateMan = new UserGateRuleManager( con, IPN_MODULE_ID ); | ||
+ | |||
+ | ModuleSetup ipnSetup = new ModuleSetup( con, IPN_MODULE_ID ); | ||
+ | |||
+ | IPNContractStatusManager statusManager = new IPNContractStatusManager( con , IPN_MODULE_ID, ipnSetup ); | ||
+ | |||
+ | |||
+ | |||
+ | Date now = new Date(); | ||
+ | |||
+ | m1: | ||
+ | while ( rs.next() ) | ||
+ | { | ||
+ | int cid = rs.getInt( "contract.id" ); | ||
+ | |||
+ | int ipnStatus = statusManager.getContractStatus( cid ); | ||
+ | //удаленные договора игнорим | ||
+ | if( ipnStatus == IPNContractStatus.STATUS_REMOVED ) | ||
+ | { | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | |||
+ | int inetStatus = InetServ.STATUS_ACTIVE; | ||
+ | |||
+ | switch ( ipnStatus ) | ||
+ | { | ||
+ | case IPNContractStatus.STATUS_LOCK : | ||
+ | case IPNContractStatus.STATUS_OPEN : inetStatus = InetServ.STATUS_ACTIVE; break; | ||
+ | case IPNContractStatus.STATUS_REMOVED: | ||
+ | case IPNContractStatus.STATUS_CLOSED : inetStatus = InetServ.STATUS_CLOSED; break; | ||
+ | |||
+ | case IPNContractStatus.STATUS_HARD_LOCK : inetStatus = InetServ.STATUS_LOCKED; break; | ||
+ | } | ||
+ | |||
+ | |||
+ | for ( InetServ oldServ : wsServ.inetServList( cid ) ) | ||
+ | { | ||
+ | //во такой вот костыль чтобы удалить сервис, иначе не дает | ||
+ | if ( oldServ.getDateTo() == null || TimeUtils.dateBefore( now, oldServ.getDateTo() ) ) | ||
+ | { | ||
+ | oldServ.setDateTo( TimeUtils.getPrevDay( now ) ); | ||
+ | |||
+ | try | ||
+ | { | ||
+ | //logger.info( "updating serv date for cid = " + cid ); | ||
+ | wsServ.inetServUpdate( oldServ, new ArrayList<InetServOption>(), false, false, 0 ); | ||
+ | } | ||
+ | catch( Exception e ) | ||
+ | { | ||
+ | String message = "Error while updating service date for contract " + cid + ":" + e.getMessage() ; | ||
+ | logger.error( message, e ); | ||
+ | print( message ); | ||
+ | //logger.error( "", e ); | ||
+ | continue; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | //InetServ oldServ= wsServ.inetServGet( inetServId ); | ||
+ | |||
+ | try | ||
+ | { | ||
+ | cmm.deleteContractModule( cid, INET_MODULE_ID ); | ||
+ | cmm.addContractModule( cid, INET_MODULE_ID ); | ||
+ | EventProcessor.getInstance().publishAfterCommit( new ContractModifiedEvent( User.USER_SERVER, cid ) ); | ||
+ | } | ||
+ | catch( Exception e ) | ||
+ | { | ||
+ | logger.error( "", e ); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | List<AddressRange> ranges = adrRangeMan.getContractAddressRange( cid, TimeUtils.convertDateToCalendar( now ), -1 ); | ||
+ | |||
+ | List<UserGateRule> rules = userGateMan.getUserGateRules( cid ); | ||
+ | |||
+ | //UserGateRule dlinkRule = null; | ||
+ | //UserGateRule mikrotikRule = null; | ||
+ | |||
+ | List<UserGateRule> dlinkRules = new ArrayList<UserGateRule>(); | ||
+ | List<UserGateRule> mikrotikRules = new ArrayList<UserGateRule>(); | ||
+ | |||
+ | |||
+ | for( UserGateRule rule : rules ) | ||
+ | { | ||
+ | if( dlinkIpnInetMap.containsKey( rule.getGateId() ) ) | ||
+ | { | ||
+ | dlinkRules.add( rule ); | ||
+ | //dlinkRule = rule; | ||
+ | } | ||
+ | else if( mikrotikGateMap.containsKey( rule.getGateId() ) ) | ||
+ | { | ||
+ | //mikrotikRule = rule; | ||
+ | mikrotikRules.add( rule ); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | //Gate dlinkGate = dlinkGateMap.get( dlinkRule.getGateId() ); | ||
+ | |||
+ | /* | ||
+ | Set<Integer> options = new HashSet<Integer>(); | ||
+ | |||
+ | if ( mikrotikRule != null ) | ||
+ | { | ||
+ | |||
+ | InetOption option = ipnInetOptionMap.get( mikrotikRule.getRuleTypeId() ); | ||
+ | |||
+ | if ( option != null ) | ||
+ | { | ||
+ | options.add( option.getId() ); | ||
+ | |||
+ | } | ||
+ | else | ||
+ | { | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | */ | ||
+ | |||
+ | |||
+ | //если нет алресов , то и ничего переносить | ||
+ | if( ranges.size() == 0 ) | ||
+ | { | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | //если есть адреса, но нет dlink-а и mikrotik-а, то ругаемся | ||
+ | if( dlinkRules.size() == 0 && mikrotikRules.size() == 0 ) | ||
+ | { | ||
+ | logger.info( "There is no dlink or mikrotik on contact " + cid + ";ipnStatus=" + ipnStatus ); | ||
+ | print( "There is no dlink on contact " + cid + ";ipnStatus=" + ipnStatus ); | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | //String dlinkRuleText = "" ; | ||
+ | |||
+ | List<Map<Long, Integer>> dlinkIpPortMaps = new ArrayList<Map<Long,Integer>>(); | ||
+ | |||
+ | //Map<String, Integer> ipPortMap = new HashMap<String, Integer>(); | ||
+ | |||
+ | |||
+ | if( dlinkRules.size() != 0 ) | ||
+ | { | ||
+ | for( UserGateRule dlinkRule : dlinkRules ) | ||
+ | { | ||
+ | String dlinkRuleText = dlinkRule.getRuleText(); | ||
+ | Map<Long, Integer> dlinkIpPortMap = getPorts( dlinkRuleText ); | ||
+ | dlinkIpPortMaps.add( dlinkIpPortMap ); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | //String mikrotikRuleText = ""; | ||
+ | |||
+ | //if ( mikrotikRule != null ) | ||
+ | //{ | ||
+ | //mikrotikRuleText = mikrotikRule.getRuleText(); | ||
+ | //} | ||
+ | |||
+ | |||
+ | List<Set<Long>> mikrotikIpSets = new ArrayList<Set<Long>>(); | ||
+ | |||
+ | for( UserGateRule mikRule : mikrotikRules ) | ||
+ | { | ||
+ | String mikrotikRuleText = mikRule.getRuleText(); | ||
+ | Set<Long> mikrotikISet = getIp( mikrotikRuleText ); | ||
+ | mikrotikIpSets.add( mikrotikISet ); | ||
+ | } | ||
+ | |||
+ | //Set<Long> ipSet = getIp( mikrotikRuleText ); | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | for( AddressRange range : ranges ) | ||
+ | { | ||
+ | |||
+ | List<Long> mikrotikIps = new ArrayList<Long>(); | ||
+ | |||
+ | UserGateRule curMikrotikRule =null; | ||
+ | |||
+ | for( long ip = range.getAddr1(); ip <= range.getAddr2(); ip++ ) | ||
+ | { | ||
+ | //boolean isMikrotik = false; | ||
+ | |||
+ | Integer port = null; | ||
+ | |||
+ | UserGateRule dlinkRule = null; | ||
+ | |||
+ | for( int i = 0; i < dlinkRules.size(); i++ ) | ||
+ | { | ||
+ | port = dlinkIpPortMaps.get( i ).get( ip ); | ||
+ | if( port != null ) | ||
+ | { | ||
+ | dlinkRule = dlinkRules.get( i ); | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | UserGateRule mikrotikRule =null; | ||
+ | |||
+ | if( dlinkRule == null ) | ||
+ | { | ||
+ | for( int i = 0; i < mikrotikRules.size(); i++ ) | ||
+ | { | ||
+ | if( mikrotikIpSets.get( i ).contains( ip ) ) | ||
+ | { | ||
+ | // isMikrotik = true; | ||
+ | mikrotikRule = mikrotikRules.get( i ); | ||
+ | |||
+ | if( curMikrotikRule != null && curMikrotikRule != mikrotikRule ) | ||
+ | { | ||
+ | String mess = "Error: range belongs to diffrent mikrotiks ;cid=" + cid; | ||
+ | print( mess ); | ||
+ | logger.error( mess ); | ||
+ | } | ||
+ | |||
+ | curMikrotikRule = mikrotikRule; | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | //если нет порта в dlink и нет привязки в микротик, то игнорим ip | ||
+ | |||
+ | if( dlinkRule == null && mikrotikRule == null ) | ||
+ | { | ||
+ | /*//print( "port is null for contract " + cid ); | ||
+ | |||
+ | //String str = getIpFromSet( ipPortMaps.get( i).keySet() ); | ||
+ | String allPorts = ""; | ||
+ | for( int i = 0; i < dlinkRules.size(); i++ ) | ||
+ | { | ||
+ | |||
+ | for( Map.Entry<Long, Integer> entry : dlinkIpPortMaps.get( i ).entrySet() ) | ||
+ | { | ||
+ | allPorts += IPUtils.convertLongIpToString( entry.getKey() ) + "=" + | ||
+ | entry.getValue() + ","; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | String allIPs = ""; | ||
+ | for( int i = 0; i < mikrotikRules.size(); i++ ) | ||
+ | { | ||
+ | allIPs += getIpFromSet( mikrotikIpSets.get( i ) ); | ||
+ | } | ||
+ | |||
+ | String message = "empty ip for contract " + cid+ ";ip=" + IPUtils.convertLongIpToString( ip ) + | ||
+ | ";dlinkRule=" + dlinkRule + ";dlinkIpPortMap=" + allPorts + ";mikrotikRule=" + mikrotikRule + | ||
+ | " mikrotikIps= " + allIPs; | ||
+ | |||
+ | logger.info( message ); | ||
+ | print ( message ); | ||
+ | */ | ||
+ | |||
+ | continue; | ||
+ | } | ||
+ | |||
+ | if ( dlinkRule != null ) | ||
+ | { | ||
+ | InetServ serv = new InetServ(); | ||
+ | serv.setContractId( cid ); | ||
+ | serv.setComment( "Импортирован из IPN" ); | ||
+ | serv.setDateFrom( now ); | ||
+ | serv.setDateTo( TimeUtils.convertCalendarToDate( range.getDate2() ) ); | ||
+ | serv.setLogin( "" ); | ||
+ | serv.setPassword( "" ); | ||
+ | serv.setStatus( inetStatus ); | ||
+ | |||
+ | |||
+ | serv.setTypeId( INET_SERV_TYPE_DLINK_ID ); | ||
+ | InetDevice device = dlinkIpnInetMap.get( dlinkRule.getGateId() ); | ||
+ | |||
+ | if ( device == null ) | ||
+ | { | ||
+ | //print( "device is null for contract " + cid ); | ||
+ | logger.info( "Dlink device is null for contract " + cid ); | ||
+ | print( "mikrotik device is null for contract " + cid ); | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | serv.setDeviceId( device.getId() ); | ||
+ | serv.setInterfaceId( port ); | ||
+ | |||
+ | serv.setAddressFrom( Utils.convertIntToBytes( (int) ip ) ); | ||
+ | serv.setAddressTo( Utils.convertIntToBytes( (int) ip ) ); | ||
+ | |||
+ | |||
+ | updateServ( cid, serv ); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | mikrotikIps.add( ip ); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | Collections.sort( mikrotikIps ); | ||
+ | |||
+ | if ( mikrotikIps.size() > 0 ) | ||
+ | { | ||
+ | |||
+ | |||
+ | //проверяем есть ли пропущенные ip в диапазоне | ||
+ | long start = mikrotikIps.get( 0 ); | ||
+ | long end = mikrotikIps.get( mikrotikIps.size() - 1 ); | ||
+ | boolean ragged = false; | ||
+ | |||
+ | int c = 0; | ||
+ | |||
+ | for ( long i = start; i <= end; i++ ) | ||
+ | { | ||
+ | if ( c >= mikrotikIps.size() || ( i != mikrotikIps.get( c++ ) ) ) | ||
+ | { | ||
+ | ragged = true; | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | String ips = getIpFromSet( mikrotikIps ); | ||
+ | |||
+ | //logger.info( "add mikrotikIps=" + ips + ";cid=" +cid + ";ragged=" + ragged ); | ||
+ | |||
+ | if ( ragged ) | ||
+ | { | ||
+ | print( "error: ranges are ragged;cid=" + cid ); | ||
+ | logger.error( "error: ranges are ragged;cid=" + cid ); | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | InetServ serv = new InetServ(); | ||
+ | serv.setContractId( cid ); | ||
+ | serv.setComment( "Импортирован из IPN" ); | ||
+ | serv.setDateFrom( now ); | ||
+ | serv.setDateTo( TimeUtils.convertCalendarToDate( range.getDate2() ) ); | ||
+ | serv.setLogin( "" ); | ||
+ | serv.setPassword( "" ); | ||
+ | serv.setStatus( inetStatus ); | ||
+ | |||
+ | |||
+ | serv.setTypeId( INET_SERV_TYPE_MIKROTIK_ID ); | ||
+ | InetDevice device = mikrotikIpnInetMap.get( curMikrotikRule.getGateId() ); | ||
+ | |||
+ | if( device == null ) | ||
+ | { | ||
+ | //print( "device is null for contract " + cid ); | ||
+ | logger.info( "mikrotik device is null for contract " + cid ); | ||
+ | print( "mikrotik device is null for contract " + cid ); | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | serv.setDeviceId( device.getId() ); | ||
+ | |||
+ | serv.setAddressFrom( Utils.convertIntToBytes( (int) start ) ); | ||
+ | serv.setAddressTo( Utils.convertIntToBytes( (int) end ) ); | ||
+ | |||
+ | updateServ( cid, serv ); | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | ps.close(); | ||
+ | |||
+ | } | ||
+ | private void updateServ( int cid, InetServ serv ) | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | //logger.info( "updating serv for cid = " + cid ); | ||
+ | wsServ.inetServUpdate( serv, new ArrayList<InetServOption>(), false, false, 0 ); | ||
+ | } | ||
+ | catch( Exception e ) | ||
+ | { | ||
+ | String message = "Error while updating service for contract " + cid + ":" + e.getMessage(); | ||
+ | |||
+ | logger.error( message, e ); | ||
+ | print( message ); | ||
+ | //logger.error( "", e ); | ||
+ | } | ||
+ | } | ||
+ | private String getIpFromSet( Collection<Long> mikrotikIps ) | ||
+ | { | ||
+ | String ips = ""; | ||
+ | for ( long ip : mikrotikIps) | ||
+ | { | ||
+ | |||
+ | ips += IPUtils.convertLongIpToString( ip ) + ","; | ||
+ | |||
+ | } | ||
+ | return ips; | ||
+ | } | ||
+ | private Map<Long, Integer> getPorts( String ruleText ) | ||
+ | { | ||
+ | Map<Long, Integer> result = new HashMap<Long, Integer>(); | ||
+ | if ( Utils.isEmptyString( ruleText ) ) | ||
+ | { | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | String parts[] = ruleText.split( ";" ); | ||
+ | for ( String part : parts ) | ||
+ | { | ||
+ | if ( Utils.isEmptyString( part ) ) | ||
+ | { | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | String parts2[] = part.split( ":" ); | ||
+ | if ( parts2.length < 2 ) | ||
+ | { | ||
+ | print( "wrong port " + part ); | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | result.put( IPUtils.convertStringIPtoLong( parts2[1] ), Integer.valueOf( parts2[0] ) ); | ||
+ | |||
+ | } | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | |||
+ | private Set<Long> getIp( String ruleText ) | ||
+ | { | ||
+ | Set<Long> result = new HashSet<Long>(); | ||
+ | |||
+ | if ( Utils.isEmptyString( ruleText ) ) | ||
+ | { | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | String parts[] = ruleText.split( ";" ); | ||
+ | |||
+ | String ipStr = ""; | ||
+ | if ( parts.length > 0 ) | ||
+ | { | ||
+ | ipStr = parts[0]; | ||
+ | } | ||
+ | |||
+ | if ( Utils.isEmptyString( ipStr ) ) | ||
+ | { | ||
+ | return result; | ||
+ | } | ||
+ | |||
+ | |||
+ | String parts2[] = ipStr.split( "," ); | ||
+ | |||
+ | for ( String ip : parts2 ) | ||
+ | { | ||
+ | if ( Utils.isEmptyString( ip ) ) | ||
+ | { | ||
+ | continue; | ||
+ | } | ||
+ | result.add( Long.valueOf( ip ) ); | ||
+ | } | ||
+ | |||
+ | return result; | ||
+ | } | ||
+ | private void createDevices( ConnectionSet connectionSet, | ||
+ | Map<Integer, Integer> mapIpnInetCategories, | ||
+ | Map<Integer, InetDevice> dlinkIpnInetMap, | ||
+ | Map<Integer, Gate> mikrotikGateMap, | ||
+ | Map<Integer, InetDevice> mikrotikIpnInetMap ) | ||
+ | throws BGException | ||
+ | { | ||
+ | List<InetDevice> inetDevicelist = new ArrayList<InetDevice>(); | ||
+ | |||
+ | inetDevicelist.addAll( wsDevice.deviceList( INET_DLINK_DEVICE_TYPE_ID ) ); | ||
+ | inetDevicelist.addAll( wsDevice.deviceList( INET_MIKROTIK_DEVICE_TYPE_ID ) ); | ||
+ | |||
+ | Map<String, InetDevice> inetDeviceMap = new HashMap<String, InetDevice>(); | ||
+ | |||
+ | for ( InetDevice device : inetDevicelist ) | ||
+ | { | ||
+ | inetDeviceMap.put( device.getHost(), device ); | ||
+ | } | ||
+ | |||
+ | Connection con = connectionSet.getConnection(); | ||
+ | GateManager man = new GateManager( con, IPN_MODULE_ID ); | ||
+ | |||
+ | |||
+ | Map<Integer, InetDevice> ipnFolderInetDeviceMap = new HashMap<Integer, InetDevice>(); | ||
+ | |||
+ | createMikrotikDevcices( inetDeviceMap, man, ipnFolderInetDeviceMap, mapIpnInetCategories, mikrotikGateMap, mikrotikIpnInetMap ); | ||
+ | |||
+ | createDlinkDevices( inetDeviceMap, man, ipnFolderInetDeviceMap, dlinkIpnInetMap ); | ||
+ | } | ||
+ | private void createDlinkDevices( Map<String, InetDevice> inetDeviceMap, | ||
+ | GateManager man, Map<Integer, | ||
+ | InetDevice> ipnFolderInetDeviceMap, | ||
+ | Map<Integer, InetDevice> dlinkIpnInetMap ) | ||
+ | throws BGException | ||
+ | { | ||
+ | GateFilter filter = new GateFilter(); | ||
+ | filter.setType( IPN_DLINK_GATE_TYPE_ID ); | ||
+ | List<Gate> dlinkGates = man.getGatesList( filter ); | ||
+ | |||
+ | InetDeviceType type = wsDevice.deviceTypeGet( INET_DLINK_DEVICE_TYPE_ID ); | ||
+ | |||
+ | for ( Gate gate : dlinkGates ) | ||
+ | { | ||
+ | |||
+ | String hostPort = gate.getHost() + ":" + gate.getPort(); | ||
+ | |||
+ | InetDevice device = inetDeviceMap.get( hostPort ); | ||
+ | |||
+ | if ( device == null ) | ||
+ | { | ||
+ | |||
+ | device = new InetDevice(); | ||
+ | inetDeviceMap.put( hostPort, device ); | ||
+ | } | ||
+ | |||
+ | Preferences gateSetup = new Preferences( gate.getConfig(), "\r\n" ); | ||
+ | |||
+ | int mikrotikGateId = mikrotikFolderMap.get( gate.getParentId() ); | ||
+ | |||
+ | if ( unusedGates.contains( mikrotikGateId ) ) | ||
+ | { | ||
+ | //print ( "Parent Gate " + mikrotikGateId + " was skipped.all( " + unusedGates + ")" ); | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | device.setHost( hostPort ); | ||
+ | device.setPassword( gate.getKeyword() ); | ||
+ | device.setUsername( gateSetup.get ( "login", null ) ); | ||
+ | device.setSecret( gateSetup.get( "enablepwd", null) ); | ||
+ | device.setComment( gate.getComment() ); | ||
+ | device.setDeviceTypeId( INET_DLINK_DEVICE_TYPE_ID ); | ||
+ | device.setTitle( Device.generateTitle( device, type ) ); | ||
+ | device.setIdentifier( "" ); | ||
+ | device.setConfig(""); | ||
+ | device.setDeviceGroupIds( new HashSet<Integer>() ); | ||
+ | |||
+ | InetDevice parent = ipnFolderInetDeviceMap.get( gate.getParentId() ); | ||
+ | |||
+ | device.setParentId( parent.getId() ); | ||
+ | |||
+ | int id = wsDevice.deviceUpdate( device ); | ||
+ | |||
+ | if ( device.getId() <= 0 ) | ||
+ | { | ||
+ | device.setId( id ); | ||
+ | } | ||
+ | |||
+ | dlinkIpnInetMap.put( gate.getId(), device ); | ||
+ | } | ||
+ | } | ||
+ | private void createMikrotikDevcices( Map<String, InetDevice> inetDeviceMap, | ||
+ | GateManager man, Map<Integer, InetDevice> ipnFolderInetDeviceMap, | ||
+ | Map<Integer, Integer> mapIpnInetCategories, | ||
+ | Map<Integer, Gate> mikrotikGateMap, | ||
+ | Map<Integer, InetDevice> mikrotikIpnInetMap ) | ||
+ | throws BGException | ||
+ | { | ||
+ | GateFilter filter = new GateFilter(); | ||
+ | filter.setType( 0 ); | ||
+ | List<Gate> folderGates = man.getGatesList( filter ); | ||
+ | |||
+ | |||
+ | filter.setType( IPN_MIKROTIK_GATE_TYPE_ID ); | ||
+ | List<Gate> mikrotikGates = man.getGatesList( filter ); | ||
+ | |||
+ | for ( Gate gate : mikrotikGates ) | ||
+ | { | ||
+ | mikrotikGateMap.put( gate.getId(), gate ); | ||
+ | } | ||
+ | |||
+ | |||
+ | InetDeviceType type = wsDevice.deviceTypeGet( INET_MIKROTIK_DEVICE_TYPE_ID ); | ||
+ | for ( Gate foldeGate : folderGates ) | ||
+ | { | ||
+ | int mikrotikGateId = mikrotikFolderMap.get( foldeGate.getId() ); | ||
+ | |||
+ | Gate gate = mikrotikGateMap.get( mikrotikGateId ); | ||
+ | if ( gate == null ) | ||
+ | { | ||
+ | print ( "Gate was not found for " + mikrotikGateId ); | ||
+ | } | ||
+ | |||
+ | if ( unusedGates.contains( gate.getId() ) ) | ||
+ | { | ||
+ | print ( "Gate " + gate.getId() + " was skipped " ); | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | String hostPort = gate.getHost() + ":" + gate.getPort(); | ||
+ | |||
+ | |||
+ | InetDevice device = inetDeviceMap.get( hostPort ); | ||
+ | |||
+ | if ( device == null ) | ||
+ | { | ||
+ | |||
+ | device = new InetDevice(); | ||
+ | inetDeviceMap.put( hostPort, device ); | ||
+ | } | ||
+ | |||
+ | |||
+ | Preferences gateSetup = new Preferences( gate.getConfig(), "\r\n" ); | ||
+ | |||
+ | |||
+ | String oldCatsStr = gateSetup.get( "ip.resource.categoryId", "" ); | ||
+ | List<Integer> oldCats = Utils.toIntegerList( oldCatsStr ); | ||
+ | |||
+ | List<Integer> newCats = new ArrayList<Integer>(); | ||
+ | |||
+ | for ( Integer oldCatId : oldCats ) | ||
+ | { | ||
+ | Integer newCatId = mapIpnInetCategories.get( oldCatId ); | ||
+ | if ( newCatId != null ) | ||
+ | { | ||
+ | newCats.add( newCatId ); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | //всем добавляем универсальную белую категорию | ||
+ | newCats.add( INET_IP_CATEGORY_WHITE_UNIVERSAL_ID ); | ||
+ | newCats.add( INET_IP_CATEGORY_GREY_UNIVERSAL_ID ); | ||
+ | |||
+ | String config = ""; | ||
+ | if ( !Utils.isEmptyString( Utils.toString( newCats ) ) ) | ||
+ | { | ||
+ | config += "ip.resource.categoryId=" + Utils.toString( newCats ); | ||
+ | } | ||
+ | |||
+ | device.setHost( hostPort ); | ||
+ | device.setPassword( gate.getKeyword() ); | ||
+ | device.setUsername( gateSetup.get( "login", "root" ) ); | ||
+ | device.setComment( gate.getComment() ); | ||
+ | device.setDeviceTypeId( INET_MIKROTIK_DEVICE_TYPE_ID ); | ||
+ | device.setParentId( INET_ROOT_DEVICE_ID ); | ||
+ | device.setTitle( Device.generateTitle( device, type ) ); | ||
+ | device.setIdentifier( "" ); | ||
+ | device.setSecret( "" ); | ||
+ | device.setConfig( config ); | ||
+ | device.setDeviceGroupIds( new HashSet<Integer>() ); | ||
+ | |||
+ | |||
+ | int id = wsDevice.deviceUpdate( device ); | ||
+ | |||
+ | if ( device.getId() <= 0 ) | ||
+ | { | ||
+ | device.setId( id ); | ||
+ | } | ||
+ | |||
+ | ipnFolderInetDeviceMap.put( foldeGate.getId(), device ); | ||
+ | |||
+ | mikrotikIpnInetMap.put( gate.getId(), device ); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | </source> |
Текущая версия на 06:14, 1 октября 2012
Содержание |
Схема подключения в IPN
Было такая схема шлюзов в IPN.
1) Иерархия шлюзов:
DHCP-Папка-Dlink и отдельный Mikrotik(без родителя).
На самом деле папка это фактически по иерархии является шлюзом mikrotik(папка - это район город, а на район приходится один Mikrotik) , но в случае dhcp Dlink такую иерархию не получалось выстроить в IPN .Поэтому Mikrotik был ванесен отдельно. На каждый договор подключался шлюз Mikrotik , чтобы управлять доступом клиента (добавлять/удалять ip на mikrotik) и управлять скоростью . И Dlink чтобы управлять портом клиента и выдавать Ip по dhcp на порту по option 82. На договоре добавлен адрес(как часть диапазон), он выбран на mikrotik , для него хранится привязка к порту на dlink-е.
2) Просто шлюз mikrotik(без родителя). Т.е некоторые абоненты были просто напрямую подключены к mikrotik.
На договор добавлен диапазон адресов, он привязан mikrotik.
Схема подключения в Inet
При переносе этой схемы в Inet получилось:
1) Иерархия устройств: Access+Accounting-mikrotik-Dlink
На договор добавлен сервис Dlink, его привязывают устройству Dlink, и заводят на нем ip-адрес и порт.
2) Иерархия устройств: Access+Accounting-mikrotik
На договор добавлен сервис Mikrotik, его привязывают устройству mikrotik и заводят на нем диапазон адресов.
Управление оборудованием
Изначально для Шлюза mikrotik использовался скрипт подобный вот этому : http://wiki.bgbilling.ru/index.php/%D0%A8%D0%BB%D1%8E%D0%B7_Mikrotik,_%D0%BE%D1%82%D1%80%D0%B0%D0%B1%D0%B0%D1%82%D1%8B%D0%B2%D0%B0%D1%8E%D1%89%D0%B8%D0%B9_%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB_%D0%BD%D0%B0_%D0%B4%D0%BE%D0%B3%D0%BE%D0%B2%D0%BE%D1%80%D0%B5
Для него в inet получился вот такой обработчик активации сервисов:
Для Шлюза Dlink использовался скрипт подобный вот этому:
http://wiki.bgbilling.ru/index.php/%D0%A0%D0%B5%D0%B0%D0%BB%D0%B8%D0%B0%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B2%D0%B3%D0%BE_%D1%88%D0%BB%D1%8E%D0%B7%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BC%D1%83%D1%82%D0%B0%D1%82%D0%BE%D1%80%D0%BE%D0%B2_DES-3526,_DES-3550,_DES-3828,_DES-3852,_DGS-3200-10_%D0%B8_%D0%B8%D0%BC_%D0%BF%D0%BE%D0%B4%D0%BE%D0%B1%D0%BD%D1%8B%D1%85
Для него в inet получился вот такой обработчик активации сервисов:
Настройка
1) Создаем тип сервиса Dlink
Тип инициации : по сигналу тип адреса: статический адрес привязка типов трафика : <Некоторая привязка, которую нужно создать > Интрерфейс:Да Устройство:Да Интерфейс персонален:Да
Конфигурация:
# Шаблон имени сервиса title.pattern=интернет : (${addressRange}) : (${interfaceId})
2) Создаем тип сервиса Mikrotik
Тип инициации : по трафику тип адреса: статический диапазон привязка типов трафика : <Некоторая привязка, которую нужно создать > Устройство:Да Интерфейс персонален:Да
Конфигурация:
# Шаблон имени сервиса title.pattern=интернет : (${addressRange}) : (${interfaceId})
3) Создаем тип устройства Dlink
Конфигурация :
dhcp.deviceSearchMode=2 dhcp.servSearchMode=1 # Код субопции 82, содержащей интерфейс, позиция и длина в субопции dhcp.option82.interfaceId.code=1 dhcp.option82.interfaceId.position=5 dhcp.option82.interfaceId.length=1 dhcp.disable.mode=1 #Uplink - порты uplink-и, используются в Обработчике активации сервисов. uplink=25,26,27,28 #Открытый адрес при закрытом договоре, например адрес сервера статистики. open.address=172.31.0.254 dhcp.option.serverIdentifier=172.31.0.254 dhcp.option.leaseTime=43200 ###Сети dhcp.net.option.172.168.184.0:255.255.0.0.gate=172.168.184.253 dhcp.net.option.172.168.185.0:255.255.0.0.dns=172.168.184.253 dhcp.net.option.1172.168.184.0:255.255.0.0.subnetMask=255.255.0.0 dhcp.net.option.172.168.184.0:255.255.0.0.domainName=example.info
4) Создаем тип устройства Mikrotik
Конфигурация :
flow.agent.type=netflow flow.agent.link={@deviceId}:-1
5) Создаем тип устройства Access+Accounting
Конфигурация :
dhcp.relay.deviceTypeIds=3 dhcp.xid=0 # Количество потоков на worker'а dhcp.xid=0 accounting.worker.1.thread.count=1 # Тарификатор: # минимальная сумма трафика, при которой тарифицировать соединение accounting.worker.1.tariffication.1.minDeltaAmount=0 # пауза между заданиями тарификации accounting.worker.1.tariffication.1.delay=10 # максимальное количество тарифицируемых соединений за задание accounting.worker.1.tariffication.1.batchSize=100 # Трекер (обработка сессий без наработки): # пауза между заданиями трекинга accounting.worker.1.tracking.1.delay=20 # максимальное количество проверенных соединений за задание accounting.worker.1.tracking.1.batchSize=100 # Количество потоков на worker'а accounting.worker.2.thread.count=1 # Сброс в базу трафиков и наработки: # минимальная наработка, при которой сбрасывать соединение в базу accounting.worker.2.flushing.1.minDeltaAccount=0 # минимальная сумма трафика, при которой сбрасывать соединение в базу accounting.worker.2.flushing.1.minDeltaAmount=0 # пауза между заданиями сброса в базу accounting.worker.2.flushing.1.delay=20 # максимальное количество сброшенных соединений в базу за задание accounting.worker.2.flushing.1.batchSize=500 # Количество потоков на worker'а accounting.worker.3.thread.count=1 # Завершатель соединений: # пауза между заданиями accounting.worker.3.finishing.1.delay=20 # максимальное количество сброшенных соединений в базу за задание accounting.worker.3.finishing.1.batchSize=500 # При выдаче access-accept добавлять запись в базу; # необходимо, если используется reject-to-accept и по старт пакету нельзя определить в каком состоянии соединение #connection.start.fromAccept=0 # При создании сессии по update пакету, 0 - не создавать сессии без старт пакета, 1 - создать сессию от текущего момента, # 2 - создавать сессию от реального времени начала, если время сессии не больше connection.close.timeout #connection.start.fromUpdate=1 # Таймаут перевода соединения в статус suspended при остутствии радиус пакетов connection.suspend.timeout=900 # Таймаут перевода соединения в статус suspended при остутствии радиус пакетов для сессии в состоянии отключен # (по умолчанию используется значение connection.suspend.timeout) connection.disable.suspend.timeout=900 # Таймаут закрытия соединения при остутствии радиус-пакетов или, для сессий, создаваемых по наличии трафика, при отсутствии flow пакетов # (не складывается с connection.suspend.timeout) connection.close.timeout=1300 # Таймаут закрытия соединения при остутствии радиус-пакетов или, для сессий, создаваемых по наличии трафика, при отсутствии flow пакетов, # в состоянии отключен (не складывается с connection.disable.suspend.timeout, по умолчанию используется значение connection.close.timeout) connection.disable.close.timeout=1300 # Таймаут завершения закрытой сессии connection.finish.timeout=5 # Нужно ли логически разрывать сессию при переключении состояния session.split.onDeviceState=0 # Нужно ли логически разрывать сессию при активации или деактивации тарифной опции session.split.onTariffOption=1
6) Создаем Головное устройство Access+Accounting в дереве устройства
7) Далее запуск конвертера (после его настройки т.п ) создаст иерархию устройств
Access+Accounting ->Mikrotik->Dlink
в дереве устройств.
Для шлюза mikrotik будет указан хост/порт в формате хост:порт, логин, пароль . В конфигурации будет проставлена настройка вида:
ip.resource.categoryId=14,21,3,2
Для шлюза dlink будет указан хост/порт в формате хост:порт, логин, пароль,секрет .
Конвертация данных
Конвертер это глобальный скрипт поведения . Он работает так
1) Для каждого шлюза IPN в inet ищется устройство с таким же ip, если на найдено, то создается новое. Параметры устройства обновляются.
2) Для каждой категории ip-ресурсов IPN ищется категория с таким-же именем в INET. Если не найдена, то создается. Потом в ней удаляются все ресурсы и добавляются заново.
3) Для каждого типа правила в IPN ищется опция с таким-же именем в INET. Если не найдена, то создается.
4) Удаляются все сервисы с договоров (кроме исключающих групп договоров) .
5) На каждом договоре берутся все действующие ip из IPN(диапазон дробится ) и для каждого ip, ищется порт в настройках шлюза dlink и для каждого найденного порта создается сервис Dlink с этим ip и портом. Если ip не привязан к dlink, то ищется привязка к шлюзу mikrotik и если найдена ,то создается сервис mikrotik. Если что-то не нашло (dlink/порт и mikrotik) , то ругается в лог и не создает сервис.
Код конвертера:
package ru.gigacom.inet.dyn.convert; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import ru.bitel.bgbilling.common.BGException; import ru.bitel.bgbilling.kernel.container.managed.ServerContext; import ru.bitel.bgbilling.kernel.contract.api.common.event.ContractModifiedEvent; import ru.bitel.bgbilling.kernel.event.EventProcessor; import ru.bitel.bgbilling.kernel.module.common.bean.User; import ru.bitel.bgbilling.kernel.script.server.dev.GlobalScriptBase; import ru.bitel.bgbilling.modules.inet.api.common.bean.InetDevice; import ru.bitel.bgbilling.modules.inet.api.common.bean.InetDeviceType; import ru.bitel.bgbilling.modules.inet.api.common.bean.InetOption; import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServ; import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServOption; import ru.bitel.bgbilling.modules.inet.api.common.service.InetDeviceService; import ru.bitel.bgbilling.modules.inet.api.common.service.InetServService; import ru.bitel.bgbilling.modules.ipn.common.bean.AddressRange; import ru.bitel.bgbilling.modules.ipn.server.bean.AddressRangeManager; import ru.bitel.bgbilling.modules.ipn.server.bean.GateFilter; import ru.bitel.bgbilling.server.util.ModuleSetup; import ru.bitel.bgbilling.server.util.Setup; import ru.bitel.common.Preferences; import ru.bitel.common.Utils; import ru.bitel.common.sql.ConnectionSet; import ru.bitel.oss.systems.inventory.resource.common.ResourceService; import ru.bitel.oss.systems.inventory.resource.common.bean.Device; import ru.bitel.oss.systems.inventory.resource.common.bean.IpCategory; import ru.bitel.oss.systems.inventory.resource.common.bean.IpResource; import bitel.billing.common.IPUtils; import bitel.billing.common.TimeUtils; import bitel.billing.common.module.ipn.IPNContractStatus; import bitel.billing.server.admin.resource.bean.IPResourceCategory; import bitel.billing.server.admin.resource.bean.IPResourceCategoryManager; import bitel.billing.server.admin.resource.bean.ip.IPResourceRange; import bitel.billing.server.contract.bean.ContractModuleManager; import bitel.billing.server.ipn.bean.Gate; import bitel.billing.server.ipn.bean.GateManager; import bitel.billing.server.ipn.bean.IPNContractStatusManager; import bitel.billing.server.ipn.bean.IPNResourceManager; import bitel.billing.server.ipn.bean.RuleType; import bitel.billing.server.ipn.bean.RuleTypeManager; import bitel.billing.server.ipn.bean.UserGateRule; import bitel.billing.server.ipn.bean.UserGateRuleManager; public class ConvertFromIPNToInet extends GlobalScriptBase { //код модуля IPN private static int IPN_MODULE_ID = 1; //тип шлюза микротик в IPN private static int IPN_MIKROTIK_GATE_TYPE_ID = 3; //тип шлюза dlink в IPN private static int IPN_DLINK_GATE_TYPE_ID = 10; //код модуля Inet private static int INET_MODULE_ID = 20; //код модуля Inet private static int INET_DLINK_DEVICE_TYPE_ID = 3; //код модуля Inet private static int INET_MIKROTIK_DEVICE_TYPE_ID = 2; //код корня дерева устройств (устойство access+accountig в модуле Inet) private static int INET_ROOT_DEVICE_ID = 1; //код родительской опции в модуле Inet private static int INET_OPTION_ROOT_ID = 1; //код типа сервиса dlink модуля Inet private static int INET_SERV_TYPE_DLINK_ID = 1; //код типа сервиса mikrotik модуля Inet private static int INET_SERV_TYPE_MIKROTIK_ID = 2; //код универсальной категории белых Ip в модуле Inet public static int INET_IP_CATEGORY_WHITE_UNIVERSAL_ID = 3; //код универсальной категории серых Ip в модуле Inet public static int INET_IP_CATEGORY_GREY_UNIVERSAL_ID = 2; //коды неиспользуемых групп private static Set<Integer> unusedGroups = new HashSet<Integer>(); { unusedGroups.add( 5 ); unusedGroups.add( 10 ); unusedGroups.add( 11 ); } //коды неиспользуемых категорий ресурсов private static Set<Integer> unusedResources = new HashSet<Integer>(); { unusedResources.add( 13 ); unusedResources.add( 14 ); } //коды неиспользуемых шлюзов IPN private static Set<Integer> unusedGates = new HashSet<Integer>(); { unusedGates.add( 171 ); unusedGates.add( 172 ); } //связка кодов шлюзов папок со шлюзами микротик private static Map<Integer, Integer> mikrotikFolderMap = new HashMap<Integer, Integer>(); { //заря mikrotikFolderMap.put( 49, 7 ); //бугорок mikrotikFolderMap.put( 240, 239 ); //гальчино mikrotikFolderMap.put( 43, 52 ); //городок mikrotikFolderMap.put( 121, 143 ); //ильнское mikrotikFolderMap.put( 91, 89 ); //малино mikrotikFolderMap.put( 173, 172 ); //троицое mikrotikFolderMap.put( 219, 220 ); //харино mikrotikFolderMap.put( 174, 171 ); //цос mikrotikFolderMap.put( 65, 64 ); //южное mikrotikFolderMap.put( 131, 140 ); } private InetDeviceService wsDevice = null;; private ResourceService wsResource = null; private InetServService wsServ = null; Logger logger = Logger.getLogger( ConvertFromIPNToInet.class ); @Override public void execute( Setup setup, ConnectionSet connectionSet ) throws Exception { print ( "connectionSet.getAutoCommit()=" + connectionSet.getAutoCommit() ); ServerContext context = ServerContext.get(); ; wsDevice = context.getService( InetDeviceService.class, INET_MODULE_ID ); wsResource = context.getService( ResourceService.class, INET_MODULE_ID ); wsServ = context.getService( InetServService.class, INET_MODULE_ID ); Map<Integer, Integer> mapIpnInetCategories = new HashMap<Integer, Integer>(); //Map<Integer, Gate> dlinkGateMap = new HashMap<Integer, Gate>(); Map<Integer, InetDevice> dlinkIpnInetMap = new HashMap<Integer, InetDevice>(); Map<Integer, Gate> mikrotikGateMap = new HashMap<Integer, Gate>(); Map<Integer, InetOption > ipnInetOptionMap = new HashMap<Integer, InetOption>(); createIpResources( connectionSet, mapIpnInetCategories ); connectionSet.commit(); Map<Integer, InetDevice> mikrotikIpnInetMap = new HashMap<Integer, InetDevice>(); createDevices( connectionSet, mapIpnInetCategories, dlinkIpnInetMap, mikrotikGateMap, mikrotikIpnInetMap ); connectionSet.commit(); createOptions( connectionSet, ipnInetOptionMap ); connectionSet.commit(); createServices( connectionSet, dlinkIpnInetMap, ipnInetOptionMap, mikrotikGateMap, mikrotikIpnInetMap ); print ( "Ok" ); } private void createOptions( ConnectionSet connectionSet, Map<Integer, InetOption > ipnInetOptionMap ) throws BGException { Connection con = connectionSet.getConnection(); List<InetOption> list = wsServ.inetOptionList(); Map<String, InetOption> optMap = new HashMap<String, InetOption>(); for ( InetOption option : list ) { optMap.put( option.getTitle(), option ); } RuleTypeManager rtMan = new RuleTypeManager( con, IPN_MODULE_ID ); for( RuleType type : rtMan.getTypeList( ) ) { InetOption option = optMap.get( type.getTitle() ); if ( option == null ) { option = new InetOption(); } option.setTitle( type.getTitle() ); option.setComment( type.getComment() ); option.setParentId( INET_OPTION_ROOT_ID ); option.setConfig( type.getData() ); int id = wsServ.inetOptionUpdate( option ); if ( option.getId() <= 0 ) { option.setId( id ); } ipnInetOptionMap.put( type.getId(), option ); } } private void createIpResources( ConnectionSet connectionSet, Map<Integer, Integer> mapIpnInetCategories ) throws BGException { List<IpCategory> categoryList = wsResource.ipCategoryList(); Map<String, IpCategory> categoryMap = new HashMap<String, IpCategory>(); for ( IpCategory cat : categoryList ) { categoryMap.put( cat.getTitle(), cat ); } Connection con = connectionSet.getConnection(); List<IPResourceCategory> topLevelList = new IPResourceCategoryManager( con, IPN_MODULE_ID ).getCategoryTree(); for( IPResourceCategory category : topLevelList ) { if ( !unusedResources.contains( category.getId() ) ) { addSubcategories( category, wsResource.ipCategoryRoot(), categoryMap, con, mapIpnInetCategories ); } } } private void addSubcategories( IPResourceCategory categoryIPN, IpCategory categoryParent, Map<String, IpCategory> categoryMap, Connection con, Map<Integer, Integer> mapIpnInetCategories ) throws BGException { IpCategory cat = categoryMap.get( categoryIPN.getTitle() ); if ( cat == null ) { cat = new IpCategory(); categoryMap.put( categoryIPN.getTitle(), cat ); } cat.setTitle( categoryIPN.getTitle() ); cat.setParentId( categoryParent.getId() ); int id = wsResource.ipCategoryUpdate( cat ); if ( cat.getId() <= 0 ) { cat.setId( id ); } mapIpnInetCategories.put( categoryIPN.getId(), cat.getId() ); //print( "cat.id = " + cat.getId() ); IPNResourceManager resourceManager = new IPNResourceManager( con, IPN_MODULE_ID ); Iterable<IPResourceRange> resourceList = resourceManager.getResourceIterator( categoryIPN.getId(), 0, 0, false ); //удаляем все Set<Integer> cats = new HashSet<Integer>(); cats.add( cat.getId() ); for ( IpResource res : wsResource.ipResourceList( cats ) ) { wsResource.ipResourceDelete( res.getId() ); } for( IPResourceRange resource : resourceList ) { IpResource res = new IpResource(); res.setDateFrom( resource.getDateFrom() ); res.setDateTo( resource.getDateTo() ); res.setAddressFrom( Utils.convertIntToBytes( (int) resource.getIp1() ) ); res.setAddressTo( Utils.convertIntToBytes( (int) resource.getIp2() ) ); res.setCategoryId( cat.getId() ); res.setComment( "" ); wsResource.ipResourceUpdate( res ); } List<IPResourceCategory> subCategories = categoryIPN.getSubCategories(); if( subCategories != null ) { for( int index = 0; index < subCategories.size(); index++ ) { addSubcategories( subCategories.get( index ), cat, categoryMap, con, mapIpnInetCategories ); } } } private void createServices( ConnectionSet connectionSet, Map<Integer, InetDevice> dlinkIpnInetMap, Map<Integer, InetOption > ipnInetOptionMap, Map<Integer, Gate> mikrotikGateMap, Map<Integer, InetDevice> mikrotikIpnInetMap ) throws SQLException, BGException { Connection con = connectionSet.getConnection(); String query = "SELECT * FROM contract " + " LEFT JOIN contract_module as cm ON contract.id = cm.cid " + " WHERE cm.mid = " + IPN_MODULE_ID ; for ( Integer gr : unusedGroups ) { query += " AND contract.gr & (1 << " + gr + ") = 0"; } PreparedStatement ps = con.prepareStatement( query ); ResultSet rs = ps.executeQuery(); ContractModuleManager cmm = new ContractModuleManager( con ); AddressRangeManager adrRangeMan = new AddressRangeManager( con, IPN_MODULE_ID ); UserGateRuleManager userGateMan = new UserGateRuleManager( con, IPN_MODULE_ID ); ModuleSetup ipnSetup = new ModuleSetup( con, IPN_MODULE_ID ); IPNContractStatusManager statusManager = new IPNContractStatusManager( con , IPN_MODULE_ID, ipnSetup ); Date now = new Date(); m1: while ( rs.next() ) { int cid = rs.getInt( "contract.id" ); int ipnStatus = statusManager.getContractStatus( cid ); //удаленные договора игнорим if( ipnStatus == IPNContractStatus.STATUS_REMOVED ) { continue; } int inetStatus = InetServ.STATUS_ACTIVE; switch ( ipnStatus ) { case IPNContractStatus.STATUS_LOCK : case IPNContractStatus.STATUS_OPEN : inetStatus = InetServ.STATUS_ACTIVE; break; case IPNContractStatus.STATUS_REMOVED: case IPNContractStatus.STATUS_CLOSED : inetStatus = InetServ.STATUS_CLOSED; break; case IPNContractStatus.STATUS_HARD_LOCK : inetStatus = InetServ.STATUS_LOCKED; break; } for ( InetServ oldServ : wsServ.inetServList( cid ) ) { //во такой вот костыль чтобы удалить сервис, иначе не дает if ( oldServ.getDateTo() == null || TimeUtils.dateBefore( now, oldServ.getDateTo() ) ) { oldServ.setDateTo( TimeUtils.getPrevDay( now ) ); try { //logger.info( "updating serv date for cid = " + cid ); wsServ.inetServUpdate( oldServ, new ArrayList<InetServOption>(), false, false, 0 ); } catch( Exception e ) { String message = "Error while updating service date for contract " + cid + ":" + e.getMessage() ; logger.error( message, e ); print( message ); //logger.error( "", e ); continue; } } } //InetServ oldServ= wsServ.inetServGet( inetServId ); try { cmm.deleteContractModule( cid, INET_MODULE_ID ); cmm.addContractModule( cid, INET_MODULE_ID ); EventProcessor.getInstance().publishAfterCommit( new ContractModifiedEvent( User.USER_SERVER, cid ) ); } catch( Exception e ) { logger.error( "", e ); } List<AddressRange> ranges = adrRangeMan.getContractAddressRange( cid, TimeUtils.convertDateToCalendar( now ), -1 ); List<UserGateRule> rules = userGateMan.getUserGateRules( cid ); //UserGateRule dlinkRule = null; //UserGateRule mikrotikRule = null; List<UserGateRule> dlinkRules = new ArrayList<UserGateRule>(); List<UserGateRule> mikrotikRules = new ArrayList<UserGateRule>(); for( UserGateRule rule : rules ) { if( dlinkIpnInetMap.containsKey( rule.getGateId() ) ) { dlinkRules.add( rule ); //dlinkRule = rule; } else if( mikrotikGateMap.containsKey( rule.getGateId() ) ) { //mikrotikRule = rule; mikrotikRules.add( rule ); } } //Gate dlinkGate = dlinkGateMap.get( dlinkRule.getGateId() ); /* Set<Integer> options = new HashSet<Integer>(); if ( mikrotikRule != null ) { InetOption option = ipnInetOptionMap.get( mikrotikRule.getRuleTypeId() ); if ( option != null ) { options.add( option.getId() ); } else { } } */ //если нет алресов , то и ничего переносить if( ranges.size() == 0 ) { continue; } //если есть адреса, но нет dlink-а и mikrotik-а, то ругаемся if( dlinkRules.size() == 0 && mikrotikRules.size() == 0 ) { logger.info( "There is no dlink or mikrotik on contact " + cid + ";ipnStatus=" + ipnStatus ); print( "There is no dlink on contact " + cid + ";ipnStatus=" + ipnStatus ); continue; } //String dlinkRuleText = "" ; List<Map<Long, Integer>> dlinkIpPortMaps = new ArrayList<Map<Long,Integer>>(); //Map<String, Integer> ipPortMap = new HashMap<String, Integer>(); if( dlinkRules.size() != 0 ) { for( UserGateRule dlinkRule : dlinkRules ) { String dlinkRuleText = dlinkRule.getRuleText(); Map<Long, Integer> dlinkIpPortMap = getPorts( dlinkRuleText ); dlinkIpPortMaps.add( dlinkIpPortMap ); } } //String mikrotikRuleText = ""; //if ( mikrotikRule != null ) //{ //mikrotikRuleText = mikrotikRule.getRuleText(); //} List<Set<Long>> mikrotikIpSets = new ArrayList<Set<Long>>(); for( UserGateRule mikRule : mikrotikRules ) { String mikrotikRuleText = mikRule.getRuleText(); Set<Long> mikrotikISet = getIp( mikrotikRuleText ); mikrotikIpSets.add( mikrotikISet ); } //Set<Long> ipSet = getIp( mikrotikRuleText ); for( AddressRange range : ranges ) { List<Long> mikrotikIps = new ArrayList<Long>(); UserGateRule curMikrotikRule =null; for( long ip = range.getAddr1(); ip <= range.getAddr2(); ip++ ) { //boolean isMikrotik = false; Integer port = null; UserGateRule dlinkRule = null; for( int i = 0; i < dlinkRules.size(); i++ ) { port = dlinkIpPortMaps.get( i ).get( ip ); if( port != null ) { dlinkRule = dlinkRules.get( i ); break; } } UserGateRule mikrotikRule =null; if( dlinkRule == null ) { for( int i = 0; i < mikrotikRules.size(); i++ ) { if( mikrotikIpSets.get( i ).contains( ip ) ) { // isMikrotik = true; mikrotikRule = mikrotikRules.get( i ); if( curMikrotikRule != null && curMikrotikRule != mikrotikRule ) { String mess = "Error: range belongs to diffrent mikrotiks ;cid=" + cid; print( mess ); logger.error( mess ); } curMikrotikRule = mikrotikRule; break; } } } //если нет порта в dlink и нет привязки в микротик, то игнорим ip if( dlinkRule == null && mikrotikRule == null ) { /*//print( "port is null for contract " + cid ); //String str = getIpFromSet( ipPortMaps.get( i).keySet() ); String allPorts = ""; for( int i = 0; i < dlinkRules.size(); i++ ) { for( Map.Entry<Long, Integer> entry : dlinkIpPortMaps.get( i ).entrySet() ) { allPorts += IPUtils.convertLongIpToString( entry.getKey() ) + "=" + entry.getValue() + ","; } } String allIPs = ""; for( int i = 0; i < mikrotikRules.size(); i++ ) { allIPs += getIpFromSet( mikrotikIpSets.get( i ) ); } String message = "empty ip for contract " + cid+ ";ip=" + IPUtils.convertLongIpToString( ip ) + ";dlinkRule=" + dlinkRule + ";dlinkIpPortMap=" + allPorts + ";mikrotikRule=" + mikrotikRule + " mikrotikIps= " + allIPs; logger.info( message ); print ( message ); */ continue; } if ( dlinkRule != null ) { InetServ serv = new InetServ(); serv.setContractId( cid ); serv.setComment( "Импортирован из IPN" ); serv.setDateFrom( now ); serv.setDateTo( TimeUtils.convertCalendarToDate( range.getDate2() ) ); serv.setLogin( "" ); serv.setPassword( "" ); serv.setStatus( inetStatus ); serv.setTypeId( INET_SERV_TYPE_DLINK_ID ); InetDevice device = dlinkIpnInetMap.get( dlinkRule.getGateId() ); if ( device == null ) { //print( "device is null for contract " + cid ); logger.info( "Dlink device is null for contract " + cid ); print( "mikrotik device is null for contract " + cid ); continue; } serv.setDeviceId( device.getId() ); serv.setInterfaceId( port ); serv.setAddressFrom( Utils.convertIntToBytes( (int) ip ) ); serv.setAddressTo( Utils.convertIntToBytes( (int) ip ) ); updateServ( cid, serv ); } else { mikrotikIps.add( ip ); } } Collections.sort( mikrotikIps ); if ( mikrotikIps.size() > 0 ) { //проверяем есть ли пропущенные ip в диапазоне long start = mikrotikIps.get( 0 ); long end = mikrotikIps.get( mikrotikIps.size() - 1 ); boolean ragged = false; int c = 0; for ( long i = start; i <= end; i++ ) { if ( c >= mikrotikIps.size() || ( i != mikrotikIps.get( c++ ) ) ) { ragged = true; break; } } String ips = getIpFromSet( mikrotikIps ); //logger.info( "add mikrotikIps=" + ips + ";cid=" +cid + ";ragged=" + ragged ); if ( ragged ) { print( "error: ranges are ragged;cid=" + cid ); logger.error( "error: ranges are ragged;cid=" + cid ); continue; } InetServ serv = new InetServ(); serv.setContractId( cid ); serv.setComment( "Импортирован из IPN" ); serv.setDateFrom( now ); serv.setDateTo( TimeUtils.convertCalendarToDate( range.getDate2() ) ); serv.setLogin( "" ); serv.setPassword( "" ); serv.setStatus( inetStatus ); serv.setTypeId( INET_SERV_TYPE_MIKROTIK_ID ); InetDevice device = mikrotikIpnInetMap.get( curMikrotikRule.getGateId() ); if( device == null ) { //print( "device is null for contract " + cid ); logger.info( "mikrotik device is null for contract " + cid ); print( "mikrotik device is null for contract " + cid ); continue; } serv.setDeviceId( device.getId() ); serv.setAddressFrom( Utils.convertIntToBytes( (int) start ) ); serv.setAddressTo( Utils.convertIntToBytes( (int) end ) ); updateServ( cid, serv ); } } } ps.close(); } private void updateServ( int cid, InetServ serv ) { try { //logger.info( "updating serv for cid = " + cid ); wsServ.inetServUpdate( serv, new ArrayList<InetServOption>(), false, false, 0 ); } catch( Exception e ) { String message = "Error while updating service for contract " + cid + ":" + e.getMessage(); logger.error( message, e ); print( message ); //logger.error( "", e ); } } private String getIpFromSet( Collection<Long> mikrotikIps ) { String ips = ""; for ( long ip : mikrotikIps) { ips += IPUtils.convertLongIpToString( ip ) + ","; } return ips; } private Map<Long, Integer> getPorts( String ruleText ) { Map<Long, Integer> result = new HashMap<Long, Integer>(); if ( Utils.isEmptyString( ruleText ) ) { return result; } String parts[] = ruleText.split( ";" ); for ( String part : parts ) { if ( Utils.isEmptyString( part ) ) { continue; } String parts2[] = part.split( ":" ); if ( parts2.length < 2 ) { print( "wrong port " + part ); continue; } result.put( IPUtils.convertStringIPtoLong( parts2[1] ), Integer.valueOf( parts2[0] ) ); } return result; } private Set<Long> getIp( String ruleText ) { Set<Long> result = new HashSet<Long>(); if ( Utils.isEmptyString( ruleText ) ) { return result; } String parts[] = ruleText.split( ";" ); String ipStr = ""; if ( parts.length > 0 ) { ipStr = parts[0]; } if ( Utils.isEmptyString( ipStr ) ) { return result; } String parts2[] = ipStr.split( "," ); for ( String ip : parts2 ) { if ( Utils.isEmptyString( ip ) ) { continue; } result.add( Long.valueOf( ip ) ); } return result; } private void createDevices( ConnectionSet connectionSet, Map<Integer, Integer> mapIpnInetCategories, Map<Integer, InetDevice> dlinkIpnInetMap, Map<Integer, Gate> mikrotikGateMap, Map<Integer, InetDevice> mikrotikIpnInetMap ) throws BGException { List<InetDevice> inetDevicelist = new ArrayList<InetDevice>(); inetDevicelist.addAll( wsDevice.deviceList( INET_DLINK_DEVICE_TYPE_ID ) ); inetDevicelist.addAll( wsDevice.deviceList( INET_MIKROTIK_DEVICE_TYPE_ID ) ); Map<String, InetDevice> inetDeviceMap = new HashMap<String, InetDevice>(); for ( InetDevice device : inetDevicelist ) { inetDeviceMap.put( device.getHost(), device ); } Connection con = connectionSet.getConnection(); GateManager man = new GateManager( con, IPN_MODULE_ID ); Map<Integer, InetDevice> ipnFolderInetDeviceMap = new HashMap<Integer, InetDevice>(); createMikrotikDevcices( inetDeviceMap, man, ipnFolderInetDeviceMap, mapIpnInetCategories, mikrotikGateMap, mikrotikIpnInetMap ); createDlinkDevices( inetDeviceMap, man, ipnFolderInetDeviceMap, dlinkIpnInetMap ); } private void createDlinkDevices( Map<String, InetDevice> inetDeviceMap, GateManager man, Map<Integer, InetDevice> ipnFolderInetDeviceMap, Map<Integer, InetDevice> dlinkIpnInetMap ) throws BGException { GateFilter filter = new GateFilter(); filter.setType( IPN_DLINK_GATE_TYPE_ID ); List<Gate> dlinkGates = man.getGatesList( filter ); InetDeviceType type = wsDevice.deviceTypeGet( INET_DLINK_DEVICE_TYPE_ID ); for ( Gate gate : dlinkGates ) { String hostPort = gate.getHost() + ":" + gate.getPort(); InetDevice device = inetDeviceMap.get( hostPort ); if ( device == null ) { device = new InetDevice(); inetDeviceMap.put( hostPort, device ); } Preferences gateSetup = new Preferences( gate.getConfig(), "\r\n" ); int mikrotikGateId = mikrotikFolderMap.get( gate.getParentId() ); if ( unusedGates.contains( mikrotikGateId ) ) { //print ( "Parent Gate " + mikrotikGateId + " was skipped.all( " + unusedGates + ")" ); continue; } device.setHost( hostPort ); device.setPassword( gate.getKeyword() ); device.setUsername( gateSetup.get ( "login", null ) ); device.setSecret( gateSetup.get( "enablepwd", null) ); device.setComment( gate.getComment() ); device.setDeviceTypeId( INET_DLINK_DEVICE_TYPE_ID ); device.setTitle( Device.generateTitle( device, type ) ); device.setIdentifier( "" ); device.setConfig(""); device.setDeviceGroupIds( new HashSet<Integer>() ); InetDevice parent = ipnFolderInetDeviceMap.get( gate.getParentId() ); device.setParentId( parent.getId() ); int id = wsDevice.deviceUpdate( device ); if ( device.getId() <= 0 ) { device.setId( id ); } dlinkIpnInetMap.put( gate.getId(), device ); } } private void createMikrotikDevcices( Map<String, InetDevice> inetDeviceMap, GateManager man, Map<Integer, InetDevice> ipnFolderInetDeviceMap, Map<Integer, Integer> mapIpnInetCategories, Map<Integer, Gate> mikrotikGateMap, Map<Integer, InetDevice> mikrotikIpnInetMap ) throws BGException { GateFilter filter = new GateFilter(); filter.setType( 0 ); List<Gate> folderGates = man.getGatesList( filter ); filter.setType( IPN_MIKROTIK_GATE_TYPE_ID ); List<Gate> mikrotikGates = man.getGatesList( filter ); for ( Gate gate : mikrotikGates ) { mikrotikGateMap.put( gate.getId(), gate ); } InetDeviceType type = wsDevice.deviceTypeGet( INET_MIKROTIK_DEVICE_TYPE_ID ); for ( Gate foldeGate : folderGates ) { int mikrotikGateId = mikrotikFolderMap.get( foldeGate.getId() ); Gate gate = mikrotikGateMap.get( mikrotikGateId ); if ( gate == null ) { print ( "Gate was not found for " + mikrotikGateId ); } if ( unusedGates.contains( gate.getId() ) ) { print ( "Gate " + gate.getId() + " was skipped " ); continue; } String hostPort = gate.getHost() + ":" + gate.getPort(); InetDevice device = inetDeviceMap.get( hostPort ); if ( device == null ) { device = new InetDevice(); inetDeviceMap.put( hostPort, device ); } Preferences gateSetup = new Preferences( gate.getConfig(), "\r\n" ); String oldCatsStr = gateSetup.get( "ip.resource.categoryId", "" ); List<Integer> oldCats = Utils.toIntegerList( oldCatsStr ); List<Integer> newCats = new ArrayList<Integer>(); for ( Integer oldCatId : oldCats ) { Integer newCatId = mapIpnInetCategories.get( oldCatId ); if ( newCatId != null ) { newCats.add( newCatId ); } } //всем добавляем универсальную белую категорию newCats.add( INET_IP_CATEGORY_WHITE_UNIVERSAL_ID ); newCats.add( INET_IP_CATEGORY_GREY_UNIVERSAL_ID ); String config = ""; if ( !Utils.isEmptyString( Utils.toString( newCats ) ) ) { config += "ip.resource.categoryId=" + Utils.toString( newCats ); } device.setHost( hostPort ); device.setPassword( gate.getKeyword() ); device.setUsername( gateSetup.get( "login", "root" ) ); device.setComment( gate.getComment() ); device.setDeviceTypeId( INET_MIKROTIK_DEVICE_TYPE_ID ); device.setParentId( INET_ROOT_DEVICE_ID ); device.setTitle( Device.generateTitle( device, type ) ); device.setIdentifier( "" ); device.setSecret( "" ); device.setConfig( config ); device.setDeviceGroupIds( new HashSet<Integer>() ); int id = wsDevice.deviceUpdate( device ); if ( device.getId() <= 0 ) { device.setId( id ); } ipnFolderInetDeviceMap.put( foldeGate.getId(), device ); mikrotikIpnInetMap.put( gate.getId(), device ); } } }