Реализация функций формирований команд: GateCommandUtil
Материал из BiTel WiKi
Работает для версии 5.1 .
1. Нужно создать библитеку сриптов manad(Автоматизация->Библиотеки скриптов).
2. В скрипт шлюза вначале добавить
includeBGBS( "bgbs://ru.bitel.bgbilling.kernel.script.common.bean.ScriptLibrary/gateCommands" );
3. Убрать "GateCommandUtil." из вашего сриптового шлюза и использовать аналогичные функции библиотеки
код библиотеки скриптов:
private static StringBuffer processBlock( String ruleText, LoopPattern loopPattern ) { StringBuffer result = new StringBuffer(); List<PatternItem> items = new ArrayList<PatternItem>( 10 ); Map<String, Integer> letterMaxNumbers = new HashMap<String, Integer>(); Pattern pattern = Pattern.compile( "\\{([A-Z]+)(\\d+)\\}" ); Matcher m = pattern.matcher( ruleText ); while( m.find() ) { String letter = m.group( 1 ); int number = Utils.parseInt( m.group( 2 ), 0 ); PatternItem item = new PatternItem(); item.number = number; item.letter = letter; items.add( item ); Integer maxNumber = letterMaxNumbers.get( letter ); if( maxNumber == null || maxNumber < number ) { letterMaxNumbers.put( letter, number ); } } final int size = loopPattern.getObjects().size(); for( int i = 0; i < size; i++ ) { //String address = IPUtils.convertLongIpToString( Utils.parseLong( addreses[i], 0 ) ); String addressRule = new String( ruleText ); for( PatternItem item : items ) { int number = i*(letterMaxNumbers.get( item.letter ) + 1) + item.number; addressRule = addressRule.replaceAll( "\\{" + item.letter + item.number + "\\}", "{" + item.letter + number + "}" ); } String str = addressRule; for ( int j = 0; j < loopPattern.getReplacements().size(); j ++) { String key = loopPattern.getReplacements().get( j ); String value = loopPattern.getObjects().get( i ).get( j ); str = str.replaceAll( key, value ); } result.append( str ); } return result; } /** * Формирует команды для шлюза. * @param ruleText * @param addressList * @param replacements * @param ruleType * @return */ public static final String generateRule( String ruleText, String addressList, Map<String, String> replacements, RuleType ruleType ) { List<LoopPattern> loops = getAddresLoops( addressList ); return generateRule( ruleText, replacements, ruleType, loops); } /** * строку адреса преобразует в 2 LoopPattern-а : для диапазонов и сетей * @param addressList * @return */ public static List<LoopPattern> getAddresLoops( String addressList ) { String parts[] = addressList.split( ";" ); List <String> replacements = new ArrayList<String>(); replacements.add ( "\\{A\\}" ); List<List<String>> objects = new ArrayList<List<String>>(); if ( parts.length > 0 && !Utils.isEmptyString( parts[0] ) ) { String[] addrs = parts[0].split( "\\s*,\\s*" ); if ( addrs.length > 0) { for ( int i = 0; i < addrs.length; i++) { String address = IPUtils.convertLongIpToString( Utils.parseLong( addrs[i], 0 ) ); List<String> list = new ArrayList<String>(); list.add( address ); objects.add( list ); } } } List<LoopPattern> loops =new ArrayList<LoopPattern>(); //адреса LoopPattern p = new LoopPattern(); p.setLoopPatern( "LOOP" ); p.setReplacements( replacements ); p.setObjects( objects ); loops.add( p ); replacements = new ArrayList<String>(); replacements.add ( "\\{IP\\}" ); replacements.add ( "\\{MASK\\}" ); replacements.add ( "\\{MASK_WILD\\}" ); replacements.add ( "\\{MASK_BIT\\}" ); objects = new ArrayList<List<String>>(); //String[] nets = new String [0]; //String[] net_masks = new String [0]; if ( parts.length > 1 && !Utils.isEmptyString( parts[1] ) ) { String[] nets = parts[1].split( "\\s*,\\s*" ); if ( nets.length > 0) { for ( int i = 0; i < nets.length; i++) { String parts2[] = nets[i].split( "/" ); if ( parts2.length == 2) { String address = IPUtils.convertLongIpToString( Utils.parseLong( parts2[0], 0 ) ); String maskBit = parts2[1]; long mask = ( 0xFFFFFFFFl << ( 32 - Utils.parseInt( maskBit, 0 ) ) ) & 0xFFFFFFFFl; long maskWild = mask ^ 0xFFFFFFFFl; List<String> list = new ArrayList<String>(); list.add( address ); list.add( IPUtils.convertLongIpToString( mask ) ); list.add( IPUtils.convertLongIpToString( maskWild ) ); list.add( maskBit ); objects.add( list ); } } } } //сети p = new LoopPattern(); p.setLoopPatern( "LOOP_NET" ); p.setReplacements( replacements ); p.setObjects( objects ); loops.add( p ); return loops; } /** * Формирует команды для шлюза. * @param ruleText * @param replacements * @param ruleType * @param loops * @return */ public static final String generateRule( String ruleText, Map<String, String> replacements, RuleType ruleType, List<LoopPattern> loops) { StringBuffer resultBuf = null; for ( LoopPattern loop : loops) { resultBuf = new StringBuffer (); String loopPattern = "(<LOOP>.*?</LOOP>)?(.*?)<LOOP>(.*?)</LOOP>"; loopPattern = loopPattern.replaceAll( "LOOP", loop.getLoopPatern() ); Pattern pattern = Pattern.compile( loopPattern, Pattern.DOTALL ); Matcher m = pattern.matcher( ruleText ); boolean find = false; while( m.find() ) { find = true; String block = m.group( 3 ); block = processBlock( block, loop ).toString(); resultBuf.append( m.group( 2 ) ); resultBuf.append( block ); } if (find) { //хвост(ищем жадным алгоритмом) или если вообще нет ни одного цикла loopPattern = "(?:<LOOP>(?:.*)</LOOP>)(.*)\\z"; loopPattern = loopPattern.replaceAll( "LOOP", loop.getLoopPatern() ); pattern = Pattern.compile( loopPattern, Pattern.DOTALL ); m = pattern.matcher( ruleText ); if( m.find() ) { resultBuf.append( m.group( 1 ) ); } } else { resultBuf = new StringBuffer( ruleText ); } //пошли по второму и т.п заходу ruleText = resultBuf.toString(); } String result = resultBuf.toString(); result = result.replaceAll( "<ver 2\\.0/>", "" ); //убиваем пустые строки result = result.replaceAll( "\r", "" ); result = result.replaceAll( "\n\\s*\n", "\n" ); result = result.replaceAll( "(\n){2,}", "\n" ); result = result.trim(); String ruleData = ruleType.getData(); ruleData.replaceAll( "\r", "\n" ); ruleData = ruleData.trim(); Preferences setup = new DefaultSetup( ruleData, "\n"); //получаем все значения Map<String, String> values = setup.getHashValuesWithPrefix( "" ); if( replacements == null) { replacements = new HashMap<String, String>(); } for (Map.Entry<String, String> entry : values.entrySet()) { String key = "\\$\\{" + entry.getKey() + "\\}"; replacements.put( key, entry.getValue() ); } if (replacements != null) { for (Map.Entry<String, String> rep : replacements.entrySet()) { //result = result.replaceAll( "\\{CID\\}", String.valueOf( cid ) ); result = result.replaceAll( rep.getKey(), rep.getValue() ); } } return result.toString(); } private static class PatternItem { public String letter; public int number; } /** * Получает команды для шлюза в непереработанном виде. * @param gateType * @param ruleType * @return */ public static String getRule( GateType gateType, RuleType ruleType ) { String result = ""; String template = "\\[RULE ID=\"((?:\\d+,*)+)\"\\](.*?)\\[/RULE\\]"; Pattern pattern = Pattern.compile( template, Pattern.DOTALL ); Matcher m = pattern.matcher( gateType.getRule() ); while( m.find() ) { String idsStr = m.group(1); String rule = m.group( 2 ); int ids [] = parseIds( idsStr ); for (int i = 0; i < ids.length; i++) { if (ruleType.getId() == ids [i] ) { return rule; } } } //default template = "\\[DEFAULT\\](.*)\\[/DEFAULT\\]"; pattern = Pattern.compile( template, Pattern.DOTALL ); m = pattern.matcher( gateType.getRule() ); if( m.find() ) { String rule = m.group( 1 ); return rule; } return result; } private static int[] parseIds( String idsStr ) { String strs [] = idsStr.split( "," ); int result [] = new int [strs.length]; for (int i = 0; i < strs.length; i++) { result[i] = Integer.parseInt( strs[i]); } return result; }
Это код написан на java, адаптация под BeanShell не производилась . Чтобы работало нужно будет заменить Map.Entry<String, String> на Map, String strs [] на String[] strs и т.п (по логам будет понятно где ругается). Желательно после всех исправлений и проверки обновить статью тут.