Обработчик активации сервисов для Mikrotik c изменениями скорости

Материал из BiTel WiKi

Перейти к: навигация, поиск

Изначально получен из скриптового шлюза IPN подобного этому: 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


Описание настроек устройства, типа сервиса есть тут: http://wiki.bgbilling.ru/index.php/%D0%9A%D0%BE%D0%BD%D0%B2%D0%B5%D1%80%D1%82%D0%B5%D1%80:_%D1%88%D0%BB%D1%8E%D0%B7%D1%8B(%D0%B2_%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0_INET),_ip-%D1%80%D0%B5c%D1%83%D1%80%D1%81%D1%8B,_%D1%82%D0%B8%D0%BF%D1%8B_%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB(%D0%B2_%D0%BE%D0%BF%D1%86%D0%B8%D0%B8_INET),_%D0%BF%D1%80%D0%B8%D0%B2%D1%8F%D0%B7%D0%BA%D1%83_%D0%B4%D0%BE%D0%B3%D0%BE%D0%B2%D0%BE%D1%80%D0%BE%D0%B2_%D0%BA_%D1%88%D0%BB%D1%8E%D0%B7%D0%B0%D0%BC(%D0%B2_%D1%81%D0%B5%D1%80%D0%B2%D0%B8%D1%81%D1%8B_Inet).%D0%A1%D1%85%D0%B5%D0%BC%D0%B0_dhcp-mikrotik-dlink/mirotik


Для поддержки макросов из команд шлюза IPN ( <LOOP></LOOP> и т.п) используется класс InetDeviceCommandUtils . Сами команды заводятся в коде самого класса обработчика.

Код обработчика

package ru.gigacom.inet.dyn.device.mikrotik;
 
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import org.apache.log4j.Logger;
 
import ru.bitel.bgbilling.common.BGException;
import ru.bitel.bgbilling.modules.inet.access.sa.ServiceActivator;
import ru.bitel.bgbilling.modules.inet.access.sa.ServiceActivatorAdapter;
import ru.bitel.bgbilling.modules.inet.access.sa.ServiceActivatorEvent;
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.InetServ;
import ru.bitel.bgbilling.modules.inet.api.server.bean.InetDeviceCommandUtils;
import ru.bitel.bgbilling.modules.inet.runtime.InetOptionRuntime;
import ru.bitel.bgbilling.modules.inet.runtime.InetOptionRuntimeMap;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.ParameterMap;
import ru.bitel.common.inet.IpAddress;
import bitel.billing.server.util.ssh.SSHSession;
import bitel.billing.server.util.ssh.SSHSessionExec;
 
public class MikrotikServiceActivator
	extends ServiceActivatorAdapter
	implements ServiceActivator
{
	private static final Logger log = Logger.getLogger( MikrotikServiceActivator.class );
	private static final  String COMMANDS = 
 
		"[DEFAULT]" +
		 "[OPEN]" +
		 ":global list \"\";" + 
		 ":foreach i in [/ip firewall address-list find]  do={:if ([:find [/ip firewall address-list get $i comment] \"sid=serv_id;cid={CID};\"]=0) do={[/ip firewall address-list remove $i]}};" +
		 ":global list \"\";" +
	  	 ":foreach i in [/ip firewall address-list find]  do={:if ([:find [/ip firewall address-list get $i comment] \"cid={CID};\"]=0) do={[/ip firewall address-list remove $i]}};" +
		 //":foreach i in [/ip firewall address-list find]  do={:if ([:find [/ip firewall address-list get $i address] \"{A}\"]=0) do={[/ip firewall address-list remove $i]}};" +
		"<LOOP>" + 	
		 "ip firewall address-list add address={A} list=ACCESS_LIST comment=\"sid=serv_id;cid={CID};rid=rule_id;\";" +
		 "ip firewall address-list add address={A} list=${list_name} comment=\"sid=serv_id;cid={CID};rid=rule_id;\";" +
		 "</LOOP>" +
 
		 "[/OPEN]" +
 
		 "[CLOSE]" +
		 ":global list \"\";" +
		 ":foreach i in [/ip firewall address-list find]  do={:if ([:find [/ip firewall address-list get $i comment] \"sid=serv_id;cid={CID};\"]=0) do={[/ip firewall address-list remove $i]}};" +
		 ":global list \"\";" +
		 ":foreach i in [/ip firewall address-list find]  do={:if ([:find [/ip firewall address-list get $i comment] \"cid={CID};\"]=0) do={[/ip firewall address-list remove $i]}};" +
		 //":foreach i in [/ip firewall address-list find]  do={:if ([:find [/ip firewall address-list get $i address] \"{A}\"]=0) do={[/ip firewall address-list remove $i]}};" +
		 "<LOOP>" + 	
		 "ip firewall address-list add address={A} list=DENY_LIST comment=\"sid=serv_id;cid={CID};rid=rule_id;\";" +
		 "</LOOP>" +
		 "[/CLOSE]" +
 
		 "[DELETE]" +
		 ":global list \"\";" +
		 ":foreach i in [/ip firewall address-list find]  do={:if ([:find [/ip firewall address-list get $i comment] \"sid=serv_id;cid={CID};\"]=0) do={[/ip firewall address-list remove $i]}};" +
		 ":global list \"\";" +
	     ":foreach i in [/ip firewall address-list find]  do={:if ([:find [/ip firewall address-list get $i comment] \"cid={CID};\"]=0) do={[/ip firewall address-list remove $i]}};" +
		 //":foreach i in [/ip firewall address-list find]  do={:if ([:find [/ip firewall address-list get $i address] \"{A}\"]=0) do={[/ip firewall address-list remove $i]}};" +
		 "[/DELETE]" +
		 "[/DEFAULT]";
 
 
	private static Pattern OPEN_PATTERN = Pattern.compile( "\\[OPEN\\](.*)\\[/OPEN\\]", Pattern.DOTALL );
	private static Pattern CLOSE_PATTERN = Pattern.compile( "\\[CLOSE\\](.*)\\[/CLOSE\\]", Pattern.DOTALL );
	private static Pattern DELETE_PATTERN = Pattern.compile( "\\[DELETE\\](.*)\\[/DELETE\\]", Pattern.DOTALL );
 
	private SSHSession session = null;
 
	private InetDevice inetDevice;
	@Override
	public Object init( Setup setup, int moduleId, InetDevice inetDevice, InetDeviceType inetDeviceType, ParameterMap parameterMap )
		throws Exception
	{
		this.inetDevice = inetDevice;
		//this.parameterMap = parameterMap;
		return true;
	}
 
	@Override
	public Object connect()
		throws Exception
	{	
		List<InetSocketAddress> hosts = inetDevice.getHosts();
		String host = hosts.get( 0 ).getHostName();
		int port = hosts.get( 0 ).getPort();
 
		String login = inetDevice.getUsername() + "+ct";
		String pswd = inetDevice.getPassword();
 
		if( log.isDebugEnabled() )
		{
			log.debug( " gate: " + host + ":" + port + " login: " + login + " pswd: " + pswd );
		}
 
		session = new SSHSession( host, port, login, pswd );
		int timeout = 10000;
		session.setTimeout( timeout );
		session.setEndString( " > " );
		session.connect();
 
		return true;
 
	}
 
	@Override
	public Object disconnect()
		throws Exception
	{
		session.doCommandAsync( "quit" );
 
		session.disconnect();
		log.debug( "ok" );
 
		return true;
	}
 
 
	@Override
	public Object serviceModify( ServiceActivatorEvent serviceActivatorEvent )
		throws Exception
	{		
		InetServ serv = serviceActivatorEvent.getNewInetServ();
		proccesServ( serviceActivatorEvent, serv );
 
 
		return null;
	}
 
	private Object proccesServ( ServiceActivatorEvent serviceActivatorEvent, InetServ serv )
        throws BGException, Exception
    {
		Set<Integer> oldOptions = serviceActivatorEvent.getOldOptions();
		Set<Integer> newOptions = serviceActivatorEvent.getNewOptions();
 
		log.debug( "oldState=" + serviceActivatorEvent.getOldState() + ";" + "newState=" + serviceActivatorEvent.getNewState() );
		log.debug( "oldOptions=" + oldOptions + ";" + "newOptions=" + newOptions );
 
		log.debug( "state!=state " + ( serviceActivatorEvent.getNewState() != serviceActivatorEvent.getOldState() ) );
 
		if( serviceActivatorEvent.getNewState() != serviceActivatorEvent.getOldState() || !oldOptions.equals( newOptions ) )
		{									
			int state = serviceActivatorEvent.getNewState();
			int servId = serviceActivatorEvent.getInetServId();
 
			IpAddress addressFrom = new IpAddress( serv.getAddressFrom() ).clone();
			IpAddress addressTo = new IpAddress( serv.getAddressTo() != null ? serv.getAddressTo() : serv.getAddressFrom()  ).clone();
 
			IpAddress current =  addressFrom;
 
			List<String> ips = new ArrayList<String>();
 
			log.info( "from =" + addressFrom.toString() );
			log.info( "to =" + addressTo.toString() );
 
			while ( current.compareTo( addressTo ) <= 0 )
			{
				String ip = IpAddress.toString( current.address );
				ips.add( ip );
				log.info( ip );
				log.info( "increment =" + IpAddress.increment( current.address ) );
			}
 
 
 
			int cid = serv.getContractId();
 
 
			int ruleId = 0;
 
 
 
			String optionConfig = "";
			if( newOptions.size() > 0 )
			{
				ruleId = (Integer)newOptions.toArray()[0];
				InetOptionRuntime option = InetOptionRuntimeMap.getInstance().get( ruleId );
				optionConfig = option.config.toString();
				//listName = option.config.get( "list_name", "" );
				//log.debug( "listName=" + listName );
				log.debug( "optionConfig=" + optionConfig );
			}
			//обход проблемы старта
			else
			{ 
				optionConfig="list_name=ACCESS_LIST"; 
			}
 
 
			log.info( "cid=" + cid + ";rule_id=" + ruleId + ";" + "optionConfig=" + optionConfig  );
 
			String rules[] = null;
 
			if( state == InetServ.STATE_ENABLE )
			{
 
				log.info( "open" );					
				// открываем
				rules = getRules( cid, servId, ruleId, ips, optionConfig, OPEN_PATTERN );				
			}
 
			else if( state == InetServ.STATE_DELETED )
			{
				log.info( "detete" );
				// удаляем
				rules = getRules( cid, servId, ruleId, ips, optionConfig, DELETE_PATTERN );
			}
			else if( state == InetServ.STATE_DISABLE )
			{
				// закрываем
				log.info( "close" );
				rules = getRules( cid, servId, ruleId, ips, optionConfig, CLOSE_PATTERN );
			}
 
			StringBuffer result = new StringBuffer();
 
			log.debug( "rules.length=" + rules.length );
			if( rules != null )
			{
				for( String rule : rules )
				{
					log.debug( "rule=" + rule );
 
					result.append( session.doCommand( rule ) );
				}
 
				log.debug( " result = " + result.toString() );	
			}
 
 
 
		}
 
		log.debug( "processed!" );
 
		return null;
    }
 
 
 
	private String [] getRules( int cid, int serviceId, int ruleId, List<String> ips, String optionConfig, Pattern pattern  )
	{
 
 
	   Map<String, String> replacements = new HashMap<String, String>();
 
	   replacements.put( "\\{CID\\}", String.valueOf( cid ) );
	   replacements.put( "rule_id", String.valueOf( ruleId ) );
	   replacements.put( "serv_id", String.valueOf( serviceId ) );
 
	   String result = InetDeviceCommandUtils.generateCommands( COMMANDS, pattern, ips, replacements, optionConfig );
 
 
	   result = result.replaceAll( "\r", "" );
 
	   //GateCommandUtil.
 
	   return result.split( "\n" );
	}
 
	@Override
    public Object serviceCreate( ServiceActivatorEvent e )
        throws Exception
    {
	    log.debug( "serviceCreate" );	    	    
	    return serviceModify( e );	    
    }
 
	@Override
    public Object serviceCancel( ServiceActivatorEvent e )
        throws Exception
    {
	    log.debug( "serviceCancel" );
	    InetServ serv = e.getOldInetServ();		
	    return proccesServ( e, serv );
    }
 
}
Личные инструменты