Конвертер: логины Dialup в сервисы inet
Материал из BiTel WiKi
Глобальный скрипт. Конвертер переносящий логины Dilaup в сервисы inet . Работает по такому принципу - для каждого логина создает сервисы с цифровым значением логина, и создает сервис для альяса (если есть). Все настройки - заданы константами с пояснениями в начале класса . При повторном запуске скрипт добавляет/удаляет только то что изменилось .
1) Нужно создать тип устройства для VPN соответственно устройство для каждого NAS . Все NAS-лучше объединить одним общим устройством в иерархии (папка). В конфигурации устройств(типов) нужно указать какие устройства являются radius-устройствами - radius.deviceTypeIds.
2) Нужно создать тип сервиса в Inet, в нем указать const.device.id - устройство являющиеся NAS . Если NAS несколько, то указать общее устройство (папку), которое объединяет все NAS-ы. В конфигурации типа сервиса задайте шаблон типа такого title.pattern=(${login})
3) Добавить вручную сервис на договор и проверить работу на каком-нибудь теством NAS .
4) Запустить конвертер. Внимание - это java класс, а не bgbs(bsh) скрипт, добавляете его на соответствующей вкладке в Глобальных скриптах.
Код конвертера
package ru.maglan.bgbilling.script.global; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import ru.bitel.bgbilling.common.BGException; import ru.bitel.bgbilling.kernel.container.managed.ServerContext; import ru.bitel.bgbilling.kernel.script.server.dev.GlobalScriptBase; import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServ; import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServOption; import ru.bitel.bgbilling.modules.inet.api.common.service.InetDeviceService; import ru.bitel.bgbilling.modules.inet.api.common.service.InetServService; import ru.bitel.bgbilling.server.util.Setup; import ru.bitel.common.Utils; import ru.bitel.common.sql.ConnectionSet; import bitel.billing.common.TimeUtils; import bitel.billing.server.contract.bean.ContractModuleManager; import bitel.billing.server.contract.bean.ContractScriptManager; public class ConvertVPNLoginsToInet extends GlobalScriptBase { //код модуля Dialup private static int DIALUP_MODULE_ID = 5; //код модуля Inet private static int INET_MODULE_ID = 18; //код сервиса типа сервиса в модуле Inet private static int INET_SERV_TYPE_VPN_ID = 1; private InetServService wsServ = null; private InetDeviceService wsDevice = null; Logger logger = Logger.getLogger( ConvertVPNLoginsToInet.class ); @Override public void execute( Setup setup, ConnectionSet connectionSet ) throws Exception { ServerContext context = ServerContext.get(); wsServ = context.getService( InetServService.class, INET_MODULE_ID ); wsDevice = context.getService( InetDeviceService.class, INET_MODULE_ID ); createServices ( connectionSet ); print( "OK" ); } private void createServices( ConnectionSet connectionSet ) throws SQLException, BGException { Connection con = connectionSet.getConnection(); //обязательно чтобы мы с этого места могли делать rollback если что connectionSet.commit(); logger.info( "creating services..." ); /*String query = "SELECT * FROM from user_login_ " + DIALUP_MODULE_ID + " as login " + " LEFT JOIN user_alias_ " + DIALUP_MODULE_ID + " as alias " + " LIMIT 0,10 "; */ String query = "SELECT * FROM contract " + " LEFT JOIN contract_module as cm ON contract.id = cm.cid " + " WHERE cm.mid = " + DIALUP_MODULE_ID; //" AND contract.id = 212" ; //" LIMIT 0,1000 "; PreparedStatement ps = con.prepareStatement( query ); ResultSet rs = ps.executeQuery(); ContractModuleManager cmm = new ContractModuleManager( con ); Date now = new Date(); //int portIdx = 0 ; //int idx = 0 ; Map<String, InetServ> servMap = new HashMap<String, InetServ>(); Map<String, InetServ> servMapСopy = new HashMap<String, InetServ>(); while ( rs.next() ) { int cid = rs.getInt( "contract.id" ); /* //удаленные договора игнорим if( ipnStatus == IPNContractStatus.STATUS_REMOVED ) { continue; } */ //int count = 0; List<InetServ> list = wsServ.inetServList( cid ); //print( "list.size() = " + list.size() ); // for ( InetServ oldServ : list ) { if ( oldServ.getTypeId() == INET_SERV_TYPE_VPN_ID ) { servMap.put( getKey( oldServ.getLogin(), cid ), oldServ ); servMapСopy.put( getKey( oldServ.getLogin(), cid ), oldServ ); } } //print( count + " services was deleted" ); connectionSet.commit(); query = "SELECT * FROM user_login_" + DIALUP_MODULE_ID + " as login " + " LEFT JOIN user_alias_" + DIALUP_MODULE_ID + " as alias ON alias.login_id=login.id " + " WHERE login.cid = " + cid; //" LIMIT 0, 10"; PreparedStatement psLogin = con.prepareStatement( query ); ResultSet rsLogin = psLogin.executeQuery(); boolean flag = false; //print( "cid before ports = " + cid ); while ( rsLogin.next() ) { int loginInt = rsLogin.getInt( "login.login" ); String alias = rsLogin.getString( "alias.login_alias" ); int loginStatus = rsLogin.getInt( "login.status" ); Date dateFrom = rsLogin.getDate( "login.date1" ); Date dateTo = rsLogin.getDate( "login.date2" ); String pswd = rsLogin.getString( "login.pswd" ); int sessionCount = rsLogin.getInt( "session" ); int inetStatus = loginStatus == 0 ? InetServ.STATUS_ACTIVE : InetServ.STATUS_LOCKED; logger.info( "create login =" + loginInt + ";alias=" + alias ); //print( "create login =" + loginInt + ";alias=" + alias ); //в первый раз добавляем модуль и скрипт поведения if ( !flag ) { try { Set<Integer> moduleSet = cmm.getContractModuleSet( cid ); if( !moduleSet.contains( INET_MODULE_ID ) ) { cmm.addContractModule( cid, INET_MODULE_ID ); //EventProcessor.getInstance().publishAfterCommit( new ContractModifiedEvent( User.USER_SERVER, cid ) ); } connectionSet.commit(); } catch( Exception e ) { print("error=" + e.getMessage() ); logger.error( "", e ); connectionSet.rollback(); continue; } flag = true; } String login = String.valueOf( loginInt ); updateLogin( login, servMap, servMapСopy, dateFrom, dateTo, pswd, cid, inetStatus, connectionSet, sessionCount ); if ( !Utils.isEmptyString( alias ) ) { updateLogin( alias, servMap, servMapСopy, dateFrom, dateTo, pswd, cid, inetStatus, connectionSet, sessionCount ); } } psLogin.close(); } ps.close(); //delete extra services int extraIdx = 0; connectionSet.commit(); print( "deleting extra services" ); for ( Map.Entry<String,InetServ> entry : servMapСopy.entrySet() ) { InetServ serv = entry.getValue(); print ( "deleting serv " + serv.getId() + ";serv.getLogin()=" + serv.getLogin() + ";cid=" + serv.getContractId() + ";key=" + entry.getKey() ); //во такой вот костыль чтобы удалить сервис, иначе не дает logger.info( "delete extra service =" + extraIdx++ ); connectionSet.commit(); if ( serv.getDateTo() == null || TimeUtils.dateBefore( now, serv.getDateTo() ) ) { serv.setDateTo( TimeUtils.getPrevDay( now ) ); try { // logger.info( "updating serv date for cid = " + cid ); wsServ.inetServUpdate( serv, new ArrayList<InetServOption>(), false, false, 0 ); } catch( Exception e ) { printError( serv.getContractId(), e, "Error while updating extra service date for contract " + serv.getContractId() + ";" + serv.getLogin() + ":" + e.getMessage() ); // logger.error( "", e ); } } try { wsServ.inetServDelete( serv.getId() ); } catch( Exception e ) { printError( serv.getContractId(), e, "Error while deleting extra service date for contract " + serv.getContractId() + ";" + serv.getLogin() + ":" + e.getMessage() ); // logger.error( "", e ); connectionSet.commit(); continue; } connectionSet.commit(); } } void updateLogin( String login, Map<String, InetServ> servMap, Map<String, InetServ> servMapCopy, Date dateFrom, Date dateTo, String pswd, int cid, int inetStatus, ConnectionSet connectionSet, int sessionCount ) throws BGException { InetServ serv = servMap.get( getKey( login, cid ) ); boolean needUpdate = false; if ( serv == null ) { print( "add new service for cid " + cid + ";login" + login ); serv = new InetServ(); serv.setContractId( cid ); serv.setComment( "Импортирован из VPN" ); serv.setDateFrom( dateFrom ); serv.setDateTo( dateTo ); serv.setLogin( login ); serv.setPassword( pswd ); serv.setTypeId( INET_SERV_TYPE_VPN_ID ); serv.setSessionCountLimit( sessionCount ); //serv.setDeviceId( inetDeviceId ); needUpdate = true; } //print( "dateFrom=" + dateFrom + ";dateTo =" + dateTo ); //print( "serv.Login=" + serv.getLogin() + ";serv.getDateFrom()= " + serv.getDateFrom() + ";;serv.getDateTo()= " + serv.getDateTo() ); //TimeUtils.dateEqual( date1, date2 ); if ( !needUpdate && dateChanged( dateFrom, serv.getDateFrom() ) ) { print( "dateFrom changed"); serv.setDateFrom( dateFrom ); needUpdate = true; } if ( !needUpdate && dateChanged( dateTo, serv.getDateTo() ) ) { print( "dateTo changed"); serv.setDateTo( dateTo ); needUpdate = true; } if ( !needUpdate && serv.getStatus() != inetStatus ) { print( "status changed"); serv.setStatus( inetStatus ); needUpdate = true; } if ( !needUpdate && !login.equals( serv.getLogin() ) ) { print( "Login changed"); serv.setLogin( login ); needUpdate = true; } if ( !needUpdate && !pswd.equals( serv.getPassword() ) ) { print( "pswd changed; was:" + serv.getPassword() + ";now:" + pswd + ";" ); serv.setPassword( pswd ); print( "pswd new:" + serv.getPassword() ); needUpdate = true; } if ( !needUpdate && serv.getSessionCountLimit() != sessionCount ) { print( "Session count changed"); serv.setSessionCountLimit( sessionCount ); needUpdate = true; } //удаляем чтобы потом найти те, которые не использовались servMapCopy.remove( getKey( login, cid ) ); //print( "removed login = " + login + ";cid= " + cid ); try { if ( needUpdate ) { print( "updating serv " + serv.getId() + " for cid = " + cid + ";login=" + login ); logger.info( "updating serv for cid = " + cid + ";login=" + login ); wsServ.inetServUpdate( serv, new ArrayList<InetServOption>(), false, false, 0 ); } } catch( Exception e ) { printError( cid, e, "Error while updating service for contract " + cid + ";login=" +login +":" + e.getMessage() ); //logger.error( "", e ); connectionSet.rollback(); } connectionSet.commit(); } private String getKey( String login, int cid ) { return cid + "_" + login; } private boolean dateChanged( Date date1, Date date2 ) { return ( date2 != null ^ date1 != null ) || ( date2 != null && date1 != null && !TimeUtils.dateEqual( date2, date1 ) ); } private void printError( int cid, Exception e, String message ) { logger.error( message, e ); print( message ); } }