Обработчик активации сервисов для Mikrotik c изменениями скорости
Материал из BiTel WiKi
(Различия между версиями)
Simpl3x (Обсуждение | вклад) |
Stark (Обсуждение | вклад) (добавил методы serviceCreate и serviceCancel) |
||
Строка 25: | Строка 25: | ||
import org.apache.log4j.Logger; | 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.ServiceActivator; | ||
import ru.bitel.bgbilling.modules.inet.access.sa.ServiceActivatorAdapter; | import ru.bitel.bgbilling.modules.inet.access.sa.ServiceActivatorAdapter; | ||
Строка 67: | Строка 68: | ||
":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 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]}};" + | //":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]" + | "[/CLOSE]" + | ||
Строка 113: | Строка 117: | ||
session = new SSHSession( host, port, login, pswd ); | session = new SSHSession( host, port, login, pswd ); | ||
+ | int timeout = 10000; | ||
+ | session.setTimeout( timeout ); | ||
session.setEndString( " > " ); | session.setEndString( " > " ); | ||
session.connect(); | session.connect(); | ||
Строка 137: | Строка 143: | ||
throws Exception | throws Exception | ||
{ | { | ||
- | // log.debug( "newState= " + serviceActivatorEvent.getNewState() ); | + | InetServ serv = serviceActivatorEvent.getNewInetServ(); |
+ | proccesServ( serviceActivatorEvent, serv ); | ||
+ | |||
+ | |||
+ | return null; | ||
+ | } | ||
+ | |||
+ | private Object proccesServ( ServiceActivatorEvent serviceActivatorEvent, InetServ serv ) | ||
+ | throws BGException, Exception | ||
+ | { | ||
+ | // log.debug( "newState= " + serviceActivatorEvent.getNewState() ); | ||
Set<Integer> oldOptions = serviceActivatorEvent.getOldOptions(); | Set<Integer> oldOptions = serviceActivatorEvent.getOldOptions(); | ||
Set<Integer> newOptions = serviceActivatorEvent.getNewOptions(); | Set<Integer> newOptions = serviceActivatorEvent.getNewOptions(); | ||
Строка 153: | Строка 169: | ||
// log.info("addres_list="+address_list); | // log.info("addres_list="+address_list); | ||
- | |||
- | |||
+ | int state = serviceActivatorEvent.getNewState(); | ||
+ | //slebed test | ||
int servId = serviceActivatorEvent.getInetServId(); | int servId = serviceActivatorEvent.getInetServId(); | ||
//String ip = IpAddress.toString( serv.getAddressFrom() ); | //String ip = IpAddress.toString( serv.getAddressFrom() ); | ||
Строка 196: | Строка 212: | ||
log.debug( "optionConfig=" + optionConfig ); | log.debug( "optionConfig=" + optionConfig ); | ||
} | } | ||
+ | //обход проблемы старта | ||
+ | else | ||
+ | { optionConfig="list_name=ACCESS_LIST"; } | ||
Строка 235: | Строка 254: | ||
//rule = rule.replaceAll( "\\{A\\}", ip ); | //rule = rule.replaceAll( "\\{A\\}", ip ); | ||
//rule = rule.replaceAll( "rule_id", "rule_id=" + rule_id ); | //rule = rule.replaceAll( "rule_id", "rule_id=" + rule_id ); | ||
+ | //slebed test | ||
//rule = rule.replaceAll( "serv_id", "serv_id=" + serv_id ); | //rule = rule.replaceAll( "serv_id", "serv_id=" + serv_id ); | ||
//rule = rule.replaceAll( "\\$\\{list_name\\}", listName ); | //rule = rule.replaceAll( "\\$\\{list_name\\}", listName ); | ||
Строка 252: | Строка 272: | ||
log.debug( "processed!" ); | log.debug( "processed!" ); | ||
- | |||
return null; | return null; | ||
- | + | } | |
Строка 264: | Строка 283: | ||
Map<String, String> replacements = new HashMap<String, String>(); | Map<String, String> replacements = new HashMap<String, String>(); | ||
+ | |||
+ | //slebed test | ||
+ | //rule = rule.replaceAll( "\\$\\{list_name\\}", listName ); | ||
replacements.put( "\\{CID\\}", String.valueOf( cid ) ); | replacements.put( "\\{CID\\}", String.valueOf( cid ) ); | ||
Строка 278: | Строка 300: | ||
return result.split( "\n" ); | 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 ); | ||
+ | } | ||
} | } | ||
</source> | </source> |
Версия 10:01, 23 октября 2012
Изначально получен из скриптового шлюза 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
Для поддержки макросов из команд шлюза 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(); ; // gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" ); 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 { // log.debug( "newState= " + serviceActivatorEvent.getNewState() ); 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 ) ) { // String address_list = session.command( // "ip firewall address-list print without-paging" ); // String new_address_list = null; // log.info("addres_list="+address_list); int state = serviceActivatorEvent.getNewState(); //slebed test int servId = serviceActivatorEvent.getInetServId(); //String ip = IpAddress.toString( serv.getAddressFrom() ); 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 ) { //rule = rule.replaceAll( "\\{CID\\}", String.valueOf( cid ) ); //rule = rule.replaceAll( "\\{A\\}", ip ); //rule = rule.replaceAll( "rule_id", "rule_id=" + rule_id ); //slebed test //rule = rule.replaceAll( "serv_id", "serv_id=" + serv_id ); //rule = rule.replaceAll( "\\$\\{list_name\\}", listName ); 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>(); //slebed test //rule = rule.replaceAll( "\\$\\{list_name\\}", listName ); 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 ); } }