BiTel

Форум BiTel
bgbilling.ru     docs.bitel.ru     wiki.bitel.ru     dbinfo.bitel.ru     bgcrm.ru     billing.bitel.ru     bitel.ru    
Текущее время: 21 июн 2025, 00:23

Часовой пояс: UTC + 5 часов [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 44 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Оптимизация конфига устройств
СообщениеДобавлено: 24 сен 2012, 12:59 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Сейчас для radius-устройств соответствие "опция" -> "набор радиус-атрибутов" прописывается напрямую.
Выглядит это примерно так:
Вложение:
options.png

Соответственно, в конфиге типа устройства нужно будет прописывать однотипные атрибуты для каждого:
Код:
radius.inetOption.12.attributes=cisco-SSG-Account-Info=AINET478
radius.inetOption.55.attributes=cisco-SSG-Account-Info=AINET650
...(несколько десятков строк)...


ISG:
Код:
radius.inetOption.12.attributes=cisco-SSG-Service-Info=IINET478;{@accounting900.isgservice.attributes};{@internet.default.attributes};cisco-SSG-Service-Info=QU;;478000;;89625;;D;;478000;;89625
radius.inetOption.55.attributes=cisco-SSG-Service-Info=IINET650;{@accounting900.isgservice.attributes};{@internet.default.attributes};cisco-SSG-Service-Info=QU;;650000;;121875;;D;;65000;;121875
...(несколько десятков строк)...



Для redback:
Код:
radius.inetOption.12.attributes=Service-Name:3=RSE-BASIC-INET;Service-Options:3=1;Service-Parameter:3=Rate-Inet=478 Burst-Inet=59750 ExBurst-Inet=119500
radius.inetOption.55.attributes=Service-Name:3=RSE-BASIC-INET;Service-Options:3=1;Service-Parameter:3=Rate-Inet=650 Burst-Inet=81250 ExBurst-Inet=162500
...(несколько десятков строк)...


А ещё есть группа LOCAL и т.п. ...

Удобнее было бы определить один шаблон для всех дочерних опций в группе "[INET]":
Код:
radius.inetOption.1.template=cisco-SSG-Account-Info=A<name>


Код:
radius.inetOption.1.template=cisco-SSG-Service-Info=I<name>;{@accounting900.isgservice.attributes};{@internet.default.attributes};cisco-SSG-Service-Info=QU;;<speed>000;;<cisco.burst>;;D;;<speed>000;;<cisco.burst>


Код:
radius.inetOption.1.template=Service-Name:3=RSE-BASIC-INET;Service-Options:3=1;Service-Parameter:3=Rate-Inet=<speed> Burst-Inet=<redback.burst> ExBurst-Inet=<redback.exburst>


Где 1 - код опции-группы "[INET]".
Параметры задавать в конфиге опции INET:
Вложение:
inet650.png


План такой:
В AbstractRadiusServiceActivator.init() :
1. подключаемся к mysql, выгребаем нужные конфиги опций.
2. запиливаем optionRadiusAttributesMap по шаблонам из конфига устройства "radius.inetOption.x.template" для всех дочерних опций опции x.
3. добавляем в optionRadiusAttributesMap явно определённые атрибуты из "radius.inetOption.y.attributes", если такие есть.

Плюсы:
+ Скорости указываются в одном месте, наглядно.
+ Можно использовать один параметр опции для нескольких типов устройств (один и тот же speed по-разному трактовать для разных типов устройств например)
+ Сокращается размер конфига устройства/типа устройства.

Минусы:
- Ломается обработка в ISGPPPoEServiceActivator, где соответствие "опция->сервис ISG" выгребается из radius.inetOption.<y>.attributes. Но, имхо, это потому, что так выгребать изначально неправильно. Логичнее получать из optionRadiusAttributesMap например.

Могу написать код, скажем, RadiusAttributeSet.newRadiusAttributeSetRealmMapByTemplate(...)
Уже сделал нечто подобное для своего RedBack ServiceActivator-а, только более костыльно.

Что скажут разработчики? :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 24 сен 2012, 13:04 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Цитата:
- Ломается обработка в ISGPPPoEServiceActivator, где соответствие "опция->сервис ISG" выгребается из radius.inetOption.<y>.attributes.

У себя обошёл через создание "подставного" конфига устройства, в котором шаблон "radius.inetOption.x.template" превращён в набор "radius.inetOption.y.attributes":

Код:
ParameterMap newDeviceConfig = deviceConfig.inherit(pConf);
super.init( setup, moduleId, device, deviceType, newDeviceConfig );


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 24 сен 2012, 13:06 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Плюс, можно подумать и реализовать простенький калькулятор, чтобы burst брать не из конфига, а рассчитывать по формулам.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 26 сен 2012, 12:54 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Нет, ну правда!

Картинка для привлечения внимания:
Изображение


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 27 сен 2012, 14:50 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Изображение


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 02 окт 2012, 21:50 
Не в сети
Клиент

Зарегистрирован: 12 фев 2008, 18:10
Сообщения: 3951
Карма: 249
Изображение

Ну ты понел ...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 03 окт 2012, 00:21 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 29 мар 2010, 23:11
Сообщения: 5854
Карма: 472
Вложение:
9598592.png

Так лучше :lol:

_________________
Цитаты великих людей :umnik:
Напишите в helpdesk © stark
повторяю: => хелпдеск => доработка => профит © dimOn
свершилось... © skn
Мой код изящен, лёгок, оригинален, краток. Как прохладный весенний ветерок, как звонкий ручей! © dimOn
Вежливый разработчик © Artur
Эти баги тоже исправлены, как и те, которые еще не написаны © Artur
ну т.е. существует воркэраунд, ок © dimOn


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 03 окт 2012, 14:31 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
А для чего radius.inetOption.1.template, а не radius.inetOption.template, например?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 04 окт 2012, 06:25 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Цитата:
Где 1 - код опции-группы "[INET]".

разным группам опций - разные шаблоны


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 13 ноя 2012, 12:38 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Запилил.
Потестировал предварительно. На практике ещё не применял.

Изменил бителовский dyn-класс AbstractRadiusServiceActivator
Ещё нужно поправить ISGPPPoEServiceActivator, чтобы брал соответствие "опция"-"сервис ISG" не из конфига, а из optionRadiusAttributesMap.

Поскольку при обновлении это всё перетрётся, то скорее всего сделаю свой AbstractRadiusServiceActivator, в своём package, и все стандартные активаторы скопирую туда. Короче, заведу себе отдельный branch. Может быть попозже выложу куда-нибудь.
Так или иначе, всё равно буду переделывать активаторы под себя ведь. Можно конечно каждый раз просить разработчиков внедрять более-менее абстрактные фичи у себя, но это муторно и опасно для них.

Возникает такой вопрос - как быть с копирайтом, если я скопипастил, скажем ru.bitel.bgbilling.modules.inet.dyn.device.radius.AbstractRadiusServiceActivator
в ru.dsi.bgbilling.modules.inet.dyn.device.radius.AbstractRadiusServiceActivator, поменял там кой-чего и выложил здесь, или на github например?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 13 ноя 2012, 12:40 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
diff:

Код:
5,9c5,7
< import java.util.Arrays;
< import java.util.HashSet;
< import java.util.List;
< import java.util.Map;
< import java.util.Set;
---
> import java.util.*;
> import java.util.regex.Matcher;
> import java.util.regex.Pattern;
14a13,14
> import ru.bitel.bgbilling.common.BGException;
> import ru.bitel.bgbilling.kernel.container.managed.ServerContext;
28a29,30
> import ru.bitel.bgbilling.modules.inet.api.common.bean.InetOption;
> import ru.bitel.bgbilling.modules.inet.api.server.bean.InetOptionDao;
31a34,35
> import ru.bitel.common.Preferences;
> import ru.bitel.common.TreeUtils;
32a37
> import ru.bitel.common.worker.ThreadContext;
50a56,60
>     /**
>      * id модуля
>      */
>     protected int moduleId;
>
157a168
>         this.moduleId = moduleId;
185c196,204
<               optionRadiusAttributesMap = RadiusAttributeSet.newRadiusAttributeSetRealmMap( deviceConfig, deviceConfig.get( "sa.radius.option.attributesPrefix", defaultOptionsPrefix ), "attributes" );
---
>         String optionsPrefix = deviceConfig.get( "sa.radius.option.attributesPrefix", defaultOptionsPrefix );
>         String param = "attributes";
>         ParameterMap newDeviceConfig = deviceConfig;
>         try{
>             newDeviceConfig = parseInetOptionRadiusAttributesTemplates(deviceConfig, optionsPrefix, "template", param);
>         }catch (BGException e){
>             logger.error("Error parsing option radius attribute templates: ", e);
>         }
>               optionRadiusAttributesMap = RadiusAttributeSet.newRadiusAttributeSetRealmMap( newDeviceConfig, optionsPrefix, param );
359a379,550
>
>     /**
>      * Функция обрабатывает конфиг устройства, находит в нём вхождения вида <prefix><option_id>.<param>=<template> или
>      * <prefix><option_id>.<realm>.<param>=<template> и добавляет соответствующие параметры в результирующий конфиг для всех
>      * дочерних опций sub_option_id опции option_id:
>      * <prefix><sub_option_id>.<targetParam>=<value> или <prefix><sub_option_id>.<realm>.<targetParam>=<value>
>      * значение параметра value получается из шаблона template подстановкой значений параметров из конфига опции.
>      * Например cisco-SSG-Service-Info=QU;;$(speed)000;;$(cisco.burst);;D;;$(speed)000;;$(cisco.burst)
>      * ->
>      * [
>      * speed=100
>      * cisco.burst=50000
>      * ]
>      * ->
>      * cisco-SSG-Service-Info=QU;;100000;;50000;;D;;100000;;50000
>      * При этом конфиги опций наследуются, начиная с родительской option_id
>      * Также при обработке дерева к конфигу опции добавляется параметр name=option.getTitle(), т.е. в шаблонах можно
>      * использовать параметр $(name) - имя опции
>      *
>      * @param deviceConfig  - исходный конфиг устройства
>      * @param prefix        - ex "radius.inetOption."
>      * @param param         - ex "template"
>      * @param targetParam   - ex "attributes"
>      * @return возвращает новый конфиг устройства, в который добавлены атрибуты опций, полученные по шалонам
>      * @see #insertVariablesValues(String, ru.bitel.common.ParameterMap)
>      * @see #processSubTree
>      */
>     private ParameterMap parseInetOptionRadiusAttributesTemplates(ParameterMap deviceConfig,
>                                                                   String prefix, String param, String targetParam) throws BGException {
>         Map<String, String> conf = new HashMap<String, String>();
>         ServerContext ctx = (ServerContext) ThreadContext.get();
>         InetOptionDao inetOptionDao = new InetOptionDao(ctx.getConnectionSet().getSlaveConnection(), this.moduleId);
>
>         //Список всех опций
>         List<InetOption> optionList = inetOptionDao.list();
>         //Карта : id опции -> опция из optionList
>         Map<Integer, InetOption> optionMap = new HashMap<Integer, InetOption>();
>         for (InetOption d : optionList)
>         {
>             optionMap.put(d.getId(), d);
>         }
>         //Строим полное дерево опций
>         InetOption root = new InetOption();
>         root.setGroupIntersection(true);
>         root = TreeUtils.tree(optionList, root);//Теперь всем опциям из optionList назначены потомки
>
>         //
>         //Можно было бы зайти с другой стороны - перебирать все параметры вида "prefix<id>.param", брать по id опцию и
>         //обрабатывать её поддерево, но тогда нарушается порядокобработки - если в дереве одной опции с шаблоном будет
>         //другой шаблон, то не факт, что последний перетрётся. В случае с рекурсивным перебором - всё ок
>         processTree(root,deviceConfig,conf,prefix,param,targetParam);
>         //перебираем все ,  например radius.inetOption.1.template
>
>         inetOptionDao.recycle();
>
>         //Поверх полученных значений пишем значения из конфига, т.к. они более приоритетны, чем шаблоны.
>         //Т.е. если в deviceConfig задать шаблон radius.inetOption.10.template = xxx и
>         //radius.inetOption.12.attributes = yyy, где опция 12 лежит в субветке опции 10,
>         //то radius.inetOption.12.attributes будет приоритетнее
>         ParameterMap newConf = (new Preferences(conf)).inherit(deviceConfig);
>
>         return newConf;
>     }
>
>     /**
>      * Рекурсивная обработка всех опций модуля Inet - если для какой то опции в конфиге устройства deviceConfig найдётся
>      * параметр <prefix><option_id>.<param>=... или параметр <prefix><option_id>.<realmname>.<param>=... ,
>      * то опять же рекурсивно обрабатываем субдерево для этой опции: см. processSubTree
>      *
>      * @param node
>      * @param deviceConfig
>      * @param conf
>      * @param prefix
>      * @param param
>      * @param targetParam
>      *
>      * @see #processSubTree(ru.bitel.bgbilling.modules.inet.api.common.bean.InetOption, java.util.Map, String, String, String, ru.bitel.common.ParameterMap)
>      */
>     private void processTree(InetOption node, ParameterMap deviceConfig, Map<String, String> conf, String prefix, String param, String targetParam){
>         ParameterMap sub = deviceConfig.sub(prefix+node.getId()+".");
>         if(null==sub){return;}
>         String templateValue;
>         String targetParamLocal;
>
>         for(Map.Entry<String, ParameterMap> e : sub.subKeyed("").entrySet()){
>             targetParamLocal = targetParam; //"attributes"
>             if(param.equals(e.getKey())){//radius.inetOption.1.template=<templateValue>
>                 templateValue=e.getValue().get("", null);
>             }else{//radius.inetOption.1.<realm>.template
>                 templateValue=e.getValue().get(param, null);
>                 targetParamLocal=e.getKey()+"."+targetParam; //"<realm>.attributes"
>             }
>             if(null!=templateValue){
>                 //рекурсивно обрабатываем поддерево
>                 this.processSubTree(node, conf, prefix, targetParamLocal, templateValue, null);
>             }
>         }
>
>         //рекурсия
>         if(node.getChildren()!=null){
>             for (InetOption child : node.getChildren()){
>                 processTree(child, deviceConfig, conf, prefix, param, targetParam);
>             }
>         }
>     }
>
>     /**
>      * Рекурсивно обрабатываем поддерево опций модуля Inet, пишем в конфиг conf параметры <prefix><node.id>.<param>=parseTemplate(templateValue)
>      * @param node - родительский узел, должен содержать потомков в getChildren()
>      * @param conf - итоговый конфиг, куда пишем результаты
>      * @param prefix - префикс параметра конфига, например "inetOption."
>      * @param param - суффикс параметра, например "attributes"
>      * @param templateValue - шаблон значения параметра. обрабатывается функцией insertVariablesValues
>      * @param parentNodeConf - значение родительский конфиг. Необходимо для наследования конфигов в пределах поддерева. Может быть null.
>      * @see #insertVariablesValues(String, ru.bitel.common.ParameterMap)
>      */
>     private void processSubTree(InetOption node, Map<String, String> conf, String prefix, String param, String templateValue, ParameterMap parentNodeConf){
>         ParameterMap nodeConf = new Preferences(node.getConfig(), "\n");
>         //Добавляем в конфиг опции параметр name=<имя_опции>
>         ((Preferences)nodeConf).set("name", node.getTitle());
>         //Конфиг для опций будет наследоваться внутри субветки
>         if(parentNodeConf!=null){
>             nodeConf = parentNodeConf.inherit(nodeConf);
>         }
>
>         //Обрабатываем шаблон, добавляем текущий узел в итоговый конфиг
>         //ex: radius.inetOption.<id>.attributes=blablabla;foo;
>         conf.put(prefix+node.getId()+"."+param, insertVariablesValues(templateValue, nodeConf));
>
>         //рекурсивно обрабатываем дочерние узлы
>         if(node.getChildren()!=null){
>             for(InetOption child : node.getChildren()){
>                 processSubTree(child, conf, prefix, param, templateValue, nodeConf);
>             }
>         }
>     }
>
>     /**
>      * Подстановка переменных из data в value по шаблону "blabla$(varibale.1.value)" -> "blabla123"
>      * @param value example: $(speed)000;;$(cisco.burst);;D;;$(speed)000;;$(cisco.burst)
>      * @param data соответствие значений, например: speed=100, cisco.burst=50000
>      * @return
>      */
>     private String insertVariablesValues(String value, ParameterMap data){
>
>         Matcher m = Pattern.compile("\\$\\(([\\w\\.]+)\\)").matcher(value);
>         if (m.find()){
>             StringBuffer newValue = new StringBuffer(value.length() + 16);
>             String varName = m.group(1);
>
>             String var = data.get(varName, null);
>             if (var != null){
>                 var = Matcher.quoteReplacement(var);
>                 m.appendReplacement(newValue, var);
>             }
>
>             while (m.find()){
>                 var = data.get(m.group(1), null);
>                 if (var == null)
>                     continue;
>                 var = Matcher.quoteReplacement(var);
>                 m.appendReplacement(newValue, var);
>             }
>
>             m.appendTail(newValue);
>
>             return newValue.toString();
>         }
>
>         return value;
>     }
>


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 16 ноя 2012, 07:24 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
FAIL

Опции конфигурации "radius.inetOption" читаются ещё и самим InetNas-ом, вне динамического кода.

Итого, этот конфиг используется напрямую в 3 местах:
- InetNas
- AbstractRadiusServiceActivator
- ISGPPPoEServiceActivator

абстракция, my ass


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 16 ноя 2012, 08:34 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Фактически, в таком виде опции опции модуля Inet ничем не отличаются от наборов радиус-атрибутов.

Посмотрим, что даёт нам прямая привязка "опция"->"набор радиус атрибутов":

- Выдача атрибутов radiusProcessor-ом при подключении (InetNas).
- Выдача атрибутов serviceActivator-ом при подключении опции
Но тут возникают вопросы:
- что делать при отключении опции?
- как быть, если логика устройства более сложная, чем прямое соответствие "опция"-"набор радиус-атрибутов"?

Например, SmartEdge 100:
Цитата:
Допустим, к у клиента было 2 сервиса: inet (интернет) и dsiserv (доступ к нашим серверам в отдельную трубу). Если мы хотим поменять их параметры, то проблем нет - в зависимости от опций модуля посылаем CoA и радуемся. Но если мы захотим подключить третий сервис, скажем, local (локальный трафик в отдельную трубу), то придется сначала сменить ему набор разрешенных сервисов. Набор сервисов задаётся радиус-атрибутами QoS-Policing-Profile-Name и QoS-Metering-Profile-Name. Параметры конкретного сервиса - RSE-Service-Name.
(с) внутренняя документация
Т.е. появляется ещё одна сущность - "пакет сервисов", который должен строиться на основе активных в данный момент опций. Эту логику можно реализовать в ServiceActivator-е, но только для смены сервисов. При первичной авторизации же отрабатывает стандартный RadiusProcessor.

Т.о. логика работы устройства вынесена в ServiceActivator не полностью.
Первичную авторизацию нужно тоже прогонять через ServiceActivator.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 16 ноя 2012, 08:34 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Это как сделать крутой MVC-веб-фреймворк, но захардкодить стартовую страницу.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 16 ноя 2012, 12:12 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Другой пример, когда на основе опций строится профиль для оборудования - Cisco SCE. Там на железке преконфигурируются packageId - id профиля, назначаемого абоненту. А индивидуально скорости на разные типы трафика например, или другие параметры, задать нельзя.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 16 ноя 2012, 13:32 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
А какую логику лучше в ServiceActivator(тут скорее ProtocolHandler, по принципу вызовов методов он больше подходит), кроме выдачи атрибутов, вынести?
Все-таки не хочется усложнять и весь InetRadiusProcessor туда переносить.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 16 ноя 2012, 14:04 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Хм, я подумаю.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 19 ноя 2012, 10:33 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Посмотрел класс InetRadiusProcessor. Вроде больше ничего не нужно выносить в активатор.

Amir писал(а):
тут скорее ProtocolHandler, по принципу вызовов методов он больше подходит

ProtocolHandler на более низком уровне работает - обрабатывает радиус-пакеты и ничего не знает об опциях и InetConnection.

Мне кажется, логично вынести из InetRadiusProcessor.authorization() логику назначения атрибутов по опциям:
Код:
nas.addRadiusAttributes(...)

в ServiceActivator.onAuthAccept(...)
При этом, если connection.start.fromAccept=1, то в метод можно сразу передавать и InetConnection, на всякий случай.
Туда же попадает выдача атрибутов для disable realm-а.
Старую логику сделать в виде затычки в ServiceActivatorAdapter.

Что думаете?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 19 ноя 2012, 14:11 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
Цитата:
ProtocolHandler на более низком уровне работает - обрабатывает радиус-пакеты и ничего не знает об опциях и InetConnection.
В этом согласен, но проблема в том, что этот метод будет вызываться не так, как connectionModify - без предварительных вызовов connect и последующем disconnect, к тому же вообще в других(сразу многих) потоках - т.е. так же, как сейчас происходит вызов в ProtocolHander.
Как бы не привело к путанице (например, использовании одного и того же java.sql.Connection в connectionModify и onAuthAccept).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 19 ноя 2012, 14:36 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Хм, ну да, тогда получается ближе к предобработке. Тогда и InetConnection не нужно передавать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 19 ноя 2012, 15:24 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Завтра посмотрю, как радиус-атрибуты для InetNas можно причесать.
Получается, атрибуты выдаются и Nas-ом стандартно, и ServiceActivator-ом. Надо подумать, как это можно объединить и абстрагировать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 20 ноя 2012, 08:13 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Получается, логика работы с радиус-атрибутами размазана по классам:
InetNas
ProtocolHandler
ServiceActivator

Это:
- выдача атрибутов для reaml-а
- атрибуты сервиса
- disable-атрибуты
- атрибуты на основе опций

При этом многие вещи дублируются, например проверка состояния сессии по наличию определённых атрибутов (disablePatternAttributes) есть в AbstractRadiusProtocolHandler и в InetNas.

Мне кажется, логично было бы сделать отдельный класс, наподобие ProtocolHandler-а, который бы занимался работой с радиус-атрибутами, и был доступен из InetNas, ProtocolHandler, ServiceActivator. Или добавить соответствующие методы в ProtocolHandler (правда как его получить из активатора?). Плюс возможность его реализации в динамическом коде.

Конкретно мне это нужно для двух вещей:
- собственный способ задания соответствия "опция -> набор радиус-атрибутов" (оптимизация конфига устройств)
- сложная логика задания атрибутов на основе опций для SE 100


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 20 ноя 2012, 14:32 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Имеет смысл надеяться на доработку, или придётся прописывать 100500 строчек "radius.inetOption."?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 20 ноя 2012, 14:49 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
Имеет :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 22 ноя 2012, 15:02 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
А когда?
Хочу внедрять Inet уже наконец :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 27 ноя 2012, 10:09 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
up


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 27 ноя 2012, 13:36 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
Уже почти :)
По поводу конфига, будет поддержка
Опции:
Код:
- 1 - Опция 1
-- 2 - Опция 2 [speed=100]
-- 3 - Опция 3 [speed=200]
В конфигурации устройства:
Код:
radius.inetOption.1.template=Speed=$speed


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 27 ноя 2012, 13:49 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Круто!
Тогда сразу 2 фичреквеста туда:
- встроенный параметр $name - title опции (или $title, неважно)
- наследование конфигов в дереве опций

У меня это сделано так:

Код:
        ParameterMap nodeConf = new Preferences(node.getConfig(), "\n");
        //Добавляем в конфиг опции параметр name=<имя_опции>
        if(node.getTitle()!=null){
            ((Preferences)nodeConf).set("name", node.getTitle());
        }
        //Конфиг для опций будет наследоваться глобально
        if(parentNodeConf!=null){
            nodeConf = parentNodeConf.inherit(nodeConf);
        }


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 27 ноя 2012, 13:51 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Олсо, вот глобальный скрипт, который по шаблону генерирует строки radius.inetOption:

Код:
package ru.dsi.bgbilling.kernel.scripts.global;

import ru.bitel.bgbilling.kernel.script.server.dev.GlobalScriptBase;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetOption;
import ru.bitel.bgbilling.modules.inet.api.server.bean.InetOptionDao;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.ParameterMap;
import ru.bitel.common.Preferences;
import ru.bitel.common.TreeUtils;
import ru.bitel.common.sql.ConnectionSet;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GenerateInetDeviceConf
        extends GlobalScriptBase
{
    /**
     * Шаблон поиска подстановок для значений опций.
     */
    private Pattern optionValuePattern;

    protected Map<Integer, ParameterMap> optionValues;
    protected Map<String, ParameterMap> featureConfig;

    @Override
    public void execute( Setup setup, ConnectionSet connectionSet )
            throws Exception
    {
        int mid=28;
        ParameterMap deviceConfig = new Preferences(
                "# INET\n" +
                "sa.feature.inet.id=1\n" +
                "sa.feature.inet.values.attributes=cisco-SSG-Account-Info=A$(name)","\n");


        this.featureConfig = new HashMap<String, ParameterMap>();
        this.optionValues = new TreeMap<Integer, ParameterMap>();
        this.optionValuePattern = Pattern.compile("\\$\\(([\\w\\.]+)\\)");

        InetOptionDao inetOptionDao = new InetOptionDao(connectionSet.getSlaveConnection(), mid);

        //Список всех опций
        List<InetOption> optionList = inetOptionDao.list();

        //Строим полное дерево опций
        InetOption root = new InetOption();
        root.setGroupIntersection(true);
        root.setId(0);
        root = TreeUtils.tree(optionList, root);//Теперь всем опциям из optionList назначены потомки

        int featureId;
        //Временная карта root_option_id -> feature. Обратная к featureToRootOptionMap.
        Map<Integer, String> rootOptionToFeatureMap = new TreeMap<Integer, String>();

        //Берём конфиги признаков (фич)
        //sa.feature.<featureName>.id=<root_option_id>
        //sa.feature.<featureName>.values.<something1>=<...>
        //sa.feature.<featureName>.values.<something2>=<...>
        for(Map.Entry<String, ParameterMap> e : deviceConfig.subKeyed( "sa.feature.").entrySet()){
            featureId = e.getValue().getInt("id", -1);
            if(featureId==-1){
                print("No root option id found for feature " + e.getKey() + ". 'sa.feature." + e.getKey() + ".id=<inet_root_option_id>' must be defined");
                continue;
            }
            this.featureConfig.put(e.getKey(),e.getValue());
            //featureToRootOptionMap.put(e.getKey(),featureId);
            rootOptionToFeatureMap.put(featureId, e.getKey());
        }

        //Рекурсивно обходим опции модуля Inet, заполняем optionValues и optionToFeatureMap
        processTree(root, deviceConfig, rootOptionToFeatureMap, null, null);

        print("\n\n\n");
        //генерируем конфиг:
        for(Map.Entry<Integer,ParameterMap> e : optionValues.entrySet()){
            print("#"+inetOptionDao.get(e.getKey()).getTitle());
            for(Map.Entry<String, String> p : e.getValue().entrySet()){
                print("radius.inetOption."+e.getKey()+"."+p.getKey()+"="+p.getValue());
            }
        }

        inetOptionDao.recycle();
    }

    /**
     * Рекурсивно обрабатываем дерево тарифных опций, заполняем optionValues и optionToFeatureMap по конфигурации
     * фич featureToRootOptionMap и featureConfig
     * При этом конфиги опций наследуются, а значения опций в optionValues собираются по шаблону из
     * featureConfig.sub("values.") подстановкой параметров из конфига опции по шаблону optionValuePattern
     *
     * @param node - текущий узел дерева для рекурсии
     * @param rootOptionToFeatureMap - соответствие "корневая опция фичи" -> "фича"
     * @param currentFeature - текущая фича, в поддереве которой мы находимся. null - если нет
     * @param parentNodeConf - конфиг родительского узла
     */
    private void processTree(InetOption node, ParameterMap deviceConfig, Map<Integer, String> rootOptionToFeatureMap, String currentFeature, ParameterMap parentNodeConf){
        ParameterMap nodeConf = new Preferences(node.getConfig(), "\n");
        //Добавляем в конфиг опции параметр name=<имя_опции>
        if(node.getTitle()!=null){
            ((Preferences)nodeConf).set("name", node.getTitle());
        }
        //Конфиг для опций будет наследоваться глобально
        if(parentNodeConf!=null){
            nodeConf = parentNodeConf.inherit(nodeConf);
        }
        //Если текущая ветка является рутом для какой-то фичи, то устанавливаем текущую фичу
        if(rootOptionToFeatureMap.containsKey(node.getId())){
            currentFeature = rootOptionToFeatureMap.get(node.getId());
        }

        //обрабатываем фичу, если мы внутри её дерева
        if(currentFeature!=null){
            //this.optionToFeatureMap.put(node.getId(), currentFeature);
            parseOptionValues(node.getId(), currentFeature, nodeConf);
        }

        //Ищем индивидуальный конфиг для опции, если есть
        //sa.option.<id>.values.*
        //перетирает values для фичи
        Preferences optValues = new Preferences();
        String value;
        for(Map.Entry<String, String> e : deviceConfig.sub("sa.option."+node.getId()+".values.").entrySet()){
            value = this.parseTemplate(e.getValue(), nodeConf);
            if(null!=value){
                optValues.set(e.getKey(),value);
            }
        }
        if(optValues.entrySet().size()>0){
            //this.optionValues.put(node.getId(),optValues);
            ParameterMap map = this.optionValues.get(node.getId());
            if(map!=null){//Если для опции уже что-то определено, то добавляем к этому и переопределяем при необходимости
                map = map.inherit(optValues);//переопределяем map значениями из optValues
                this.optionValues.put(node.getId(), map);
            }else{//раньше у опции не было значений - просто берём наши
                this.optionValues.put(node.getId(), optValues);
            }
        }

        //Также пишем в лог
        if(this.optionValues.containsKey(node.getId())){
            print("option values for id=" + node.getId() + " (" + node.getTitle() + ") :\n" + this.optionValues.get(node.getId()).toString());
        }

        //рекурсивно обрабатываем дочерние узлы
        if(node.getChildren()!=null){
            for(InetOption child : node.getChildren()){
                processTree(child, deviceConfig, rootOptionToFeatureMap, currentFeature, nodeConf);
            }
        }
    }

    /**
     * Задаём значения параметров опции на остнове параметров фичи по шаблону
     * @param id - id опции
     * @param feature - фича, к которой относится эта опция
     * @param nodeConf - конфиг опции
     */
    private void parseOptionValues(int id, String feature, ParameterMap nodeConf) {
        //Берём все параметры фич из sa.feature.<feature>.values.* и обрабатываем их через подстановки
        //Результат помещаем в optionValues
        Preferences params;
        String v;
        if(this.featureConfig.containsKey(feature)){
            params = new Preferences();
            for(Map.Entry<String,String> e : this.featureConfig.get(feature).sub("values.").entrySet()){
                v = parseTemplate(e.getValue(), nodeConf);
                if(v!=null){
                    params.set(e.getKey(), v);
                }
            }
            optionValues.put(id, params);
        }
    }

    /**
     *
     * @param template
     * @param conf
     * @return
     */
    private String parseTemplate(String template, ParameterMap conf){
        String result = null;
        Matcher m = optionValuePattern.matcher(template);
        if (m.find()){
            StringBuffer newValue = new StringBuffer(template.length() + 16);
            String varName = m.group(1);

            String var = conf.get(varName, null);
            if (var != null){
                var = Matcher.quoteReplacement(var);
                m.appendReplacement(newValue, var);
            }

            while (m.find()){
                var = conf.get(m.group(1), null);
                if (var == null)
                    continue;
                var = Matcher.quoteReplacement(var);
                m.appendReplacement(newValue, var);
            }

            m.appendTail(newValue);
            result = newValue.toString();
        }
        return result;
    }
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оптимизация конфига устройств
СообщениеДобавлено: 27 ноя 2012, 14:35 
Не в сети
Клиент
Аватара пользователя

Зарегистрирован: 20 апр 2009, 12:03
Сообщения: 3092
Откуда: Иркутск
Карма: 338
Теперь расскажу, как я представляю себе определение профилей на основе наборов опций.

Например, есть Сisco SCE.
Каждому сабскрайберу (сервису Inet) назначается packageId - числовой идентификатор профиля. Профили конфигурируются заранее на SCE.
В биллинге мы хотим задавать следующие параметры профиля:
- скорость
- класс сервиса клиента (приоритет трафика на уровне сабскрайбера)
- запретить торрент-трафик (да/нет)
- запретить доступ к соц сетям (да/нет)
- (могут появиться новые)

Последние 2 услуги рулятся с помощью тарифных опций.
Скорость тоже может меняться от тарифной опции (турбокнопка)

Если делать прямое соответствие 'опция Inet' -> 'package_id', то придётся все возможные варианты комбинаций ветвить в тарифе. У нас так сейчас сделано в dialup (не спрашивайте, как :) ) - это ужасно. Приходится одно и то же дублировать во всех ветках.

Долго думал, сняв очки, как сопоставить опции и профили.
Получается такая схема:
опции -> фичи -> профили

feature (фича) - это группировка опций по типам. Например:
inet - скорость в интернет
local - скорость локального трафика
flow (on/off) - включен ли netflow на интерфейсе (тоже рулится тарифной опцией)
notorrent (on/off) - закрыт ли торрент-трафик у клиента
nosocial (on/off) - закрыты ли соц. сети у клиента

На первом этапе ServiceActivator, или кто у нас будет определять профиль (packageId в случае SCE), определяет по набору опций значения фич:
inet = <inet_option_id>
local = <local_option_id>
итд

фича может быть не определена

Затем на основе фич подбираем подходящий packageId. Например, можно сконфигурировать все packageId в виде:
[packageId=101]
inet = 123, 124 (Id опций через запятую)
notorrent = - (не указано)
nosocial = - (не указано)

[packageId=102] (101, но с закрытыми торрентами)
inet = 123, 124
notorrent = 10 (id опции)
nosocial = - (не указано)

Потом перебирать их и подбирать первый подходящий.
Как-то так. Ну или можно использовать не id опций, а значения (скорости, true/false)

Воот.

Т.о. группировка опций по типам - довольно естественная вещь и может пригодиться в будущем.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 44 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 5 часов [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
POWERED_BY
Русская поддержка phpBB
[ Time : 0.069s | 76 Queries | GZIP : On ]