Реализация стандартного шлюза коммутатора Qtech/Zyxel (под Cisco2) на BeanShell со встроенным шлюзом DHCP

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

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

После длительных раздумий вырисовалась связка Cisco2+(Zyxel/Qtech+DHCP) вместо предложенной разработчиками связки DHCP+Cisco2+Zyxel/Qtech. Данная связка нарисовалась в связи с тем, что некоторые параметры, которые нужно передать в шлюз DHCP, зависят от шлюза Zyxel/Qtech, а не от Cisco2, и получить к ним доступ в шлюзе DHCP не удалось. Т.е. шлюз Zyxel/Qtech совмещен с шлюзом DHCP. Суть состоит в том, что После синхронизации клиента на коммутаторе Zyxel, будет вызываться синхронизация с родительским шлюзом Cisco2, и синхронизация с сервером DHCP BgBilling'a. Все это написано для биллинга в.4.6 Ip адреса выдаются по влану клиента, т.к. в параметрах шлюза нельза менять vlan, а в сети может быть несколько одинаковых vlan находящихся в разных сегментах сети, принадлежащих одной сиске, влан клиента заносим в параметр договора. VLAN клиента уникальный в квартале. Можно выдавать ip адреса и по порту свича, что предпочтительней, но пока есть с этим у нас проблемы, поэтому и не используем. Конфигурация шлюза Cisco2:

#имя пользователя
login=test
#пароль шлюза который задаётся для enable 
cfg.pswd=123456
#диапазон выделения vlan 
range=1100-1900
#время ожидания ответа, по истечению которого, шлюз сбрасывает соединение и выдаёт ошибку
timeout=2000
#код Vlan клиента параметра договора
vlanId=1

Конфигурация типа шлюза Cisco2:

user_rule.editor.class=bitel.billing.module.services.ipn.editor.vlan.CiscoVlanContactRuleEditor
#gate_manager.class=bitel.billing.server.ipn.vlan.CiscoVlanGateWorker
#gate_manager.class=bitel.billing.server.ipn.DHCPGateWorker
gate_manager.class=bitel.billing.server.ipn.vlan.CiscoVlanParentGateWorker
use.script=1
#диапазон выделения vlan 
range=1100-1900

Команды шлюза Cisco2:

[DEFAULT]
 
[REMOVE]
   <LOOP>          
         no ip route {A} 255.255.255.255 Vlan{VID}
   </LOOP>          
[/REMOVE]
 
[OPEN]
   <LOOP>          
           ip route {A} 255.255.255.255 Vlan{VID}
           ip route {DHCP_Relay} 255.255.255.255 Vlan{VID}
   </LOOP>          
[/OPEN]
 
[CLOSE]
   <LOOP>          
        no ip route {A} 255.255.255.255 Vlan{VID}
   </LOOP>          
[/CLOSE]
[/DEFAULT]

Скрипт шлюза Cisco2:

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.StringTokenizer;
import java.util.Map.Entry;
import java.sql.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
 
import org.apache.xml.serializer.ToXMLStream;
import org.xml.sax.SAXException;
 
import bitel.billing.common.module.ipn.IPNContractStatus;
import bitel.billing.server.ipn.GateWorker;
import bitel.billing.server.ipn.UserStatus;
import bitel.billing.server.ipn.bean.ManadUtils;
import bitel.billing.server.ipn.bean.VlanManager;
import bitel.billing.server.ipn.bean.GateType;
import bitel.billing.server.ipn.bean.RuleType;
import bitel.billing.server.ipn.bean.VlanManager;
import bitel.billing.server.ipn.bean.Gate;
import bitel.billing.server.util.DefaultServerSetup;
import bitel.billing.server.util.Utils;
import bitel.billing.server.util.telnet.TelnetSession;
import ru.bitel.bgbilling.common.DefaultSetup;
import bitel.billing.common.IPUtils;
import ru.bitel.bgbilling.common.DefaultSetup;
import bitel.billing.common.module.ipn.IPNContractStatus;
import bitel.billing.server.ipn.dlink.UserPortStatus;
import bitel.billing.server.ipn.dlink.UserPortStatus.UserPortStatusParser;
 
/////protected void doSync()
protected void parentSync( child, childWorker)
{
   try
   {
      log.info( "start of cisco........................................................");
      host = gate.getHost();
      port = gate.getPort();
 
      DefaultServerSetup gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" );        
 
      pswdLogin = gate.getKeyword();
      login = gateSetup.getStringValue( "login");
      pswdCfg = gateSetup.getStringValue( "cfg.pswd");
      timeout = gateSetup.getIntValue( "timeout", 0 );
      vlanId = gateSetup.getIntValue( "vlanId",0);
      result = new StringBuffer();
 
      if( log.isDebugEnabled() )
      {
          log.debug( gate.getId() + " gate: " + host + ":" + port  + " pswdLogin: " + pswdLogin + " pswdCfg: " +        pswdCfg );
      }
      session = new TelnetSession( host, port);
       session.setTimeout( timeout );
      session.setLoginPromptSequence( ":" );                  
      session.connect();
      result.append( session.doCommand( login ) );
      session.setLoginPromptSequence( ">" );
      result.append( session.doCommand( pswdLogin ) );
      result.append( session.doCommand( "terminal length 0" ) );
      result.append( session.doCommand( "terminal width 0" ) );
      session.setLoginPromptSequence( ":" );
      result.append( session.doCommand( "enable" ) );
      session.setLoginPromptSequence( "#" );
      result.append( session.doCommand( pswdCfg ) );
 
      result.append( session.doCommand( "configure terminal" ) );
 
//      log.debug( "execute commands" );
//      log.info( "------1------");
//      log.info( "relayId = " + relayId);
      doCommands( session, result, child, vlanId);
 
      result.append( session.doCommand( "exit" ) );
        session.doCommandAsync( "exit" );
 
//      log.info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
      log.info( result );
/*      log.info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");      
      log.debug( "ok" );
*/ 
   } catch (Exception e)
   {
      throw new RuntimeException ( e );
   } 
 
   log.info( "end of cisco........................................................");
}
 
protected void add()
{
 
}
 
/////private void doCommands( TelnetSession session, StringBuffer result, vlanId, relayId) throws IOException
private void doCommands( TelnetSession session, StringBuffer result, Gate child, vlanId) throws IOException
{      
   for( UserStatus status : statusList )
   {
      gateId  = gate.getId();
//      log.info("gateId=" + gateId);
//        log.info("vlanId=" + vlanId);
//        log.info("contractId=" + status.contractId);
      int vid_dog = getVlan( status.contractId, vlanId );
/////      Relay = getRelay( status.contractId, relayId );
      DefaultServerSetup childSetup = new DefaultServerSetup( child.getConfig(), "\r\n" );        
      int vid = childSetup.getIntValue( "relay.vlan",1100);
      Relay = childSetup.getStringValue( "relay.ip","10.35.255.254");
//      log.info("vid=" + vid);   
//      log.info("Relay=" + Relay);   
      //TODO - подумать что сделать справилами на добавление
      rules = null;
      if (status.status == IPNContractStatus.STATUS_OPEN)
      {
         rules = getOpenRules( status, vid, Relay, vid_dog);
      }          
//      else if (status.status == IPNContractStatus.STATUS_REMOVED)
//      {
//         rules = getRemoveRules( status, vid );   
//      }
      //if closed and etc 
      else 
      {
         rules = getCloseRules( status, vid, Relay, vid_dog );
      }
      if (vid > 0)
      {
         for ( String rule : rules )
         {               
//      log.info("rule=" + rule);   
            result.append(  session.doCommand( rule ) );            
         }
      }
   }      
}
 
getOpenRules( status, vid, Relay, vid_dog )
{
    return getRules( status, "\\[OPEN\\](.*)\\[/OPEN\\]", vid, Relay, vid_dog );
}
 
getCloseRules( status, vid, Relay, vid_dog )
{
    return getRules( status, "\\[CLOSE\\](.*)\\[/CLOSE\\]", vid, Relay, vid_dog );
}
 
getRemoveRules( UserStatus status, int vid, Relay, vid_dog )
{
    return getRules( status, "\\[REMOVE\\](.*)\\[/REMOVE\\]", vid, Relay, vid_dog );
}
 
getRules(  status, template, vid, Relay, vid_dog )
{
   // пользовательское правило, без типа - то все оставляем как есть
   rule = status.rule.getRuleText();
//   log.info("rule=" + rule);
        //порты идут до #, а адреса идут после  
   String [] parts  = rule.split( "#" );
   portsStr = "";
   addresesStr = "";
   if ( parts.length > 0 )
   {
       portsStr = parts[0];
   }
   if ( parts.length > 1 )
   {
      addresesStr = parts[1];
   }
   //типизированное правило
   if( status.ruleType != null )
   {   
       rule = generateRule( addresesStr, status.gateType, status.ruleType, vid, Relay, vid_dog );
   }
//   log.info("2rule=" + rule);
   pattern = Pattern.compile( template, Pattern.DOTALL );
   m = pattern.matcher( rule );
   if (m.find())
   {
       rule = m.group( 1 );
   }      
   rule.replaceAll( "\r", "" );
   parts  = rule.split( "\n" );
   result = new ArrayList();
   for ( String part : parts )
   {
      if ( !Utils.isEmptyString( part ))
      {
         result.add( part );
      }
   }
 
   return result;
}      
 
generateRule( addresses, gateType, ruleType, vid, Relay, vid_dog )
{      
//    ruleText = ManadUtils.getRule( gateType, ruleType );
   ruleText="[REMOVE]\n"+
      "<LOOP>\n"+
            "no ip route {A} 255.255.255.255 Vlan{VIDD}\n"+
      "</LOOP>\n"+
   "[/REMOVE]\n"+
   "[OPEN]\n"+
      "<LOOP>\n"+
              "ip route {A} 255.255.255.255 Vlan{VIDD}\n"+
              "ip route {DHCP_Relay} 255.255.255.255 Vlan{VID}\n"+
      "</LOOP>\n"+
   "[/OPEN]\n"+
   "[CLOSE]\n"+
      "<LOOP>\n"+
           "no ip route {A} 255.255.255.255 Vlan{VIDD}\n"+
      "</LOOP>\n"+
   "[/CLOSE]\n";
 
   log.info("ruleText = "+ruleText);
 
    replacements =  new HashMap ();
    if (Relay != null || Relay.length()>0 )
    {
       replacements.put( "\\{DHCP_Relay\\}", Relay );
   }
    if ( vid_dog > 0)
    {
        replacements.put( "\\{VIDD\\}", String.valueOf( vid_dog ) );
    }
    if ( vid > 0)
    {
        replacements.put( "\\{VID\\}", String.valueOf( vid ) );
    }
    return ManadUtils.generateRule( ruleText, addresses, replacements, ruleType );      
}
 
getVlan( cid , pid )
{
   int result = 1102; 
   String query =  "select val from contract_parameter_type_1 where cid=" + cid + " and pid= " + pid;
   PreparedStatement ps = con.prepareStatement( query ); 
   ResultSet rs = ps.executeQuery();
   rs.first();
//   log.info("Row = "+rs.getRow());
   if ( rs. isFirst() )
   {
//   log.info("---- First ------");
      result = rs.getInt(1);
   }
//   log.info("Vlan = "+result);
   return result;   
}

У нас имеется 2 вида свичей Zyxel и Qtech, шлюзы у них одинаковые, только разные команды. Конфигурация шлюза Qtech/Zyxel:

login=admin
#время ожидания ответа, по истечению которого, шлюз сбрасывает соединение и выдаёт ошибку
timeout=20000
#Код услуги для выставления скорости на порту
sid=1
#код Vlan клиента параметра договора
vlanId=1
#Код типа правила для 100Мб
speed100=3
speed10=6
#Relay
relay.ip=10.35.2.240
relay.vlan=1103
#BGDHCP
dhcp.ip=127.0.0.1
dhcp.port=1868
#Time Offset в секундах
dhcp.timeOffset=-18000
#Роутер(ы), если несколько - через запятую 10.21.255.1
dhcp.router=10.35.255.1
#Домен
#dhcp.domain=
#DNS сервер(а), если несколько - через запятую 10.176.74.129
dhcp.dns=10.176.74.131
#Маска подсети
#dhcp.subnetMask=255.0.0.0
dhcp.subnetMask=255.240.0.0
#Время аренды ip адресов, в секундах, по умолчанию 43200
dhcp.ipAddressLeaseTime=86400
#
#Также можно выдавать все остальные опции dhcp, в виде dhcp.option.x=ffffffff
#где x - код dhcp опции, ffffffff - байты в 16ричном виде
#Например, сервер NTP по адресу 127.0.0.1, в конфиге нужно указать:
#dhcp.option.42=7F000001
#Коды других опций можно узнать в rfc2132
#dhcp.option.121=0AB04A80190A15FF01
#для компьютеров
dhcp.option.121=190AB04A800A23FF011B511E3B000A23FF01100A100A23FF01100A110A23FF01
#для D-Link DIR-100, DIR-300, DIR-320 с dual access
dhcp.option.249=190AB04A800A23FF011B511E3B000A23FF01100A100A23FF01100A110A23FF01

Конфигурация типа шлюза Qtech/Zyxel:

user_rule.editor.class=bitel.billing.module.services.ipn.editor.vlan.CiscoSSHSwitchRuleEditor
gate_manager.class=bitel.billing.server.ipn.vlan.CiscoSSHSwitchGateWorker
use.script=1
#Код услуги для выставления скорости на порту
sid=3

Команды шлюза Qtech:

[DEFAULT]
[OPEN_FULL]
  <LOOP_PORT>
    vlan {VID}
    switchport ethernet 0/{PORT}
    exit
    interface ethernet 0/{PORT}
    switchport access vlan  {VID}
    no shutdown
    no bandwidth egress
    speed ${speed}
    exit 
    access-list 1{PORT} permit <LOOP>{A} 0.0.0.0 any</LOOP>
    access-list 1{PORT} permit <LOOP>any {A} 0.0.0.0</LOOP>
    access-list 2{PORT} permit ingress interface ethernet 0/{PORT}
    access-group ip-group 1{PORT} subitem 0 link-group 2{PORT} subitem 0
</LOOP_PORT>
[/OPEN_FULL]
[OPEN]
<LOOP>
  <LOOP_PORT>
    vlan {VID}
    switchport ethernet 0/{PORT}
    exit
    interface ethernet 0/{PORT}
    switchport access vlan  {VID}
    no shutdown
    speed 10auto
    bandwidth egress ${speed}
    exit 
    access-list 1{PORT} permit {A} 0.0.0.0 any
    access-list 1{PORT} permit any {A} 0.0.0.0
    access-list 2{PORT} permit ingress interface ethernet 0/{PORT}
    access-group ip-group 1{PORT} subitem 0 link-group 2{PORT} subitem 0
</LOOP_PORT>
</LOOP>
[/OPEN]
[CLOSE]
  <LOOP_PORT>
    vlan {VID}
    no switchport ethernet 0/{PORT}
    exit
    interface ethernet 0/{PORT}
    shutdown
    exit 
    no access-group ip-group 1{PORT} subitem 0 link-group 2{PORT} subitem 0
    no access-list 1{PORT}
    no access-list 2{PORT}
</LOOP_PORT>
[/CLOSE]
[/DEFAULT]

Скрипт шлюза Qtech/Zyxel: Данный скриптовый шлюз устанавливает тип правила для даного шлюза в договоре, полученный из текущего тарифа для модуля IPN.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.lang.Integer;
import java.util.Map.Entry;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
import org.apache.xml.serializer.ToXMLStream;
import org.xml.sax.SAXException;
 
import java.util.*;
import java.util.regex.*;
import java.text.*; 
import java.sql.*;
 
import bitel.billing.common.IPUtils;
import bitel.billing.common.module.ipn.IPNContractStatus;
import bitel.billing.server.ipn.UserStatus;
import bitel.billing.server.ipn.dlink.UserPortStatus;
import bitel.billing.server.util.DefaultServerSetup;
import bitel.billing.server.util.Utils;
import bitel.billing.server.util.telnet.TelnetSession;
import bitel.billing.server.ipn.bean.*;
 
import ru.bitel.bgbilling.common.*;
import bitel.billing.common.module.ipn.*;
import bitel.billing.server.ipn.*;
import bitel.billing.server.util.*;
 
protected void doSync()
{
   try
   {
      String host = gate.getHost();
      int port = gate.getPort();
 
      DefaultServerSetup gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" );        
 
      String pswd = gate.getKeyword();
      String login = gateSetup.getStringValue( "login");
 
      StringBuffer result = new StringBuffer();
 
      if( log.isDebugEnabled() )
      {
          log.debug( gate.getId() + " gate: " + host + ":" + port  + " login: " + login + " pswd: " +       pswd );
      }
       log.info( gate.getId() + " gate: " + host + ":" + port  + " login: " + login + " pswd: " +       pswd );
 
      TelnetSession session = new TelnetSession( host, port);
 
      session.setLoginPromptSequence( ":" );                  
      log.info( "before connect" );
      session.connect();      
      log.info( "after connect" );
      result.append( session.doCommand( "terminal length 0" ) );
//      log.info( session.doCommand( "terminal length 0" ) );
      result.append( session.doCommand( "\n" ) );
//      log.info( session.doCommand( "\n" ) );
      result.append( session.doCommand( login ) );
//      log.info( session.doCommand( login ) );
      log.info( "after login" );
      session.setLoginPromptSequence( ">" );
      result.append( session.doCommand( pswd ) );
//      log.info( session.doCommand( pswd ));
      log.info( "after pswd" );
      log.info( "execute commands" );
      session.setLoginPromptSequence( "#" );
      result.append( session.doCommand( "enable" ) );      
//      log.info( session.doCommand( "enable" ) );
//      log.info( "after execute commands" );
      result.append( session.doCommand( "configure terminal" ) );
 
      doCommands( session, result, gateSetup);
      log.info( "after commands" );
//Выход из конфигурации
      result.append( session.doCommand( "exit" ) );
//      log.info( session.doCommand( "exit" ) );
      log.info( "exit Выход  из конфигурации" );
//Выход из enable
      session.setLoginPromptSequence( ">" );
      result.append( session.doCommand( "exit" ) );
//      log.info(session.doCommand( "exit" ) );
//Выход
      session.disconnect();
 
//      log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!! Qtech!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
      log.info( result.toString() );
//      log.info( "!!!!!!!!!!!!!!!!!!!!!!!!!!! Qtech!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
 
      log.debug( "ok" );
   } catch (Exception e)
   {
      throw new RuntimeException ( e );
   } 
}
 
private void doCommands( TelnetSession session, StringBuffer result, DefaultServerSetup gateSetup) 
throws IOException
{
    Speed100 = gateSetup.getIntValue( "Speed100", 0 );
    Speed10 = gateSetup.getIntValue( "Speed10", 0 );
    dhcp_ip = gateSetup.getStringValue( "dhcp.ip", "127.0.0.1" );
    dhcp_port = gateSetup.getIntValue( "dhcp.port", 1868 );
   vlanId = gateSetup.getIntValue( "vlanId",0);
   BGDHCP = new Hashtable();
   BGDHCP.put("dhcp.ip", dhcp_ip);
   BGDHCP.put("dhcp.port", dhcp_port);
   BGDHCP.put("gateId", String.valueOf( gate.getId() ));
   BGDHCP.put("gateIP", gate.getHost());
    for( UserStatus status : statusList )
   {
      BGDHCP.put("Relay", gateSetup.getStringValue( "relay.ip","10.35.255.254"));
      BGDHCP.put("vid_dog",getVlan( status.contractId, vlanId ) );
//          log.info( "Relay = " + gateSetup.getStringValue( "relay.ip"));
      getNewRule(status,gateSetup.getIntValue( "sid",0 ));
      if ( status.status == IPNContractStatus.STATUS_OPEN )
      {
//          log.info( "-------1-------" );
          BGDHCP.put("start", "port");
         rules  = getOpenRules( status, Speed100, Speed10, BGDHCP);
         for ( String rule : rules )
         {
          log.info("rule = " + rule );
            result.append( session.doCommand( rule ) );   
         }
         setDHCP( BGDHCP, gateSetup);
      }
      else if ( status.status == IPNContractStatus.STATUS_REMOVED ){
          BGDHCP.put("start", "removePort");
         rules = getCloseRules( status, BGDHCP);
         for ( String rule : rules )
         {
//          log.info( "-------9-------" );
//          log.info( rule );
            result.append( session.doCommand( rule ) );   
         }
         setDHCP( BGDHCP, gateSetup );
      }
      else
      {
//        log.info( "-------4-------" );
          BGDHCP.put("start", "port");
         rules = getCloseRules( status, BGDHCP);
         for ( String rule : rules )
         {
//          log.info( "-------9-------" );
//          log.info( rule );
            result.append( session.doCommand( rule ) );   
         }
//         setDHCP( BGDHCP );
      }                              
   }     
}
 
//------- шлюз BGDHCP---------
setDHCP( DHCP, gateSetup )
{
//log.info("------Set DHCP------");
      Socket socket = null; 
        socket = new Socket( DHCP.get("dhcp.ip"), DHCP.get("dhcp.port") );
        InputStreamReader isr = new InputStreamReader( socket.getInputStream() );
        BufferedReader in = new BufferedReader( isr );
      ToXMLStream stream = new ToXMLStream();
        stream.setOutputStream(  socket.getOutputStream() );
        stream.setEncoding( "UTF-8");
        stream.startDocument();
        stream.startElement( "sync" );
        stream.addAttribute( "type", "dhcp" );
 
      stream.startElement( "gate" );
        stream.addAttribute( "id", String.valueOf( DHCP.get("gateId")) );
        stream.addAttribute( "host", DHCP.get("Relay") );   
      ParamDHCP(stream, "dhcp.router", gateSetup);
      ParamDHCP(stream, "dhcp.subnetMask", gateSetup);
      ParamDHCP(stream, "dhcp.dns", gateSetup);
      ParamDHCP(stream, "dhcp.ipAddressLeaseTime", gateSetup);
      ParamDHCP(stream, "dhcp.timeOffset", gateSetup);
      ParamDHCP(stream, "dhcp.option.121", gateSetup);
      ParamDHCP(stream, "dhcp.option.249", gateSetup);
        stream.endElement( "gate" );
      id = DHCP.get("id");
      ip = DHCP.get("ip").split(",");
      for (int i = 0; i < id.length; i++)
      {
           stream.startElement( DHCP.get("start") );
           stream.addAttribute( "gateId", DHCP.get("gateId") );
           stream.addAttribute( "id", String.valueOf( id[i] ) );//по порту
//           stream.addAttribute( "id", String.valueOf( DHCP.get("vid_dog") ) ); //по влан
         ip[i] = ip[i].substring(0 , 9);
         Hex_ip = Integer.toHexString(Integer.parseInt(ip[i]));
         if(Hex_ip.length() < 8){
            Hex_ip = "0" + Hex_ip;
         }
//log.info("ip["+i+"]= " + Hex_ip.toUpperCase());
         Hex_ip   = Hex_ip.substring(0,2) + " " + Hex_ip.substring(2,4) + " " +Hex_ip.substring(4,6) + " " + 
                  Hex_ip.substring(6,8);
           stream.addAttribute( "ip", Hex_ip.toUpperCase() );                           
           stream.endElement( DHCP.get("start") );
/*log.info("id["+i+"] = " + id[i]);
log.info("ip["+i+"]= " + ip[i]);
log.info("ip["+i+"]= " + Hex_ip.toUpperCase());
*/      }
 
//-------BGDHCP---------
        stream.flushPending();
        stream.getWriter().flush();
        stream.endElement( "sync" );
        stream.endDocument();
        stream.getWriter().flush();
        if( socket != null )
        {
            try 
            {
                socket.close();
            } 
            catch (Exception e) 
            {}
        }
//-------BGDHCP---------
}
 
//private String[]  getOpenRules( UserStatus status, RuleTypeId, DHCP)
private String[]  getOpenRules( UserStatus status, Speed100, Speed10, DHCP)
{
//log.info("ruleTypeid="+status.rule.getRuleTypeId());    
//log.info("ruleTypeId="+RuleTypeId);    
//   if(status.rule.getRuleTypeId() == RuleTypeId)
   if(status.rule.getRuleTypeId() == Speed100 || status.rule.getRuleTypeId() == Speed10)
      return getRules( status, "\\[OPEN_FULL\\]((.|\n)*)\\[/OPEN_FULL\\]", DHCP);
   else
      return getRules( status, "\\[OPEN\\]((.|\n)*)\\[/OPEN\\]", DHCP);
}
private String[]  getCloseRules( UserStatus status , DHCP)
{
//        log.info( "-------3-------" );
   return getRules( status, "\\[CLOSE\\]((.|\n)*)\\[/CLOSE\\]", DHCP);
}
getRules(  status, template, DHCP)
{
        // пользовательское правило, без типа - то все оставляем как есть
//        log.info( "-------5-------" );
   rule = status.rule.getRuleText();
        //порты идут до #, а адреса идут после  
   String [] parts  = rule.split( "#" );
   portsStr = "";
   addresesStr = "";
   if ( parts.length > 0 )
   {
       portsStr = parts[0];
//log.info("portsStr = " +portsStr);
   }
   if ( parts.length > 1 )
   {
      addresesStr = parts[1];
//log.info("addresesStr = " +addresesStr);
   }
   //типизированное правило
   if( status.ruleType != null )   
   {                       
            rule = generateRule( addresesStr, portsStr, status.gateType, status.ruleType, DHCP );
   }
    pattern = Pattern.compile( template, Pattern.DOTALL );
//log.info("rule = " + rule);
   m = pattern.matcher( rule );
   if (m.find())
   {
       rule = m.group( 1 );
   }      
   rule.replaceAll( "\r", "" );
   parts  = rule.split( "\n" );
   return parts;
}      
 
generateRule(  addreses, ports, gateType, ruleType, DHCP )
{      
//        log.info( "-------6-------" );
   ports_ = getPorts( ports );      
   DHCP.put("id", ports_);
   DHCP.put("ip", addreses);
   ruleText = ManadUtils.getRule( gateType, ruleType );
   replacements =  new HashMap();
   vid_dog = DHCP.get("vid_dog");
    if ( vid_dog > 0)
    {
        replacements.put( "\\{VID\\}", String.valueOf( vid_dog ) );
    }
   loops = ManadUtils.getAddresLoops( addreses );
   //адреса
   p = new LoopPattern();      
   p.setLoopPatern( "LOOP_PORT" );
   p.setReplace( "\\{PORT\\}" );
   p.setObjects( ports_ );      
   loops.add( p );
   return ManadUtils.generateRule( ruleText, replacements, ruleType, loops );      
}
 
getPorts( ports )
{
//        log.info( "-------7-------" );
      portList = new ArrayList();
      parts  = ports.split( ";" );
      for (String part : parts )
      {
         parts2  = part.split( ":" );
         if ( parts2.length <  2)
         {
            continue;
         }
         port = parts2 [1];
         portList.add( port );
      }
      String [] ports_ = new String [portList.size()];
      for (int i = 0; i < ports_.length; i++)
      {
         if((portList.get( i )).length() ==1 )
         {
            ports_[i] = "0" + portList.get( i );
//            port="0"+port;
         }else{
            ports_[i] = portList.get( i );
         }
//           log.info( "port["+i+"] = " + ports_[i]);
      }
      return ports_;
}
 
private getNewRule(status,sid)
{
   if (status.ruleType == null){
      return;
   };
   H = new Hashtable();
   H.put("operation", "get_ipn_rule_id");
   H.put("cid", status.contractId);
   H.put("mid", status.mid);
   H.put("sid", sid);
   H.put("time", new GregorianCalendar());
   ParseTarif(H);
   rule_id = H.get("rule_id");
   if (rule_id != null)
   {
log.info("rule_id="+rule_id);
      rule_type_manager = new RuleTypeManager(con,status.mid);
      status.ruleType = rule_type_manager.getType(Integer.parseInt(rule_id));
     rule_type_manager.updateType(status.ruleType);   
     //Сохраняюм тип правила из тарифа в шлюз договора
      status.rule.setRuleTypeId(Integer.parseInt(rule_id));
       UserGateRuleManager = new UserGateRuleManager(con,status.mid);
     UserGateRuleManager.updateUserGateRule((status.rule.getID()).toString(),status.rule); 
   };
}
 
private ParseTarif(H)
{
   H.put("is_found", false);
   cid = H.get("cid");
   if (cid == null)
   {
      return;
   };
   time = H.get("time");
   if (time == null)
   {
      return;
   };
   formatter = new SimpleDateFormat("yyyy-MM-dd");
   tarif_date = formatter.format(time.getTime()).toString(); 
 
   query = "SELECT contract_tree_link.tree_id "+
   "FROM contract_tree_link "+
   "WHERE "+
   "(contract_tree_link.date1 is NULL OR contract_tree_link.date1<='"+tarif_date+"') AND "+
   "(contract_tree_link.date2 is NULL OR contract_tree_link.date2>='"+tarif_date+"') AND "+
   "contract_tree_link.cid='"+cid+"' "+
   "UNION "+
   "SELECT tariff_tree_link.tree_id "+
   "FROM contract_tariff "+
   "  INNER JOIN tariff_tree_link "+
   "  ON (contract_tariff.tpid=tariff_tree_link.tpid) "+
   "WHERE (contract_tariff.date1 is NULL OR contract_tariff.date1<='"+tarif_date+"') AND "+
   "(contract_tariff.date2 is NULL OR contract_tariff.date2>='"+tarif_date+"') AND "+
   "contract_tariff.cid='"+cid+"'";
   re = con.prepareStatement(query); 
   rs = re.executeQuery();
   while (rs.next())
   {
      tree_id = rs.getString(1);
//  log.info("tree_id1=" + tree_id);
      ParseMTree(tree_id,H);
   };
}
private ParseMTree(tree_id,H)
{   
   is_found = H.get("is_found");
   if (is_found == null)
   {
      return;
   };
   if (is_found)
   {
      return;
   };
   mid = H.get("mid");
   if (mid == null)
   {
      return;
   };
 
   ParseMTree_(tree_id,H);
 
   is_found = H.get("is_found");
   if (is_found == null)
   {
      return;
   };
   //Если не найден тип правила, возможно используется иерархия тарифов(создание тарифа на основе другого тарифа)
//   log.info("is_found1="+is_found);
   if (!is_found)
   {
      query = "SELECT id, parent_tree "+
      "FROM module_tariff_tree "+
         "WHERE tree_id='"+tree_id+"' and mid='"+mid+"'";
       re = con.prepareStatement(query); 
       rs = re.executeQuery();
       while (rs.next())
      {
         //просмотрим верхний тариф, если есть
          mtree_id = rs.getString(1);
          tree_id = rs.getString(2);
//      log.info("tree_id2=" + tree_id);
//      log.info("mtree_id2=" + mtree_id);
          ParseMTree_(tree_id,mtree_id,H);
       };
   };
//   log.info("rule_id="+H.get("rule_id"));
}
 
private ParseMTree_(tree_id,H){
   query = "SELECT mtree_node.id, mtree_node.mtree_id "+
   "FROM module_tariff_tree "+
   "  INNER JOIN mtree_node "+
   "  ON (module_tariff_tree.id=mtree_node.mtree_id) "+
   "WHERE mtree_node.type='root' AND module_tariff_tree.tree_id='"+tree_id+"' AND module_tariff_tree.mid='"+mid+"'";
   re = con.prepareStatement(query); 
   rs = re.executeQuery();
   while (rs.next())
   {
      node_id = rs.getString(1);
     mtree_id    = rs.getString(2);
      ParseNode(node_id, mtree_id, H);
   };
}
 
private ParseMTree_(tree_id,mtree_id,H)
{
   query = "SELECT mtree_node.id, mtree_node.mtree_id "+
   "FROM module_tariff_tree "+
   "  INNER JOIN mtree_node "+
   "  ON (module_tariff_tree.id=mtree_node.mtree_id) "+
   "WHERE mtree_node.type='root' AND module_tariff_tree.tree_id='"+tree_id+"' AND module_tariff_tree.mid='"+mid+"'";
   re = con.prepareStatement(query); 
   rs = re.executeQuery();
   while (rs.next())
   {
      node_id = rs.getString(1);
     mtree_id_    = rs.getString(2);
//      ParseNode(node_id, mtree_id_, H);
   //Если не найден тип правила, возможно используется иерархия тарифов(создание тарифа на основе другого тарифа)
      ParseNode(node_id, mtree_id_, mtree_id, H);
//      log.info("node_id3=" + node_id);
//      log.info("mtree_id3=" + mtree_id);
//      log.info("mtree_id3_=" + mtree_id_);
   };
}
 
private ParseNode(node_id, mtree_id, H)
{
   is_found = H.get("is_found");
   if (is_found == null)
   {
      return;
   };
   if (is_found)
   {
      return;
   };
   sid = H.get("sid");
   if (sid == null)
   {
      return;
   };
   operation = H.get("operation");
   if (operation == null)
   {
      return;
   };
   time = H.get("time");
   if (time == null)
   {
      return;
   };
//      log.info("node_id5=" + node_id);
//      log.info("mtree_id5=" + mtree_id);
   query = "SELECT id, type, data FROM mtree_node WHERE parent_node='"+node_id+"' and mtree_id='"+mtree_id+
         "' order by pos";
   re = con.prepareStatement(query); 
   rs = re.executeQuery();
   while (rs.next())
   {
      id = rs.getString(1);
      type = rs.getString(2);
      data = rs.getString(3);
      if (type.equals("service") && sid != Integer.parseInt(data))
      {
         continue;
      };
      if (type.equals("ipn_rule") && operation.equals("get_ipn_rule_id"))
      {
         datas = data.split ("&");
         H.put("rule_id",datas[1]);
         H.put("is_found",true);
      };
      if (type.equals("period"))
      {
         datas = data.split ("%");
         date1 = null;
         date2 = null;
         for (i=0; i<datas.length; i++)
         {
            date_arr = datas[i].split("&");
            if (date_arr.length != 2)
            {
               continue;
            };
            formatter = new SimpleDateFormat("dd.MM.yyy"); 
            date = formatter.parse(date_arr[1]);
            if (date_arr[0].equals("date1"))
            {
               date1 = date;
            };
            if (date_arr[0].equals("date2"))
            {
               date2 = date;
            };
         };
         if (date1 != null && date1.compareTo(time.getTime()) != -1){
            continue;
         };
         if (date2 != null && date2.compareTo(time.getTime()) != 1){
            continue;
         };
      };
      if (type.equals("uplim")){
 
     };
      ParseNode(id, mtree_id, H);
   };
};
 
private ParseNode(node_id, mtree_id , sec_mtree_id, H)
{
   is_found = H.get("is_found");
   if (is_found == null)
   {
      return;
   };
   if (is_found)
   {
      return;
   };
   sid = H.get("sid");
   if (sid == null)
   {
      return;
   };
   operation = H.get("operation");
   if (operation == null)
   {
      return;
   };
   time = H.get("time");
   if (time == null)
   {
      return;
   };
//      log.info("node_id6=" + node_id);
//      log.info("mtree_id6=" + mtree_id);
   query = "SELECT id, type, data FROM mtree_node WHERE parent_node='"+node_id+"' and mtree_id='"+mtree_id+
         "' order by pos";
   re = con.prepareStatement(query); 
   rs = re.executeQuery();
   while (rs.next())
   {
      id = rs.getString(1);
      type = rs.getString(2);
      data = rs.getString(3);
      if (type.equals("service") && sid != Integer.parseInt(data))
      {
         continue;
      };
      if (type.equals("ipn_rule") && operation.equals("get_ipn_rule_id"))
      {
         datas = data.split ("&");
         H.put("rule_id",datas[1]);
         H.put("is_found",true);
      };
      if (type.equals("period"))
      {
         datas = data.split ("%");
         date1 = null;
         date2 = null;
         for (i=0; i<datas.length; i++)
         {
            date_arr = datas[i].split("&");
            if (date_arr.length != 2)
            {
               continue;
            };
            formatter = new SimpleDateFormat("dd.MM.yyy"); 
            date = formatter.parse(date_arr[1]);
            if (date_arr[0].equals("date1"))
            {
               date1 = date;
            };
            if (date_arr[0].equals("date2"))
            {
               date2 = date;
            };
         };
         if (date1 != null && date1.compareTo(time.getTime()) != -1){
            continue;
         };
         if (date2 != null && date2.compareTo(time.getTime()) != 1){
            continue;
         };
      };
      if (type.equals("uplim")){
 
     };
      ParseNode(id, mtree_id, H);
      ParseNode(id, sec_mtree_id, H);
   };
};
 
 
private Download(H){
   if (mid == null)
   {
      return;
   };
   if (cid == null)
   {
      return;
   };
   time = H.get("time");
   if (time == null)
   {
      return;
   };
   formatter = new SimpleDateFormat("yyyy-MM");
   month = formatter.format(time.getTime()).toString(); 
   sid = H.get("sid");
   if (sid == null)
   {
      return;
   };
   query = "select sum(amount) from ipn_contract_data_"+mid+"_"+month+" where cid="+cid+" and sid="+sid;
   re = con.prepareStatement(query); 
   rs = re.executeQuery();
   while (rs.next())
   {
      H.put("download", rs.getBigDecimal(1));
   };
};
 
ParamDHCP(stream, paramStr, gateSetup)
{
      param = gateSetup.getStringValue( paramStr, null );
      if (param != null){
           stream.startElement( "param" );
         stream.addAttribute( "id", paramStr );   
         stream.addAttribute( "value", param );   
           stream.endElement( "param" );
      }
}
/* Получаем влан из параметра договора
 */
getVlan( cid , pid )
{
   int result = 1102; 
   String query =  "select val from contract_parameter_type_1 where cid=" + cid + " and pid= " + pid;
   PreparedStatement ps = con.prepareStatement( query ); 
   ResultSet rs = ps.executeQuery();
   rs.first();
//   log.info("Row = "+rs.getRow());
   if ( rs. isFirst() )
   {
//   log.info("---- First ------");
      result = rs.getInt(1);
   }
//   log.info("Vlan = "+result);
   return result;   
}

Скрипт проверки уникальности VLAN в договорах одного квартала. Вешается на изменение параметра договора.

import bitel.billing.server.contract.bean.*; 
import bitel.billing.server.script.event.*; 
import java.util.*;
 
//id параметра договора для VLAN
VLAN_PARAM_ID = 33;
paramId = event.getParamId();
if( paramId == VLAN_PARAM_ID )
{
	VLAN = event.getValue();
//Определяем квартал , к которому принадлежит договор 
	ps = con.prepareStatement( "SELECT house.quarterid FROM contract_parameter_type_2 as address "+ 
 				"LEFT JOIN address_house as house ON house.id=address.hid "+
				"WHERE address.cid=? AND address.pid=24;");
	ps.setInt(1, event.getContractID()); 
	rs = ps.executeQuery(); 
	if(rs.next()){ 
		quarterId = rs.getInt( 1 );
//		print("quarterId = " + quarterId);
//Если введенный влан в этом квартале
		ps = con.prepareStatement( "SELECT contract.title, vlan.val FROM contract "+ 
				 "LEFT JOIN contract_parameter_type_2 as address ON contract.id=address.cid AND address.pid=24 "+
				 "LEFT JOIN contract_parameter_type_1 as vlan ON contract.id=vlan.cid AND vlan.pid=33 "+
				 "LEFT JOIN address_house as house ON house.id=address.hid "+
				 "WHERE  house.quarterid=? AND vlan.val=? AND contract.status != 3;");
		ps.setInt(1, quarterId); 
		ps.setString(2, VLAN); 
		rs = ps.executeQuery(); 
//		print("VLAN = " + VLAN);
//		print("ContractID = " + event.getContractID());
		if(rs.next()){ 
    	    event.setError( "VLAN - " + VLAN + " присвоен договору №" +rs.getString( 1 ));
        	return;
		}
	}
}
< /source>
Спасибо всем, кто писал и выкладывал скрипты в wiki. Очень помогли и съэкономили время.
Личные инструменты