Реализация функций формирований команд: 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 и т.п (по логам будет понятно где ругается). Желательно после всех исправлений и проверки обновить статью тут.

Личные инструменты