fix: adjustment directory structure
This commit is contained in:
8
proxy/.idea/.gitignore
generated
vendored
Normal file
8
proxy/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
6
proxy/.idea/encodings.xml
generated
Normal file
6
proxy/.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/redis" charset="GBK" />
|
||||
</component>
|
||||
</project>
|
||||
6
proxy/.idea/misc.xml
generated
Normal file
6
proxy/.idea/misc.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
||||
8
proxy/.idea/modules.xml
generated
Normal file
8
proxy/.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/selfcare_proxy_go.iml" filepath="$PROJECT_DIR$/.idea/selfcare_proxy_go.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
9
proxy/.idea/selfcare_proxy_go.iml
generated
Normal file
9
proxy/.idea/selfcare_proxy_go.iml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
7
proxy/.idea/vcs.xml
generated
Normal file
7
proxy/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/public/protobuf@v1.5.0" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/public/protobuf@v1.5.2" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
11
proxy/.project
Normal file
11
proxy/.project
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>selfcare_proxy</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
26
proxy/Makefile
Normal file
26
proxy/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
# Makefile for rest agent project
|
||||
|
||||
PROJECT = restproxy_go
|
||||
VERSION = 2.2502.3
|
||||
PLATFORM = amd64
|
||||
# ARMPLATFORM = aarch64
|
||||
# BUILDDIR = ../../build
|
||||
# DEBBUILDDIR = ../../debbuild
|
||||
# RPMBUILDDIR = $(HOME)/goprojects/rpmbuild
|
||||
# INSTALLDIR = /usr/local/omc
|
||||
# RELEASEDIR = ../../release
|
||||
# LIBDIR = be.ems/lib
|
||||
BINDIR = ../bin
|
||||
BINNAME = $(BINDIR)/restproxy_go
|
||||
|
||||
.PHONY: build $(BINNAME)
|
||||
build $(BINNAME):
|
||||
go build -o $(BINNAME) -v -ldflags "-s -w -X '$(LIBDIR)/global.Version=$(VERSION)' \
|
||||
-X '$(LIBDIR)/global.BuildTime=`date`' \
|
||||
-X '$(LIBDIR)/global.GoVer=`go version`'"
|
||||
|
||||
run: $(BINNAME)
|
||||
./$(BINNAME)
|
||||
|
||||
clean:
|
||||
rm ./$(BINNAME)
|
||||
177
proxy/MsgDef/canal.go
Normal file
177
proxy/MsgDef/canal.go
Normal file
@@ -0,0 +1,177 @@
|
||||
package MsgDef
|
||||
|
||||
const (
|
||||
TbAcctInfo = "tb_prd_prd_inst_551"
|
||||
TbOfrDetail = "tb_prd_ofr_detail_inst_551"
|
||||
TbTariff = "tb_bil_tariff"
|
||||
TbOfrInfo = "tb_prd_ofr"
|
||||
TbPricingStrategy = "tb_bil_evt_pricing_strategy"
|
||||
TbConfigArea = "config_area"
|
||||
TbPricingArea = "tb_bil_pricing_area"
|
||||
TbRr = "ratable_history"
|
||||
TbHoliday = "tb_bil_holiday_rel"
|
||||
TbBilHoliday = "tb_bil_holiday"
|
||||
TbSmsInfo = "tb_sms_info"
|
||||
TbSyncMobile = "tb_sync_mobile"
|
||||
)
|
||||
|
||||
type RecordChange struct {
|
||||
TableName string
|
||||
EventType string//entry.EventType
|
||||
|
||||
ChgAcctInfo []ChgAcctInfo
|
||||
ChgOfrDetail []ChgOfrDetail
|
||||
ChgTariff []ChgTariff
|
||||
ChgOfrInfo []ChgOfrInfo
|
||||
ChgPricingStrategy []ChgPricingStrategy
|
||||
ChgConfigArea []ChgConfigArea
|
||||
ChgPricingArea []ChgPricingArea
|
||||
ChgRr []ChgRr
|
||||
ChgHoliday []ChgHoliday
|
||||
ChgBilHoliday []ChgBilHoliday
|
||||
ChgAlertSms []ChgAlertSms
|
||||
ChgSyncMobile []ChgSyncMobile
|
||||
}
|
||||
|
||||
type ChgAcctInfo struct {
|
||||
PrdInstId int//string
|
||||
ServiceNbr string
|
||||
IfPrepaid string
|
||||
OldPrdInstStasId string
|
||||
NewPrdInstStasId string
|
||||
|
||||
BUpdate bool
|
||||
}
|
||||
|
||||
type ChgOfrDetail struct {
|
||||
OfrDetailInstId int//string
|
||||
OfrDetailTypeId string
|
||||
OldEffDate string
|
||||
NewEffDate string
|
||||
OldExpDate string
|
||||
NewExpDate string
|
||||
//OldCalcPriority string
|
||||
//NewCalcPriority string
|
||||
|
||||
BUpdate bool
|
||||
}
|
||||
|
||||
type ChgTariff struct {
|
||||
TariffId int//string
|
||||
}
|
||||
|
||||
type ChgOfrInfo struct {
|
||||
OfrId int//string
|
||||
OfrTypeId string
|
||||
IfPrepaid string
|
||||
OldCalcPriority string
|
||||
NewCalcPriority string
|
||||
OldOfrState string
|
||||
NewOfrState string
|
||||
|
||||
BUpdate bool
|
||||
}
|
||||
|
||||
type ChgPricingStrategy struct {
|
||||
EventPricingStrategyId int//string
|
||||
OldEventPriority string
|
||||
NewEventPriority string
|
||||
OldCallType string
|
||||
NewCallType string
|
||||
|
||||
BUpdate bool
|
||||
}
|
||||
|
||||
type ChgConfigArea struct {
|
||||
AreaId int//string
|
||||
OldAreaCode string
|
||||
NewAreaCode string
|
||||
OldState string
|
||||
NewState string
|
||||
|
||||
BUpdate bool
|
||||
}
|
||||
|
||||
type ChgPricingArea struct {
|
||||
OldStrategyId int//string
|
||||
NewStrategyId int//string
|
||||
OldAreaId int//string
|
||||
NewAreaId int//string
|
||||
|
||||
BUpdate bool
|
||||
}
|
||||
|
||||
type ChgRr struct {
|
||||
Id int64//tring
|
||||
OldBeginTime string
|
||||
NewBeginTime string
|
||||
OldEndTime string
|
||||
NewEndTime string
|
||||
OldFreeValue int64//string
|
||||
NewFreeValue int64//string
|
||||
OldValue int64//string
|
||||
NewValue int64//string
|
||||
OldOwnId string
|
||||
NewOwnId string
|
||||
OldOfrInstId string
|
||||
NewOfrInstId string
|
||||
OldPricingSubSectionId string
|
||||
NewPricingSubSectionId string
|
||||
|
||||
BUpdate bool
|
||||
}
|
||||
|
||||
type ChgHoliday struct {
|
||||
OldState string
|
||||
NewState string
|
||||
OldTariffId int//string
|
||||
NewTariffId int//string
|
||||
OldTariffSeq int//string
|
||||
NewTariffSeq int//string
|
||||
|
||||
BUpdate bool
|
||||
}
|
||||
|
||||
type ChgBilHoliday struct {
|
||||
HolidayId int//string
|
||||
OldState string
|
||||
NewState string
|
||||
|
||||
BUpdate bool
|
||||
}
|
||||
|
||||
type ChgAlertSms struct {
|
||||
AlertId int
|
||||
ServiceNbr string
|
||||
SmsContent string
|
||||
OldState int
|
||||
NewState int
|
||||
|
||||
BUpdate bool
|
||||
}
|
||||
|
||||
type ChgSyncMobile struct {
|
||||
PreId int `redis:"preId,omitempty"`// key
|
||||
OperType int `redis:"operType"`// == 1, new; 2, replace imsi
|
||||
State int `redis:"state"`// == 1
|
||||
//Imsi string
|
||||
ServiceNbr string `redis:"serviceNbr"`
|
||||
CustId int `redis:"custId"`
|
||||
AcctId int `redis:"acctId"`
|
||||
PrdInstId int `redis:"prdInstId"`
|
||||
MobileType int `redis:"mobileType"`// == 1, mobile type
|
||||
BirthDate string `redis:"birthDate"`// date
|
||||
Balance int `redis:"balance"`
|
||||
BalanceExpDate string `redis:"balanceExpDate"`// datetime
|
||||
OfrId int `redis:"ofrId"`
|
||||
|
||||
Imsi string `redis:"imsi"`
|
||||
Ki string `redis:"ki"`
|
||||
Opc string `redis:"opc"`
|
||||
VmsFlag int `redis:"vmsFlag"`
|
||||
ExpDate string `redis:"expDate"`// datetime
|
||||
CugId int `redis:"cugId"`
|
||||
|
||||
OldState int// == 1
|
||||
//BUpdate bool
|
||||
}
|
||||
95
proxy/MsgDef/msg_struct.go
Normal file
95
proxy/MsgDef/msg_struct.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package MsgDef
|
||||
|
||||
import (
|
||||
|
||||
)
|
||||
|
||||
//&prd_inst_id, &service_nbr, &prd_inst_stas_id, &acct_id, &cust_id
|
||||
type AcctData struct {
|
||||
AcctType int `redis:"acctType"`
|
||||
PrdInstId int `redis:"prdInstId"`
|
||||
ServiceNbr string `redis:"serviceNbr"`
|
||||
PrdInstStasId int `redis:"prdInstStasId"`
|
||||
AcctId int `redis:"acctId"`
|
||||
CustId int `redis:"custId"`
|
||||
OfrId int `redis:"ofrId"`
|
||||
OfrInstId int `redis:"ofrInstId"`
|
||||
EffTime string `redis:"effTime"`
|
||||
ExpTime string `redis:"expTime"`
|
||||
}
|
||||
|
||||
//SELECT rr.ID ratableId, rr.PRICING_SUB_SECTION_ID, rr.OFR_INST_ID, rr.BEGIN_TIME, rr.END_TIME,
|
||||
//rr.FREE_VALUE AS ratableValue, rr.`VALUE` usedRatable, g.MEASURE_DOMAIN, c.OFR_ID,
|
||||
//c.OFR_NAME, g.TARIFF_ID, g.START_REF_VALUE, g.END_REF_VALUE, c.CALC_PRIORITY, h.EVENT_PRIORITY
|
||||
type RrData struct {
|
||||
RrId int64 `redis:"rrId"`
|
||||
ServiceNbr string `redis:"serviceNbr"`
|
||||
PrdInstId int `redis:"prdInstId"`
|
||||
PricingSectionId int `redis:"pricingSectionId"`
|
||||
OfrInstId int `redis:"ofrInstId"`
|
||||
OfrId int `redis:"ofrId"`
|
||||
OfrName string `redis:"ofrName"`
|
||||
BeginTime string `redis:"beginTime"`
|
||||
EndTime string `redis:"endTime"`
|
||||
FreeValue int64 `redis:"freeValue"`
|
||||
UsedValue int64 `redis:"usedValue"`
|
||||
MeasureDomain string `redis:"measureDomain"`
|
||||
TariffId int `redis:"tariffId"`
|
||||
StartRefTime int `redis:"startRefTime"`
|
||||
EndRefTime int `redis:"endRefTime"`
|
||||
CalcPriority int `redis:"calcPriority"`
|
||||
EventPriority int `redis:"eventPriority"`
|
||||
StrategyId int `redis:"strategyId"`
|
||||
UnitFee int `redis:"unitFee"`
|
||||
RateUnit int `redis:"rateUnit"`
|
||||
}
|
||||
|
||||
// g.MEASURE_DOMAIN, time_to_sec(g.START_REF_VALUE) startTime, time_to_sec(g.END_REF_VALUE) endTime, g.SCALED_RATE_VALUE_ID feeUnit,
|
||||
// g.rate_unit rateUnit, c.CALC_PRIORITY,h.EVENT_PRIORITY,h.event_pricing_strategy_id,h.EVENT_PRICING_STRATEGY_NAME,c.ofr_id,c.OFR_NAME
|
||||
type TariffData struct {
|
||||
TariffId int `redis:"tariffId"`
|
||||
TariffSeq int `redis:"tariffSeq"`
|
||||
MeasureDomain string `redis:"measureDomain"`
|
||||
StartTime int `redis:"startTime"`
|
||||
EndTime int `redis:"endTime"`
|
||||
FeeUnit int `redis:"feeUnit"`
|
||||
RateUnit int `redis:"rateUnit"`
|
||||
CalcPriority int `redis:"calcPriority"`
|
||||
EventPriority int `redis:"eventPriority"`
|
||||
OfrId int `redis:"ofrId"`
|
||||
OfrName string `redis:"ofrName"`
|
||||
StrategyId int `redis:"strategyId"`
|
||||
StrategyName string `redis:"strategyName"`
|
||||
}
|
||||
|
||||
// SELECT DISTINCT ca.area_name, ca.area_code FROM TB_BIL_PRICING_AREA ar INNER JOIN config_area ca ON ca.area_id = ar.area_id WHERE ar.STRATEGY_ID = ?;
|
||||
type PrefixData struct {
|
||||
StrategyId int `redis:"StrategyId"`
|
||||
AreaName string `redis:"areaName"`
|
||||
AreaCode string `redis:"areaCode"`
|
||||
}
|
||||
|
||||
/*
|
||||
HD table import
|
||||
SELECT hr.ofr_id, hr.tariff_id, hr.tariff_seq, hr.holiday_group, hr.state hr_state, hr.holiday_discount,
|
||||
hd.HOLIDAY_ID, hd.STATE hd_state, hd.HOLIDAY_PRIORITY, hd.HOLIDAY_NAME, hd.HOLIDAY_TYPE, hd.HOLIDAY_BEGIN_DATE, hd.HOLIDAY_END_DATE
|
||||
FROM tb_bil_holiday_rel hr
|
||||
INNER JOIN tb_bil_holiday hd ON hr.holiday_group = hd.HOLIDAY_GROUP
|
||||
WHERE hr.tariff_id=? AND hr.tariff_seq=? AND hr.state = 1 AND hd.STATE = 'L0R';
|
||||
*/
|
||||
type HolidayDiscountData struct {
|
||||
OfrId int `redis:"ofrId"`
|
||||
TariffId int `redis:"tariffId"`
|
||||
TariffSeq int `redis:"tariffSeq"`
|
||||
HdGroup int `redis:"hdGroup"`
|
||||
HrState int `redis:"hrState"`
|
||||
HrDiscount int `redis:"hrDiscount"`
|
||||
|
||||
HdId int `redis:"hdId"`
|
||||
HdName string `redis:"hdName"`
|
||||
HdType string `redis:"hdType"`
|
||||
HdState string `redis:"hdState"`
|
||||
HdPriority int `redis:"hdPriority"`
|
||||
HdBeginDate string `redis:"hdBeginDate"`
|
||||
HdEndDate string `redis:"hdEndDate"`
|
||||
}
|
||||
35
proxy/Nmysql/alert_sms.go
Normal file
35
proxy/Nmysql/alert_sms.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package Nmysql
|
||||
|
||||
import (
|
||||
// "fmt"
|
||||
l4g "proxy/logger"
|
||||
)
|
||||
|
||||
func SetAlertSmsState2Sent(alertId int) error {
|
||||
stmt, _ := MySqlDb.Prepare("update tb_sms_info set sms_state=2 where sms_alert_id=?;")
|
||||
defer stmt.Close()
|
||||
|
||||
_, err := stmt.Exec(alertId)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("SetAlertSmsState2Sent err: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
l4g.MysqlLog.Debugf("SetAlertSmsState2Sent succ!")
|
||||
return nil
|
||||
}
|
||||
|
||||
func InsertExpiredNotifySms(accountId uint32, planId uint32, expiredDate int64) error {
|
||||
stmt, _ := MySqlDb.Prepare("INSERT into tb_sync_msg SET msg_type=1, acct_id=?, ofr_inst_id=?, exp_date=FROM_UNIXTIME(?), state=1;")
|
||||
defer stmt.Close()
|
||||
|
||||
_, err := stmt.Exec(accountId, planId, expiredDate)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("InsertExpiredNotifySms acctId[%d], planId[%d], expiredDate[%d] err: %v", accountId, planId, expiredDate, err)
|
||||
return err
|
||||
}
|
||||
|
||||
l4g.MysqlLog.Debugf("InsertExpiredNotifySms acctId[%d], planId[%d], expiredDate[%d] succ!", accountId, planId, expiredDate)
|
||||
return nil
|
||||
}
|
||||
|
||||
72
proxy/Nmysql/create_acct.go
Normal file
72
proxy/Nmysql/create_acct.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package Nmysql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
l4g "proxy/logger"
|
||||
)
|
||||
|
||||
func QueryOfrIdByPrdInstId(prdInstId int) (int, error) {
|
||||
sqlStr := fmt.Sprintf("select OFR_ID from tb_prd_sub_prd_inst_551 where MAIN_PRD_INST_ID=%d limit 1;", prdInstId)
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query tb_prd_sub_prd_inst_551, prdInstId[%d] fail: %v", prdInstId, err)
|
||||
return 0, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var ofrId int
|
||||
for rows.Next(){
|
||||
if err = rows.Scan(&ofrId); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of TB_RESOURCE_EXAM fail: %v", err)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return ofrId, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func QueryOfrLevelByOfrId(ofrId int) (int, error) {
|
||||
sqlStr := fmt.Sprintf("select OFR_LEVEL from tb_prd_ofr where OFR_ID=%d limit 1;", ofrId)
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query tb_prd_ofr, ofrId[%d] fail: %v", ofrId, err)
|
||||
return 0, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var ofrLevel int
|
||||
for rows.Next(){
|
||||
if err = rows.Scan(&ofrLevel); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of tb_prd_ofr fail: %v", err)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return ofrLevel, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func QueryRentByOfrId(ofrId int) (int, error) {
|
||||
sqlStr := fmt.Sprintf("SELECT f.FEE_VALUE rentValue FROM tb_prd_prd_once_fee f WHERE f.PRD_ID = %d AND f.TYPE = 2 AND f.FEE_TYPE = 5;", ofrId)
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query tb_prd_prd_once_fee, ofrId[%d] fail: %v", ofrId, err)
|
||||
return 0, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var onceFee int
|
||||
for rows.Next(){
|
||||
if err = rows.Scan(&onceFee); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of tb_prd_prd_once_fee fail: %v", err)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return onceFee, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
4
proxy/Nmysql/map.go
Normal file
4
proxy/Nmysql/map.go
Normal file
@@ -0,0 +1,4 @@
|
||||
package Nmysql
|
||||
|
||||
type void struct{}
|
||||
var member void
|
||||
1311
proxy/Nmysql/mysql_db.go
Normal file
1311
proxy/Nmysql/mysql_db.go
Normal file
File diff suppressed because it is too large
Load Diff
175
proxy/Nmysql/provision.go
Normal file
175
proxy/Nmysql/provision.go
Normal file
@@ -0,0 +1,175 @@
|
||||
package Nmysql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
l4g "proxy/logger"
|
||||
)
|
||||
|
||||
func QuerySyncMobileInfo() ([]SyncMobileInfo, error) {
|
||||
sqlStr := fmt.Sprintf("select PRE_ID, OPER_TYPE, IMSI, SERVICE_NBR, KI, IFNULL(OPC,'') as OPC, CUST_ID, ACCT_ID, PRD_INST_ID, MOBILE_TYPE, VMS_FLAG, IFNULL(BIRTH_DATE,'') as BIRTH_DATE, BALANCE, BALANCE_EXP_DATE, OFR_ID, EXP_DATE, IFNULL(CUG_ID,0) as CUG_ID from tb_sync_mobile where STATE=1 limit 10;")
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query tb_sync_mobile fail: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var rsp []SyncMobileInfo= nil
|
||||
for rows.Next(){
|
||||
var si SyncMobileInfo
|
||||
if err = rows.Scan(&si.PreId, &si.OperType, &si.Imsi, &si.ServiceNbr, &si.Ki, &si.Opc, &si.CustId, &si.AcctId, &si.PrdInstId,
|
||||
&si.MobileType, &si.VmsFlag, &si.BirthDate, &si.Balance, &si.BalanceExpDate, &si.OfrId, &si.ExpDate, &si.CugId); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of tb_sync_mobile fail: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
if si.BirthDate == "" {
|
||||
si.BirthDate = "2000-01-01"
|
||||
}
|
||||
|
||||
rsp = append(rsp, si)
|
||||
}
|
||||
|
||||
return rsp, nil
|
||||
}
|
||||
|
||||
type SyncMobileInfo struct {
|
||||
PreId int// auto incr
|
||||
OperType int// 1: create subs, 2: replace IMSI
|
||||
Imsi string
|
||||
ServiceNbr string
|
||||
Ki string
|
||||
Opc string
|
||||
CustId int
|
||||
AcctId int
|
||||
PrdInstId int
|
||||
MobileType int//0: postpaid, 1: prepaid
|
||||
VmsFlag int//0: not VMS service, 1: VMS service
|
||||
BirthDate string
|
||||
Balance int
|
||||
BalanceExpDate string
|
||||
OfrId int
|
||||
ExpDate string
|
||||
CugId int// 1: staff, 2: customer
|
||||
}
|
||||
|
||||
func QueryOldImsiInfo(serviceNbr string) (*OldImsiInfo, error) {
|
||||
sqlStr := fmt.Sprintf("select PRE_ID, IMSI, PRD_INST_ID from tb_sync_mobile WHERE SERVICE_NBR='%s' and STATE>1 ORDER BY PRE_ID DESC limit 1;", serviceNbr)
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query tb_sync_mobile fail: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var rsp OldImsiInfo
|
||||
for rows.Next(){
|
||||
if err = rows.Scan(&rsp.PreId, &rsp.Imsi, &rsp.PrdInstId); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of tb_sync_mobile fail: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &rsp, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type OldImsiInfo struct {
|
||||
PreId int
|
||||
Imsi string
|
||||
PrdInstId int
|
||||
}
|
||||
|
||||
func AddSmcliCmd2Mysql(cmdType int, nt int, serviceNbr string, cmdStr string) error {
|
||||
sqlStr := fmt.Sprintf("INSERT INTO tb_sync_cn_cmd SET cmd_type=%d, node_type=%d, node_name='%s', srv_num='%s', command='%s', state=1, result=0, timestamp=NOW();",
|
||||
cmdType, nt, NodeName[nt], serviceNbr, cmdStr)
|
||||
stmt, _ := MySqlDb.Prepare(sqlStr)
|
||||
defer stmt.Close()
|
||||
|
||||
_, err := stmt.Exec()
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("AddSmcliCmd2Mysql, cmdType[%d], nt[%d], prdInstId[%s], cmd[%s] error: %v", cmdType, nt, serviceNbr, cmdStr, err)
|
||||
return err
|
||||
}
|
||||
|
||||
l4g.MysqlLog.Debugf("AddSmcliCmd2Mysql, cmdType[%d], nt[%d], prdInstId[%s], cmd[%s] succ!", cmdType, nt, serviceNbr, cmdStr)
|
||||
return nil
|
||||
}
|
||||
|
||||
func AddSmcliCmdSucc2Mysql(cmdType int, nt int, serviceNbr string, cmdStr string) error {
|
||||
cause := "000:Command Successful"
|
||||
sqlStr := fmt.Sprintf("INSERT INTO tb_sync_cn_cmd SET cmd_type=%d, node_type=%d, node_name='%s', srv_num='%s', command='%s', state=2, result=1, cause='%s', timestamp=NOW();",
|
||||
cmdType, nt, NodeName[nt], serviceNbr, cmdStr, cause)
|
||||
stmt, _ := MySqlDb.Prepare(sqlStr)
|
||||
defer stmt.Close()
|
||||
|
||||
_, err := stmt.Exec()
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("AddSmcliCmd2Mysql, cmdType[%d], nt[%d], prdInstId[%s], cmd[%s] error: %v", cmdType, nt, serviceNbr, cmdStr, err)
|
||||
return err
|
||||
}
|
||||
|
||||
l4g.MysqlLog.Debugf("AddSmcliCmd2Mysql, cmdType[%d], nt[%d], prdInstId[%s], cmd[%s] succ!", cmdType, nt, serviceNbr, cmdStr)
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdateSyncMobileState(preId int, state int) error {
|
||||
sqlStr := fmt.Sprintf("UPDATE tb_sync_mobile set STATE=%d where PRE_ID=%d;", state, preId)
|
||||
stmt, _ := MySqlDb.Prepare(sqlStr)
|
||||
defer stmt.Close()
|
||||
|
||||
_, err := stmt.Exec()
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("UpdateSyncMobileState, preId[%d], state[%d] error: %v", preId, state, err)
|
||||
return err
|
||||
}
|
||||
|
||||
l4g.MysqlLog.Debugf("UpdateSyncMobileState, preId[%d], state[%d] succ!", preId, state)
|
||||
return nil
|
||||
}
|
||||
|
||||
func QuerySyncCnCmd() ([]CnCmdInfo, error) {
|
||||
sqlStr := fmt.Sprintf("select id, node_type, command from tb_sync_cn_cmd where state=1 limit 40;")
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query tb_sync_cn_cmd fail: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var rsp []CnCmdInfo= nil
|
||||
for rows.Next(){
|
||||
var si CnCmdInfo
|
||||
if err = rows.Scan(&si.Id, &si.NodeType, &si.Command); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of tb_sync_cn_cmd fail: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rsp = append(rsp, si)
|
||||
}
|
||||
|
||||
return rsp, nil
|
||||
}
|
||||
|
||||
type CnCmdInfo struct {
|
||||
Id int// auto incr
|
||||
NodeType int
|
||||
Command string
|
||||
}
|
||||
|
||||
func UpdateCnCmdResult(id int, state int, result int, desc string) error {
|
||||
sqlStr := fmt.Sprintf("update tb_sync_cn_cmd set state=%d,result=%d,cause='%s',timestamp=NOW() where id=%d;",
|
||||
state, result, desc, id)
|
||||
stmt, _ := MySqlDb.Prepare(sqlStr)
|
||||
defer stmt.Close()
|
||||
|
||||
_, err := stmt.Exec()
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("UpdateCnCmdResult, id[%d], state[%d], result[%d], cause[%s] error: %v", id, state, result, desc, err)
|
||||
return err
|
||||
}
|
||||
|
||||
l4g.MysqlLog.Debugf("UpdateCnCmdResult, id[%d], state[%d], result[%d], cause[%s] succ!", id, state, result, desc)
|
||||
return nil
|
||||
}
|
||||
|
||||
29
proxy/Nmysql/smcli_cmd.go
Normal file
29
proxy/Nmysql/smcli_cmd.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package Nmysql
|
||||
|
||||
const (
|
||||
CT_CREATE_NA int= 0
|
||||
CT_CREATE_SUB int= 1
|
||||
CT_REPLACE_SUB int= 2
|
||||
CT_SUSPEND_ACCOUNT int= 3
|
||||
CT_DISABLE_ACCOUNT int= 4
|
||||
CT_RESUME_ACCOUNT int= 5
|
||||
CT_DISCONNECT_ACCOUNT int= 6
|
||||
CT_UPDATE_SUB int= 7
|
||||
CT_MAX int= 8
|
||||
)
|
||||
|
||||
const (
|
||||
NT_NA int= 0
|
||||
NT_OCS int= 1
|
||||
NT_HSS int= 2
|
||||
NT_AUC int= 3
|
||||
NT_VMS int= 4
|
||||
NT_PSTN int= 5
|
||||
NT_MSAN int= 6
|
||||
NT_ADSL int= 7
|
||||
NT_PCRF int= 8
|
||||
NT_MAX int= 9
|
||||
)
|
||||
|
||||
var NodeName = []string{"NULL","OCS","HSS","AUC","VMS","PSTN","MSAN","ADSL","PCRF"}
|
||||
|
||||
68
proxy/Nmysql/update_plan_usage.go
Normal file
68
proxy/Nmysql/update_plan_usage.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package Nmysql
|
||||
|
||||
import (
|
||||
l4g "proxy/logger"
|
||||
)
|
||||
|
||||
func UpdateDataPlanInfo(bundleId uint32, thisTimeAdded uint64, opFlag bool) error {
|
||||
var sqlStr string
|
||||
if !opFlag {
|
||||
sqlStr = "UPDATE ratable_history SET `VALUE`= `VALUE`+? WHERE ID=?;"
|
||||
} else {
|
||||
sqlStr = "UPDATE ratable_history SET `VALUE`= `VALUE`-? WHERE ID=?;"
|
||||
}
|
||||
stmt, _ := MySqlDb.Prepare(sqlStr)
|
||||
defer stmt.Close()
|
||||
|
||||
_, err := stmt.Exec(thisTimeAdded, bundleId)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("UpdateDataPlanInfo for bundle[%d], added[%d], op[%t] error: %v", bundleId, thisTimeAdded, opFlag, err)
|
||||
return err
|
||||
}
|
||||
|
||||
l4g.MysqlLog.Debugf("UpdateDataPlanInfo for bundle[%d], added[%d], op[%t] succ!", bundleId, thisTimeAdded, opFlag)
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdateVoiceAndSmsPlanInfo(serviceType byte, bundleId uint32, usedValue uint64, totalValue uint64, updateExpiryDate bool) error {
|
||||
var sqlStr string
|
||||
var value uint64
|
||||
if updateExpiryDate {
|
||||
sqlStr = "UPDATE ratable_history SET `VALUE`=? WHERE ID=?;"
|
||||
value = totalValue
|
||||
} else {
|
||||
sqlStr = "UPDATE ratable_history SET `VALUE`=? WHERE ID=?;"
|
||||
value = usedValue
|
||||
}
|
||||
stmt, _ := MySqlDb.Prepare(sqlStr)
|
||||
defer stmt.Close()
|
||||
|
||||
_, err := stmt.Exec(value, bundleId)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("UpdateVoiceAndSmsPlanInfo for bundle[%d], value[%d] error: %v", bundleId, value, err)
|
||||
return err
|
||||
}
|
||||
|
||||
l4g.MysqlLog.Debugf("UpdateVoiceAndSmsPlanInfo for bundle[%d], value[%d] succ!", bundleId, value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func AddNotificationSms(accountId uint32, planId uint32, serviceType byte, updateExpiryDate bool, rateUsed int) error {
|
||||
var sqlStr string= "INSERT into tb_sync_msg SET msg_type=2, rate_type=?, acct_id=?, rate_value=?, state=1, ofr_inst_id=?;"
|
||||
rate := rateUsed
|
||||
//if updateExpiryDate {
|
||||
// rate = 100
|
||||
//}
|
||||
|
||||
stmt, _ := MySqlDb.Prepare(sqlStr)
|
||||
defer stmt.Close()
|
||||
|
||||
_, err := stmt.Exec(serviceType, accountId, rate, planId)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("AddNotificationSms for plan[%d], acct[%d], type[%d], rate[%d/100] error: %v", planId, accountId, serviceType, rate, err)
|
||||
return err
|
||||
}
|
||||
|
||||
l4g.MysqlLog.Debugf("AddNotificationSms for plan[%d], acct[%d], type[%d], rate[%d/100] succ!", planId, accountId, serviceType, rate)
|
||||
return nil
|
||||
}
|
||||
303
proxy/Nmysql/user_status.go
Normal file
303
proxy/Nmysql/user_status.go
Normal file
@@ -0,0 +1,303 @@
|
||||
package Nmysql
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
. "proxy/config"
|
||||
l4g "proxy/logger"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func UpdateUserStatus2Mdb(accountId uint32, status byte) error {
|
||||
statusInCrm := 1001
|
||||
switch status {
|
||||
case 1:
|
||||
statusInCrm = 1001
|
||||
case 2:
|
||||
statusInCrm = 1205
|
||||
case 4:
|
||||
statusInCrm = 1101
|
||||
case 6:
|
||||
statusInCrm = 1202
|
||||
}
|
||||
|
||||
if false {
|
||||
stmt, _ := MySqlDb.Prepare("update tb_prd_prd_inst_551 set PRD_INST_STAS_ID=?, MOD_DATE=NOW() where ACCT_ID=?;")
|
||||
defer stmt.Close()
|
||||
|
||||
_, _ = stmt.Exec(statusInCrm, accountId)
|
||||
}
|
||||
|
||||
if status == 4 {
|
||||
stmt, _ := MySqlDb.Prepare("INSERT INTO tb_mobile_disc_cmd set ACCT_ID=?, ACCT_STATUS=0, UPDATE_DATE=NOW();")
|
||||
defer stmt.Close()
|
||||
|
||||
_, err := stmt.Exec(accountId)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("UpdateUserStatus2Mdb acctId[%d] err: %v", accountId, err)
|
||||
//return err
|
||||
}
|
||||
|
||||
l4g.MysqlLog.Debugf("UpdateUserStatus2Mdb acctId[%d] succ!", accountId)
|
||||
|
||||
_ = InsertPrepaidUserDeleteCliCmd(accountId)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func InsertPrepaidUserDeleteCliCmd(accountId uint32) error {
|
||||
//sqlStr := "select PRE_ID, OPER_TYPE, IMSI, SERVICE_NBR, KI, OPC, CUST_ID, STATE, PRD_INST_ID, MOBILE_TYPE, VMS_FLAG, BIRTH_DATE, BALANCE, "
|
||||
//sqlStr += "BALANCE_EXP_DATE, OFR_ID, EXP_DATE, CUG_ID from tb_sync_mobile where ACCT_ID=? ORDER BY PRE_ID DESC limit 1;"
|
||||
sqlStr := "select IMSI, SERVICE_NBR, PRD_INST_ID "
|
||||
sqlStr += "from tb_sync_mobile where ACCT_ID=" + strconv.Itoa(int(accountId)) + " ORDER BY PRE_ID DESC limit 1;"
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query tb_sync_mobile, accountId[%d] fail: %v", accountId, err)
|
||||
return err
|
||||
}
|
||||
//defer rows.Close()
|
||||
|
||||
var imsi, msisdn string
|
||||
var prdInstId int
|
||||
for rows.Next(){
|
||||
if err = rows.Scan(&imsi, &msisdn, &prdInstId); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of tb_sync_mobile fail: %v", err)
|
||||
_ = rows.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
_ = rows.Close()
|
||||
|
||||
if imsi != "" {
|
||||
cmd := "delete subscriber -imsi " + imsi
|
||||
stmt, _ := MySqlDb.Prepare("INSERT INTO tb_sync_cn_cmd SET cmd_type=?, node_type=?, node_name=?, srv_num=?, command=?, state=1, result=0, timestamp=NOW();")
|
||||
//defer stmt.Close()
|
||||
_, err := stmt.Exec(CT_DISCONNECT_ACCOUNT, NT_HSS, NodeName[NT_HSS], prdInstId, cmd)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("add cmd[%s], msisdn[%s], prdInstId[%d] err: %v", cmd, msisdn, prdInstId, err)
|
||||
//return err
|
||||
} else {
|
||||
l4g.MysqlLog.Debugf("add cmd[%s], msisdn[%s], prdInstId[%d]", cmd, msisdn, prdInstId)
|
||||
}
|
||||
stmt.Close()
|
||||
|
||||
cmd = "delete aucSubscriber -imsi " + imsi
|
||||
stmt, _ = MySqlDb.Prepare("INSERT INTO tb_sync_cn_cmd SET cmd_type=?, node_type=?, node_name=?, srv_num=?, command=?, state=1, result=0, timestamp=NOW();")
|
||||
//defer stmt.Close()
|
||||
_, err = stmt.Exec(CT_DISCONNECT_ACCOUNT, NT_AUC, NodeName[NT_AUC], prdInstId, cmd)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("add cmd[%s], msisdn[%s], prdInstId[%d] err: %v", cmd, msisdn, prdInstId, err)
|
||||
//return err
|
||||
} else {
|
||||
l4g.MysqlLog.Debugf("add cmd[%s], msisdn[%s], prdInstId[%d]", cmd, msisdn, prdInstId)
|
||||
}
|
||||
stmt.Close()
|
||||
|
||||
cmd = "delete vmsSubscriber -msisdn " + msisdn
|
||||
stmt, _ = MySqlDb.Prepare("INSERT INTO tb_sync_cn_cmd SET cmd_type=?, node_type=?, node_name=?, srv_num=?, command=?, state=1, result=0, timestamp=NOW();")
|
||||
//defer stmt.Close()
|
||||
_, err = stmt.Exec(CT_DISCONNECT_ACCOUNT, NT_VMS, NodeName[NT_VMS], prdInstId, cmd)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("add cmd[%s], msisdn[%s], prdInstId[%d] err: %v", cmd, msisdn, prdInstId, err)
|
||||
//return err
|
||||
} else {
|
||||
l4g.MysqlLog.Debugf("add cmd[%s], msisdn[%s], prdInstId[%d]", cmd, msisdn, prdInstId)
|
||||
}
|
||||
stmt.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CrmDeleteSubsProfile(serviceNbr string, acctType string, acctId string) {
|
||||
if acctType == "1" {
|
||||
//sqlStr := "select PRE_ID, OPER_TYPE, IMSI, SERVICE_NBR, KI, OPC, CUST_ID, STATE, PRD_INST_ID, MOBILE_TYPE, VMS_FLAG, BIRTH_DATE, BALANCE, "
|
||||
//sqlStr += "BALANCE_EXP_DATE, OFR_ID, EXP_DATE, CUG_ID from tb_sync_mobile where ACCT_ID=? ORDER BY PRE_ID DESC limit 1;"
|
||||
sqlStr := "select IMSI, SERVICE_NBR, PRD_INST_ID, MOBILE_TYPE, VMS_FLAG "
|
||||
sqlStr += "from tb_sync_mobile where ACCT_ID=" + acctId + " ORDER BY PRE_ID DESC limit 1;"
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query tb_sync_mobile, accountId[%d] fail: %v", acctId, err)
|
||||
return
|
||||
}
|
||||
//defer rows.Close()
|
||||
|
||||
var imsi, msisdn string
|
||||
var prdInstId, mobileType, vmsFlag int
|
||||
for rows.Next(){
|
||||
if err = rows.Scan(&imsi, &msisdn, &prdInstId, &mobileType, &vmsFlag); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of tb_sync_mobile fail: %v", err)
|
||||
_ = rows.Close()
|
||||
return
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
_ = rows.Close()
|
||||
|
||||
if imsi != "" {
|
||||
cmd := "delete subscriber -imsi " + imsi
|
||||
stmt, _ := MySqlDb.Prepare("INSERT INTO tb_sync_cn_cmd SET cmd_type=?, node_type=?, node_name=?, srv_num=?, command=?, state=1, result=0, timestamp=NOW();")
|
||||
//defer stmt.Close()
|
||||
_, err := stmt.Exec(CT_DISCONNECT_ACCOUNT, NT_HSS, NodeName[NT_HSS], strconv.Itoa(prdInstId), cmd)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("add cmd[%s], msisdn[%s], prdInstId[%d] err: %v", cmd, msisdn, prdInstId, err)
|
||||
//return err
|
||||
} else {
|
||||
l4g.MysqlLog.Debugf("add cmd[%s], msisdn[%s], prdInstId[%d]", cmd, msisdn, prdInstId)
|
||||
}
|
||||
stmt.Close()
|
||||
|
||||
cmd = "delete aucSubscriber -imsi " + imsi
|
||||
stmt, _ = MySqlDb.Prepare("INSERT INTO tb_sync_cn_cmd SET cmd_type=?, node_type=?, node_name=?, srv_num=?, command=?, state=1, result=0, timestamp=NOW();")
|
||||
//defer stmt.Close()
|
||||
_, err = stmt.Exec(CT_DISCONNECT_ACCOUNT, NT_AUC, NodeName[NT_AUC], strconv.Itoa(prdInstId), cmd)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("add cmd[%s], msisdn[%s], prdInstId[%d] err: %v", cmd, msisdn, prdInstId, err)
|
||||
//return err
|
||||
} else {
|
||||
l4g.MysqlLog.Debugf("add cmd[%s], msisdn[%s], prdInstId[%d]", cmd, msisdn, prdInstId)
|
||||
}
|
||||
stmt.Close()
|
||||
|
||||
if mobileType == 1{
|
||||
cmd = "delete ppsSubscriber -msisdn " + msisdn
|
||||
stmt, _ = MySqlDb.Prepare("INSERT INTO tb_sync_cn_cmd SET cmd_type=?, node_type=?, node_name=?, srv_num=?, command=?, state=2, result=1, cause='0000:Command successful', timestamp=NOW();")
|
||||
//defer stmt.Close()
|
||||
_, err = stmt.Exec(CT_DISCONNECT_ACCOUNT, NT_OCS, NodeName[NT_OCS], strconv.Itoa(prdInstId), cmd)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("add cmd[%s], msisdn[%s], prdInstId[%d] err: %v", cmd, msisdn, prdInstId, err)
|
||||
//return err
|
||||
} else {
|
||||
l4g.MysqlLog.Debugf("add cmd[%s], msisdn[%s], prdInstId[%d]", cmd, msisdn, prdInstId)
|
||||
}
|
||||
stmt.Close()
|
||||
}
|
||||
|
||||
if vmsFlag == 1{
|
||||
cmd = "delete vmsSubscriber -msisdn " + msisdn
|
||||
stmt, _ = MySqlDb.Prepare("INSERT INTO tb_sync_cn_cmd SET cmd_type=?, node_type=?, node_name=?, srv_num=?, command=?, state=1, result=0, timestamp=NOW();")
|
||||
//defer stmt.Close()
|
||||
_, err = stmt.Exec(CT_DISCONNECT_ACCOUNT, NT_VMS, NodeName[NT_VMS], strconv.Itoa(prdInstId), cmd)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("add cmd[%s], msisdn[%s], prdInstId[%d] err: %v", cmd, msisdn, prdInstId, err)
|
||||
//return err
|
||||
} else {
|
||||
l4g.MysqlLog.Debugf("add cmd[%s], msisdn[%s], prdInstId[%d]", cmd, msisdn, prdInstId)
|
||||
}
|
||||
stmt.Close()
|
||||
}
|
||||
}
|
||||
} else if acctType == "2" {
|
||||
ssEntryIdInCrm := Config.Provision.SsEntryIdInCrm
|
||||
orderId := queryOrderIdByServiceNbr(serviceNbr)
|
||||
if orderId == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
examNumStr := queryResourceExamNumByOrderId(orderId)
|
||||
if examNumStr == "" {
|
||||
return
|
||||
}
|
||||
kronePairId, _ := strconv.Atoi(examNumStr)
|
||||
if kronePairId <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
examNumStr = querySsEntryByResIdAndOrderId(ssEntryIdInCrm, orderId)
|
||||
if examNumStr == "" {
|
||||
return
|
||||
}
|
||||
ssEntry, _ := strconv.Atoi(examNumStr)
|
||||
|
||||
cmdDelPstn := fmt.Sprintf("delete pstn user isdn=%s, krone_pair_id=%d, ssentry=%d, state=Deleted, account_id=%s;",
|
||||
serviceNbr,kronePairId, ssEntry,acctId)
|
||||
insertCmdDelPstn(cmdDelPstn, serviceNbr)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func insertCmdDelPstn(cmd string, serviceNbr string) {
|
||||
stmt, _ := MySqlDb.Prepare("INSERT INTO tb_sync_cn_cmd SET cmd_type=?, node_type=?, node_name=?, srv_num=?, command=?, state=1, result=1, timestamp=NOW();")
|
||||
//defer stmt.Close()
|
||||
_, err := stmt.Exec(CT_DISCONNECT_ACCOUNT, NT_PSTN, NodeName[NT_PSTN], serviceNbr, cmd)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("insertCmdDelPstn cmd[%s], msisdn[%s] err: %v", cmd, serviceNbr, err)
|
||||
//return err
|
||||
} else {
|
||||
l4g.MysqlLog.Debugf("insertCmdDelPstn cmd[%s], msisdn[%s]", cmd, serviceNbr)
|
||||
}
|
||||
stmt.Close()
|
||||
}
|
||||
|
||||
func queryOrderIdByServiceNbr(serviceNbr string) int {
|
||||
sqlStr := "select ORDER_ID from tb_sync_pstn where SERVICE_NBR=" + serviceNbr + " ORDER by ORDER_ID desc limit 1;"
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query tb_sync_pstn, serviceNbr[%s] fail: %v", serviceNbr, err)
|
||||
return 0
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var orderId int
|
||||
for rows.Next(){
|
||||
if err = rows.Scan(&orderId); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of tb_sync_pstn fail: %v", err)
|
||||
//_ = rows.Close()
|
||||
return 0
|
||||
}
|
||||
|
||||
return orderId
|
||||
}
|
||||
//_ = rows.Close()
|
||||
return 0
|
||||
}
|
||||
|
||||
func queryResourceExamNumByOrderId(orderId int) string {
|
||||
sqlStr := "SELECT C.RESOURCE_EXAM_NUM FROM TB_PRD_RES_INST_551 A, TB_PRD_RES_INST_DETAIL_551 B, TB_RESOURCE_EXAM C "
|
||||
sqlStr += "WHERE A.RES_INST_ID=B.RES_INST_ID AND B.RESOURCE_EXAM_ID=C.RESOURCE_EXAM_ID AND C.RESOURCE_ID=1046 AND A.ORDER_ID=" + strconv.Itoa(orderId)+";"
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query TB_RESOURCE_EXAM, orderId[%d] fail: %v", orderId, err)
|
||||
return ""
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var resExamNum string
|
||||
for rows.Next(){
|
||||
if err = rows.Scan(&resExamNum); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of TB_RESOURCE_EXAM fail: %v", err)
|
||||
//_ = rows.Close()
|
||||
return ""
|
||||
}
|
||||
|
||||
return resExamNum
|
||||
}
|
||||
//_ = rows.Close()
|
||||
return ""
|
||||
}
|
||||
|
||||
func querySsEntryByResIdAndOrderId(resId, orderId int) string {
|
||||
sqlStr := fmt.Sprintf("%s%sC.RESOURCE_ID=%d AND A.ORDER_ID=%d;",
|
||||
"SELECT C.RESOURCE_EXAM_NUM FROM TB_PRD_RES_INST_551 A, TB_PRD_RES_INST_DETAIL_551 B, TB_RESOURCE_EXAM C ",
|
||||
"WHERE A.RES_INST_ID=B.RES_INST_ID AND B.RESOURCE_EXAM_ID=C.RESOURCE_EXAM_ID AND ", resId, orderId)
|
||||
rows, err := MySqlDb.Query(sqlStr)
|
||||
if err != nil {
|
||||
l4g.MysqlLog.Errorf("Query TB_RESOURCE_EXAM, orderId[%d] fail: %v", orderId, err)
|
||||
return ""
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var resExamNum string
|
||||
for rows.Next(){
|
||||
if err = rows.Scan(&resExamNum); err != nil {
|
||||
l4g.MysqlLog.Errorf("query row of TB_RESOURCE_EXAM fail: %v", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return resExamNum
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
115
proxy/Nredis/acctount.go
Normal file
115
proxy/Nredis/acctount.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package Nredis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
. "proxy/MsgDef"
|
||||
l4g "proxy/logger"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// "Acct:"+acctData.ServiceNbr
|
||||
func RdbDelAcctRecord(serviceNbr string) {
|
||||
var cursor uint64= 0
|
||||
for {
|
||||
keys, cursorNew, err := rdb.SScan(ctx, "Acct:"+serviceNbr, cursor, "", 0).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("SScan Acct:%s, err: %v", serviceNbr, err)
|
||||
break
|
||||
}
|
||||
|
||||
//fmt.Printf("\nfound %d keys\n", len(keys))
|
||||
for _, key := range keys {
|
||||
acctKey := "Acct:"+serviceNbr+":"+key
|
||||
err := rdb.Del(ctx, acctKey).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Del %s, err: %v", acctKey, err)
|
||||
} else {
|
||||
//subFields := strings.Split(key, ":")
|
||||
//if len(subFields) == 3 && subFields[2] != "" {
|
||||
_ = rdb.SRem(ctx, "Acct:"+serviceNbr, key)
|
||||
//return srem.Err()
|
||||
//}
|
||||
}
|
||||
}
|
||||
if cursorNew == 0 {
|
||||
break
|
||||
} else {
|
||||
cursor = cursorNew
|
||||
}
|
||||
}
|
||||
_ = rdb.Del(ctx, "Acct:"+serviceNbr).Err()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func RdbDelAcctOfr(serviceNbr string, ofrId int) error {
|
||||
acctKey := "Acct:"+serviceNbr+":"+strconv.Itoa(ofrId)
|
||||
err := rdb.Del(ctx, acctKey).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Del %s, err: %v", acctKey, err)
|
||||
} else {
|
||||
_ = rdb.SRem(ctx, "Acct:"+serviceNbr, strconv.Itoa(ofrId))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbSetAcctRecord(acctData *AcctData) error {
|
||||
//&prd_inst_id, &service_nbr, &prd_inst_stas_id, &acct_id, &cust_id
|
||||
key := "Acct:"+acctData.ServiceNbr+":"+strconv.Itoa(acctData.OfrId)
|
||||
err := rdb.HMSet(ctx, key, "acctType", acctData.AcctType, "prdInstId", acctData.PrdInstId, "serviceNbr", acctData.ServiceNbr,
|
||||
"prdInstStasId", acctData.PrdInstStasId, "acctId", acctData.AcctId, "custId", acctData.CustId, "ofrId", acctData.OfrId, "ofrInstId", acctData.OfrInstId,
|
||||
"effTime", acctData.EffTime, "expTime", acctData.ExpTime).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HMSet Acct:%s, err: %v", acctData.ServiceNbr, err)
|
||||
} else {
|
||||
sadd := rdb.SAdd(ctx, "Acct:"+acctData.ServiceNbr, strconv.Itoa(acctData.OfrId))
|
||||
if sadd.Err() != nil {
|
||||
l4g.RedisLog.Errorf("SAdd Acct:%s %d, err: %v", acctData.ServiceNbr, acctData.OfrId, sadd.Err())
|
||||
return sadd.Err()
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("SAdd Acct:%s %d", acctData.ServiceNbr, acctData.OfrId)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbGetAcctRecordByServiceNbr(serviceNbr string) (rsp string, err error) {
|
||||
var cursor uint64= 0
|
||||
for {
|
||||
keys, cursorNew, err := rdb.SScan(ctx, "Acct:"+serviceNbr, cursor, "", 0).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("SScan Acct:%s, err: %v", serviceNbr, err)
|
||||
break
|
||||
}
|
||||
|
||||
//fmt.Printf("\nfound %d keys\n", len(keys))
|
||||
for _, key := range keys {
|
||||
acctKey := "Acct:"+serviceNbr+":"+key
|
||||
res := rdb.HGetAll(ctx, acctKey)
|
||||
if res.Err() != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll %s, err: %v", acctKey, err)
|
||||
} else {
|
||||
var acctData AcctData
|
||||
if err = res.Scan(&acctData); err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll Scan %s, err: %v", acctKey, err)
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("Get %s, [%v]", acctKey, acctData)
|
||||
rsp += fmt.Sprintf("%s:***************************************\r\nPrdInstId: %d\r\nPrdInstStasId: %d\r\nCustId: %d\r\nAcctId: %d\r\n",
|
||||
acctKey, acctData.PrdInstId, acctData.PrdInstStasId, acctData.CustId, acctData.AcctId)
|
||||
rsp += fmt.Sprintf("OfrId: %d\r\nOfrInstId: %d\r\nEffTime: %s\r\nExpTime: %s\r\n",
|
||||
acctData.OfrId, acctData.OfrInstId, acctData.EffTime, acctData.ExpTime)
|
||||
return rsp, err
|
||||
}
|
||||
}
|
||||
}
|
||||
if cursorNew == 0 {
|
||||
break
|
||||
} else {
|
||||
cursor = cursorNew
|
||||
}
|
||||
}
|
||||
|
||||
return "", err
|
||||
}
|
||||
63
proxy/Nredis/alert_sms.go
Normal file
63
proxy/Nredis/alert_sms.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package Nredis
|
||||
|
||||
import (
|
||||
l4g "proxy/logger"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func RdbSetAlertSmsRecord(alertId int, serviceNbr, smsContent string) error {
|
||||
key := "AlertSms:"+serviceNbr+":"+strconv.Itoa(alertId)
|
||||
err := rdb.Set(ctx, key, smsContent, 0).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Set %s, err: %v", key, err)
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("Set %s, err: %s", key, smsContent)
|
||||
sadd := rdb.SAdd(ctx, "Msg2OcsSet", key)
|
||||
if sadd.Err() != nil {
|
||||
l4g.RedisLog.Errorf("SAdd Msg2OcsSet %s, err: %v", key, sadd.Err())
|
||||
return sadd.Err()
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("SAdd Msg2OcsSet %s", key)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbGetAlertSmsContent(key string) string {
|
||||
var sms string
|
||||
var err error
|
||||
sms, err = rdb.Get(ctx, key).Result()
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return sms
|
||||
}
|
||||
}
|
||||
|
||||
func RdbScanAlertSmsRecord() []string {
|
||||
var cursor uint64= 0
|
||||
var keysFound []string
|
||||
for {
|
||||
keys, cursor, err := rdb.SScan(ctx, "Msg2OcsSet", cursor, "", 50).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("SScan Msg2OcsSet, err: %v", err)
|
||||
break
|
||||
}
|
||||
|
||||
keysFound = append(keysFound, keys...)
|
||||
|
||||
if cursor == 0 {
|
||||
break
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return keysFound
|
||||
}
|
||||
|
||||
func RdsDelMsg2OcsKey(key string) {
|
||||
_ = rdb.SRem(ctx, "Msg2OcsSet", key)
|
||||
_ = rdb.Del(ctx, key).Err()
|
||||
}
|
||||
169
proxy/Nredis/bundleclr.go
Normal file
169
proxy/Nredis/bundleclr.go
Normal file
@@ -0,0 +1,169 @@
|
||||
package Nredis
|
||||
|
||||
import (
|
||||
"proxy/MsgDef"
|
||||
. "proxy/MsgDef"
|
||||
l4g "proxy/logger"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CheckIfRrExpired(rr *MsgDef.RrData) bool {
|
||||
if rr == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if rr.MeasureDomain == "01" || rr.MeasureDomain == "03" {
|
||||
if rr.UsedValue >= rr.FreeValue {
|
||||
return true
|
||||
}
|
||||
nowStr := time.Now().Format("20060102150405")
|
||||
if strings.Compare(nowStr, rr.EndTime) > 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if rr.MeasureDomain == "02" {
|
||||
nowStr := time.Now().Format("20060102150405")
|
||||
if strings.Compare(nowStr, rr.EndTime) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func RdbGetRrByKey(key string) (*RrData, error) {
|
||||
res := rdb.HGetAll(ctx, key)
|
||||
err := res.Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll %s, err: %v", key, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var rr RrData
|
||||
if err = res.Scan(&rr); err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll Scan %s, err: %v", key, err)
|
||||
return nil, err
|
||||
} else {
|
||||
//l4g.RedisLog.Debugf("Get %s, [%v]", key, rr)
|
||||
}
|
||||
|
||||
return &rr, err
|
||||
}
|
||||
|
||||
func RdbClrExpireRrRecord() error {
|
||||
l4g.RedisLog.Warnf("cron clear expire rr!")
|
||||
var cursor uint64= 0
|
||||
var err error
|
||||
for {
|
||||
var keys []string
|
||||
keys, cursor, err = rdb.Scan(ctx, cursor, "Rr:*", 30).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Scan Rr:*, err: %v", err)
|
||||
break
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
subFields := strings.Split(key, ":")
|
||||
if len(subFields) == 4 {
|
||||
rr, err1 := RdbGetRrByKey(key)
|
||||
if rr != nil && err1 == nil && CheckIfRrExpired(rr) {
|
||||
err1 = rdb.Del(ctx, key).Err()
|
||||
if err1 != nil {
|
||||
l4g.RedisLog.Errorf("Del Rr[%s], err: %v", key, err1)
|
||||
} else {
|
||||
l4g.RedisLog.Warnf("Del Rr[%s] succ", key)
|
||||
|
||||
l4g.RedisLog.Warnf("SRem RrSet:%s:%s %s", subFields[1], subFields[2], subFields[3])
|
||||
_ = rdb.SRem(ctx, "RrSet:"+subFields[1]+":"+subFields[2], subFields[3])
|
||||
l4g.RedisLog.Warnf("Del RrId:%s", subFields[3])
|
||||
_ = rdb.Del(ctx, "RrId:"+subFields[3]).Err()
|
||||
//return srem.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbGetAcctPlanByKey(key string) (*AcctData, error) {
|
||||
res := rdb.HGetAll(ctx, key)
|
||||
err := res.Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll %s, err: %v", key, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var acct AcctData
|
||||
if err = res.Scan(&acct); err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll Scan %s, err: %v", key, err)
|
||||
return nil, err
|
||||
} else {
|
||||
//l4g.RedisLog.Debugf("Get %s, [%v]", key, acct)
|
||||
}
|
||||
|
||||
return &acct, err
|
||||
}
|
||||
|
||||
func CheckIfAcctExpired(acct *MsgDef.AcctData) bool {
|
||||
if acct == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
nowStr := time.Now().Format("2006-01-02 15:04:05")
|
||||
if strings.Compare(nowStr, acct.ExpTime[:len(nowStr)]) > 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func RdbClrExpirePlanRecord() error {
|
||||
l4g.RedisLog.Warnf("cron clear expire plan!")
|
||||
var cursor uint64= 0
|
||||
var err error
|
||||
for {
|
||||
var keys []string
|
||||
keys, cursor, err = rdb.Scan(ctx, cursor, "Acct:*", 30).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Scan Acct:*, err: %v", err)
|
||||
break
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
subFields := strings.Split(key, ":")
|
||||
if len(subFields) == 3 {
|
||||
acct, err1 := RdbGetAcctPlanByKey(key)
|
||||
if acct != nil && err1 == nil && CheckIfAcctExpired(acct) {
|
||||
err1 = rdb.Del(ctx, key).Err()
|
||||
if err1 != nil {
|
||||
l4g.RedisLog.Errorf("Del Acct Plan[%s], err: %v", key, err1)
|
||||
} else {
|
||||
l4g.RedisLog.Warnf("Del Acct Plan[%s] succ", key)
|
||||
|
||||
l4g.RedisLog.Warnf("SRem Acct:%s %s", subFields[1], subFields[2])
|
||||
_ = rdb.SRem(ctx, "Acct:"+subFields[1], subFields[2])
|
||||
//return srem.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func ClrExpRes() {
|
||||
_ = RdbClrExpireRrRecord()
|
||||
_ = RdbClrExpirePlanRecord()
|
||||
}
|
||||
40
proxy/Nredis/canal_info.go
Normal file
40
proxy/Nredis/canal_info.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package Nredis
|
||||
|
||||
import (
|
||||
l4g "proxy/logger"
|
||||
)
|
||||
|
||||
type BinLogPos struct {
|
||||
File string `redis:"file"`
|
||||
Position uint32 `redis:"position"`
|
||||
}
|
||||
|
||||
func RdbSetBinLogPos(file string, pos uint32) error {
|
||||
err := rdb.HMSet(ctx, "binlogpos", "file", file, "position", pos).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HMSet binlogpos %s %d, err: %v", file, pos, err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbGetBinLogPos() *BinLogPos {
|
||||
// Get the map. The same approach works for HmGet().
|
||||
res := rdb.HGetAll(ctx, "binlogpos")
|
||||
err := res.Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll binlogpos, err: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Scan the results into the struct.
|
||||
var pos BinLogPos
|
||||
if err = res.Scan(&pos); err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll Scan binlogpos, err: %v", err)
|
||||
return nil
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("Get binlogpos, [%v]", pos)
|
||||
return &pos
|
||||
}
|
||||
}
|
||||
|
||||
47
proxy/Nredis/create_acct.go
Normal file
47
proxy/Nredis/create_acct.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package Nredis
|
||||
|
||||
import (
|
||||
"proxy/MsgDef"
|
||||
l4g "proxy/logger"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func RdbSetCreateAcctRecord(r *MsgDef.ChgSyncMobile) error {
|
||||
key := "CreateAcct:"+r.ServiceNbr+":"+strconv.Itoa(r.PreId)
|
||||
err := rdb.HMSet(ctx, key, "prdInstId", r.PrdInstId, "serviceNbr", r.ServiceNbr,
|
||||
"operType", r.OperType, "state", r.State, "ofrId", r.OfrId,
|
||||
"custId", r.CustId, "acctId", r.AcctId, "mobileType", r.MobileType, "balance", r.Balance, "birthDate", r.BirthDate, "balanceExpDate", r.BalanceExpDate).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HMSet %s, err: %v", key, err)
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("HMSet %s, [%#v]", key, r)
|
||||
sadd := rdb.SAdd(ctx, "Msg2OcsSet", key)
|
||||
if sadd.Err() != nil {
|
||||
l4g.RedisLog.Errorf("SAdd Msg2OcsSet %s, err: %v", key, sadd.Err())
|
||||
return sadd.Err()
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("SAdd Msg2OcsSet %s", key)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbGetCreateAcct(key string) *MsgDef.ChgSyncMobile {
|
||||
res := rdb.HGetAll(ctx, key)
|
||||
err := res.Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll %s, err: %v", key, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Scan the results into the struct.
|
||||
var acctInfo MsgDef.ChgSyncMobile
|
||||
if err = res.Scan(&acctInfo); err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll Scan %s, err: %v", key, err)
|
||||
return nil
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("Get %s, [%v]", key, acctInfo)
|
||||
return &acctInfo
|
||||
}
|
||||
}
|
||||
30
proxy/Nredis/holiday.go
Normal file
30
proxy/Nredis/holiday.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package Nredis
|
||||
|
||||
import (
|
||||
l4g "proxy/logger"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func SetHdId2TariffId(id int, tariffId int) bool {
|
||||
err := rdb.Set(ctx, "HdId:"+strconv.Itoa(id), strconv.Itoa(tariffId), 0).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Set HdId:%d %s, err: %v", id, strconv.Itoa(tariffId), err)
|
||||
return false
|
||||
} else {
|
||||
l4g.RedisLog.Infof("Set HdId:%d %s", id, tariffId)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func GetTariffIdByHdId(id int) string {
|
||||
var tariffIdStr string
|
||||
var err error
|
||||
tariffIdStr, err = rdb.Get(ctx, "HdId:"+strconv.Itoa(id)).Result()
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return tariffIdStr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
33
proxy/Nredis/plan_expiry.go
Normal file
33
proxy/Nredis/plan_expiry.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package Nredis
|
||||
|
||||
import (
|
||||
l4g "proxy/logger"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CheckIfBundleLimitSent(planId uint32, rate int) bool {
|
||||
n, err := rdb.Exists(ctx, "BundleLimit:"+strconv.Itoa(int(planId))+":"+strconv.Itoa(rate)).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Check Exists PlanExpiry:%d, err: %v", planId, err)
|
||||
return false
|
||||
} else {
|
||||
if n >= 1 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetPlanExpire(planId uint32, rate int) error {
|
||||
key := "BundleLimit:"+strconv.Itoa(int(planId))+":"+strconv.Itoa(rate)
|
||||
err := rdb.Set(ctx, key, "1", time.Hour * 24 * 15).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Set BundleLimit:%d:%d, err: %v", planId, rate, err)
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("Set BundleLimit:%d:%d, succ", planId, rate)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
601
proxy/Nredis/rds_client.go
Normal file
601
proxy/Nredis/rds_client.go
Normal file
@@ -0,0 +1,601 @@
|
||||
package Nredis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
rds "github.com/go-redis/redis/v8"
|
||||
"os"
|
||||
l4g "proxy/logger" //"github.com/sirupsen/logrus"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
. "proxy/MsgDef"
|
||||
)
|
||||
|
||||
var ctx = context.Background()
|
||||
|
||||
var rdb *rds.Client
|
||||
var locRdb *rds.Client
|
||||
func NewRedisClient(netType, addr, passwd string, sentinels []string) {
|
||||
if sentinels != nil {
|
||||
rdb = rds.NewFailoverClient(&rds.FailoverOptions{
|
||||
MasterName: "mymaster",
|
||||
SentinelAddrs: sentinels,
|
||||
Password: passwd,
|
||||
DB: 0,
|
||||
PoolSize: 5,
|
||||
})
|
||||
locRdb = rds.NewClient(&rds.Options{
|
||||
Network: netType,// The network type, either tcp or unix. Default is tcp.
|
||||
Addr: addr,// can be: /var/run/redis/redis-server.sock???
|
||||
Password: passwd, // no password set
|
||||
DB: 0, // use default DB
|
||||
PoolSize: 5,
|
||||
})
|
||||
} else {
|
||||
rdb = rds.NewClient(&rds.Options{
|
||||
Network: netType,// The network type, either tcp or unix. Default is tcp.
|
||||
Addr: addr,// can be: /var/run/redis/redis-server.sock???
|
||||
Password: passwd, // no password set
|
||||
DB: 0, // use default DB
|
||||
PoolSize: 5,
|
||||
})
|
||||
locRdb = rdb
|
||||
}
|
||||
|
||||
pong, err := rdb.Ping(ctx).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("%v, err: %v", pong, err)// Output: PONG <nil>
|
||||
os.Exit(1)
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("%v", pong)// Output: PONG <nil>
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func CheckIfNeedToSyncDb() (bool, error) {
|
||||
/*if CheckIfRdbMaster() == false {
|
||||
return false, nil
|
||||
}*/
|
||||
|
||||
size, err := rdb.DBSize(ctx).Result()
|
||||
if err == nil {
|
||||
if size < 10 {
|
||||
return true, nil
|
||||
} else {
|
||||
return false, nil
|
||||
}
|
||||
} else {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
func ClrTariffAndBundle() {
|
||||
rdb.FlushDB(ctx)
|
||||
/*n, err := rdb.Del(ctx, "Acct:*").Result()
|
||||
if err != nil {
|
||||
l4g.Errorf("Del Acct, err: %v", err)
|
||||
} else {
|
||||
l4g.Debugf("Del Acct, num[%d]", n)
|
||||
}
|
||||
|
||||
n, err = rdb.Del(ctx, "Rr:*").Result()
|
||||
if err != nil {
|
||||
l4g.Errorf("Del Rr, err: %v", err)
|
||||
} else {
|
||||
l4g.Debugf("Del Rr, num[%d]", n)
|
||||
}
|
||||
|
||||
n, err = rdb.Del(ctx, "Prefix:*").Result()
|
||||
if err != nil {
|
||||
l4g.Errorf("Del Prefix, err: %v", err)
|
||||
} else {
|
||||
l4g.Debugf("Del Prefix, num[%d]", n)
|
||||
}
|
||||
|
||||
n, err = rdb.Del(ctx, "Tariff:*").Result()
|
||||
if err != nil {
|
||||
l4g.Errorf("Del Tariff, err: %v", err)
|
||||
} else {
|
||||
l4g.Debugf("Del Tariff, num[%d]", n)
|
||||
}*/
|
||||
}
|
||||
|
||||
func CheckIfRdbMaster() bool {
|
||||
info := locRdb.Info(ctx, "Replication")
|
||||
if strings.Contains(info.Val(), "role:master") || strings.Contains(info.Val(), "role:active-replica") {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func SetRrId2RrKey(id int64, rrKey string) bool {
|
||||
err := rdb.Set(ctx, "RrId:"+strconv.FormatInt(id, 10), rrKey, 0).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Set RrId:%d %s, err: %v", id, rrKey, err)
|
||||
return false
|
||||
} else {
|
||||
l4g.RedisLog.Infof("Set RrId:%d %s", id, rrKey)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func GetRrKeyByRrId(id int64) string {
|
||||
var rrKey string
|
||||
var err error
|
||||
rrKey, err = rdb.Get(ctx, "RrId:"+strconv.FormatInt(id, 10)).Result()
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return rrKey
|
||||
}
|
||||
}
|
||||
|
||||
func RdbSetRrRecord(rr *RrData) error {
|
||||
key := "Rr:"+rr.ServiceNbr+":"+rr.MeasureDomain+":"+strconv.FormatInt(rr.RrId, 10)
|
||||
err := rdb.HMSet(ctx, key, "prdInstId", rr.PrdInstId, "serviceNbr", rr.ServiceNbr,
|
||||
"pricingSectionId", rr.PricingSectionId, "ofrInstId", rr.OfrInstId, "ofrId", rr.OfrId,
|
||||
"ofrName", rr.OfrName, "beginTime", rr.BeginTime, "endTime", rr.EndTime, "freeValue", rr.FreeValue, "rateUnit", rr.RateUnit, "unitFee", rr.UnitFee,
|
||||
"usedValue", rr.UsedValue, "measureDomain", rr.MeasureDomain, "tariffId", rr.TariffId, "strategyId", rr.StrategyId,
|
||||
"startRefTime", rr.StartRefTime, "endRefTime", rr.EndRefTime, "calcPriority", rr.CalcPriority, "eventPriority", rr.EventPriority).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HMSet Rr:%s, err: %v", rr.ServiceNbr, err)
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("HMSet Rr:%s, [%#v]", rr.ServiceNbr, rr)
|
||||
sadd := rdb.SAdd(ctx, "RrSet:"+rr.ServiceNbr+":"+rr.MeasureDomain, strconv.FormatInt(rr.RrId, 10))
|
||||
if sadd.Err() != nil {
|
||||
l4g.RedisLog.Errorf("SAdd RrSet:%s:%s %d, err: %v", rr.ServiceNbr, rr.MeasureDomain, rr.RrId, sadd.Err())
|
||||
return sadd.Err()
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("SAdd RrSet:%s:%s %d", rr.ServiceNbr, rr.MeasureDomain, rr.RrId)
|
||||
}
|
||||
SetRrId2RrKey(rr.RrId, key)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbSetStrategyEventPriority(rr *RrData) error {
|
||||
err := rdb.HMSet(ctx, "Rr:"+rr.ServiceNbr+":"+rr.MeasureDomain+":"+strconv.FormatInt(rr.RrId, 10), "eventPriority", rr.EventPriority).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HMSet Rr:%s, err: %v", rr.ServiceNbr, err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbSetOfrCalcPriority(rr *RrData) error {
|
||||
err := rdb.HMSet(ctx, "Rr:"+rr.ServiceNbr+":"+rr.MeasureDomain+":"+strconv.FormatInt(rr.RrId, 10), "calcPriority", rr.CalcPriority).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HMSet Rr:%s, err: %v", rr.ServiceNbr, err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// "Rr:"+rr.ServiceNbr+":"+rr.MeasureDomain+":"+strconv.Itoa(rr.RrId)
|
||||
func RdbUpdateRrRecordOnly(rrId int64, ratableVal, usedVal int64, beginTime, endTime string) (int, error) {
|
||||
key := GetRrKeyByRrId(rrId)
|
||||
if key != "" {
|
||||
err := rdb.HMSet(ctx, key, "beginTime", beginTime, "endTime", endTime, "freeValue", ratableVal,
|
||||
"usedValue", usedVal).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HMSet %s, err: %v", key, err)
|
||||
return -1, err
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("HMSet %s, beginTime[%s], endTime[%s], free/used:[%d/%d]", key, beginTime, endTime, ratableVal, usedVal)
|
||||
return 1, nil
|
||||
}
|
||||
} else {
|
||||
l4g.RedisLog.Errorf("HMSet rrId[%d], err not found, beginTime[%s], endTime[%s], free/used:[%d/%d]", rrId, beginTime, endTime, ratableVal, usedVal)
|
||||
return 0, nil
|
||||
}
|
||||
/*var cursor uint64
|
||||
var err error
|
||||
for {
|
||||
var keys []string
|
||||
// 20 keys each scan
|
||||
keys, cursor, err = rdb.Scan(ctx, cursor, "Rr:*:"+strconv.FormatInt(rrId, 10), 2).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Scan Rr:*:%d, err: %v", rrId, err)
|
||||
break
|
||||
}
|
||||
|
||||
//fmt.Printf("\nfound %d keys\n", len(keys))
|
||||
for _, key := range keys {
|
||||
err := rdb.HMSet(ctx, key, "beginTime", beginTime, "endTime", endTime, "freeValue", ratableVal,
|
||||
"usedValue", usedVal).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HMSet %s, err: %v", key, err)
|
||||
}
|
||||
}
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err*/
|
||||
}
|
||||
|
||||
// "Rr:"+rr.ServiceNbr+":"+rr.MeasureDomain+":"+strconv.Itoa(rr.RrId)
|
||||
func RdbDelRrRecordByRrId(rrId int64) error {
|
||||
key := GetRrKeyByRrId(rrId)
|
||||
if key != "" {
|
||||
err := rdb.Del(ctx, key).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Del %s, err: %v", key, err)
|
||||
} else {
|
||||
l4g.RedisLog.Infof("Del %s succ", key)
|
||||
subFields := strings.Split(key, ":")
|
||||
if len(subFields) == 4 {
|
||||
_ = rdb.SRem(ctx, "RrSet:"+subFields[1]+":"+subFields[2], strconv.FormatInt(rrId, 10))
|
||||
l4g.RedisLog.Infof("SRem %d from RrSet:%s:%s", rrId, subFields[1], subFields[2])
|
||||
//return srem.Err()
|
||||
}
|
||||
|
||||
}
|
||||
rdb.Del(ctx, "RrId:"+strconv.FormatInt(rrId, 10))
|
||||
l4g.RedisLog.Infof("Del RrId:%d", rrId)
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// "Rr:"+rr.ServiceNbr+":"+rr.MeasureDomain+":"+strconv.Itoa(rr.RrId)
|
||||
func RdbDelRrRecordByServiceNbr(serviceNbr string) error {
|
||||
var cursor uint64
|
||||
var err error
|
||||
for {
|
||||
var keys []string
|
||||
// 20 keys each scan
|
||||
keys, cursor, err = rdb.Scan(ctx, cursor, "Rr:"+serviceNbr+":*", 30).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Scan Rr:%s:*, err: %v", serviceNbr, err)
|
||||
break
|
||||
}
|
||||
|
||||
//fmt.Printf("\nfound %d keys\n", len(keys))
|
||||
for _, key := range keys {
|
||||
err = rdb.Del(ctx, key).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Del %s, err: %v", key, err)
|
||||
} else {
|
||||
subFields := strings.Split(key, ":")
|
||||
if len(subFields) == 4 {
|
||||
_ = rdb.SRem(ctx, "RrSet:"+serviceNbr+":"+subFields[2], subFields[3])
|
||||
//return srem.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbDelRrRecord(rr *RrData) error {
|
||||
err := rdb.Del(ctx, "Rr:"+rr.ServiceNbr+":"+rr.MeasureDomain+":"+strconv.FormatInt(rr.RrId, 10)).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Del Rr:%s:%d, err: %v", rr.ServiceNbr, rr.RrId, err)
|
||||
} else {
|
||||
_ = rdb.SRem(ctx, "RrSet:"+rr.ServiceNbr+":"+rr.MeasureDomain, strconv.FormatInt(rr.RrId, 10))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbSetOfrRecord(ofrId int) error {
|
||||
err := rdb.Set(ctx, "Ofr:"+strconv.Itoa(ofrId), ofrId, 0).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Set Ofr:%d, err: %v", ofrId, err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbCheckIfOfrExist(ofrId int) bool {
|
||||
n, err := rdb.Exists(ctx, "Ofr:"+strconv.Itoa(ofrId)).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Check Exists Ofr:%d, err: %v", ofrId, err)
|
||||
return false
|
||||
} else {
|
||||
if n >= 1 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func RdbSetPrefixRecord(prefix *PrefixData) error {
|
||||
sadd := rdb.SAdd(ctx, "Prefix:"+strconv.Itoa(prefix.StrategyId), prefix.AreaCode)
|
||||
return sadd.Err()
|
||||
}
|
||||
|
||||
// Add holiday discount table
|
||||
// Hd:tariff_id:tariff_seq:hdId, group, name, discount, state;;; type, subState, priority, begin, end;
|
||||
// triggers: 1, create, modify(state), delete of tb_bil_holiday_rel;
|
||||
// 2, modify(STATE), delete of tb_bil_holiday;
|
||||
/* holiday discount
|
||||
SELECT hd.HOLIDAY_GROUP, hd.HOLIDAY_PRIORITY, COUNT(1) AS HOLIDAY_COUNT FROM tb_bil_holiday hd
|
||||
WHERE (((hd.HOLIDAY_TYPE = '02' AND hd.HOLIDAY_BEGIN_DATE <= (WEEKDAY(SYSDATE()) + 1) AND hd.holiday_end_date >= (WEEKDAY(SYSDATE()) + 1))
|
||||
OR (hd.holiday_type = '03' AND DATE_FORMAT(SYSDATE(),'%m%d') >= DATE_FORMAT(CONCAT('2020', hd.HOLIDAY_BEGIN_DATE), '%m%d') AND DATE_FORMAT(SYSDATE(),'%m%d') <= DATE_FORMAT(CONCAT('2020', hd.holiday_end_date), '%m%d'))
|
||||
OR (hd.holiday_type = '04' AND DATE_FORMAT(SYSDATE(), '%H%i%s') >= DATE_FORMAT(STR_TO_DATE(CONCAT('20200101', hd.HOLIDAY_BEGIN_DATE), '%Y%m%d%H%i%s'),'%H%i%s')
|
||||
AND DATE_FORMAT(SYSDATE(), '%H%i%s') <= DATE_FORMAT(STR_TO_DATE(CONCAT('20200101', hd.holiday_end_date), '%Y%m%d%H%i%s'),'%H%i%s')))
|
||||
and hd.STATE='L0R')
|
||||
GROUP BY hd.HOLIDAY_PRIORITY, hd.HOLIDAY_GROUP;
|
||||
*/
|
||||
func RdbSetHolidayDiscountRecord(hd *HolidayDiscountData) error {
|
||||
err := rdb.HMSet(ctx, "Hd:"+strconv.Itoa(hd.TariffId)+":"+strconv.Itoa(hd.HdId),
|
||||
"ofrId", hd.OfrId, "tariffId", hd.TariffId, "tariffSeq", hd.TariffSeq, "hdGroup", hd.HdGroup,
|
||||
"hrState", hd.HrState, "hrDiscount", hd.HrDiscount, "hdId", hd.HdId, "hdName", hd.HdName,
|
||||
"hdType", hd.HdType, "hdState", hd.HdState, "hdPriority", hd.HdPriority,
|
||||
"hdBeginDate", hd.HdBeginDate, "hdEndDate", hd.HdEndDate).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HMSet Hd:%d:%d, err: %v", hd.TariffId, hd.HdId, err)
|
||||
} else {
|
||||
sadd := rdb.SAdd(ctx, "HdSet:"+strconv.Itoa(hd.TariffId), strconv.Itoa(hd.HdId))
|
||||
if sadd.Err() != nil {
|
||||
l4g.RedisLog.Errorf("SAdd HdSet:%d %d, err: %v", hd.TariffId, hd.HdId, sadd.Err())
|
||||
return sadd.Err()
|
||||
}
|
||||
SetHdId2TariffId(hd.HdId, hd.TariffId)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbDelHolidayDiscountRecord(tariffId int) {
|
||||
var cursor uint64= 0
|
||||
for {
|
||||
// 20 keys each scan
|
||||
keys, cursorNew, err := rdb.SScan(ctx, "HdSet:"+strconv.Itoa(tariffId), cursor, "", 0).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("SScan HdSet:%d, err: %v", tariffId, err)
|
||||
break
|
||||
}
|
||||
|
||||
//fmt.Printf("\nfound %d keys\n", len(keys))
|
||||
for _, key := range keys {
|
||||
hdKey := "Hd:"+strconv.Itoa(tariffId) + ":" + key
|
||||
err := rdb.Del(ctx, hdKey).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Del %s, err: %v", key, err)
|
||||
} else {
|
||||
//subFields := strings.Split(key, ":")
|
||||
//if len(subFields) == 3 && subFields[2] != "" {
|
||||
_ = rdb.SRem(ctx, "HdSet:"+strconv.Itoa(tariffId), key)
|
||||
//return srem.Err()
|
||||
//}
|
||||
}
|
||||
}
|
||||
if cursorNew == 0 {
|
||||
break
|
||||
} else {
|
||||
cursor = cursorNew
|
||||
}
|
||||
}
|
||||
_ = rdb.Del(ctx, "HdSet:"+strconv.Itoa(tariffId)).Err()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func RdbDelHolidayDiscountRecordByHd(holidayId int) error {
|
||||
tariffIdStr := GetTariffIdByHdId(holidayId)
|
||||
tariffId, err := strconv.Atoi(tariffIdStr)
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Get tariffId by HdId %d, err: %v", holidayId, err)
|
||||
} else {
|
||||
key := "Hd:" + strconv.Itoa(tariffId) + ":"+strconv.Itoa(holidayId)
|
||||
err := rdb.Del(ctx, key).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Del %s, err: %v", key, err)
|
||||
} else {
|
||||
_ = rdb.SRem(ctx, "HdSet:"+tariffIdStr, strconv.Itoa(holidayId))
|
||||
}
|
||||
}
|
||||
/*var cursor uint64
|
||||
for {
|
||||
var keys []string
|
||||
// 20 keys each scan
|
||||
keys, cursor, err = rdb.Scan(ctx, cursor, "Hd:*:"+strconv.Itoa(holidayId), 200).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Scan Hd:*:%d, err: %v", holidayId, err)
|
||||
break
|
||||
}
|
||||
|
||||
//fmt.Printf("\nfound %d keys\n", len(keys))
|
||||
for _, key := range keys {
|
||||
err := rdb.Del(ctx, key).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Del %s, err: %v", key, err)
|
||||
} else {
|
||||
subFields := strings.Split(key, ":")
|
||||
if len(subFields) == 3 && subFields[1] != "" {
|
||||
_ = rdb.SRem(ctx, "HdSet:"+subFields[1], strconv.Itoa(holidayId))
|
||||
//return srem.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}*/
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// "Tariff:"+strconv.Itoa(tariff.OfrId)+":"+tariff.MeasureDomain+":"+strconv.Itoa(tariff.TariffId)
|
||||
func RdbDelTariffRecord(tariffId int) error {
|
||||
var cursor uint64
|
||||
var err error
|
||||
for {
|
||||
var keys []string
|
||||
// 20 keys each scan
|
||||
keys, cursor, err = rdb.Scan(ctx, cursor, "Tariff:*:"+strconv.Itoa(tariffId), 2).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Scan Tariff:*:%d, err: %v", tariffId, err)
|
||||
break
|
||||
}
|
||||
|
||||
//fmt.Printf("\nfound %d keys\n", len(keys))
|
||||
for _, key := range keys {
|
||||
err := rdb.Del(ctx, key).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Del %s, err: %v", key, err)
|
||||
} else {
|
||||
subFields := strings.Split(key, ":")
|
||||
if len(subFields) == 4 {
|
||||
_ = rdb.SRem(ctx, "TariffSet:"+subFields[1]+":"+subFields[2], strconv.Itoa(tariffId))
|
||||
//return srem.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// "Tariff:"+strconv.Itoa(tariff.OfrId)+":"+tariff.MeasureDomain+":"+strconv.Itoa(tariff.TariffId)
|
||||
func RdbDelTariffRecordByOfr(ofrId int) error {
|
||||
var cursor uint64
|
||||
var err error
|
||||
for {
|
||||
var keys []string
|
||||
// 20 keys each scan
|
||||
keys, cursor, err = rdb.Scan(ctx, cursor, "Tariff:"+strconv.Itoa(ofrId)+":*", 2).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Scan Tariff:%d:*, err: %v", ofrId, err)
|
||||
break
|
||||
}
|
||||
|
||||
//fmt.Printf("\nfound %d keys\n", len(keys))
|
||||
for _, key := range keys {
|
||||
err := rdb.Del(ctx, key).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Del %s, err: %v", key, err)
|
||||
} else {
|
||||
subFields := strings.Split(key, ":")
|
||||
if len(subFields) == 4 {
|
||||
_ = rdb.SRem(ctx, "TariffSet:"+subFields[1]+":"+subFields[2], subFields[3])
|
||||
//return srem.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbDelPrefixRecord(strategyId int, areaCode string) error {
|
||||
srem := rdb.SRem(ctx, "Prefix:"+strconv.Itoa(strategyId), areaCode)
|
||||
return srem.Err()
|
||||
}
|
||||
|
||||
func RdbSetTariffRecord(tariff *TariffData) error {
|
||||
//&prd_inst_id, &service_nbr, &prd_inst_stas_id, &acct_id, &cust_id
|
||||
err := rdb.HMSet(ctx, "Tariff:"+strconv.Itoa(tariff.OfrId)+":"+tariff.MeasureDomain+":"+strconv.Itoa(tariff.TariffId), "tariffId", tariff.TariffId,
|
||||
"tariffSeq", tariff.TariffSeq, "measureDomain", tariff.MeasureDomain,
|
||||
"startTime", tariff.StartTime, "endTime", tariff.EndTime, "feeUnit", tariff.FeeUnit,
|
||||
"rateUnit", tariff.RateUnit, "calcPriority", tariff.CalcPriority, "eventPriority", tariff.EventPriority, "ofrId", tariff.OfrId,
|
||||
"ofrName", tariff.OfrName, "strategyId", tariff.StrategyId, "strategyName", tariff.StrategyName).Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HMSet Tariff:%d, err: %v", tariff.TariffId, err)
|
||||
} else {
|
||||
sadd := rdb.SAdd(ctx, "TariffSet:"+strconv.Itoa(tariff.OfrId)+":"+tariff.MeasureDomain, strconv.Itoa(tariff.TariffId))
|
||||
if sadd.Err() != nil {
|
||||
l4g.RedisLog.Errorf("SAdd TariffSet:%d:%s %d, err: %v", tariff.OfrId, tariff.MeasureDomain, tariff.TariffId, sadd.Err())
|
||||
return sadd.Err()
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func RdbGetRrByServiceNbrAndDomain(serviceNbrAndDomain string) (rsp string, err error) {
|
||||
var cursor uint64= 0
|
||||
for {
|
||||
keys, cursorNew, err := rdb.SScan(ctx, "RrSet:"+serviceNbrAndDomain, cursor, "", 0).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("SScan RrSet:%s, err: %v", serviceNbrAndDomain, err)
|
||||
break
|
||||
}
|
||||
|
||||
//fmt.Printf("\nfound %d keys\n", len(keys))
|
||||
for _, key := range keys {
|
||||
rrKey := "Rr:"+serviceNbrAndDomain+":"+key
|
||||
res := rdb.HGetAll(ctx, rrKey)
|
||||
if res.Err() != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll %s, err: %v", rrKey, err)
|
||||
return "err: HGetAll "+rrKey, err
|
||||
} else {
|
||||
var rrData RrData
|
||||
if err = res.Scan(&rrData); err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll Scan %s, err: %v", rrKey, err)
|
||||
return "err: Scan "+rrKey, err
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("Get %s, [%v]", rrKey, rrData)
|
||||
rsp += fmt.Sprintf("%s:***************************************\r\nPrdInstId: %d\r\nOfrInstId: %d\r\nOfrId: %d\r\nOfrName: %s\r\nBeginTime: %s\r\nEndTime: %s\r\n",
|
||||
rrKey, rrData.PrdInstId, rrData.OfrInstId, rrData.OfrId, rrData.OfrName, rrData.BeginTime, rrData.EndTime)
|
||||
rsp += fmt.Sprintf("FreeValue: %d\r\nUsedValue: %d\r\nTariffId: %d\r\nStrategyId: %d\r\nCalcPriority: %d\r\nEventPriority: %d\r\nRateUnit: %d\r\nUnitFee: %d\r\n",
|
||||
rrData.FreeValue, rrData.UsedValue, rrData.TariffId, rrData.StrategyId, rrData.CalcPriority, rrData.EventPriority, rrData.RateUnit, rrData.UnitFee)
|
||||
}
|
||||
}
|
||||
}
|
||||
if cursorNew == 0 {
|
||||
break
|
||||
} else {
|
||||
cursor = cursorNew
|
||||
}
|
||||
}
|
||||
|
||||
return rsp, err
|
||||
}
|
||||
|
||||
func RdbGetTariffByOfrId(ofrId string) (*TariffData, error) {
|
||||
keys := rdb.Keys(ctx, "Tariff:"+ofrId+":*")
|
||||
err := keys.Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("Get Keys of Tariff:%s:*, err: %v", ofrId, err)
|
||||
return nil, err
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("Get Keys of Tariff:%s:*, keys:%v", ofrId, keys.Val())
|
||||
}
|
||||
|
||||
// Scan the results into the struct.
|
||||
var ta TariffData
|
||||
for _, value := range keys.Val() {
|
||||
// Get the map. The same approach works for HmGet().
|
||||
res := rdb.HGetAll(ctx, value)
|
||||
err := res.Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll %s, err: %v", value, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = res.Scan(&ta); err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll Scan %s, err: %v", value, err)
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("Get %s, [%v]", value, ta)
|
||||
|
||||
// Get prefix related tariff
|
||||
sMembers := rdb.SMembers(ctx, "Prefix:"+strconv.Itoa(ta.StrategyId))
|
||||
if sMembers.Err() == nil {
|
||||
l4g.RedisLog.Debugf("Prefix, [%v]", sMembers.Val())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &ta, err
|
||||
}
|
||||
51
proxy/Nrestful/alert_sms.go
Normal file
51
proxy/Nrestful/alert_sms.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package Nrestful
|
||||
|
||||
import (
|
||||
mysql "proxy/Nmysql"
|
||||
rdb "proxy/Nredis"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func RdbScanAlertSmsRecord() {
|
||||
keys := rdb.RdbScanAlertSmsRecord()
|
||||
|
||||
for _, key := range keys {
|
||||
if strings.HasPrefix(key, "AlertSms:") {
|
||||
smsContent := rdb.RdbGetAlertSmsContent(key)
|
||||
if smsContent != "" {
|
||||
ss := strings.Split(key, ":")
|
||||
if len(ss) >= 3 {
|
||||
SendNtfSms2Ocs(ss[1], smsContent)
|
||||
|
||||
alertId, _ := strconv.Atoi(ss[2])
|
||||
_ = mysql.SetAlertSmsState2Sent(alertId)
|
||||
}
|
||||
}
|
||||
rdb.RdsDelMsg2OcsKey(key)
|
||||
} else if strings.HasPrefix(key, "CreateAcct:") {
|
||||
ai := rdb.RdbGetCreateAcct(key)
|
||||
if ai != nil {
|
||||
ss := strings.Split(key, ":")
|
||||
if len(ss) >= 3 {
|
||||
cugId, err := mysql.QueryOfrIdByPrdInstId(ai.PrdInstId)
|
||||
userClass := 1
|
||||
ofrLevel, err := mysql.QueryOfrLevelByOfrId(ai.OfrId)
|
||||
if err == nil {
|
||||
userClass = ofrLevel
|
||||
}
|
||||
rent, _ := mysql.QueryRentByOfrId(ai.OfrId)
|
||||
//SendCrtAcct2Ocs(ss[1], ai, cugId, userClass, rent)
|
||||
CreateAcct2Ocs(ss[1], ai, cugId, userClass, rent, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//for _, key := range keys {
|
||||
// rdb.RdsDelMsg2OcsKey(key)
|
||||
//}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
575
proxy/Nrestful/decode_udp.go
Normal file
575
proxy/Nrestful/decode_udp.go
Normal file
@@ -0,0 +1,575 @@
|
||||
package Nrestful
|
||||
|
||||
import (
|
||||
"time"
|
||||
"encoding/binary"
|
||||
_ "strings"
|
||||
"strconv"
|
||||
|
||||
l4g "proxy/logger"//"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func decode_authcode_rsp(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
var result byte = 1
|
||||
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset];
|
||||
offset++
|
||||
vallen = buf[offset];
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_RESULT:
|
||||
result = buf[offset]
|
||||
if result == 0 {
|
||||
rsp.AuthCodeRsp.Code = strconv.Itoa(int(ERRCODE_SUCCESS))
|
||||
rsp.AuthCodeRsp.Message = Rest_proxy_errcodemsg(ERRCODE_SUCCESS)
|
||||
}
|
||||
case IE_ERROR_CODE:
|
||||
err_code := binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
rsp.AuthCodeRsp.Code = strconv.Itoa(int(err_code))
|
||||
rsp.AuthCodeRsp.Message = Rest_proxy_errcodemsg(err_code)
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decode_authcode_rsp: %#v", rsp.AuthCodeRsp)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
func decode_query_userData_rsp(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
var result byte = 1
|
||||
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset];
|
||||
offset++
|
||||
vallen = buf[offset];
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_RESULT:
|
||||
result = buf[offset]
|
||||
if result == 0 {
|
||||
rsp.QueryUserDataRsp.Code = strconv.Itoa(int(ERRCODE_SUCCESS))
|
||||
rsp.QueryUserDataRsp.Message = Rest_proxy_errcodemsg(ERRCODE_SUCCESS)
|
||||
}
|
||||
case IE_ERROR_CODE:
|
||||
err_code := binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
rsp.QueryUserDataRsp.Code = strconv.Itoa(int(err_code))
|
||||
rsp.QueryUserDataRsp.Message = Rest_proxy_errcodemsg(err_code)
|
||||
case IE_MSISDN:
|
||||
rsp.QueryUserDataRsp.TelNumber = string(buf[offset:offset+int(vallen)])
|
||||
case IE_REMARK:
|
||||
rsp.QueryUserDataRsp.Remark = string(buf[offset:offset+int(vallen)])
|
||||
case IE_GROUP_NAME:
|
||||
rsp.QueryUserDataRsp.UserGroupName = string(buf[offset:offset+int(vallen)])
|
||||
case IE_STATUS:
|
||||
rsp.QueryUserDataRsp.Status = strconv.Itoa(int(buf[offset]))
|
||||
case IE_BALANCE:
|
||||
rsp.QueryUserDataRsp.Balance = strconv.Itoa(int(binary.BigEndian.Uint32(buf[offset:offset+4])))
|
||||
case IE_EXPIRY_TIME:
|
||||
tm := time.Unix(int64(binary.BigEndian.Uint64(buf[offset:offset+8])), 0)
|
||||
rsp.QueryUserDataRsp.ExpireDate = tm.Format("2006-01-02 15:04:05")
|
||||
case IE_REMAIN_MO_VOICE_MIN:
|
||||
rsp.QueryUserDataRsp.RemainMoVoiceMinute = strconv.Itoa(int(binary.BigEndian.Uint32(buf[offset:offset+4])))
|
||||
case IE_REMAIN_MT_VOICE_MIN:
|
||||
rsp.QueryUserDataRsp.RemainMtVoiceMinute = strconv.Itoa(int(binary.BigEndian.Uint32(buf[offset:offset+4])))
|
||||
case IE_REMAIN_SMS_NUM:
|
||||
rsp.QueryUserDataRsp.RemainSmsVolume = strconv.Itoa(int(binary.BigEndian.Uint32(buf[offset:offset+4])))
|
||||
case IE_REMAIN_DATA_VOL_MB:
|
||||
rsp.QueryUserDataRsp.RemainDataVolume = strconv.Itoa(int(binary.BigEndian.Uint32(buf[offset:offset+4])))
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decode_query_userData_rsp: %#v", rsp.QueryUserDataRsp)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
func decode_bundleSubs_rsp(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
var result byte = 1
|
||||
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset];
|
||||
offset++
|
||||
vallen = buf[offset];
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_RESULT:
|
||||
result = buf[offset]
|
||||
if result == 0 {
|
||||
rsp.BundleSubsRsp.Code = strconv.Itoa(int(ERRCODE_SUCCESS))
|
||||
rsp.BundleSubsRsp.Message = Rest_proxy_errcodemsg(ERRCODE_SUCCESS)
|
||||
}
|
||||
case IE_ERROR_CODE:
|
||||
err_code := binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
rsp.BundleSubsRsp.Code = strconv.Itoa(int(err_code))
|
||||
rsp.BundleSubsRsp.Message = Rest_proxy_errcodemsg(err_code)
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decode_bundleSubs_rsp: %#v", rsp.BundleSubsRsp)
|
||||
return 0
|
||||
}
|
||||
|
||||
func decode_query_balance_rsp(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
var result byte = 1
|
||||
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset];
|
||||
offset++
|
||||
vallen = buf[offset];
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_RESULT:
|
||||
result = buf[offset]
|
||||
if result == 0 {
|
||||
rsp.QueryBalanceRsp.Code = strconv.Itoa(int(ERRCODE_SUCCESS))
|
||||
rsp.QueryBalanceRsp.Message = Rest_proxy_errcodemsg(ERRCODE_SUCCESS)
|
||||
}
|
||||
case IE_ERROR_CODE:
|
||||
err_code := binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
rsp.QueryBalanceRsp.Code = strconv.Itoa(int(err_code))
|
||||
rsp.QueryBalanceRsp.Message = Rest_proxy_errcodemsg(err_code)
|
||||
case IE_STATUS:
|
||||
rsp.QueryBalanceRsp.Status = strconv.Itoa(int(buf[offset]))
|
||||
case IE_BALANCE:
|
||||
rsp.QueryBalanceRsp.Balance = strconv.Itoa(int(binary.BigEndian.Uint32(buf[offset:offset+4])))
|
||||
case IE_MO_EXPIRY:
|
||||
tm := time.Unix(int64(binary.BigEndian.Uint32(buf[offset:offset+4])), 0)
|
||||
rsp.QueryBalanceRsp.ExpireDate = tm.Format("2006-01-02 15:04:05")
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decode_query_balance_rsp: %#v", rsp.QueryBalanceRsp)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func decode_recharge_rsp(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
var result byte = 1
|
||||
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset];
|
||||
offset++
|
||||
vallen = buf[offset];
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_RESULT:
|
||||
result = buf[offset]
|
||||
if result == 0 {
|
||||
rsp.RechargeRsp.Code = strconv.Itoa(int(ERRCODE_SUCCESS))
|
||||
rsp.RechargeRsp.Message = Rest_proxy_errcodemsg(ERRCODE_SUCCESS)
|
||||
}
|
||||
case IE_ERROR_CODE:
|
||||
var err_code uint32
|
||||
if vallen == 1 {
|
||||
err_code = uint32(buf[offset])
|
||||
} else {
|
||||
err_code = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
}
|
||||
|
||||
rsp.RechargeRsp.Code = strconv.Itoa(int(err_code))
|
||||
rsp.RechargeRsp.Message = Rest_proxy_errcodemsg(err_code)
|
||||
case IE_STATUS:
|
||||
rsp.RechargeRsp.Status = strconv.Itoa(int(buf[offset]))
|
||||
case IE_BALANCE:
|
||||
rsp.RechargeRsp.Balance = strconv.Itoa(int(binary.BigEndian.Uint32(buf[offset:offset+4])))
|
||||
case IE_MO_EXPIRY:
|
||||
tm := time.Unix(int64(binary.BigEndian.Uint32(buf[offset:offset+4])), 0)
|
||||
rsp.RechargeRsp.ExpiredTimestamp = tm.Format("2006-01-02 15:04:05")
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decode_recharge_rsp: %#v", rsp.RechargeRsp)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func decode_transfer_rsp(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
var result byte = 1
|
||||
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset];
|
||||
offset++
|
||||
vallen = buf[offset];
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_RESULT:
|
||||
result = buf[offset]
|
||||
if result == 0 {
|
||||
rsp.TransferRsp.Code = strconv.Itoa(int(ERRCODE_SUCCESS))
|
||||
rsp.TransferRsp.Message = Rest_proxy_errcodemsg(ERRCODE_SUCCESS)
|
||||
}
|
||||
case IE_ERROR_CODE:
|
||||
var err_code uint32
|
||||
if vallen == 1 {
|
||||
err_code = uint32(buf[offset])
|
||||
} else {
|
||||
err_code = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
}
|
||||
|
||||
rsp.TransferRsp.Code = strconv.Itoa(int(err_code))
|
||||
rsp.TransferRsp.Message = Rest_proxy_errcodemsg(err_code)
|
||||
case IE_AMOUNT:
|
||||
rsp.TransferRsp.Balance = strconv.Itoa(int(binary.BigEndian.Uint32(buf[offset:offset+4])))
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decode_transfer_rsp: %#v", rsp.TransferRsp)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func decode_create_acct_rsp(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
var result byte = 1
|
||||
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset];
|
||||
offset++
|
||||
vallen = buf[offset];
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_RESULT:
|
||||
result = buf[offset]
|
||||
if result == 0 {
|
||||
rsp.CreateAccountRsp.Code = strconv.Itoa(int(ERRCODE_SUCCESS))
|
||||
rsp.CreateAccountRsp.Message = Rest_proxy_errcodemsg(ERRCODE_SUCCESS)
|
||||
}
|
||||
case IE_ERROR_CODE:
|
||||
var err_code uint32
|
||||
if vallen == 1 {
|
||||
err_code = uint32(buf[offset])
|
||||
} else {
|
||||
err_code = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
}
|
||||
|
||||
rsp.CreateAccountRsp.Code = strconv.Itoa(int(err_code))
|
||||
rsp.CreateAccountRsp.Message = Rest_proxy_errcodemsg(err_code)
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decode_create_acct_rsp: %#v", rsp.CreateAccountRsp)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func decode_update_subs_req(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
|
||||
rsp.UpdateSubsReq.OptFlag = 0
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset]
|
||||
offset++
|
||||
vallen = buf[offset]
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_MSISDN:
|
||||
rsp.UpdateSubsReq.TelNumber = string(buf[offset:offset+int(vallen)])
|
||||
case IE_ACCOUNT_ID:
|
||||
rsp.UpdateSubsReq.AccountIdU32 = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
case IE_STATUS:
|
||||
rsp.UpdateSubsReq.StatusU8 = buf[offset]
|
||||
rsp.UpdateSubsReq.OptFlag |= 0x01
|
||||
case IE_BALANCE:
|
||||
rsp.UpdateSubsReq.BalanceU32 = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
rsp.UpdateSubsReq.OptFlag |= 0x02
|
||||
case IE_EXPIRY_TIME:
|
||||
rsp.UpdateSubsReq.ExpDateU32 = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
rsp.UpdateSubsReq.OptFlag |= 0x04
|
||||
case IE_PLAN_ID:
|
||||
rsp.UpdateSubsReq.PackageIdU32 = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
rsp.UpdateSubsReq.OptFlag |= 0x08
|
||||
case IE_RENT_CHARGE:
|
||||
rsp.UpdateSubsReq.RentChargeU32 = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
rsp.UpdateSubsReq.OptFlag |= 0x10
|
||||
case IE_VAS_CUG_STATUS:
|
||||
rsp.UpdateSubsReq.VasCugStatusU8 = buf[offset]
|
||||
rsp.UpdateSubsReq.OptFlag |= 0x20
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decode_update_subs_req: %#v", rsp.UpdateSubsReq)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func decode_update_subs_rsp(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
var result byte = 1
|
||||
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset];
|
||||
offset++
|
||||
vallen = buf[offset];
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_RESULT:
|
||||
result = buf[offset]
|
||||
if result == 0 {
|
||||
rsp.UpdateSubsRsp.Code = strconv.Itoa(int(ERRCODE_SUCCESS))
|
||||
rsp.UpdateSubsRsp.Message = Rest_proxy_errcodemsg(ERRCODE_SUCCESS)
|
||||
}
|
||||
case IE_ERROR_CODE:
|
||||
var err_code uint32
|
||||
if vallen == 1 {
|
||||
err_code = uint32(buf[offset])
|
||||
} else {
|
||||
err_code = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
}
|
||||
|
||||
rsp.UpdateSubsRsp.Code = strconv.Itoa(int(err_code))
|
||||
rsp.UpdateSubsRsp.Message = Rest_proxy_errcodemsg(err_code)
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decode_update_subs_rsp: %#v", rsp.UpdateSubsRsp)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func decode_delete_subs_rsp(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
var result byte = 1
|
||||
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset]
|
||||
offset++
|
||||
vallen = buf[offset]
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_RESULT:
|
||||
result = buf[offset]
|
||||
rsp.DeleteSubsRsp.Result = result
|
||||
if result == 0 {
|
||||
rsp.DeleteSubsRsp.Code = strconv.Itoa(int(ERRCODE_SUCCESS))
|
||||
rsp.DeleteSubsRsp.Message = Rest_proxy_errcodemsg(ERRCODE_SUCCESS)
|
||||
}
|
||||
case IE_ERROR_CODE:
|
||||
var err_code uint32
|
||||
if vallen == 1 {
|
||||
err_code = uint32(buf[offset])
|
||||
} else {
|
||||
err_code = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
}
|
||||
|
||||
rsp.DeleteSubsRsp.ErrorCode = err_code
|
||||
rsp.DeleteSubsRsp.Code = strconv.Itoa(int(err_code))
|
||||
rsp.DeleteSubsRsp.Message = Rest_proxy_errcodemsg(err_code)
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decode_update_subs_rsp: %#v", rsp.UpdateSubsRsp)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func decodeUpdateBundleUsageReq(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
var tag byte = 0
|
||||
var vallen byte = 0
|
||||
|
||||
for {
|
||||
if offset >= msglen {
|
||||
break
|
||||
}
|
||||
tag = buf[offset]
|
||||
offset++
|
||||
vallen = buf[offset]
|
||||
offset++
|
||||
|
||||
switch tag {
|
||||
case IE_SRC_REF:
|
||||
rsp.Src_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_DST_REF:
|
||||
rsp.Dst_id = binary.BigEndian.Uint16(buf[offset:offset+2])
|
||||
case IE_MSISDN:
|
||||
rsp.UpdateBundleUsageReq.Msisdn = string(buf[offset:offset+int(vallen)])
|
||||
case IE_SERVICE_TYPE:
|
||||
rsp.UpdateBundleUsageReq.ServiceType = buf[offset]
|
||||
case IE_ACCOUNT_ID:
|
||||
rsp.UpdateBundleUsageReq.AccountId = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
case IE_PLAN_ID:
|
||||
rsp.UpdateBundleUsageReq.PlanId = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
case IE_BUNDLE_ID:
|
||||
rsp.UpdateBundleUsageReq.BundleId = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
case IE_PLAN_VALUE:
|
||||
rsp.UpdateBundleUsageReq.PlanValue = binary.BigEndian.Uint64(buf[offset:offset+8])
|
||||
case IE_PLAN_USED_VALUE:
|
||||
rsp.UpdateBundleUsageReq.PlanUsedValue = binary.BigEndian.Uint64(buf[offset:offset+8])
|
||||
case IE_SESS_UPDATE_TIME:
|
||||
rsp.UpdateBundleUsageReq.SessUpdateTime = binary.BigEndian.Uint32(buf[offset:offset+4])
|
||||
case IE_PLAN_VALUE_ADD_THIS_TIME:
|
||||
rsp.UpdateBundleUsageReq.PlanValueAddThisTime = binary.BigEndian.Uint64(buf[offset:offset+8])
|
||||
default:
|
||||
}
|
||||
offset += int(vallen)
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("decodeUpdateBundleUsageReq: %#v", rsp.UpdateSubsRsp)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func Decode_udp_msg(buf []byte, msglen int, rsp *RestRsp) int {
|
||||
var offset int = 0
|
||||
|
||||
if msglen <= 9 {
|
||||
return -1
|
||||
}
|
||||
|
||||
rsp.MsgType = buf[offset]
|
||||
offset++
|
||||
switch (rsp.MsgType) {
|
||||
case REST_SEND_AUTHCODE_RSP:
|
||||
return decode_authcode_rsp(buf[1:], msglen-1, rsp)
|
||||
case REST_QUERY_USERDATA_RSP:
|
||||
return decode_query_userData_rsp(buf[1:], msglen-1, rsp)
|
||||
case REST_BUNDLE_SUBS_RSP:
|
||||
return decode_bundleSubs_rsp(buf[1:], msglen-1, rsp)
|
||||
case REST_RECHARGE_RSP:
|
||||
return decode_recharge_rsp(buf[1:], msglen-1, rsp)
|
||||
case REST_TRANSFER_RSP:
|
||||
return decode_transfer_rsp(buf[1:], msglen-1, rsp)
|
||||
case REST_QUERY_BALANCE_RSP:
|
||||
return decode_query_balance_rsp(buf[1:], msglen-1, rsp)
|
||||
case REST_CRM_CREATE_ACCT_RES:
|
||||
return decode_create_acct_rsp(buf[1:], msglen-1, rsp)
|
||||
case REST_CRM_UPDATE_SUBS_REQ:
|
||||
return decode_update_subs_req(buf[1:], msglen-1, rsp)
|
||||
case REST_CRM_UPDATE_SUBS_RES:
|
||||
return decode_update_subs_rsp(buf[1:], msglen-1, rsp)
|
||||
case REST_CRM_DELETE_SUBS_RES:
|
||||
return decode_delete_subs_rsp(buf[1:], msglen-1, rsp)
|
||||
case REST_CRM_UPDATE_PLAN_INFO_REQ:
|
||||
return decodeUpdateBundleUsageReq(buf[1:], msglen-1, rsp)
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
44
proxy/Nrestful/error_code.go
Normal file
44
proxy/Nrestful/error_code.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package Nrestful
|
||||
|
||||
import (
|
||||
|
||||
)
|
||||
|
||||
const ERRCODE_SUCCESS uint32 = 2001
|
||||
const ERRCODE_COM_UNSUPPORT uint32 = 3001
|
||||
const ERRCODE_UNKNOWN_PEER uint32 = 3011
|
||||
const ERRCODE_INVALID_USER_STATUS uint32 = 4001
|
||||
const ERRCODE_DEST_USER_NOT_ALLOWED uint32 = 4008
|
||||
const ERRCODE_CREDIT_LIMIT uint32 = 4012
|
||||
const ERRCODE_INVALID_PARAM_VALUE uint32 = 5004
|
||||
const ERRCODE_MISSING_PARAM uint32 = 5005
|
||||
const ERRCODE_INVALID_RECHARGE_PASSWORD uint32 = 5006
|
||||
const ERRCODE_UNABLE_TO_COMPLY uint32 = 5012
|
||||
const ERRCODE_USER_UNKNOWN uint32 = 5030
|
||||
const MAX_ERRCODE uint32 = 5000
|
||||
|
||||
var restCode2StrMap = make(map[uint32]string)
|
||||
|
||||
func init() {
|
||||
restCode2StrMap[ERRCODE_SUCCESS] = "success"
|
||||
restCode2StrMap[ERRCODE_COM_UNSUPPORT] = "command unsupported"
|
||||
restCode2StrMap[ERRCODE_UNKNOWN_PEER] = "unknown peer"
|
||||
restCode2StrMap[ERRCODE_INVALID_USER_STATUS] = "invalid user status"
|
||||
restCode2StrMap[ERRCODE_DEST_USER_NOT_ALLOWED] = "dest user not allowed"
|
||||
restCode2StrMap[ERRCODE_CREDIT_LIMIT] = "credit limit"
|
||||
restCode2StrMap[ERRCODE_INVALID_PARAM_VALUE] = "invalid parameter value"
|
||||
restCode2StrMap[ERRCODE_MISSING_PARAM] = "missing parameter"
|
||||
restCode2StrMap[ERRCODE_INVALID_RECHARGE_PASSWORD] = "invalid recharge password"
|
||||
restCode2StrMap[ERRCODE_UNABLE_TO_COMPLY] = "unable to comply"
|
||||
restCode2StrMap[ERRCODE_USER_UNKNOWN] = "user unknown"
|
||||
}
|
||||
|
||||
func Rest_proxy_errcodemsg(errcode uint32) string {
|
||||
errStr, ok := restCode2StrMap[errcode]
|
||||
if !ok {
|
||||
return "unkown"
|
||||
} else {
|
||||
return errStr
|
||||
}
|
||||
}
|
||||
|
||||
104
proxy/Nrestful/handle_ocs_msg.go
Normal file
104
proxy/Nrestful/handle_ocs_msg.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package Nrestful
|
||||
|
||||
import (
|
||||
mysql "proxy/Nmysql"
|
||||
rds "proxy/Nredis"
|
||||
"proxy/config"
|
||||
)
|
||||
|
||||
func handleOcsDeleteSubsRsp(req *RestRsp) {
|
||||
}
|
||||
|
||||
func handleOcsUpdateSubsReq(req *RestRsp) {
|
||||
expNtfFlag := false
|
||||
var expiredDate int64= 0
|
||||
if req.UpdateSubsReq.OptFlag & 0x04 == 0x04 {
|
||||
expNtfFlag = true
|
||||
expiredDate = int64(req.UpdateSubsReq.ExpDateU32)
|
||||
}
|
||||
|
||||
accountId := req.UpdateSubsReq.AccountIdU32
|
||||
if expNtfFlag {
|
||||
planId := req.UpdateSubsReq.PackageIdU32
|
||||
_ = mysql.InsertExpiredNotifySms(accountId, planId, expiredDate)
|
||||
} else {
|
||||
status := req.UpdateSubsReq.StatusU8
|
||||
_ = mysql.UpdateUserStatus2Mdb(accountId, status)
|
||||
}
|
||||
}
|
||||
|
||||
func handleUpdatePlanUsage(req *RestRsp) {
|
||||
opFlag := false
|
||||
thisTimeAdded := req.UpdateBundleUsageReq.PlanValueAddThisTime
|
||||
if thisTimeAdded & 0x8000000000000000 == 0x8000000000000000 {
|
||||
opFlag = true
|
||||
}
|
||||
thisTimeAdded &= 0x7FFFFFFFFFFFFFFF
|
||||
|
||||
totalValue := req.UpdateBundleUsageReq.PlanValue
|
||||
if totalValue <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
usedValue := req.UpdateBundleUsageReq.PlanUsedValue
|
||||
serviceType := req.UpdateBundleUsageReq.ServiceType
|
||||
rateUsed, oldRateUsed := 0, 0
|
||||
sendNotifyFlag := false
|
||||
if bSendNotifySms(serviceType) {//(service_type == 2)//data only; 1: voice; 2: data; 3: sms;
|
||||
rateUsed = int(usedValue*100 / totalValue)
|
||||
if rateUsed > 75 {
|
||||
oldRateUsed = int((usedValue-thisTimeAdded)*100 / totalValue)
|
||||
if oldRateUsed <= 75 {
|
||||
sendNotifyFlag = true
|
||||
rateUsed = 75
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateExpiryDate := false
|
||||
if usedValue >= totalValue {
|
||||
usedValue = totalValue
|
||||
rateUsed = 100
|
||||
updateExpiryDate = true
|
||||
if false {
|
||||
sendNotifyFlag = true
|
||||
}
|
||||
}
|
||||
|
||||
bundleId := req.UpdateBundleUsageReq.BundleId
|
||||
if serviceType == 2 {
|
||||
mysql.UpdateDataPlanInfo(bundleId, thisTimeAdded, opFlag)
|
||||
} else {
|
||||
mysql.UpdateVoiceAndSmsPlanInfo(serviceType, bundleId, usedValue, totalValue, updateExpiryDate)
|
||||
}
|
||||
|
||||
if sendNotifyFlag {
|
||||
planId := req.UpdateBundleUsageReq.PlanId
|
||||
if !rds.CheckIfBundleLimitSent(planId, rateUsed) {
|
||||
accountId := req.UpdateBundleUsageReq.AccountId
|
||||
mysql.AddNotificationSms(accountId, planId, serviceType, updateExpiryDate, rateUsed)
|
||||
rds.SetPlanExpire(planId, rateUsed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func bSendNotifySms(serviceType byte) bool {
|
||||
ntfCfg := &config.Config.BundleUsageNotify
|
||||
switch serviceType {
|
||||
case 1:
|
||||
if ntfCfg.Voice75Percent {
|
||||
return true
|
||||
}
|
||||
case 2:
|
||||
if ntfCfg.Data75Percent {
|
||||
return true
|
||||
}
|
||||
case 3:
|
||||
if ntfCfg.Sms75Percent {
|
||||
return true
|
||||
}
|
||||
default:
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
92
proxy/Nrestful/handle_port.go
Normal file
92
proxy/Nrestful/handle_port.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package Nrestful
|
||||
|
||||
import (
|
||||
l4g "proxy/logger" //"github.com/sirupsen/logrus"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var mutex sync.Mutex
|
||||
|
||||
type Port struct {
|
||||
|
||||
CurIndex int
|
||||
UseFlag int
|
||||
|
||||
Dst_id uint16
|
||||
Rsp chan RestRsp
|
||||
}
|
||||
|
||||
const MAX_PORT_NUM uint16 = 8192
|
||||
|
||||
type PortMngt struct {
|
||||
Seq uint16
|
||||
CurIndex uint16
|
||||
Ports [MAX_PORT_NUM]Port
|
||||
}
|
||||
|
||||
var portMngt PortMngt
|
||||
|
||||
func AssignPort(req *RestReq) *Port {
|
||||
var id uint16 = 0
|
||||
var i uint16 = 0
|
||||
var port *Port = nil
|
||||
|
||||
mutex.Lock()
|
||||
for i=0; i<MAX_PORT_NUM; i++ {
|
||||
id = (i+portMngt.CurIndex) % MAX_PORT_NUM
|
||||
if portMngt.Ports[id].UseFlag == 0 {
|
||||
portMngt.CurIndex = (id + 1) % MAX_PORT_NUM
|
||||
portMngt.Ports[id].UseFlag = 1
|
||||
req.Src_id = id
|
||||
req.Dst_id = portMngt.Seq
|
||||
portMngt.Ports[id].Dst_id = req.Dst_id
|
||||
portMngt.Seq ++
|
||||
|
||||
port = &portMngt.Ports[id]
|
||||
break
|
||||
}
|
||||
}
|
||||
mutex.Unlock()
|
||||
|
||||
return port
|
||||
}
|
||||
|
||||
func GetPortInfo(src_id uint16, dst_id uint16) *Port {
|
||||
if src_id < 0 || src_id >= MAX_PORT_NUM {
|
||||
return nil
|
||||
}
|
||||
|
||||
port := &portMngt.Ports[src_id]
|
||||
if port.UseFlag == 0 || port.Dst_id != dst_id {
|
||||
l4g.RestLog.Errorf("Get port error, src[%d], dst[%d], used_flag[%d]", src_id, dst_id, port.UseFlag)
|
||||
return nil
|
||||
}
|
||||
|
||||
return port
|
||||
}
|
||||
|
||||
/*func ClosePortChan(id int, ts int64) {
|
||||
if id < 0 || id >= MAX_PORT_NUM {
|
||||
return
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
if portMngt.Ports[id].UseFlag && (ts == portMngt.Ports[id].Ts) {
|
||||
close(portMngt.Ports[id].Rsp)
|
||||
}
|
||||
mutex.Unlock()
|
||||
|
||||
return
|
||||
}*/
|
||||
|
||||
func ReleasePort(id uint16) int {
|
||||
if id < 0 || id >= MAX_PORT_NUM {
|
||||
return -1
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
portMngt.Ports[id].UseFlag = 0
|
||||
mutex.Unlock()
|
||||
|
||||
return 0
|
||||
}
|
||||
353
proxy/Nrestful/rest_msg.go
Normal file
353
proxy/Nrestful/rest_msg.go
Normal file
@@ -0,0 +1,353 @@
|
||||
package Nrestful
|
||||
|
||||
import (
|
||||
|
||||
)
|
||||
|
||||
type AuthCodeReq struct {
|
||||
CODE_TYPE string `json:"CODE_TYPE"`// ignore?
|
||||
CUST_CODE uint32 `json:"CUST_CODE"`// ignore?
|
||||
Content string `json:"content"`
|
||||
TelNumber string `json:"telNumber"`
|
||||
}
|
||||
|
||||
type AuthCodeRsp struct {
|
||||
|
||||
Code string `json:"code"`// 2001: succ; else: fail, from uint32
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type QueryUserDataReq struct {
|
||||
|
||||
TelNumber string `json:"telNumber"`
|
||||
}
|
||||
|
||||
type QueryUserDataRsp struct {
|
||||
|
||||
Code string `json:"code"`// 2001: succ; else: fail, from uint32
|
||||
Message string `json:"message"`
|
||||
Status string `json:"status"`// from uint8
|
||||
Remark string `json:"remark"`
|
||||
TelNumber string `json:"telNumber"`
|
||||
UserGroupName string `json:"userGroupName"`
|
||||
Balance string `json:"balance"`// from uint32
|
||||
ExpireDate string `json:"expireDate"`// "YYYY-MM-DD HH:MM:SS"
|
||||
VoiceMinute string `json:"VoiceMinute,omitempty"`// from uint32
|
||||
RemainMoVoiceMinute string `json:"remainVoiceMinute"`// from uint32
|
||||
RemainMtVoiceMinute string `json:"remainMtVoiceMinute,omitempty"`// from uint32
|
||||
SmsVolume string `json:"smsVolume,omitempty"`// from uint32
|
||||
RemainSmsVolume string `json:"remainSmsVolume"`// from uint32
|
||||
DataVolume string `json:"dataVolume,omitempty"`// from uint32
|
||||
RemainDataVolume string `json:"remainDataVolume"`// from uint32
|
||||
}
|
||||
|
||||
type BundleSubsReq struct {
|
||||
|
||||
TelNumber string `json:"telNumber"`
|
||||
PayType string `json:"payType"`// from uint8
|
||||
ChargedAmount string `json:"chargedAmount"`// from uint32
|
||||
MoVoiceMinute string `json:"moVoiceMinute"`// from uint32
|
||||
MtVoiceMinute string `json:"mtVoiceMinute"`// from uint32
|
||||
DataVolume string `json:"dataVolume"`// from uint32, in MB
|
||||
SmsVolume string `json:"smsVolume"`// from uint32
|
||||
ValidPeriod string `json:"validPeriod"`// from uint32
|
||||
}
|
||||
|
||||
type BundleSubsRsp struct {
|
||||
|
||||
Code string `json:"code"`// 2001: succ; else: fail// from uint32
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type BundleUsageReq struct {
|
||||
|
||||
TelNumber string `json:"telNumber"`
|
||||
}
|
||||
|
||||
type BundleUsageRsp struct {
|
||||
|
||||
Code uint32 `json:"code"`// 2001: succ; else: fail
|
||||
Message string `json:"message"`
|
||||
|
||||
MoVoiceInSecond uint32 `json:"moVoiceInSecond"`
|
||||
MtVoiceInSecond uint32 `json:"mtVoiceInSecond"`
|
||||
DataVolumeInKB uint32 `json:"dataVolumeInKB"`
|
||||
SmsVolume uint32 `json:"smsVolume"`
|
||||
ExpiredTimestamp string `json:"expiredTimestamp"`// "YYYY-MM-DD HH:MM:SS"
|
||||
}
|
||||
|
||||
type RechargeReq struct {
|
||||
AccountId string `json:"accountId"`
|
||||
Amount string `json:"amount"`// to uint32
|
||||
OpType string `json:"opType"`// to uint8
|
||||
StaffId string `json:"staffId"`
|
||||
TelNumber string `json:"telNumber"`
|
||||
ValidyDays string `json:"validyDays"`// to uint16
|
||||
}
|
||||
|
||||
type RechargeRsp struct {
|
||||
|
||||
Code string `json:"code"`// 2001: succ; else: fail, from uint32
|
||||
Message string `json:"message"`
|
||||
Status string `json:"status"` // from uint8
|
||||
Balance string `json:"balance"`// from uint32
|
||||
ExpiredTimestamp string `json:"expiredTimestamp"`// "YYYY-MM-DD HH:MM:SS"
|
||||
}
|
||||
|
||||
type TransferReq struct {
|
||||
|
||||
TransferOut string `json:"transferOut"`
|
||||
TransferIn string `json:"transferIn"`
|
||||
Amount string `json:"amount"`// from uint32
|
||||
}
|
||||
|
||||
type TransferRsp struct {
|
||||
|
||||
Code string `json:"code"`// 2001: succ; else: fail, from uint32
|
||||
Message string `json:"message"`
|
||||
Balance string `json:"balance"`// from uint32
|
||||
}
|
||||
|
||||
type RechargeCardReq struct {
|
||||
|
||||
TelNumber string `json:"telNumber"`
|
||||
CardPwd string `json:"cardPwd"`
|
||||
}
|
||||
|
||||
type RechargeCardRsp struct {
|
||||
|
||||
Code uint32 `json:"code"`// 2001: succ; else: fail
|
||||
Message string `json:"message"`
|
||||
RechargeAmount uint32 `json:"rechargeAmount"`
|
||||
Balance uint32 `json:"balance"`
|
||||
ExpiredTimestamp string `json:"expiredTimestamp"`// "%02d-%02d-%02d %02d:%02d:%02d"
|
||||
}
|
||||
|
||||
type CheckBalanceReq struct {
|
||||
|
||||
TelNumber string `json:"telNumber"`
|
||||
Amount uint32 `json:"amount"`
|
||||
}
|
||||
|
||||
type CheckBalanceRsp struct {
|
||||
|
||||
Code uint32 `json:"code"`// 2001: succ; else: fail
|
||||
Message string `json:"message"`
|
||||
Available uint32 `json:"available"`
|
||||
}
|
||||
|
||||
type QueryBalanceReq struct {
|
||||
|
||||
TelNumber string `json:"telNumber"`
|
||||
}
|
||||
|
||||
type QueryBalanceRsp struct {
|
||||
|
||||
Code string `json:"code"`// 2001: succ; else: fail, from uint32
|
||||
Message string `json:"message"`
|
||||
Status string `json:"status"`// from uint8
|
||||
Balance string `json:"balance"`// from uint32
|
||||
ExpireDate string `json:"expireDate"`// "YYYY-MM-DD HH:MM:SS"
|
||||
}
|
||||
|
||||
type QueryRechargeCardReq struct {
|
||||
|
||||
TelNumber string `json:"telNumber"`
|
||||
}
|
||||
|
||||
type QueryRechargeCardRsp struct {
|
||||
|
||||
Code uint32 `json:"code"`// 2001: succ; else: fail
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type UpdateRechargeCardReq struct {
|
||||
|
||||
TelNumber string `json:"telNumber"`
|
||||
}
|
||||
|
||||
type UpdateRechargeCardRsp struct {
|
||||
|
||||
Code uint32 `json:"code"`// 2001: succ; else: fail
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type CreateAccountReq struct {
|
||||
|
||||
ServiceNbr string `json:"serviceNbr"`
|
||||
CustId string `json:"custId"`// from uint32
|
||||
AccountId string `json:"accountId"`// from uint32
|
||||
ProductInstId string `json:"productInstId"`// from uint32
|
||||
PackageId string `json:"packageId"`// from uint32
|
||||
Balance string `json:"balance"`// from uint32
|
||||
//CustIdUint32 uint32 `json:"custIdUint32,omitempty"`// from uint32
|
||||
//AcctIdUint32 uint32 `json:"acctIdUint32,omitempty"`// from uint32
|
||||
|
||||
BalanceExpDate string `json:"balanceExpDate"`
|
||||
Birthday string `json:"birthday"`
|
||||
RentCharge string `json:"rentCharge,omitempty"`// from uint32
|
||||
CugId string `json:"cugId,omitempty"`// from uint32
|
||||
UserClass string `json:"userClass,omitempty"`// from uint32
|
||||
}
|
||||
|
||||
type CreateAccountRsp struct {
|
||||
|
||||
Code string `json:"code"`// 2001: succ; else: fail, from uint32
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type UpdateSubsReq struct {
|
||||
|
||||
TelNumber string `json:"telNumber"`
|
||||
AccountId string `json:"accountId,omitempty"`// from uint32
|
||||
Status string `json:"status,omitempty"`// from uint8
|
||||
Balance string `json:"balance,omitempty"`// from uint32
|
||||
BalanceExpDate string `json:"balanceExpDate,omitempty"`
|
||||
|
||||
AccountIdU32 uint32 `json:"accountIdU32,omitempty"`
|
||||
StatusU8 byte `json:"statusU8,omitempty"`
|
||||
BalanceU32 uint32 `json:"balanceU32,omitempty"`
|
||||
ExpDateU32 uint32 `json:"balanceExpDateU32,omitempty"`
|
||||
OptFlag uint32 `json:"optFlagU32,omitempty"`
|
||||
PackageIdU32 uint32 `json:"packageIdU32,omitempty"`// from uint32
|
||||
RentChargeU32 uint32 `json:"rentChargeU32,omitempty"`// from uint32
|
||||
VasCugStatusU8 byte `json:"vasCugStatusU8,omitempty"`// from uint8
|
||||
|
||||
PackageId string `json:"packageId,omitempty"`// from uint32
|
||||
RentCharge string `json:"rentCharge,omitempty"`// from uint32
|
||||
VasCugStatus string `json:"vasCugStatus,omitempty"`// from uint8
|
||||
//Optional_flag uint32 `json:"optional_flag,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateSubsRsp struct {
|
||||
|
||||
Code string `json:"code"`// 2001: succ; else: fail, from uint32
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type DeleteSubsReq struct {
|
||||
|
||||
TelNumber string `json:"telNumber"`
|
||||
AcctType string `json:"acctType,omitempty"`// from uint8
|
||||
AcctId string `json:"acctID,omitempty"`// from uint32
|
||||
Cause string `json:"reason,omitempty"`// from uint8
|
||||
}
|
||||
|
||||
type DeleteSubsRsp struct {
|
||||
|
||||
Result byte
|
||||
ErrorCode uint32
|
||||
|
||||
Code string `json:"code"`// 2001: succ; else: fail, from uint32
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type UpdateBundleUsageReq struct {
|
||||
Msisdn string // tag 2
|
||||
ServiceType byte
|
||||
AccountId uint32
|
||||
PlanId uint32
|
||||
BundleId uint32
|
||||
PlanValue uint64
|
||||
PlanUsedValue uint64
|
||||
SessUpdateTime uint32
|
||||
PlanValueAddThisTime uint64
|
||||
}
|
||||
|
||||
//type RestMsgType int
|
||||
|
||||
const (
|
||||
REST_SEND_AUTHCODE_REQ byte = 5
|
||||
REST_SEND_AUTHCODE_RSP byte = 6
|
||||
REST_QUERY_USERDATA_REQ byte = 7
|
||||
REST_QUERY_USERDATA_RSP byte = 8
|
||||
REST_BUNDLE_SUBS_REQ byte = 9
|
||||
REST_BUNDLE_SUBS_RSP byte = 10
|
||||
REST_BUNDLE_USAGE_REQ byte = 11
|
||||
REST_BUNDLE_USAGE_RSP byte = 12
|
||||
REST_RECHARGE_REQ byte = 13
|
||||
REST_RECHARGE_RSP byte = 14
|
||||
REST_TRANSFER_REQ byte = 15
|
||||
REST_TRANSFER_RSP byte = 16
|
||||
REST_RECHARGE_CARD_REQ byte = 17
|
||||
REST_RECHARGE_CARD_RSP byte = 18
|
||||
REST_CHECK_BALANCE_REQ byte = 19
|
||||
REST_CHECK_BALANCE_RSP byte = 20
|
||||
REST_QUERY_BALANCE_REQ byte = 21
|
||||
REST_QUERY_BALANCE_RSP byte = 22
|
||||
REST_QUERY_RECHARGE_CARD_REQ byte = 23
|
||||
REST_QUERY_RECHARGE_CARD_RSP byte = 24
|
||||
REST_UPDATE_RECHARGE_CARD_REQ byte = 25
|
||||
REST_UPDATE_RECHARGE_CARD_RSP byte = 26
|
||||
|
||||
REST_CRM_PAYMENT_REQ byte = 27
|
||||
REST_CRM_PAYMENT_RES byte = 28
|
||||
|
||||
REST_CRM_SMS_DELIVER_REQ byte = 29
|
||||
REST_CRM_SMS_DELIVER_RES byte = 30
|
||||
|
||||
REST_CRM_CREATE_ACCT_REQ byte = 31
|
||||
REST_CRM_CREATE_ACCT_RES byte = 32
|
||||
|
||||
REST_CRM_QUERY_TARIFF_REQ byte = 33
|
||||
REST_CRM_QUERY_TARIFF_RES byte = 34
|
||||
|
||||
REST_CRM_UPDATE_SUBS_REQ byte = 35
|
||||
REST_CRM_UPDATE_SUBS_RES byte = 36
|
||||
|
||||
REST_CRM_DELETE_SUBS_REQ byte = 37
|
||||
REST_CRM_DELETE_SUBS_RES byte = 38
|
||||
|
||||
REST_CRM_UPDATE_SESS_INFO_REQ byte = 39
|
||||
REST_CRM_UPDATE_SESS_INFO_RES byte = 40
|
||||
|
||||
REST_CRM_UPDATE_PLAN_INFO_REQ byte = 41
|
||||
REST_CRM_UPDATE_PLAN_INFO_RES byte = 42
|
||||
|
||||
REST_CRM_RENT_CHARGE byte = 43
|
||||
)
|
||||
|
||||
type RestReq struct {
|
||||
MsgType byte
|
||||
Src_id uint16
|
||||
Dst_id uint16
|
||||
|
||||
AuthCodeReq AuthCodeReq
|
||||
QueryUserDataReq QueryUserDataReq
|
||||
BundleSubsReq BundleSubsReq
|
||||
BundleUsageReq BundleUsageReq
|
||||
RechargeReq RechargeReq
|
||||
TransferReq TransferReq
|
||||
RechargeCardReq RechargeCardReq
|
||||
CheckBalanceReq CheckBalanceReq
|
||||
QueryBalanceReq QueryBalanceReq
|
||||
QueryRechargeCardReq QueryRechargeCardReq
|
||||
UpdateRechargeCardReq UpdateRechargeCardReq
|
||||
CreateAccountReq CreateAccountReq
|
||||
UpdateSubsReq UpdateSubsReq
|
||||
DeleteSubsReq DeleteSubsReq
|
||||
}
|
||||
|
||||
type RestRsp struct {
|
||||
MsgType byte
|
||||
Src_id uint16
|
||||
Dst_id uint16
|
||||
|
||||
AuthCodeRsp AuthCodeRsp
|
||||
QueryUserDataRsp QueryUserDataRsp
|
||||
BundleSubsRsp BundleSubsRsp
|
||||
BundleUsageRsp BundleUsageRsp
|
||||
RechargeRsp RechargeRsp
|
||||
TransferRsp TransferRsp
|
||||
RechargeCardRsp RechargeCardRsp
|
||||
CheckBalanceRsp CheckBalanceRsp
|
||||
QueryBalanceRsp QueryBalanceRsp
|
||||
QueryRechargeCardRsp QueryRechargeCardRsp
|
||||
UpdateRechargeCardRsp UpdateRechargeCardRsp
|
||||
CreateAccountRsp CreateAccountRsp
|
||||
UpdateSubsRsp UpdateSubsRsp
|
||||
DeleteSubsRsp DeleteSubsRsp
|
||||
UpdateBundleUsageReq UpdateBundleUsageReq
|
||||
UpdateSubsReq UpdateSubsReq
|
||||
}
|
||||
|
||||
148
proxy/Nrestful/rest_response.go
Normal file
148
proxy/Nrestful/rest_response.go
Normal file
@@ -0,0 +1,148 @@
|
||||
package Nrestful
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
//"fmt"
|
||||
//"log"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
//"time"
|
||||
|
||||
l4g "proxy/logger"//"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func sendAuthCodeRsp(w http.ResponseWriter, statusCode int, rsp *RestRsp) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
if statusCode != http.StatusOK {
|
||||
rsp.AuthCodeRsp.Code = strconv.Itoa(5001)
|
||||
} else {
|
||||
//rsp.AuthCodeRsp.Code = 2001
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
l4g.RestLog.Warnf("Send AuthCodeRsp: %v", rsp.AuthCodeRsp)
|
||||
|
||||
// w.Write at last
|
||||
json.NewEncoder(w).Encode(rsp.AuthCodeRsp)
|
||||
//
|
||||
}
|
||||
|
||||
func sendQueryUserDataRsp(w http.ResponseWriter, statusCode int, rsp *RestRsp) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
if statusCode != http.StatusOK {
|
||||
rsp.QueryUserDataRsp.Code = strconv.Itoa(5001)
|
||||
} else {
|
||||
//rsp.QueryUserDataRsp.Code = 2001
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
l4g.RestLog.Warnf("Send QueryUserDataRsp: %v", rsp.QueryUserDataRsp)
|
||||
|
||||
// w.Write at last
|
||||
json.NewEncoder(w).Encode(rsp.QueryUserDataRsp)
|
||||
//
|
||||
}
|
||||
|
||||
func sendBundleSubsRsp(w http.ResponseWriter, statusCode int, rsp *RestRsp) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
if statusCode != http.StatusOK {
|
||||
rsp.BundleSubsRsp.Code = strconv.Itoa(5001)
|
||||
} else {
|
||||
//rsp.BundleSubsRsp.Code = 2001
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
l4g.RestLog.Warnf("Send QueryUserDataRsp: %v", rsp.BundleSubsRsp)
|
||||
|
||||
// w.Write at last
|
||||
json.NewEncoder(w).Encode(rsp.BundleSubsRsp)
|
||||
//
|
||||
}
|
||||
|
||||
func sendRechargeRsp(w http.ResponseWriter, statusCode int, rsp *RestRsp) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
if statusCode != http.StatusOK {
|
||||
rsp.RechargeRsp.Code = strconv.Itoa(5001)
|
||||
} else {
|
||||
//rsp.RechargeRsp.Code = 2001
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
l4g.RestLog.Warnf("Send RechargeRsp: %v", rsp.RechargeRsp)
|
||||
|
||||
// w.Write at last
|
||||
json.NewEncoder(w).Encode(rsp.RechargeRsp)
|
||||
//
|
||||
}
|
||||
|
||||
func sendTransferRsp(w http.ResponseWriter, statusCode int, rsp *RestRsp) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
if statusCode != http.StatusOK {
|
||||
rsp.TransferRsp.Code = strconv.Itoa(5001)
|
||||
} else {
|
||||
//rsp.TransferRsp.Code = 2001
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
l4g.RestLog.Warnf("Send TransferRsp: %v", rsp.TransferRsp)
|
||||
|
||||
// w.Write at last
|
||||
json.NewEncoder(w).Encode(rsp.TransferRsp)
|
||||
//
|
||||
}
|
||||
|
||||
func sendQueryBalanceRsp(w http.ResponseWriter, statusCode int, rsp *RestRsp) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
if statusCode != http.StatusOK {
|
||||
rsp.QueryBalanceRsp.Code = strconv.Itoa(5001)
|
||||
} else {
|
||||
//rsp.QueryBalanceRsp.Code = 2001
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
l4g.RestLog.Warnf("Send QueryBalanceRsp: %v", rsp.QueryBalanceRsp)
|
||||
|
||||
// w.Write at last
|
||||
json.NewEncoder(w).Encode(rsp.QueryBalanceRsp)
|
||||
//
|
||||
}
|
||||
|
||||
func sendCreateAccountRsp(w http.ResponseWriter, statusCode int, rsp *RestRsp) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
if statusCode != http.StatusOK {
|
||||
rsp.CreateAccountRsp.Code = strconv.Itoa(5001)
|
||||
} else {
|
||||
//rsp.CreateAccountRsp.Code = 2001
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
l4g.RestLog.Warnf("Send CreateAccountRsp: %v", rsp.CreateAccountRsp)
|
||||
|
||||
// w.Write at last
|
||||
json.NewEncoder(w).Encode(rsp.CreateAccountRsp)
|
||||
//
|
||||
}
|
||||
|
||||
func sendUpdateSubsRsp(w http.ResponseWriter, statusCode int, rsp *RestRsp) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
if statusCode != http.StatusOK {
|
||||
rsp.UpdateSubsRsp.Code = strconv.Itoa(5001)
|
||||
} else {
|
||||
//rsp.UpdateSubsRsp.Code = 2001
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
l4g.RestLog.Warnf("Send UpdateSubsRsp: %v", rsp.UpdateSubsRsp)
|
||||
|
||||
// w.Write at last
|
||||
json.NewEncoder(w).Encode(rsp.UpdateSubsRsp)
|
||||
//
|
||||
}
|
||||
|
||||
func sendDeleteSubsRsp(w http.ResponseWriter, statusCode int, rsp *RestRsp) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
if statusCode != http.StatusOK {
|
||||
rsp.DeleteSubsRsp.Code = strconv.Itoa(5001)
|
||||
} else {
|
||||
//rsp.DeleteSubsRsp.Code = 2001
|
||||
}
|
||||
w.WriteHeader(statusCode)
|
||||
l4g.RestLog.Warnf("Send DeleteSubsRsp: %v", rsp.DeleteSubsRsp)
|
||||
|
||||
// w.Write at last
|
||||
json.NewEncoder(w).Encode(rsp.DeleteSubsRsp)
|
||||
//
|
||||
}
|
||||
|
||||
423
proxy/Nrestful/rest_router.go
Normal file
423
proxy/Nrestful/rest_router.go
Normal file
@@ -0,0 +1,423 @@
|
||||
package Nrestful
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"fmt"
|
||||
"log"
|
||||
"encoding/json"
|
||||
mysql "proxy/Nmysql"
|
||||
|
||||
//"strconv"
|
||||
"time"
|
||||
|
||||
l4g "proxy/logger"//"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func StartHttpServer(addr string) {
|
||||
http.HandleFunc("/", handler)
|
||||
http.HandleFunc("/authcode", authcodeHandler)
|
||||
http.HandleFunc("/query_userdata", query_userdataHandler)
|
||||
http.HandleFunc("/bundle_subs", bundle_subsHandler)
|
||||
//http.HandleFunc("/bundle_usage", bundle_usageHandler)
|
||||
http.HandleFunc("/recharge", rechargeHandler)
|
||||
http.HandleFunc("/transfer", transferHandler)
|
||||
//http.HandleFunc("/recharge_card", recharge_cardHandler)
|
||||
//http.HandleFunc("/check_balance", check_balanceHandler)
|
||||
http.HandleFunc("/query_balane", query_balanceHandler)// query_balane in Pcap from CRM
|
||||
http.HandleFunc("/openPackage", openPackageHandler)
|
||||
http.HandleFunc("/updateSubs", updateSubsHandler)
|
||||
http.HandleFunc("/deleteSubs", deleteSubsHandler)
|
||||
|
||||
log.Fatal(http.ListenAndServe(addr, nil))
|
||||
}
|
||||
|
||||
// handler echoes the Path component of the requested URL.
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
|
||||
}
|
||||
|
||||
func authcodeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
rsp := RestRsp{MsgType: REST_SEND_AUTHCODE_RSP}
|
||||
var pRsp *RestRsp = &rsp
|
||||
if r.Body == nil {
|
||||
rsp.AuthCodeRsp.Message = "request body missing"
|
||||
sendAuthCodeRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
|
||||
var req RestReq
|
||||
req.MsgType = REST_SEND_AUTHCODE_REQ
|
||||
err := json.NewDecoder(r.Body).Decode(&req.AuthCodeReq)
|
||||
if err != nil {
|
||||
rsp.AuthCodeRsp.Message = "err decode authCodeReq"
|
||||
sendAuthCodeRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Got authcode request: %v", req.AuthCodeReq)
|
||||
|
||||
// handle ==========================================
|
||||
port := AssignPort(&req)
|
||||
if port == nil {
|
||||
rsp.AuthCodeRsp.Message = "err port full"
|
||||
sendAuthCodeRsp(w, http.StatusInternalServerError, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Assign port for authcode request, src[%d], dst[%d]", req.Src_id, req.Dst_id)
|
||||
|
||||
ocsRsp := getOcsRsp(&req, port)
|
||||
if ocsRsp == nil {
|
||||
rsp.AuthCodeRsp.Message = "ocs rsp timeout"
|
||||
sendAuthCodeRsp(w, http.StatusInternalServerError, pRsp)
|
||||
} else {
|
||||
sendAuthCodeRsp(w, http.StatusOK, ocsRsp)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func query_userdataHandler(w http.ResponseWriter, r *http.Request) {
|
||||
rsp := RestRsp{MsgType: REST_QUERY_USERDATA_RSP}
|
||||
var pRsp *RestRsp = &rsp
|
||||
if r.Body == nil {
|
||||
rsp.QueryUserDataRsp.Message = "request body missing"
|
||||
sendQueryUserDataRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
|
||||
var req RestReq
|
||||
req.MsgType = REST_QUERY_USERDATA_REQ
|
||||
err := json.NewDecoder(r.Body).Decode(&req.QueryUserDataReq)
|
||||
if err != nil {
|
||||
rsp.QueryUserDataRsp.Message = "err decode QueryUserDataReq"
|
||||
sendQueryUserDataRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Got query_userdata request: %v", req.QueryUserDataReq)
|
||||
|
||||
// handle ==========================================
|
||||
port := AssignPort(&req)
|
||||
if port == nil {
|
||||
rsp.QueryUserDataRsp.Message = "err port full"
|
||||
sendQueryUserDataRsp(w, http.StatusInternalServerError, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Assign port for query_userdata request, src[%d], dst[%d]", req.Src_id, req.Dst_id)
|
||||
|
||||
ocsRsp := getOcsRsp(&req, port)
|
||||
if ocsRsp == nil {
|
||||
rsp.QueryUserDataRsp.Message = "ocs rsp timeout"
|
||||
sendQueryUserDataRsp(w, http.StatusInternalServerError, pRsp)
|
||||
} else {
|
||||
sendQueryUserDataRsp(w, http.StatusOK, ocsRsp)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func bundle_subsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
rsp := RestRsp{MsgType: REST_BUNDLE_SUBS_RSP}
|
||||
var pRsp *RestRsp = &rsp
|
||||
if r.Body == nil {
|
||||
rsp.BundleSubsRsp.Message = "request body missing"
|
||||
sendBundleSubsRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
|
||||
var req RestReq
|
||||
req.MsgType = REST_BUNDLE_SUBS_REQ
|
||||
err := json.NewDecoder(r.Body).Decode(&req.BundleSubsReq)
|
||||
if err != nil {
|
||||
rsp.BundleSubsRsp.Message = "err decode BundleSubsReq"
|
||||
sendBundleSubsRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Got BundleSubs request: %v", req.BundleSubsReq)
|
||||
|
||||
// handle ==========================================
|
||||
port := AssignPort(&req)
|
||||
if port == nil {
|
||||
rsp.BundleSubsRsp.Message = "err port full"
|
||||
sendBundleSubsRsp(w, http.StatusInternalServerError, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Assign port for BundleSubs request, src[%d], dst[%d]", req.Src_id, req.Dst_id)
|
||||
|
||||
ocsRsp := getOcsRsp(&req, port)
|
||||
if ocsRsp == nil {
|
||||
rsp.BundleSubsRsp.Message = "ocs rsp timeout"
|
||||
sendBundleSubsRsp(w, http.StatusInternalServerError, pRsp)
|
||||
} else {
|
||||
sendBundleSubsRsp(w, http.StatusOK, ocsRsp)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func rechargeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
rsp := RestRsp{MsgType: REST_RECHARGE_RSP}
|
||||
var pRsp *RestRsp = &rsp
|
||||
if r.Body == nil {
|
||||
rsp.RechargeRsp.Message = "request body missing"
|
||||
sendRechargeRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
|
||||
var req RestReq
|
||||
req.MsgType = REST_RECHARGE_REQ
|
||||
err := json.NewDecoder(r.Body).Decode(&req.RechargeReq)
|
||||
if err != nil {
|
||||
rsp.RechargeRsp.Message = "err decode RechargeReq"
|
||||
sendRechargeRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Got query_userdata request: %v", req.RechargeReq)
|
||||
|
||||
// handle ==========================================
|
||||
port := AssignPort(&req)
|
||||
if port == nil {
|
||||
rsp.RechargeRsp.Message = "err port full"
|
||||
sendRechargeRsp(w, http.StatusInternalServerError, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Assign port for query_userdata request, src[%d], dst[%d]", req.Src_id, req.Dst_id)
|
||||
|
||||
ocsRsp := getOcsRsp(&req, port)
|
||||
if ocsRsp == nil {
|
||||
rsp.RechargeRsp.Message = "ocs rsp timeout"
|
||||
sendRechargeRsp(w, http.StatusInternalServerError, pRsp)
|
||||
} else {
|
||||
sendRechargeRsp(w, http.StatusOK, ocsRsp)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func transferHandler(w http.ResponseWriter, r *http.Request) {
|
||||
rsp := RestRsp{MsgType: REST_TRANSFER_RSP}
|
||||
var pRsp *RestRsp = &rsp
|
||||
if r.Body == nil {
|
||||
rsp.TransferRsp.Message = "request body missing"
|
||||
sendTransferRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
|
||||
var req RestReq
|
||||
req.MsgType = REST_TRANSFER_REQ
|
||||
err := json.NewDecoder(r.Body).Decode(&req.TransferReq)
|
||||
if err != nil {
|
||||
rsp.TransferRsp.Message = "err decode TransferReq"
|
||||
sendTransferRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Got Transfer request: %v", req.TransferReq)
|
||||
|
||||
// handle ==========================================
|
||||
port := AssignPort(&req)
|
||||
if port == nil {
|
||||
rsp.TransferRsp.Message = "err port full"
|
||||
sendTransferRsp(w, http.StatusInternalServerError, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Assign port for Transfer request, src[%d], dst[%d]", req.Src_id, req.Dst_id)
|
||||
|
||||
ocsRsp := getOcsRsp(&req, port)
|
||||
if ocsRsp == nil {
|
||||
rsp.TransferRsp.Message = "ocs rsp timeout"
|
||||
sendTransferRsp(w, http.StatusInternalServerError, pRsp)
|
||||
} else {
|
||||
sendTransferRsp(w, http.StatusOK, ocsRsp)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func query_balanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
rsp := RestRsp{MsgType: REST_QUERY_BALANCE_RSP}
|
||||
var pRsp *RestRsp = &rsp
|
||||
if r.Body == nil {
|
||||
rsp.QueryBalanceRsp.Message = "request body missing"
|
||||
sendQueryBalanceRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
|
||||
var req RestReq
|
||||
req.MsgType = REST_QUERY_BALANCE_REQ
|
||||
err := json.NewDecoder(r.Body).Decode(&req.QueryBalanceReq)
|
||||
if err != nil {
|
||||
rsp.QueryBalanceRsp.Message = "err decode QueryBalanceReq"
|
||||
sendQueryBalanceRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Got QueryBalance request: %v", req.QueryBalanceReq)
|
||||
|
||||
// handle ==========================================
|
||||
port := AssignPort(&req)
|
||||
if port == nil {
|
||||
rsp.QueryBalanceRsp.Message = "err port full"
|
||||
sendQueryBalanceRsp(w, http.StatusInternalServerError, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Assign port for QueryBalance request, src[%d], dst[%d]", req.Src_id, req.Dst_id)
|
||||
|
||||
ocsRsp := getOcsRsp(&req, port)
|
||||
if ocsRsp == nil {
|
||||
rsp.QueryBalanceRsp.Message = "ocs rsp timeout"
|
||||
sendQueryBalanceRsp(w, http.StatusInternalServerError, pRsp)
|
||||
} else {
|
||||
sendQueryBalanceRsp(w, http.StatusOK, ocsRsp)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func openPackageHandler(w http.ResponseWriter, r *http.Request) {
|
||||
rsp := RestRsp{MsgType: REST_CRM_CREATE_ACCT_RES}
|
||||
var pRsp *RestRsp = &rsp
|
||||
if r.Body == nil {
|
||||
rsp.CreateAccountRsp.Message = "request body missing"
|
||||
sendCreateAccountRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
|
||||
var req RestReq
|
||||
req.MsgType = REST_CRM_CREATE_ACCT_REQ
|
||||
err := json.NewDecoder(r.Body).Decode(&req.CreateAccountReq)
|
||||
if err != nil {
|
||||
rsp.CreateAccountRsp.Message = "err decode CreateAccountReq"
|
||||
sendCreateAccountRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Got CreateAccount request: %v", req.CreateAccountReq)
|
||||
|
||||
// handle ==========================================
|
||||
port := AssignPort(&req)
|
||||
if port == nil {
|
||||
rsp.CreateAccountRsp.Message = "err port full"
|
||||
sendCreateAccountRsp(w, http.StatusInternalServerError, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Assign port for CreateAccount request, src[%d], dst[%d]", req.Src_id, req.Dst_id)
|
||||
|
||||
ocsRsp := getOcsRsp(&req, port)
|
||||
if ocsRsp == nil {
|
||||
rsp.CreateAccountRsp.Message = "ocs rsp timeout"
|
||||
sendCreateAccountRsp(w, http.StatusInternalServerError, pRsp)
|
||||
} else {
|
||||
sendCreateAccountRsp(w, http.StatusOK, ocsRsp)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func updateSubsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
rsp := RestRsp{MsgType: REST_CRM_UPDATE_SUBS_RES}
|
||||
var pRsp *RestRsp = &rsp
|
||||
if r.Body == nil {
|
||||
rsp.UpdateSubsRsp.Message = "request body missing"
|
||||
sendUpdateSubsRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
|
||||
var req RestReq
|
||||
req.MsgType = REST_CRM_UPDATE_SUBS_REQ
|
||||
err := json.NewDecoder(r.Body).Decode(&req.UpdateSubsReq)
|
||||
if err != nil {
|
||||
rsp.UpdateSubsRsp.Message = "err decode UpdateSubsReq"
|
||||
sendUpdateSubsRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Got UpdateSubs request: %v", req.UpdateSubsReq)
|
||||
|
||||
// handle ==========================================
|
||||
port := AssignPort(&req)
|
||||
if port == nil {
|
||||
rsp.UpdateSubsRsp.Message = "err port full"
|
||||
sendUpdateSubsRsp(w, http.StatusInternalServerError, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Assign port for UpdateSubs request, src[%d], dst[%d]", req.Src_id, req.Dst_id)
|
||||
|
||||
ocsRsp := getOcsRsp(&req, port)
|
||||
if ocsRsp == nil {
|
||||
rsp.UpdateSubsRsp.Message = "ocs rsp timeout"
|
||||
sendUpdateSubsRsp(w, http.StatusInternalServerError, pRsp)
|
||||
} else {
|
||||
sendUpdateSubsRsp(w, http.StatusOK, ocsRsp)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func deleteSubsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
rsp := RestRsp{MsgType: REST_CRM_DELETE_SUBS_RES}
|
||||
var pRsp *RestRsp = &rsp
|
||||
if r.Body == nil {
|
||||
rsp.DeleteSubsRsp.Message = "request body missing"
|
||||
sendDeleteSubsRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
|
||||
var req RestReq
|
||||
req.MsgType = REST_CRM_DELETE_SUBS_REQ
|
||||
err := json.NewDecoder(r.Body).Decode(&req.DeleteSubsReq)
|
||||
if err != nil {
|
||||
rsp.DeleteSubsRsp.Message = "err decode DeleteSubsReq"
|
||||
sendDeleteSubsRsp(w, http.StatusBadRequest, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Got DeleteSubs request: %v", req.DeleteSubsReq)
|
||||
|
||||
mysql.CrmDeleteSubsProfile(req.DeleteSubsReq.TelNumber, req.DeleteSubsReq.AcctType, req.DeleteSubsReq.AcctId)
|
||||
if req.DeleteSubsReq.AcctType != "1" {// not mobile
|
||||
pRsp.DeleteSubsRsp.Result = 0
|
||||
pRsp.DeleteSubsRsp.ErrorCode = 2001
|
||||
sendDeleteSubsRsp(w, http.StatusOK, pRsp)
|
||||
return
|
||||
}
|
||||
|
||||
// handle ==========================================
|
||||
port := AssignPort(&req)
|
||||
if port == nil {
|
||||
rsp.DeleteSubsRsp.Message = "err port full"
|
||||
sendDeleteSubsRsp(w, http.StatusInternalServerError, pRsp)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Assign port for DeleteSubs request, src[%d], dst[%d]", req.Src_id, req.Dst_id)
|
||||
|
||||
ocsRsp := getOcsRsp(&req, port)
|
||||
if ocsRsp == nil {
|
||||
rsp.DeleteSubsRsp.Message = "ocs rsp timeout"
|
||||
sendDeleteSubsRsp(w, http.StatusInternalServerError, pRsp)
|
||||
} else {
|
||||
sendDeleteSubsRsp(w, http.StatusOK, ocsRsp)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getOcsRsp(req *RestReq, port *Port) (*RestRsp) {
|
||||
c := make(chan RestRsp)
|
||||
//port.Rsp = make(chan RestRsp)
|
||||
port.Rsp = c
|
||||
|
||||
go SendOcsUdpReq(req)
|
||||
|
||||
defer ReleasePort(req.Src_id)
|
||||
|
||||
timeout := time.After(5 * time.Second)
|
||||
select {
|
||||
case rsp, ok := <-c:
|
||||
if !ok {// chan closed
|
||||
l4g.RestLog.Warnf("chan getOcsRsp closed by other!")
|
||||
return nil
|
||||
} else {
|
||||
close(c)
|
||||
l4g.RestLog.Debugf("getOcsRsp succ, close chan.")
|
||||
return &rsp
|
||||
}
|
||||
case <-timeout:
|
||||
l4g.RestLog.Warnf("chan getOcsRsp timeout, close chan!")
|
||||
close(c)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
5
proxy/Nrestful/udp_msg.go
Normal file
5
proxy/Nrestful/udp_msg.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package Nrestful
|
||||
|
||||
import (
|
||||
)
|
||||
|
||||
688
proxy/Nrestful/udp_routers.go
Normal file
688
proxy/Nrestful/udp_routers.go
Normal file
@@ -0,0 +1,688 @@
|
||||
package Nrestful
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"proxy/MsgDef"
|
||||
rdb "proxy/Nredis"
|
||||
"strconv"
|
||||
_ "strings"
|
||||
"time"
|
||||
|
||||
l4g "proxy/logger" //"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var ocsConn *net.UDPConn
|
||||
|
||||
func closeConnect() {
|
||||
ocsConn.Close()
|
||||
ocsConn = nil
|
||||
}
|
||||
|
||||
var locIp, ocsIp string
|
||||
var locPort, ocsPort int
|
||||
|
||||
func Connect_ocs(loc string, rem string, loc_port int, rem_port int) error {
|
||||
locIp = loc
|
||||
ocsIp = rem
|
||||
locPort = loc_port
|
||||
ocsPort = rem_port
|
||||
|
||||
return connect_ocs()
|
||||
}
|
||||
|
||||
func connect_ocs() error {
|
||||
loc_ip := net.ParseIP(locIp)
|
||||
rem_ip := net.ParseIP(ocsIp)
|
||||
|
||||
srcAddr := &net.UDPAddr{IP: loc_ip, Port: locPort}
|
||||
dstAddr := &net.UDPAddr{IP: rem_ip, Port: ocsPort}
|
||||
|
||||
var err error
|
||||
ocsConn, err = net.DialUDP("udp", srcAddr, dstAddr)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
defer closeConnect()
|
||||
|
||||
//conn.Write([]byte("hello"))
|
||||
data := make([]byte, 1500)
|
||||
//var recLen uint16 = 0
|
||||
//var msgId uint8 = 0
|
||||
for {
|
||||
n, err := ocsConn.Read(data)
|
||||
|
||||
//msgId = data[1]
|
||||
//recLen = uint16(data[2])
|
||||
//recLen = (recLen << 8) + uint16(data[3])
|
||||
if err != nil {
|
||||
//break
|
||||
} else {
|
||||
// check param
|
||||
handle_udp_msg_from_ocs(data, n)
|
||||
}
|
||||
//fmt.Printf("read %s from <%s>\n", data[:n], conn.RemoteAddr())
|
||||
}
|
||||
l4g.RestLog.Errorln("ocs read thread exit")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//type UdpMsgIE byte
|
||||
|
||||
const (
|
||||
IE_NULL = iota
|
||||
IE_SRC_REF // UdpMsgIE = 1
|
||||
IE_DST_REF
|
||||
IE_MSISDN
|
||||
IE_RESULT
|
||||
IE_ERROR_CODE
|
||||
IE_BALANCE// 6
|
||||
IE_MO_EXPIRY
|
||||
IE_MT_EXPIRY
|
||||
IE_USERNAME
|
||||
IE_PASSWORD
|
||||
IE_MSG_CONTENT //value=11
|
||||
IE_STATUS
|
||||
IE_REMARK
|
||||
IE_GROUP_NAME// 0x0e
|
||||
IE_MO_VOICE_MIN// in minute
|
||||
IE_REMAIN_MO_VOICE_SEC// in second
|
||||
IE_REMAIN_MO_VOICE_MIN// in minute
|
||||
IE_MT_VOICE_MIN// in minute
|
||||
IE_REMAIN_MT_VOICE_SEC// in second
|
||||
IE_REMAIN_MT_VOICE_MIN// in minute
|
||||
IE_SMS_NUM//value=21
|
||||
IE_REMAIN_SMS_NUM
|
||||
IE_DATA_VOL_MB// in MB
|
||||
IE_REMAIN_DATA_VOL_KB// in KB
|
||||
IE_REMAIN_DATA_VOL_MB// in MB
|
||||
IE_PAY_TYPE
|
||||
IE_AMOUNT
|
||||
IE_VALID_DAYS
|
||||
IE_EXPIRY_TIME
|
||||
IE_MSISDN_TRANS_OUT
|
||||
IE_MSISDN_TRANS_IN //value=31
|
||||
IE_BALANCE_AVAILABLE
|
||||
IE_RECHARGE_AMOUNT
|
||||
IE_RECHARGE_TYPE
|
||||
IE_RECHARGE_CARD_STATUS
|
||||
IE_RECHARGE_CARD_FACE_VALUE
|
||||
IE_RECHARGE_CARD_EXPIRED_TS
|
||||
IE_RECHARGE_CARD_UPDATED_TS
|
||||
IE_CUSTOMER_ID
|
||||
IE_ACCOUNT_ID
|
||||
IE_PRODUCT_ID//value=41
|
||||
IE_PLAN_ID
|
||||
IE_RENT_CHARGE
|
||||
IE_BIRTHDAY
|
||||
IE_SMS_CONTENT
|
||||
IE_SERVICE_TYPE
|
||||
IE_TARIIFF_PREFIX
|
||||
IE_TARIFF_UNIT
|
||||
IE_TARIFF_CHARGE
|
||||
IE_TARIFF_DISCOUNT
|
||||
IE_PLAN_VALUE//value=51
|
||||
IE_PLAN_USED_VALUE
|
||||
IE_BUNDLE_ID
|
||||
IE_CAUSE
|
||||
IE_SESS_FLAG
|
||||
IE_TIMESTAMP
|
||||
IE_CONSUME_VALUE
|
||||
IE_CALLED_NUMBER
|
||||
IE_UE_IP
|
||||
IE_GW_IP
|
||||
IE_CUG_ID
|
||||
IE_VAS_CUG_STATUS
|
||||
IE_SESS_UPDATE_TIME
|
||||
IE_PLAN_VALUE_ADD_THIS_TIME
|
||||
IE_USER_CLASS
|
||||
IE_MAX_NUM
|
||||
)
|
||||
|
||||
func handle_udp_msg_from_ocs(buf []byte, msglen int) {
|
||||
var rsp RestRsp
|
||||
|
||||
ret := Decode_udp_msg(buf, msglen, &rsp)
|
||||
if ret < 0 {
|
||||
l4g.RestLog.Errorf("Deocde UDP msg fail, msg[%v]", buf[:msglen])
|
||||
return
|
||||
}
|
||||
|
||||
switch rsp.MsgType {
|
||||
case REST_CRM_UPDATE_PLAN_INFO_REQ:
|
||||
go handleUpdatePlanUsage(&rsp)
|
||||
return
|
||||
case REST_CRM_DELETE_SUBS_RES:
|
||||
handleOcsDeleteSubsRsp(&rsp)
|
||||
case REST_CRM_CREATE_ACCT_RES:
|
||||
//handleOcsDeleteSubsRsp(&rsp)
|
||||
case REST_CRM_UPDATE_SUBS_REQ:
|
||||
go handleOcsUpdateSubsReq(&rsp)
|
||||
return
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("Recv UDP msg from OCS, msg_id[%d], src[%d], dst[%d]", rsp.MsgType, rsp.Src_id, rsp.Dst_id)
|
||||
if rsp.Dst_id >= MAX_PORT_NUM {
|
||||
return
|
||||
}
|
||||
port := GetPortInfo(rsp.Dst_id, rsp.Src_id)
|
||||
if port == nil {
|
||||
l4g.RestLog.Errorf("Get port by dst_id[%d] fail, msg id[%d]", rsp.Dst_id, rsp.MsgType)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Get port by dst_id[%d] from UDP rsp, msg id[%d]", rsp.Dst_id, rsp.MsgType)
|
||||
|
||||
go func() {
|
||||
port.Rsp <- rsp
|
||||
}()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func encode_udp_msg(req *RestReq, buf []byte) int {
|
||||
switch req.MsgType {
|
||||
case REST_SEND_AUTHCODE_REQ:
|
||||
case REST_QUERY_USERDATA_REQ:
|
||||
case REST_BUNDLE_SUBS_REQ:
|
||||
case REST_RECHARGE_REQ:
|
||||
case REST_TRANSFER_REQ:
|
||||
case REST_QUERY_BALANCE_REQ:
|
||||
case REST_CRM_CREATE_ACCT_REQ:
|
||||
case REST_CRM_UPDATE_SUBS_REQ:
|
||||
case REST_CRM_DELETE_SUBS_REQ:
|
||||
default:
|
||||
l4g.RestLog.Errorf("Encode rest unsupport msg id[%d]", req.MsgType)
|
||||
return 0
|
||||
}
|
||||
|
||||
var msglen int = 0
|
||||
buf[msglen] = req.MsgType
|
||||
msglen++
|
||||
buf[msglen] = IE_SRC_REF
|
||||
msglen++
|
||||
buf[msglen] = 0x02
|
||||
msglen++
|
||||
binary.BigEndian.PutUint16(buf[msglen:msglen+2], req.Src_id)
|
||||
msglen += 2
|
||||
buf[msglen] = IE_DST_REF
|
||||
msglen++
|
||||
buf[msglen] = 0x02
|
||||
msglen++
|
||||
binary.BigEndian.PutUint16(buf[msglen:msglen+2], req.Dst_id)
|
||||
msglen += 2
|
||||
|
||||
var vallen int = 0
|
||||
switch (req.MsgType) {
|
||||
case REST_SEND_AUTHCODE_REQ:
|
||||
l4g.RestLog.Debugf("Encode REST_SEND_AUTHCODE_REQ[%d], %#v", req.MsgType, req.AuthCodeReq)
|
||||
// IE_MSISDN
|
||||
buf[msglen] = IE_MSISDN
|
||||
msglen++
|
||||
vallen = len(req.AuthCodeReq.TelNumber)
|
||||
buf[msglen] = byte(vallen)
|
||||
msglen++
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.AuthCodeReq.TelNumber)))
|
||||
msglen += vallen
|
||||
|
||||
// IE_MSG_CONTENT
|
||||
buf[msglen] = IE_MSG_CONTENT
|
||||
msglen++
|
||||
vallen = len(req.AuthCodeReq.Content)
|
||||
binary.BigEndian.PutUint16(buf[msglen:msglen+2], uint16(vallen))
|
||||
msglen += 2
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.AuthCodeReq.Content)))
|
||||
msglen += vallen
|
||||
|
||||
case REST_QUERY_USERDATA_REQ:
|
||||
l4g.RestLog.Debugf("Encode REST_QUERY_USERDATA_REQ[%d], %#v", req.MsgType, req.QueryUserDataReq)
|
||||
// IE_MSISDN
|
||||
buf[msglen] = IE_MSISDN
|
||||
msglen++
|
||||
vallen = len(req.QueryUserDataReq.TelNumber)
|
||||
buf[msglen] = byte(vallen)
|
||||
msglen++
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.QueryUserDataReq.TelNumber)))
|
||||
msglen += vallen
|
||||
|
||||
case REST_BUNDLE_SUBS_REQ:
|
||||
l4g.RestLog.Debugf("Encode REST_BUNDLE_SUBS_REQ[%d], %#v", req.MsgType, req.BundleSubsReq)
|
||||
// IE_MSISDN
|
||||
buf[msglen] = IE_MSISDN
|
||||
msglen++
|
||||
vallen = len(req.BundleSubsReq.TelNumber)
|
||||
buf[msglen] = byte(vallen)
|
||||
msglen++
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.BundleSubsReq.TelNumber)))
|
||||
msglen += vallen
|
||||
|
||||
buf[msglen] = IE_PAY_TYPE
|
||||
msglen++
|
||||
buf[msglen] = 0x01
|
||||
msglen++
|
||||
pay_type, _ := strconv.Atoi(req.BundleSubsReq.PayType)
|
||||
buf[msglen] = uint8(pay_type)
|
||||
msglen += 0x01
|
||||
|
||||
buf[msglen] = IE_AMOUNT
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
amount, _ := strconv.Atoi(req.BundleSubsReq.ChargedAmount)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(amount))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_MO_VOICE_MIN
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
moVocMin, _ := strconv.Atoi(req.BundleSubsReq.MoVoiceMinute)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(moVocMin))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_MT_VOICE_MIN
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
mtVocMin, _ := strconv.Atoi(req.BundleSubsReq.MtVoiceMinute)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(mtVocMin))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_SMS_NUM
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
smsNum, _ := strconv.Atoi(req.BundleSubsReq.SmsVolume)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(smsNum))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_DATA_VOL_MB
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
dataVol, _ := strconv.Atoi(req.BundleSubsReq.DataVolume)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(dataVol))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_VALID_DAYS
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
validDays, _ := strconv.Atoi(req.BundleSubsReq.ValidPeriod)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(validDays))
|
||||
msglen += 0x04
|
||||
|
||||
case REST_RECHARGE_REQ:
|
||||
l4g.RestLog.Debugf("Encode REST_RECHARGE_REQ[%d], %#v", req.MsgType, req.RechargeReq)
|
||||
// IE_MSISDN
|
||||
buf[msglen] = IE_MSISDN
|
||||
msglen++
|
||||
vallen = len(req.RechargeReq.TelNumber)
|
||||
buf[msglen] = byte(vallen)
|
||||
msglen++
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.RechargeReq.TelNumber)))
|
||||
msglen += vallen
|
||||
|
||||
buf[msglen] = IE_AMOUNT
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
amount, _ := strconv.Atoi(req.RechargeReq.Amount)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(amount))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_RECHARGE_TYPE
|
||||
msglen++
|
||||
buf[msglen] = 0x01
|
||||
msglen++
|
||||
op_type, _ := strconv.Atoi(req.RechargeReq.OpType)
|
||||
buf[msglen] = uint8(op_type)
|
||||
msglen += 0x01
|
||||
|
||||
buf[msglen] = IE_VALID_DAYS
|
||||
msglen++
|
||||
buf[msglen] = 0x02
|
||||
msglen++
|
||||
valid_days, _ := strconv.Atoi(req.RechargeReq.ValidyDays)
|
||||
binary.BigEndian.PutUint16(buf[msglen:msglen+2], uint16(valid_days))
|
||||
msglen += 0x02
|
||||
|
||||
case REST_TRANSFER_REQ:
|
||||
l4g.RestLog.Debugf("Encode REST_TRANSFER_REQ[%d], %#v", req.MsgType, req.TransferReq)
|
||||
// IE_MSISDN_TRANS_OUT
|
||||
buf[msglen] = IE_MSISDN_TRANS_OUT
|
||||
msglen++
|
||||
vallen = len(req.TransferReq.TransferOut)
|
||||
buf[msglen] = byte(vallen)
|
||||
msglen++
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.TransferReq.TransferOut)))
|
||||
msglen += vallen
|
||||
|
||||
buf[msglen] = IE_MSISDN_TRANS_IN
|
||||
msglen++
|
||||
vallen = len(req.TransferReq.TransferIn)
|
||||
buf[msglen] = byte(vallen)
|
||||
msglen++
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.TransferReq.TransferIn)))
|
||||
msglen += vallen
|
||||
|
||||
buf[msglen] = IE_AMOUNT
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
amount, _ := strconv.Atoi(req.TransferReq.Amount)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(amount))
|
||||
msglen += 0x04
|
||||
|
||||
case REST_QUERY_BALANCE_REQ:
|
||||
l4g.RestLog.Debugf("Encode REST_QUERY_BALANCE_REQ[%d], %#v", req.MsgType, req.QueryBalanceReq)
|
||||
// IE_MSISDN
|
||||
buf[msglen] = IE_MSISDN
|
||||
msglen++
|
||||
vallen = len(req.QueryBalanceReq.TelNumber)
|
||||
buf[msglen] = byte(vallen)
|
||||
msglen++
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.QueryBalanceReq.TelNumber)))
|
||||
msglen += vallen
|
||||
|
||||
case REST_CRM_CREATE_ACCT_REQ:
|
||||
l4g.RestLog.Debugf("Encode REST_CRM_CREATE_ACCT_REQ[%d], %#v", req.MsgType, req.CreateAccountReq)
|
||||
// IE_MSISDN
|
||||
buf[msglen] = IE_MSISDN
|
||||
msglen++
|
||||
vallen = len(req.CreateAccountReq.ServiceNbr)
|
||||
buf[msglen] = byte(vallen)
|
||||
msglen++
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.CreateAccountReq.ServiceNbr)))
|
||||
msglen += vallen
|
||||
|
||||
buf[msglen] = IE_CUSTOMER_ID
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
custId, _ := strconv.Atoi(req.CreateAccountReq.CustId)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(custId))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_ACCOUNT_ID
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
acctId, _ := strconv.Atoi(req.CreateAccountReq.AccountId)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(acctId))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_PRODUCT_ID
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
prdId, _ := strconv.Atoi(req.CreateAccountReq.ProductInstId)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(prdId))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_PLAN_ID
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
planId, _ := strconv.Atoi(req.CreateAccountReq.PackageId)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(planId))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_BALANCE
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
balance, _ := strconv.Atoi(req.CreateAccountReq.Balance)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(balance))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_EXPIRY_TIME
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
expire_time, err := time.Parse("2006-01-02 15:04:05", req.CreateAccountReq.BalanceExpDate)
|
||||
if err != nil {
|
||||
l4g.RestLog.Errorf("Error CreateAccountReq BalanceExpDate[%s]", req.CreateAccountReq.BalanceExpDate)
|
||||
return -1
|
||||
}
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(expire_time.Unix()))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_RENT_CHARGE
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
rent_charge, _ := strconv.Atoi(req.CreateAccountReq.RentCharge)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(rent_charge))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_BIRTHDAY
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
birthday, err := time.Parse("2006-01-02", req.CreateAccountReq.Birthday)
|
||||
if err != nil {
|
||||
l4g.RestLog.Errorf("Error CreateAccountReq Birthday[%s]", req.CreateAccountReq.Birthday)
|
||||
return -1
|
||||
}
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(birthday.Unix()))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_CUG_ID
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
cugId, _ := strconv.Atoi(req.CreateAccountReq.CugId)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(cugId))
|
||||
msglen += 0x04
|
||||
|
||||
buf[msglen] = IE_USER_CLASS
|
||||
msglen++
|
||||
buf[msglen] = 0x01
|
||||
msglen++
|
||||
userClass, _ := strconv.Atoi(req.CreateAccountReq.UserClass)
|
||||
buf[msglen] = byte(userClass)
|
||||
msglen += 0x01
|
||||
|
||||
case REST_CRM_UPDATE_SUBS_REQ:
|
||||
l4g.RestLog.Debugf("Encode REST_CRM_UPDATE_SUBS_REQ[%d], %#v", req.MsgType, req.UpdateSubsReq)
|
||||
// IE_MSISDN
|
||||
buf[msglen] = IE_MSISDN
|
||||
msglen++
|
||||
vallen = len(req.UpdateSubsReq.TelNumber)
|
||||
buf[msglen] = byte(vallen)
|
||||
msglen++
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.UpdateSubsReq.TelNumber)))
|
||||
msglen += vallen
|
||||
|
||||
buf[msglen] = IE_ACCOUNT_ID
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
acctId, _ := strconv.Atoi(req.UpdateSubsReq.AccountId)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(acctId))
|
||||
msglen += 0x04
|
||||
|
||||
if (len(req.UpdateSubsReq.Status) > 0) {
|
||||
buf[msglen] = IE_STATUS
|
||||
msglen++
|
||||
buf[msglen] = 0x01
|
||||
msglen++
|
||||
status, _ := strconv.Atoi(req.UpdateSubsReq.Status)
|
||||
buf[msglen] = byte(status)
|
||||
msglen += 0x01
|
||||
}
|
||||
|
||||
if (len(req.UpdateSubsReq.Balance) > 0) {
|
||||
buf[msglen] = IE_BALANCE
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
balance, _ := strconv.Atoi(req.UpdateSubsReq.Balance)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(balance))
|
||||
msglen += 0x04
|
||||
}
|
||||
|
||||
if (len(req.UpdateSubsReq.BalanceExpDate) > 0) {
|
||||
buf[msglen] = IE_EXPIRY_TIME
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
expiryTime, err := time.Parse("2006-01-02 15:04:05", req.UpdateSubsReq.BalanceExpDate)
|
||||
if err != nil {
|
||||
l4g.RestLog.Errorf("Error UpdateSubsReq BalanceExpDate[%s]", req.UpdateSubsReq.BalanceExpDate)
|
||||
return -1
|
||||
}
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(expiryTime.Unix()))
|
||||
msglen += 0x04
|
||||
}
|
||||
|
||||
if (len(req.UpdateSubsReq.PackageId) > 0) {
|
||||
buf[msglen] = IE_PLAN_ID
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
planId, _ := strconv.Atoi(req.UpdateSubsReq.PackageId)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(planId))
|
||||
msglen += 0x04
|
||||
}
|
||||
|
||||
if (len(req.UpdateSubsReq.RentCharge) > 0) {
|
||||
buf[msglen] = IE_RENT_CHARGE
|
||||
msglen++
|
||||
buf[msglen] = 0x04
|
||||
msglen++
|
||||
rentCharge, _ := strconv.Atoi(req.UpdateSubsReq.RentCharge)
|
||||
binary.BigEndian.PutUint32(buf[msglen:msglen+4], uint32(rentCharge))
|
||||
msglen += 0x04
|
||||
}
|
||||
|
||||
if (len(req.UpdateSubsReq.VasCugStatus) > 0) {
|
||||
buf[msglen] = IE_VAS_CUG_STATUS
|
||||
msglen++
|
||||
buf[msglen] = 0x01
|
||||
msglen++
|
||||
vasCugStatus, _ := strconv.Atoi(req.UpdateSubsReq.VasCugStatus)
|
||||
buf[msglen] = byte(vasCugStatus)
|
||||
msglen += 0x01
|
||||
}
|
||||
|
||||
case REST_CRM_DELETE_SUBS_REQ:
|
||||
l4g.RestLog.Debugf("Encode REST_CRM_DELETE_SUBS_REQ[%d], %#v", req.MsgType, req.DeleteSubsReq)
|
||||
// IE_MSISDN
|
||||
buf[msglen] = IE_MSISDN
|
||||
msglen++
|
||||
vallen = len(req.DeleteSubsReq.TelNumber)
|
||||
buf[msglen] = byte(vallen)
|
||||
msglen++
|
||||
copy(buf[msglen:msglen+vallen], ([]byte(req.DeleteSubsReq.TelNumber)))
|
||||
msglen += vallen
|
||||
|
||||
buf[msglen] = IE_CAUSE
|
||||
msglen++
|
||||
buf[msglen] = 0x01
|
||||
msglen++
|
||||
buf[msglen] = 0
|
||||
msglen += 0x01
|
||||
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
|
||||
return msglen
|
||||
}
|
||||
|
||||
func SendOcsUdpReq(req *RestReq) {
|
||||
if ocsConn == nil {
|
||||
return
|
||||
}
|
||||
|
||||
l4g.RestLog.Debugf("Send UDP msg to OCS, msg_id[%d], src[%d], dst[%d]", req.MsgType, req.Src_id, req.Dst_id)
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
|
||||
msglen := encode_udp_msg(req, buf)
|
||||
|
||||
if msglen > 0 {
|
||||
ocsConn.Write([]byte(buf[:msglen]))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func SendNtfSms2Ocs(serviceNbr string, smsContent string) {
|
||||
var req RestReq
|
||||
req.MsgType = REST_SEND_AUTHCODE_REQ
|
||||
req.Src_id = 0xFFFF
|
||||
req.Dst_id = 0xFFFF
|
||||
req.AuthCodeReq.TelNumber = serviceNbr
|
||||
req.AuthCodeReq.Content = smsContent
|
||||
|
||||
SendOcsUdpReq(&req)
|
||||
}
|
||||
|
||||
func SendCrtAcct2Ocs(serviceNbr string, ai *MsgDef.ChgSyncMobile, cugId, userClass, rent int) {
|
||||
var req RestReq
|
||||
req.MsgType = REST_CRM_CREATE_ACCT_REQ
|
||||
req.Src_id = 0xFFFF
|
||||
req.Dst_id = 0xFFFF
|
||||
req.CreateAccountReq.ServiceNbr = serviceNbr
|
||||
req.CreateAccountReq.CustId = strconv.Itoa(ai.CustId)
|
||||
req.CreateAccountReq.AccountId = strconv.Itoa(ai.AcctId)
|
||||
req.CreateAccountReq.ProductInstId = strconv.Itoa(ai.PrdInstId)
|
||||
req.CreateAccountReq.PackageId = strconv.Itoa(ai.OfrId)
|
||||
req.CreateAccountReq.UserClass = strconv.Itoa(userClass)
|
||||
req.CreateAccountReq.CugId = strconv.Itoa(cugId)
|
||||
req.CreateAccountReq.Balance = strconv.Itoa(ai.Balance)
|
||||
|
||||
//t, _ := time.Parse("2006-01-02 15:04:05", ai.BirthDate)
|
||||
req.CreateAccountReq.Birthday = ai.BirthDate
|
||||
//t, _ := time.Parse("2006-01-02 15:04:05", ai.BalanceExpDate)
|
||||
req.CreateAccountReq.BalanceExpDate = ai.BalanceExpDate
|
||||
req.CreateAccountReq.RentCharge = strconv.Itoa(rent)
|
||||
|
||||
SendOcsUdpReq(&req)
|
||||
}
|
||||
|
||||
func CreateAcct2Ocs(serviceNbr string, ai *MsgDef.ChgSyncMobile, cugId, userClass, rent int, key string) {
|
||||
var req RestReq
|
||||
req.MsgType = REST_CRM_CREATE_ACCT_REQ
|
||||
req.Src_id = 0xFFFF
|
||||
req.Dst_id = 0xFFFF
|
||||
req.CreateAccountReq.ServiceNbr = serviceNbr
|
||||
req.CreateAccountReq.CustId = strconv.Itoa(ai.CustId)
|
||||
req.CreateAccountReq.AccountId = strconv.Itoa(ai.AcctId)
|
||||
req.CreateAccountReq.ProductInstId = strconv.Itoa(ai.PrdInstId)
|
||||
req.CreateAccountReq.PackageId = strconv.Itoa(ai.OfrId)
|
||||
req.CreateAccountReq.UserClass = strconv.Itoa(userClass)
|
||||
req.CreateAccountReq.CugId = strconv.Itoa(cugId)
|
||||
req.CreateAccountReq.Balance = strconv.Itoa(ai.Balance)
|
||||
|
||||
//t, _ := time.Parse("2006-01-02 15:04:05", ai.BirthDate)
|
||||
req.CreateAccountReq.Birthday = ai.BirthDate
|
||||
//t, _ := time.Parse("2006-01-02 15:04:05", ai.BalanceExpDate)
|
||||
req.CreateAccountReq.BalanceExpDate = ai.BalanceExpDate
|
||||
req.CreateAccountReq.RentCharge = strconv.Itoa(rent)
|
||||
|
||||
l4g.RestLog.Debugf("Got createAcct request: %v", req.CreateAccountReq)
|
||||
|
||||
// handle ==========================================
|
||||
port := AssignPort(&req)
|
||||
if port == nil {
|
||||
l4g.RestLog.Warnf("Assign port for createAcct request fail, serviceNbr[%s], key[%s]", serviceNbr, key)
|
||||
return
|
||||
}
|
||||
l4g.RestLog.Debugf("Assign port for createAcct request, serviceNbr, src[%d], dst[%d]", serviceNbr, req.Src_id, req.Dst_id)
|
||||
|
||||
ocsRsp := getOcsRsp(&req, port)
|
||||
if ocsRsp == nil {
|
||||
l4g.RestLog.Warnf("getOcsRsp timeout for createAcct request, serviceNbr[%s], key[%s]", serviceNbr, key)
|
||||
} else {
|
||||
l4g.RestLog.Infof("getOcsRsp succ for createAcct request, serviceNbr[%s], key[%s]", serviceNbr, key)
|
||||
rdb.RdsDelMsg2OcsKey(key)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
80
proxy/Readme.txt
Normal file
80
proxy/Readme.txt
Normal file
@@ -0,0 +1,80 @@
|
||||
Ubuntu18.04
|
||||
1.<2E><>װredis-server
|
||||
#apt-get install redis-server
|
||||
#vim /etc/redis/redis.conf
|
||||
1)<29><><EFBFBD><EFBFBD>master
|
||||
bind 192.168.7.90
|
||||
protected-mode no
|
||||
unixsocket /var/run/redis/redis-server.sock
|
||||
unixsocketperm 700
|
||||
2)<29><><EFBFBD><EFBFBD>slave
|
||||
bind 192.168.4.61
|
||||
protected-mode no
|
||||
unixsocket /var/run/redis/redis-server.sock
|
||||
unixsocketperm 700
|
||||
slaveof 192.168.7.90 6379
|
||||
|
||||
2.<2E><>װredis-sentinel
|
||||
#apt-get install redis-sentinel
|
||||
#vim /etc/redis/sentinel.conf
|
||||
1)sentinel 1
|
||||
bind 192.168.4.63
|
||||
protected-mode no
|
||||
sentinel monitor mymaster 192.168.4.63 6379 1
|
||||
2)sentinel 2
|
||||
bind 192.168.4.64
|
||||
protected-mode no
|
||||
sentinel monitor mymaster 192.168.4.63 6379 1
|
||||
|
||||
2.<2E><>װsctp
|
||||
sudo apt install lksctp-tools
|
||||
sudo apt install libsctp-dev
|
||||
Ubuntu20.04<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
|
||||
diam/diam_adaptor<6F><72>makefile<6C>ļ<EFBFBD><C4BC><EFBFBD>CFLAGS<47><53> -DOLD_SCTP_SOCKET_API
|
||||
|
||||
3.<2E><>װlibhiredis
|
||||
sudo apt install libhiredis-dev
|
||||
<EFBFBD><EFBFBD>װglib
|
||||
#sudo apt-get install libglib2.0-dev ## 20.04
|
||||
<EFBFBD><EFBFBD>װidn
|
||||
#sudo apt -y install idn
|
||||
<EFBFBD><EFBFBD>װgnutls
|
||||
#sudo apt-get install -y libgnutls-dev
|
||||
#apt-get install libghc-gnutls-dev ## 20.04
|
||||
#apt-get install libgcrypt20-dev
|
||||
#idna.h: No such file or directory<72><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#apt-get install libidn11-dev
|
||||
|
||||
4.<2E><>װmysqldump
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>mysqldump,Ȼ<><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>װ<EFBFBD><D7B0>Ҫ<EFBFBD>İ汾
|
||||
#apt install mysql-client-5.7 ## 18.04
|
||||
#apt install mysql-client libmysqlclient-dev ## mysql-server 20.04
|
||||
|
||||
5.<2E><>װcanal
|
||||
#dpkg -i canal-1.0.1.amd64.deb
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>canal<EFBFBD><EFBFBD>
|
||||
#vim /usr/local/etc/canal/config.yaml
|
||||
log:
|
||||
output: file
|
||||
level: info #log<6F><67><EFBFBD><EFBFBD>
|
||||
path: /var/log/proxy.log
|
||||
maxAge: 120
|
||||
rotationTime: 3
|
||||
mysqlDb:
|
||||
addr: 192.168.1.211:3306 #mysql DB,nfk mysql DB: 10.10.1.156:3306
|
||||
username: canal
|
||||
password: canal
|
||||
redisDb:
|
||||
netType: unix
|
||||
addr: /var/run/kvdb.sock
|
||||
# sentinelAddrs: # <20><>sentinel addr
|
||||
# - 192.168.7.90:26379
|
||||
# - 192.168.4.61:26379
|
||||
telnetServer:
|
||||
addr: 192.168.7.90:4100
|
||||
canalServer:
|
||||
reinit: true # <20><><EFBFBD><EFBFBD>ʱ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>ͬ<EFBFBD><CDAC>mysql<71><6C>redis
|
||||
standalone: false # <20>Ƿ<C7B7><F1B5A5BB><EFBFBD><EFBFBD>У<EFBFBD>trueʱ<65><CAB1><EFBFBD><EFBFBD>ʵʱͬ<CAB1><CDAC>mysql<71><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>falseʱֻ<CAB1>б<EFBFBD><D0B1><EFBFBD>redis<69><73>masterʱ<72><CAB1>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>canal<61><6C>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD>
|
||||
|
||||
6.<2E><>װocs
|
||||
|
||||
331
proxy/TelnetShellServer/shell_server.go
Normal file
331
proxy/TelnetShellServer/shell_server.go
Normal file
@@ -0,0 +1,331 @@
|
||||
package TelnetShellServer
|
||||
|
||||
import (
|
||||
"github.com/reiver/go-oi"
|
||||
"github.com/reiver/go-telnet"
|
||||
"github.com/reiver/go-telnet/telsh"
|
||||
"proxy/canal"
|
||||
"proxy/config"
|
||||
|
||||
"io"
|
||||
|
||||
sdb "proxy/Nmysql"
|
||||
rdb "proxy/Nredis"
|
||||
)
|
||||
|
||||
// Command not found!
|
||||
func notFoundHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
_, _ = oi.LongWriteString(stdout, "\rCommand not found!")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Syn DB
|
||||
func syncDbHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
//rdb.ClrTariffAndBundle()
|
||||
_ = sdb.LoadAcctTblFromMysql()
|
||||
_, _ = oi.LongWriteString(stdout, "\rSync DB, done!")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Syn msisdn
|
||||
func syncMsisdnHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
//rdb.ClrTariffAndBundle()
|
||||
_ = sdb.LoadOneAcctFromMysql(args[1])
|
||||
_, _ = oi.LongWriteString(stdout, "\rSync DB, done!")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func syncDbProducer(ctx telnet.Context, name string, args ...string) telsh.Handler{
|
||||
if len(args) > 0 {
|
||||
if args[0] == "db" {
|
||||
return telsh.PromoteHandlerFunc(syncDbHandler)
|
||||
} else if args[0] == "msisdn" && len(args)>=2 {
|
||||
return telsh.PromoteHandlerFunc(syncMsisdnHandler, args...)
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
}
|
||||
|
||||
// Clr DB
|
||||
func clearDbHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
rdb.ClrTariffAndBundle()
|
||||
_, _ = oi.LongWriteString(stdout, "\rClear DB Finish!")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clr Expired rr
|
||||
func clearRrHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
rdb.ClrExpRes()
|
||||
_, _ = oi.LongWriteString(stdout, "\rClear Expired RR Finish!")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func clearDbProducer(ctx telnet.Context, name string, args ...string) telsh.Handler{
|
||||
if len(args) > 0 {
|
||||
if args[0] == "db" {
|
||||
return telsh.PromoteHandlerFunc(clearDbHandler)
|
||||
} else if args[0] == "rr" {
|
||||
return telsh.PromoteHandlerFunc(clearRrHandler)
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
}
|
||||
|
||||
// get ofr
|
||||
func getOfrHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
rdb.RdbGetTariffByOfrId(args[1])
|
||||
_, _ = oi.LongWriteString(stdout, "\rGet ofr Finish!")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// get act
|
||||
func getActHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
//_, _ = oi.LongWriteString(stdout, "\n\rdebug2, len(args)="+fmt.Sprintf("%d:%v", len(args), args))
|
||||
rsp, _ := rdb.RdbGetAcctRecordByServiceNbr(args[1])
|
||||
_, _ = oi.LongWriteString(stdout, "\r"+rsp+"\n\rGet acct Finish!")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// get rat
|
||||
func getRatHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
rsp, _ := rdb.RdbGetRrByServiceNbrAndDomain(args[1])
|
||||
_, _ = oi.LongWriteString(stdout, "\r"+rsp+"\n\rGet Rr Finish!")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// get state
|
||||
func getStateHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
var state string
|
||||
/*if rdb.CheckIfRdbMaster() == true {
|
||||
state = "Redis: master; state: " + canal.CurState
|
||||
} else {*/
|
||||
state = "Redis: master; state: " + canal.CurState
|
||||
//}
|
||||
_, _ = oi.LongWriteString(stdout, "\r"+state)
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRecordProducer(ctx telnet.Context, name string, args ...string) telsh.Handler{
|
||||
if len(args) >= 2 {
|
||||
/*if args[0] == "ofr" {
|
||||
return telsh.PromoteHandlerFunc(getOfrHandler)
|
||||
} else */if args[0] == "act" {
|
||||
return telsh.PromoteHandlerFunc(getActHandler, args...)
|
||||
} else if args[0] == "rat" {
|
||||
return telsh.PromoteHandlerFunc(getRatHandler, args...)
|
||||
} else if args[0] == "state" {
|
||||
return telsh.PromoteHandlerFunc(getStateHandler, args...)
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
} else if len(args) == 1 {
|
||||
if args[0] == "state" {
|
||||
return telsh.PromoteHandlerFunc(getStateHandler)
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
}
|
||||
|
||||
// enable bundle notify
|
||||
func enableVoiceBundleNtfHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
config.SetBundleUsageNtf(1, true)
|
||||
_, _ = oi.LongWriteString(stdout, "\r"+"Comand OK")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func enableDataBundleNtfHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
config.SetBundleUsageNtf(2, true)
|
||||
_, _ = oi.LongWriteString(stdout, "\r"+"Comand OK")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func enableSmsBundleNtfHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
config.SetBundleUsageNtf(3, true)
|
||||
_, _ = oi.LongWriteString(stdout, "\r"+"Comand OK")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func enableParamProducer(ctx telnet.Context, name string, args ...string) telsh.Handler{
|
||||
if len(args) == 1 {
|
||||
if args[0] == "voc75ntf" {
|
||||
return telsh.PromoteHandlerFunc(enableVoiceBundleNtfHandler)
|
||||
} else if args[0] == "dat75ntf" {
|
||||
return telsh.PromoteHandlerFunc(enableDataBundleNtfHandler)
|
||||
} else if args[0] == "sms75ntf" {
|
||||
return telsh.PromoteHandlerFunc(enableSmsBundleNtfHandler)
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
}
|
||||
|
||||
// disable bundle notify
|
||||
func disableVoiceBundleNtfHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
config.SetBundleUsageNtf(1, false)
|
||||
_, _ = oi.LongWriteString(stdout, "\r"+"Comand OK")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func disableDataBundleNtfHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
config.SetBundleUsageNtf(2, false)
|
||||
_, _ = oi.LongWriteString(stdout, "\r"+"Comand OK")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func disableSmsBundleNtfHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
config.SetBundleUsageNtf(3, false)
|
||||
_, _ = oi.LongWriteString(stdout, "\r"+"Comand OK")
|
||||
_, _ = oi.LongWriteString(stdout, "\n\r")
|
||||
_, _ = oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func disableParamProducer(ctx telnet.Context, name string, args ...string) telsh.Handler{
|
||||
if len(args) == 1 {
|
||||
if args[0] == "voc75ntf" {
|
||||
return telsh.PromoteHandlerFunc(disableVoiceBundleNtfHandler)
|
||||
} else if args[0] == "dat75ntf" {
|
||||
return telsh.PromoteHandlerFunc(disableDataBundleNtfHandler)
|
||||
} else if args[0] == "sms75ntf" {
|
||||
return telsh.PromoteHandlerFunc(disableSmsBundleNtfHandler)
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
} else {
|
||||
return telsh.PromoteHandlerFunc(notFoundHandler)
|
||||
}
|
||||
}
|
||||
|
||||
/* version handler
|
||||
func versionHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
|
||||
oi.LongWriteString(stdout, "\rCurrent PCF version:\n\r")
|
||||
oi.LongWriteString(stdout, "\r" + n.GetPcfVersion())
|
||||
oi.LongWriteString(stdout, "\n\r")
|
||||
oi.LongWriteString(stdout, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func versionProducer(ctx telnet.Context, name string, args ...string) telsh.Handler{
|
||||
return telsh.PromoteHandlerFunc(versionHandler)
|
||||
}*/
|
||||
|
||||
func Server(addr string) {
|
||||
|
||||
shellHandler := telsh.NewShellHandler()
|
||||
|
||||
shellHandler.WelcomeMessage = `
|
||||
__ __ ______ _ _____ ____ __ __ ______
|
||||
\ \ / /| ____|| | / ____| / __ \ | \/ || ____|
|
||||
\ \ /\ / / | |__ | | | | | | | || \ / || |__
|
||||
\ \/ \/ / | __| | | | | | | | || |\/| || __|
|
||||
\ /\ / | |____ | |____ | |____ | |__| || | | || |____
|
||||
\/ \/ |______||______| \_____| \____/ |_| |_||______|
|
||||
|
||||
\033[2J\033[1;1HAVAILABLE COMMANDS\n" +
|
||||
========================================================================
|
||||
| Command | Remark |
|
||||
========================================================================
|
||||
| help | Help page. |
|
||||
| date | Current date. |
|
||||
| syn db | Syn Mysql DB to Redis DB. |
|
||||
| clr db | Clear Redis DB. |
|
||||
| clr rr | Clear Expired RR. |
|
||||
| get state | Get loading/init state. |
|
||||
| get act serviceNbr | Get acct info by service number. |
|
||||
| get rat num:domain | Get RR info by service number and domain. |
|
||||
| [en|dis]able voc75ntf| Enable[Disable] %75 usage of voice bundle. |
|
||||
| [en|dis]able dat75ntf| Enable[Disable] %75 usage of data bundle. |
|
||||
| [en|dis]able sms75ntf| Enable[Disable] %75 usage of sms bundle. |
|
||||
| q | Quit. |
|
||||
========================================================================
|
||||
`
|
||||
//shellHandler.Prompt = "pcf:~$"
|
||||
shellHandler.ExitCommandName = "q"
|
||||
shellHandler.ExitMessage = "Good bye...\r\n"
|
||||
|
||||
// Register the "sync db" command.
|
||||
commandName := "syn"
|
||||
commandProducer := telsh.ProducerFunc(syncDbProducer)
|
||||
_ = shellHandler.Register(commandName, commandProducer)
|
||||
|
||||
// Register the "clear db" command.
|
||||
commandName = "clr"
|
||||
commandProducer = clearDbProducer
|
||||
_ = shellHandler.Register(commandName, commandProducer)
|
||||
|
||||
commandName = "get"
|
||||
commandProducer = getRecordProducer
|
||||
_ = shellHandler.Register(commandName, commandProducer)
|
||||
|
||||
commandName = "enable"
|
||||
commandProducer = enableParamProducer
|
||||
_ = shellHandler.Register(commandName, commandProducer)
|
||||
|
||||
commandName = "disable"
|
||||
commandProducer = disableParamProducer
|
||||
_ = shellHandler.Register(commandName, commandProducer)
|
||||
|
||||
// Register the "version" command.
|
||||
//commandName = "version"
|
||||
//commandProducer = telsh.ProducerFunc(versionProducer)
|
||||
//shellHandler.Register(commandName, commandProducer)
|
||||
|
||||
if err := telnet.ListenAndServe(addr, shellHandler); nil != err {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
194
proxy/canal/canal.go
Normal file
194
proxy/canal/canal.go
Normal file
@@ -0,0 +1,194 @@
|
||||
package canal
|
||||
|
||||
import (
|
||||
"github.com/go-mysql-org/go-mysql/canal"
|
||||
"github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/go-mysql-org/go-mysql/replication"
|
||||
mdb "proxy/Nmysql"
|
||||
rds "proxy/Nredis"
|
||||
"proxy/config"
|
||||
|
||||
//"github.com/siddontang/go-log/log"
|
||||
//"strconv"
|
||||
|
||||
"proxy/logger"
|
||||
)
|
||||
|
||||
type MyEventHandler struct {
|
||||
canal.DummyEventHandler
|
||||
}
|
||||
|
||||
// 监听数据记录
|
||||
func (h *MyEventHandler) OnRow(e *canal.RowsEvent) error {
|
||||
logger.CanalLog.Infof("OnRow: %s.%s %s %v", e.Table.Schema, e.Table.Name, e.Action, e.Rows)
|
||||
|
||||
/*if !config.Config.CanalServer.Standalone && rds.CheckIfRdbMaster() == false {
|
||||
logger.CanalLog.Warnf("not stand alone, and change to Slave!")
|
||||
cnl.Close()
|
||||
return nil
|
||||
}*/
|
||||
c := ParseAndFilterBinLog(e)
|
||||
updateRedisTable(c)
|
||||
for columnIndex, curColumn := range e.Table.Columns {
|
||||
logger.CanalLog.Debugf("row info: %v %v %v", curColumn.Name, columnIndex, e.Rows[len(e.Rows)-1][columnIndex])
|
||||
}
|
||||
//cnl.Close()// if slave
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建,更改,重命名或者删除表时触发,通常会需要清除与表相关的数据,如缓存。 It will be called before OnDDL.
|
||||
func (h *MyEventHandler) OnTableChanged(header *replication.EventHeader, schema string, table string) error {
|
||||
logger.CanalLog.Infof("OnTableChanged: %s %s", schema, table)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 监听binlog日志的变化文件与记录的位置
|
||||
func (h *MyEventHandler) OnPosSynced(header *replication.EventHeader, pos mysql.Position, set mysql.GTIDSet, force bool) error {
|
||||
// if force == true, 立即同步位置
|
||||
rds.RdbSetBinLogPos(pos.Name, pos.Pos)
|
||||
logger.CanalLog.Infof("OnPosSynced: Name[%v] Pos[%v], force[%t]", pos.Name, pos.Pos, force)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 当产生新的binlog日志后触发(在达到内存的使用限制后(默认为1GB),会开启另一个文件,每个新文件的名称后都会有一个增量.)
|
||||
func (h *MyEventHandler) OnRotate(header *replication.EventHeader, r *replication.RotateEvent) error {
|
||||
// record := fmt.Sprintf("On Rotate: %v \n", &mysql.Position{Name: string(r.NextLogName), Pos: uint32(r.Position)})
|
||||
// binlog的记录位置,新binlog的文件名
|
||||
logger.CanalLog.Infof("On Rotate: Pos[%v] NextLogName[%v] \n", r.Position, r.NextLogName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create alter drop truncate(删除当前表再新建一个一模一样的表结构)
|
||||
func (h *MyEventHandler) OnDDL(header *replication.EventHeader, nextPos mysql.Position, queryEvent *replication.QueryEvent) error {
|
||||
// binlog日志的变化文件与记录的位置
|
||||
logger.CanalLog.Infof("OnDDL: Name[%v] Pos[%v]\n", nextPos.Name, nextPos.Pos)
|
||||
logger.CanalLog.Infof("%v\n %v\n %v\n %v\n %v\n",
|
||||
queryEvent.ExecutionTime, // 猜是执行时间,但测试显示0
|
||||
string(queryEvent.Schema), // 库名
|
||||
string(queryEvent.Query), // 变更的sql语句
|
||||
string(queryEvent.StatusVars[:]), //测试显示乱码
|
||||
queryEvent.SlaveProxyID) // 从库代理ID?
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *MyEventHandler) String() string {
|
||||
return "MyEventHandler"
|
||||
}
|
||||
|
||||
var cnl *canal.Canal
|
||||
func StartMyCanal(addr string, username string, password string) {
|
||||
cfg := canal.NewDefaultConfig()
|
||||
cfg.Addr = addr //"192.168.1.211:3306"
|
||||
cfg.User = username
|
||||
cfg.Password = password
|
||||
// We only care table canal_test in test db
|
||||
cfg.Dump.TableDB = "boss"
|
||||
cfg.Dump.Tables = []string{"tb_prd_ofr_detail_inst_551",
|
||||
"tb_bil_tariff", "tb_prd_ofr", "tb_bil_evt_pricing_strategy", "config_area",
|
||||
"tb_bil_pricing_area", "ratable_history", "tb_bil_holiday_rel", "tb_bil_holiday"}//, "tb_prd_prd_inst_551"}
|
||||
cfg.IncludeTableRegex = make([]string, 0, 1)
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_prd_prd_inst_551")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_prd_ofr_detail_inst_551")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_bil_tariff")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_prd_ofr")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_bil_evt_pricing_strategy")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.config_area")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_bil_pricing_area")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.ratable_history")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_bil_holiday_rel")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_bil_holiday")
|
||||
if config.Config.CronCfg.Enabled && config.Config.CronCfg.NtfSms != "" {
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_sms_info")
|
||||
}
|
||||
if config.Config.Rest.Enabled {
|
||||
cfg.Dump.Tables = append(cfg.Dump.Tables, "tb_sync_mobile")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_sync_mobile")
|
||||
}
|
||||
|
||||
c, err := canal.NewCanal(cfg)
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("NewCanal, err: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Register a handler to handle RowsEvent
|
||||
c.SetEventHandler(&MyEventHandler{})
|
||||
|
||||
var pos *mysql.Position
|
||||
if config.Config.CanalServer.Reinit {
|
||||
pos = QueryBinLogPos(c)
|
||||
if pos == nil {
|
||||
logger.CanalLog.Errorln("fail to get binlog position.")
|
||||
return
|
||||
}
|
||||
|
||||
logger.CanalLog.Infoln("start to sync mysql DB.")
|
||||
CurState = "loading"
|
||||
if config.Config.CanalServer.FlushBeforeInit {
|
||||
rds.ClrTariffAndBundle()
|
||||
}
|
||||
_ = mdb.LoadAcctTblFromMysql()
|
||||
_ = mdb.LoadAlertSmsFromMysql()
|
||||
//_ = mdb.LoadCreateAcctFromMysql()
|
||||
config.Config.CanalServer.Reinit = false
|
||||
config.SavePcfCfg()
|
||||
logger.CanalLog.Infoln("finish sync mysql DB...")
|
||||
CurState = "synchronize"
|
||||
} else {
|
||||
ret := rds.RdbGetBinLogPos()
|
||||
if ret == nil {
|
||||
logger.CanalLog.Warnln("fail to get redis binlog position, query current position from mysql.")
|
||||
pos = QueryBinLogPos(c)
|
||||
if pos == nil {
|
||||
logger.CanalLog.Errorln("fail to get binlog position.")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
pos = &mysql.Position{Name: ret.File, Pos: ret.Position}
|
||||
}
|
||||
}
|
||||
|
||||
// Start canal
|
||||
cnl = c
|
||||
logger.CanalLog.Infof("Go run")
|
||||
err = c.RunFrom(*pos)
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("RunFrom err: %v", err)
|
||||
} else {
|
||||
logger.CanalLog.Warnf("Canal exit!!!!!!")
|
||||
c.Close()
|
||||
}
|
||||
|
||||
/* 从头开始监听
|
||||
err = c.Run()
|
||||
if err != nil {
|
||||
logger.CanalLog.Infof("Run err: %v", err)
|
||||
}*/
|
||||
|
||||
// mysql-bin.000004, 1027
|
||||
// startPos := mysql.Position{Name: "mysql-bin.000004", Pos: 1027}
|
||||
// c.RunFrom(startPos)
|
||||
}
|
||||
|
||||
func QueryBinLogPos(c *canal.Canal) *mysql.Position {
|
||||
var pos mysql.Position
|
||||
ret, err := c.Execute("SHOW MASTER STATUS;")
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("SHOW MASTER STATUS err: %v", err)
|
||||
return nil
|
||||
}
|
||||
pos.Name, err = ret.Resultset.GetStringByName(0, "File")
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("Get binlog file name err: %v", err)
|
||||
return nil
|
||||
}
|
||||
posTmp, err := ret.Resultset.GetUintByName(0, "Position")
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("Get binlog position err: %v", err)
|
||||
return nil
|
||||
}
|
||||
pos.Pos = uint32(posTmp)
|
||||
logger.CanalLog.Infof("Current Position: %v", pos)
|
||||
rds.RdbSetBinLogPos(pos.Name, pos.Pos)
|
||||
return &pos
|
||||
}
|
||||
197
proxy/canal/canal.go.bak
Normal file
197
proxy/canal/canal.go.bak
Normal file
@@ -0,0 +1,197 @@
|
||||
package canal
|
||||
|
||||
import (
|
||||
"github.com/go-mysql-org/go-mysql/canal"
|
||||
"github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/go-mysql-org/go-mysql/replication"
|
||||
mdb "proxy/Nmysql"
|
||||
rds "proxy/Nredis"
|
||||
"proxy/config"
|
||||
|
||||
//"github.com/siddontang/go-log/log"
|
||||
//"strconv"
|
||||
|
||||
"proxy/logger"
|
||||
)
|
||||
|
||||
type MyEventHandler struct {
|
||||
canal.DummyEventHandler
|
||||
}
|
||||
|
||||
// 监听数据记录
|
||||
func (h *MyEventHandler) OnRow(e *canal.RowsEvent) error {
|
||||
|
||||
logger.CanalLog.Infof("OnRow: %s.%s %s %v", e.Table.Schema, e.Table.Name, e.Action, e.Rows)
|
||||
|
||||
/*if !config.Config.CanalServer.Standalone && rds.CheckIfRdbMaster() == false {
|
||||
logger.CanalLog.Warnf("not stand alone, and change to Slave!")
|
||||
cnl.Close()
|
||||
return nil
|
||||
}*/
|
||||
c := ParseAndFilterBinLog(e)
|
||||
updateRedisTable(c)
|
||||
for columnIndex, curColumn := range e.Table.Columns {
|
||||
logger.CanalLog.Debugf("row info: %v %v %v", curColumn.Name, columnIndex, e.Rows[len(e.Rows)-1][columnIndex])
|
||||
}
|
||||
//cnl.Close()// if slave
|
||||
return nil
|
||||
}
|
||||
|
||||
// 创建,更改,重命名或者删除表时触发,通常会需要清除与表相关的数据,如缓存。 It will be called before OnDDL.
|
||||
func (h *MyEventHandler) OnTableChanged(schema string, table string) error {
|
||||
//
|
||||
logger.CanalLog.Infof("OnTableChanged: %s %s", schema, table)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 监听binlog日志的变化文件与记录的位置
|
||||
func (h *MyEventHandler) OnPosSynced(pos mysql.Position, set mysql.GTIDSet, force bool) error {// update and save
|
||||
// if force == true, 立即同步位置
|
||||
rds.RdbSetBinLogPos(pos.Name, pos.Pos)
|
||||
logger.CanalLog.Infof("OnPosSynced: Name[%v] Pos[%v], force[%t]", pos.Name, pos.Pos, force)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 当产生新的binlog日志后触发(在达到内存的使用限制后(默认为1GB),会开启另一个文件,每个新文件的名称后都会有一个增量.)
|
||||
func (h *MyEventHandler) OnRotate(r *replication.RotateEvent) error {
|
||||
// record := fmt.Sprintf("On Rotate: %v \n", &mysql.Position{Name: string(r.NextLogName), Pos: uint32(r.Position)})
|
||||
// binlog的记录位置,新binlog的文件名
|
||||
logger.CanalLog.Infof("On Rotate: Pos[%v] NextLogName[%v] \n", r.Position, r.NextLogName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create alter drop truncate(删除当前表再新建一个一模一样的表结构)
|
||||
func (h *MyEventHandler) OnDDL(nextPos mysql.Position, queryEvent *replication.QueryEvent) error {
|
||||
// binlog日志的变化文件与记录的位置
|
||||
logger.CanalLog.Infof("OnDDL: Name[%v] Pos[%v]\n", nextPos.Name, nextPos.Pos)
|
||||
logger.CanalLog.Infof("%v\n %v\n %v\n %v\n %v\n",
|
||||
queryEvent.ExecutionTime,// 猜是执行时间,但测试显示0
|
||||
string(queryEvent.Schema),// 库名
|
||||
string(queryEvent.Query),// 变更的sql语句
|
||||
string(queryEvent.StatusVars[:]),//测试显示乱码
|
||||
queryEvent.SlaveProxyID)// 从库代理ID?
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *MyEventHandler) String() string {
|
||||
return "MyEventHandler"
|
||||
}
|
||||
|
||||
var cnl *canal.Canal
|
||||
func StartMyCanal(addr string, username string, password string) {
|
||||
cfg := canal.NewDefaultConfig()
|
||||
cfg.Addr = addr//"192.168.1.211:3306"
|
||||
cfg.User = username
|
||||
cfg.Password = password
|
||||
// We only care table canal_test in test db
|
||||
cfg.Dump.TableDB = "boss"
|
||||
cfg.Dump.Tables = []string{"tb_prd_ofr_detail_inst_551",
|
||||
"tb_bil_tariff", "tb_prd_ofr", "tb_bil_evt_pricing_strategy", "config_area",
|
||||
"tb_bil_pricing_area", "ratable_history", "tb_bil_holiday_rel", "tb_bil_holiday"}//, "tb_prd_prd_inst_551"}
|
||||
cfg.IncludeTableRegex = make([]string, 0, 1)
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_prd_prd_inst_551")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_prd_ofr_detail_inst_551")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_bil_tariff")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_prd_ofr")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_bil_evt_pricing_strategy")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.config_area")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_bil_pricing_area")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.ratable_history")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_bil_holiday_rel")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_bil_holiday")
|
||||
if config.Config.CronCfg.Enabled && config.Config.CronCfg.NtfSms != "" {
|
||||
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_sms_info")
|
||||
}
|
||||
if config.Config.Rest.Enabled {
|
||||
cfg.Dump.Tables = append(cfg.Dump.Tables, "tb_sync_mobile")
|
||||
cfg.IncludeTableRegex = append(cfg.IncludeTableRegex, "boss\\.tb_sync_mobile")
|
||||
}
|
||||
|
||||
c, err := canal.NewCanal(cfg)
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("NewCanal, err: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Register a handler to handle RowsEvent
|
||||
c.SetEventHandler(&MyEventHandler{})
|
||||
|
||||
var pos *mysql.Position
|
||||
if config.Config.CanalServer.Reinit {
|
||||
pos = QueryBinLogPos(c)
|
||||
if pos == nil {
|
||||
logger.CanalLog.Errorln("fail to get binlog position.")
|
||||
return
|
||||
}
|
||||
|
||||
logger.CanalLog.Infoln("start to sync mysql DB.")
|
||||
CurState = "loading"
|
||||
if config.Config.CanalServer.FlushBeforeInit {
|
||||
rds.ClrTariffAndBundle()
|
||||
}
|
||||
_ = mdb.LoadAcctTblFromMysql()
|
||||
_ = mdb.LoadAlertSmsFromMysql()
|
||||
//_ = mdb.LoadCreateAcctFromMysql()
|
||||
config.Config.CanalServer.Reinit = false
|
||||
config.SavePcfCfg()
|
||||
logger.CanalLog.Infoln("finish sync mysql DB...")
|
||||
CurState = "synchronize"
|
||||
} else {
|
||||
ret := rds.RdbGetBinLogPos()
|
||||
if ret == nil {
|
||||
logger.CanalLog.Warnln("fail to get redis binlog position, query current position from mysql.")
|
||||
pos = QueryBinLogPos(c)
|
||||
if pos == nil {
|
||||
logger.CanalLog.Errorln("fail to get binlog position.")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
pos = &mysql.Position{Name: ret.File, Pos: ret.Position}
|
||||
}
|
||||
}
|
||||
|
||||
// Start canal
|
||||
cnl = c
|
||||
logger.CanalLog.Infof("Go run")
|
||||
err = c.RunFrom(*pos)
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("RunFrom err: %v", err)
|
||||
} else {
|
||||
logger.CanalLog.Warnf("Canal exit!!!!!!")
|
||||
c.Close()
|
||||
}
|
||||
|
||||
/* 从头开始监听
|
||||
err = c.Run()
|
||||
if err != nil {
|
||||
logger.CanalLog.Infof("Run err: %v", err)
|
||||
}*/
|
||||
|
||||
// mysql-bin.000004, 1027
|
||||
// startPos := mysql.Position{Name: "mysql-bin.000004", Pos: 1027}
|
||||
// c.RunFrom(startPos)
|
||||
}
|
||||
|
||||
func QueryBinLogPos(c *canal.Canal) *mysql.Position {
|
||||
var pos mysql.Position
|
||||
ret, err := c.Execute("SHOW MASTER STATUS;")
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("SHOW MASTER STATUS err: %v", err)
|
||||
return nil
|
||||
}
|
||||
pos.Name, err = ret.Resultset.GetStringByName(0, "File")
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("Get binlog file name err: %v", err)
|
||||
return nil
|
||||
}
|
||||
posTmp, err := ret.Resultset.GetUintByName(0, "Position")
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("Get binlog position err: %v", err)
|
||||
return nil
|
||||
}
|
||||
pos.Pos = uint32(posTmp)
|
||||
logger.CanalLog.Infof("Current Position: %v", pos)
|
||||
rds.RdbSetBinLogPos(pos.Name, pos.Pos)
|
||||
return &pos
|
||||
}
|
||||
160
proxy/canal/client.go
Normal file
160
proxy/canal/client.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package canal
|
||||
|
||||
import (
|
||||
//"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/withlin/canal-go/client"
|
||||
pbe "github.com/withlin/canal-go/protocol/entry"
|
||||
"proxy/logger"
|
||||
)
|
||||
|
||||
func ConectCanalServer(ipaddr string) {
|
||||
|
||||
// 192.168.199.17 替换成你的canal server的地址
|
||||
// example 替换成-e canal.destinations=example 你自己定义的名字
|
||||
connector := client.NewSimpleCanalConnector(ipaddr, 11111, "", "", "example", 60000, 60*60*1000)
|
||||
err := connector.Connect()
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorln(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// https://github.com/alibaba/canal/wiki/AdminGuide
|
||||
//mysql 数据解析关注的表,Perl正则表达式.
|
||||
//
|
||||
//多个正则之间以逗号(,)分隔,转义符需要双斜杠(\\)
|
||||
//
|
||||
//常见例子:
|
||||
//
|
||||
// 1. 所有表:.* or .*\\..*
|
||||
// 2. canal schema下所有表: canal\\..*
|
||||
// 3. canal下的以canal打头的表:canal\\.canal.*
|
||||
// 4. canal schema下的一张表:canal\\.test1
|
||||
// 5. 多个规则组合使用:canal\\..*,mysql.test1,mysql.test2 (逗号分隔)
|
||||
|
||||
filter := "canal.instance.filter.regex=boss.tb_prd_prd_inst_551,boss.tb_prd_ofr_detail_inst_551,boss.tb_bil_tariff,boss.tb_prd_ofr,boss.tb_bil_evt_pricing_strategy,boss.config_area,boss.tb_bil_pricing_area,boss.ratable_history,boss.tb_bil_holiday_rel,boss.tb_bil_holiday"
|
||||
//err = connector.Subscribe(".*\\..*")
|
||||
err = connector.Subscribe(filter)
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorln(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var counter int= 0
|
||||
for {
|
||||
|
||||
message, err := connector.Get(100, nil, nil)
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorln(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
batchId := message.Id
|
||||
if batchId == -1 || len(message.Entries) <= 0 {
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
counter++
|
||||
if counter == 300 {
|
||||
logger.CanalLog.Infoln("===Idle===")
|
||||
counter = 0
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
printEntry(message.Entries)
|
||||
counter = 0
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func updateRedisTable(oneR *RecordChange) {
|
||||
var synType int
|
||||
if oneR.EventType == pbe.EventType_INSERT {
|
||||
synType = 1
|
||||
} else if oneR.EventType == pbe.EventType_DELETE {
|
||||
synType = 3
|
||||
} else {
|
||||
synType = 2
|
||||
}
|
||||
switch oneR.TableName {
|
||||
case TbAcctInfo:
|
||||
mdb.UpdateRedisAcctTable(synType, oneR.ChgAcctInfo.PrdInstId, oneR.ChgAcctInfo.ServiceNbr)
|
||||
case TbOfrDetail:
|
||||
mdb.UpdateRedisAcctTableOfr(synType, oneR.ChgOfrDetail.OfrDetailInstId)
|
||||
case TbTariff:
|
||||
mdb.UpdateRedisTariffTable(synType, oneR.ChgTariff.TariffId)
|
||||
case TbOfrInfo:
|
||||
mdb.UpdateRedisTariffTableByOfr(synType, oneR.ChgOfrInfo.OfrId)
|
||||
case TbPricingStrategy:
|
||||
mdb.UpdateRedisTariffTableByStrategy(synType, oneR.ChgPricingStrategy.EventPricingStrategyId)
|
||||
case TbConfigArea:// update prefix table, while update config_area table
|
||||
mdb.UpdateRedisPrefixTableByConfigArea(synType, oneR.ChgConfigArea.AreaId, oneR.ChgConfigArea.OldAreaCode, oneR.ChgConfigArea.NewAreaCode)
|
||||
case TbPricingArea:
|
||||
mdb.UpdateRedisPrefixTable(synType, oneR.ChgPricingArea.NewStrategyId, oneR.ChgPricingArea.NewAreaId)
|
||||
case TbRr:
|
||||
if rrId > 0 {
|
||||
mdb.UpdateRedisRrTable(synType, rrId, ratableVal, usedVal, beginTime, endTime)
|
||||
} else {
|
||||
if ofrId > 0 {// ofr: CALC_PRIORITY
|
||||
mdb.UpdateRdbRrOfrPriority(ofrId, tariffSeq)
|
||||
} else if strategyId > 0 {// strategy: EVENT_PRIORITY
|
||||
mdb.UpdateRdbRrStrategyPriority(strategyId, tariffSeq)
|
||||
}
|
||||
}
|
||||
case TbHoliday:
|
||||
mdb.UpdateRedisHolidayDisTableByTariffId(synType, TariffId, tariffSeq)
|
||||
case TbBilHoliday:
|
||||
mdb.UpdateRedisHolidayDisTableByHolidayId(synType, holidayId)
|
||||
default:
|
||||
}
|
||||
}*/
|
||||
|
||||
func printEntry(entrys []pbe.Entry) {
|
||||
|
||||
for _, entry := range entrys {
|
||||
if entry.GetEntryType() == pbe.EntryType_TRANSACTIONBEGIN || entry.GetEntryType() == pbe.EntryType_TRANSACTIONEND {
|
||||
continue
|
||||
}
|
||||
rowChange := new(pbe.RowChange)
|
||||
|
||||
err := proto.Unmarshal(entry.GetStoreValue(), rowChange)
|
||||
checkError(err)
|
||||
if rowChange != nil {
|
||||
eventType := rowChange.GetEventType()
|
||||
header := entry.GetHeader()
|
||||
logger.CanalLog.Infof("================> binlog[%s : %d],name[%s,%s], eventType: %s", header.GetLogfileName(), header.GetLogfileOffset(), header.GetSchemaName(), header.GetTableName(), header.GetEventType())
|
||||
|
||||
for _, rowData := range rowChange.GetRowDatas() {
|
||||
/*oneRecordChg := ParseAndFilterChange(eventType, header.GetTableName(), rowData)
|
||||
if oneRecordChg == nil {
|
||||
continue
|
||||
}
|
||||
updateRedisTable(oneRecordChg)*/
|
||||
if eventType == pbe.EventType_DELETE {
|
||||
printColumn(rowData.GetBeforeColumns())
|
||||
} else if eventType == pbe.EventType_INSERT {
|
||||
printColumn(rowData.GetAfterColumns())
|
||||
} else {
|
||||
logger.CanalLog.Infoln("-------> before")
|
||||
printColumn(rowData.GetBeforeColumns())
|
||||
logger.CanalLog.Infoln("-------> after")
|
||||
printColumn(rowData.GetAfterColumns())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printColumn(columns []*pbe.Column) {
|
||||
for _, col := range columns {
|
||||
logger.CanalLog.Infof("%s : %s update= %t", col.GetName(), col.GetValue(), col.GetUpdated())
|
||||
}
|
||||
}
|
||||
|
||||
func checkError(err error) {
|
||||
if err != nil {
|
||||
logger.CanalLog.Errorf("Fatal error: %s", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
28
proxy/canal/client_fsm.go
Normal file
28
proxy/canal/client_fsm.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package canal
|
||||
|
||||
import (
|
||||
"proxy/logger"
|
||||
"time"
|
||||
)
|
||||
|
||||
var CurState string= "init"
|
||||
func CanalFsm(addr string, username string, password string) {
|
||||
t := time.NewTimer(time.Second * 2)
|
||||
defer t.Stop()
|
||||
for {
|
||||
<-t.C// wait for next tick
|
||||
|
||||
//if config.Config.CanalServer.Standalone || (!config.Config.CanalServer.Standalone && rds.CheckIfRdbMaster() == true) {
|
||||
StartMyCanal(addr, username, password)
|
||||
logger.CanalLog.Warnf("Exit Canal!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
||||
t.Reset(time.Second * 3)
|
||||
/*} else {
|
||||
CurState = "idle"
|
||||
if config.Config.CanalServer.Reinit {
|
||||
config.Config.CanalServer.Reinit = false
|
||||
config.SavePcfCfg()
|
||||
}
|
||||
t.Reset(time.Second * 2)
|
||||
}*/
|
||||
}
|
||||
}
|
||||
1102
proxy/canal/msg.go
Normal file
1102
proxy/canal/msg.go
Normal file
File diff suppressed because it is too large
Load Diff
114
proxy/canal/sync_redis.go
Normal file
114
proxy/canal/sync_redis.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package canal
|
||||
|
||||
import (
|
||||
"github.com/go-mysql-org/go-mysql/canal"
|
||||
. "proxy/MsgDef"
|
||||
mdb "proxy/Nmysql"
|
||||
"proxy/logger"
|
||||
)
|
||||
|
||||
func updateRedisTable(c *RecordChange) {
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
var synType int
|
||||
if c.EventType == canal.InsertAction {
|
||||
synType = 1
|
||||
} else if c.EventType == canal.DeleteAction {
|
||||
synType = 3
|
||||
} else {
|
||||
synType = 2
|
||||
}
|
||||
switch c.TableName {
|
||||
case TbAcctInfo:
|
||||
for _, row := range c.ChgAcctInfo {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbAcctInfo, type[%d]", synType)
|
||||
mdb.UpdateRedisAcctTable(synType, &row)
|
||||
}
|
||||
case TbOfrDetail:
|
||||
for _, row := range c.ChgOfrDetail {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbOfrDetail, type[%d]", synType)
|
||||
mdb.UpdateRedisAcctTableOfr(synType, &row)
|
||||
}
|
||||
case TbTariff:
|
||||
for _, row := range c.ChgTariff {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbTariff, type[%d]", synType)
|
||||
mdb.UpdateRedisTariffTable(synType, &row)
|
||||
}
|
||||
case TbOfrInfo:
|
||||
for _, row := range c.ChgOfrInfo {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbOfrInfo, type[%d]", synType)
|
||||
mdb.UpdateRedisTariffTableByOfr(synType, &row)
|
||||
}
|
||||
case TbPricingStrategy:
|
||||
for _, row := range c.ChgPricingStrategy {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbPricingStrategy, type[%d]", synType)
|
||||
mdb.UpdateRedisTariffTableByStrategy(synType, &row)
|
||||
}
|
||||
case TbConfigArea:// update prefix table, while update config_area table
|
||||
for _, row := range c.ChgConfigArea {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbConfigArea, type[%d]", synType)
|
||||
if synType == 3 {
|
||||
mdb.UpdateRedisPrefixTableByConfigArea(synType, &row)
|
||||
} else {
|
||||
mdb.UpdateRedisPrefixTableByConfigArea(synType, &row)
|
||||
}
|
||||
}
|
||||
case TbPricingArea:
|
||||
for _, row := range c.ChgPricingArea {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbPricingArea, type[%d]", synType)
|
||||
if synType == 3 {
|
||||
mdb.UpdateRedisPrefixTable(synType, &row)
|
||||
} else {
|
||||
mdb.UpdateRedisPrefixTable(synType, &row)
|
||||
}
|
||||
}
|
||||
case TbRr:
|
||||
for _, row := range c.ChgRr {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbRr, type[%d]", synType)
|
||||
//if row.Id > 0 {
|
||||
if synType == 1 {
|
||||
mdb.UpdateRedisRrTable(synType, &row)
|
||||
} else if synType == 3 {
|
||||
mdb.UpdateRedisRrTable(synType, &row)
|
||||
} else {
|
||||
mdb.UpdateRedisRrTable(synType, &row)
|
||||
}
|
||||
|
||||
/*} else {
|
||||
if ofrId > 0 {// ofr: CALC_PRIORITY
|
||||
mdb.UpdateRdbRrOfrPriority(ofrId, tariffSeq)
|
||||
} else if strategyId > 0 {// strategy: EVENT_PRIORITY
|
||||
mdb.UpdateRdbRrStrategyPriority(strategyId, tariffSeq)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
case TbHoliday:
|
||||
for _, row := range c.ChgHoliday {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbHoliday, type[%d]", synType)
|
||||
if synType == 1 {
|
||||
mdb.UpdateRedisHolidayDisTableByTariffId(synType, &row)
|
||||
} else if synType == 3 {
|
||||
mdb.UpdateRedisHolidayDisTableByTariffId(synType, &row)
|
||||
} else {
|
||||
mdb.UpdateRedisHolidayDisTableByTariffId(synType, &row)
|
||||
}
|
||||
}
|
||||
case TbBilHoliday:
|
||||
for _, row := range c.ChgBilHoliday {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbBilHoliday, type[%d]", synType)
|
||||
mdb.UpdateRedisHolidayDisTableByHolidayId(synType, &row)
|
||||
}
|
||||
case TbSmsInfo:
|
||||
for _, row := range c.ChgAlertSms {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbSmsInfo, type[%d]", synType)
|
||||
mdb.UpdateRedisAlertSms(synType, &row)
|
||||
}
|
||||
case TbSyncMobile:
|
||||
/*for _, row := range c.ChgSyncMobile {
|
||||
logger.CanalLog.Infof("entry updateRedisTable: TbSyncMobile, type[%d]", synType)
|
||||
mdb.UpdateRedisSyncMobile(synType, &row)
|
||||
}*/
|
||||
default:
|
||||
}
|
||||
}
|
||||
38
proxy/conf/config.yaml
Normal file
38
proxy/conf/config.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
log:
|
||||
level: info
|
||||
mysqlDb:
|
||||
addr: 192.168.1.211:3306
|
||||
username: boss
|
||||
password: mysqlboss
|
||||
redisDb:
|
||||
netType: unix
|
||||
addr: /var/run/kvdb.sock
|
||||
##sentinelAddrs:
|
||||
## - 192.168.7.90:26379
|
||||
## - 192.168.4.61:26379
|
||||
telnetServer:
|
||||
addr: 192.168.7.90:4100
|
||||
rest:
|
||||
enabled: true
|
||||
httpAddr: 192.168.7.90:8080
|
||||
emsAddr: 192.168.7.92:4999
|
||||
locRzIp: 192.168.7.90
|
||||
locRzPort: 4900
|
||||
ocsRzIp: 192.168.7.90
|
||||
ocsRzPort: 4951
|
||||
enableNotification: true
|
||||
canalServer:
|
||||
enabled: true
|
||||
addr: 192.168.1.211:3306
|
||||
username: canal
|
||||
password: canal
|
||||
reinit: false
|
||||
flushBeforeInit: true
|
||||
standalone: true
|
||||
cronCfg:
|
||||
enabled: true
|
||||
clrExp: '0 20 5 1,11,21 * ?'
|
||||
ntfSms: '*/3 * * * * ?'
|
||||
provision:
|
||||
enabled: true
|
||||
ssEntryIdInCrm: 1049
|
||||
141
proxy/config/config.go
Normal file
141
proxy/config/config.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
//"os"
|
||||
//"io/ioutil"
|
||||
|
||||
//"encoding/json"
|
||||
l4g "proxy/logger"//"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type LogConf struct {
|
||||
//Output string `yaml:"output"`// file; console
|
||||
Level string `yaml:"level"`// debug; info; warn; error
|
||||
//Path string `yaml:"path"`
|
||||
//MaxAge int `yaml:"maxAge"`// per Hour
|
||||
//RotationTime int `yaml:"rotationTime"`// per Hour
|
||||
}
|
||||
|
||||
type MysqlDb struct {
|
||||
Addr string `yaml:"addr"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
}
|
||||
|
||||
type RedisDb struct {
|
||||
NetType string `yaml:"netType"`
|
||||
Addr string `yaml:"addr"`
|
||||
Password string `yaml:"password,omitempty"`
|
||||
SentinelAddrs []string `yaml:"sentinelAddrs,omitempty"`
|
||||
}
|
||||
|
||||
type TelnetServer struct {
|
||||
Addr string `yaml:"addr"`
|
||||
}
|
||||
|
||||
type RestConf struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
HttpAddr string `yaml:"httpAddr"`
|
||||
//EmsAddr string `yaml:"emsAddr,omitempty"`
|
||||
LocRzIp string `yaml:"locRzIp"`
|
||||
LocRzPort int `yaml:"locRzPort"`
|
||||
OcsRzIp string `yaml:"ocsRzIp"`
|
||||
OcsRzPort int `yaml:"ocsRzPort"`
|
||||
//EnableNotification bool `yaml:"enableNotification"`
|
||||
}
|
||||
|
||||
type CanalServer struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
|
||||
Addr string `yaml:"addr"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
|
||||
Reinit bool `yaml:"reinit"`
|
||||
FlushBeforeInit bool `yaml:"flushBeforeInit"`
|
||||
//Standalone bool `yaml:"standalone"`
|
||||
}
|
||||
|
||||
type CronCfg struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
ClrExp string `yaml:"clrExp,omitempty"`
|
||||
NtfSms string `yaml:"ntfSms,omitempty"`
|
||||
}
|
||||
|
||||
type ProvisionCfg struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Interval int `yaml:"interval"`
|
||||
ReadTimout int `yaml:"readTimout"`
|
||||
|
||||
EmsIp string `yaml:"emsIp"`
|
||||
EmsPort int `yaml:"emsPort"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
ConnectHss string `yaml:"connectHss,omitempty"`
|
||||
ConnectAuc string `yaml:"connectAuc,omitempty"`
|
||||
ConnectVms string `yaml:"connectVms,omitempty"`
|
||||
DisconnectHss string `yaml:"disconnectHss,omitempty"`
|
||||
DisconnectAuc string `yaml:"disconnectAuc,omitempty"`
|
||||
DisconnectVms string `yaml:"disconnectVms,omitempty"`
|
||||
|
||||
SsEntryIdInCrm int `yaml:"ssEntryIdInCrm,omitempty"`
|
||||
}
|
||||
|
||||
type BundleUsageNotify struct {
|
||||
//Enabled bool `yaml:"enabled"`
|
||||
Voice75Percent bool `yaml:"voice75Percent"`
|
||||
Data75Percent bool `yaml:"data75Percent"`
|
||||
Sms75Percent bool `yaml:"sms75Percent"`
|
||||
}
|
||||
|
||||
type DbConfig struct {
|
||||
Log *LogConf `yaml:"log,omitempty"`
|
||||
MysqlDb MysqlDb `yaml:"mysqlDb"`
|
||||
RedisDb RedisDb `yaml:"redisDb"`
|
||||
TelnetServer TelnetServer `yaml:"telnetServer"`
|
||||
Rest RestConf `json:"rest"`
|
||||
CanalServer CanalServer `yaml:"canalServer"`
|
||||
CronCfg CronCfg `yaml:"cronCfg"`
|
||||
Provision ProvisionCfg `yaml:"provision"`
|
||||
BundleUsageNotify BundleUsageNotify `yaml:"bundleUsageNotify"`
|
||||
}
|
||||
|
||||
var Config = DbConfig{ /*mysql: "192.168.1.151:3306", username: "root", password: "rootaa"*/}
|
||||
|
||||
func ReadConfig() error {
|
||||
if content, err := ioutil.ReadFile("/usr/local/restproxy/etc/config.yaml"); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if yamlErr := yaml.Unmarshal(content, &Config); yamlErr != nil {
|
||||
return yamlErr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SavePcfCfg() {
|
||||
if content, err := yaml.Marshal(&Config); err != nil {
|
||||
l4g.CfgLog.Errorf("Marshal failed error %s", err.Error())
|
||||
return
|
||||
} else if fileErr := ioutil.WriteFile("/usr/local/restproxy/etc/config.yaml", content, 0644); fileErr != nil {
|
||||
l4g.CfgLog.Errorf("WriteFile failed error %s", fileErr.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func SetBundleUsageNtf(serviceType int, bEnable bool) {
|
||||
switch serviceType {
|
||||
case 1:
|
||||
Config.BundleUsageNotify.Voice75Percent = bEnable
|
||||
case 2:
|
||||
Config.BundleUsageNotify.Data75Percent = bEnable
|
||||
case 3:
|
||||
Config.BundleUsageNotify.Sms75Percent = bEnable
|
||||
default:
|
||||
}
|
||||
SavePcfCfg()
|
||||
}
|
||||
|
||||
46
proxy/cron/cron.go
Normal file
46
proxy/cron/cron.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
rds "proxy/Nredis"
|
||||
rest "proxy/Nrestful"
|
||||
|
||||
"github.com/robfig/cron"
|
||||
l4g "proxy/logger"
|
||||
)
|
||||
|
||||
|
||||
func cronClrExpRes() {// 3.1(+[29]/30/31); 5.1/7.1/10.1/12.1(+31);
|
||||
rds.ClrExpRes()
|
||||
}
|
||||
|
||||
func cronNtfSms() {
|
||||
rest.RdbScanAlertSmsRecord()
|
||||
}
|
||||
|
||||
var c *cron.Cron = nil
|
||||
func CronStart(clrExp, ntfSms string) {
|
||||
c = cron.New()
|
||||
|
||||
// add a func to run in cron time
|
||||
//err := c.AddFunc("0 59 * * * ?", cron_rentThisMonth)
|
||||
var err error
|
||||
if clrExp != "" {
|
||||
err = c.AddFunc(clrExp, cronClrExpRes)
|
||||
if err != nil {
|
||||
l4g.AppLog.Error("Add cron clear expire rr and acct error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if ntfSms != "" {
|
||||
err = c.AddFunc(ntfSms, cronNtfSms)
|
||||
if err != nil {
|
||||
l4g.AppLog.Error("Add cron send notify sms error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
c.Start()
|
||||
}
|
||||
|
||||
func CronStop() {
|
||||
c.Stop()
|
||||
}
|
||||
176
proxy/go.sum
Normal file
176
proxy/go.sum
Normal file
@@ -0,0 +1,176 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ=
|
||||
github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-mysql-org/go-mysql v1.11.0 h1:Y0ooXu2UtbjsgpfjFBXZEvidEl1q8n0ESxej0zZ78Zc=
|
||||
github.com/go-mysql-org/go-mysql v1.11.0/go.mod h1:y/7aggbs+Io8rPVerIjTe1+nMgt8q5tBIxIc+qQnE0k=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
||||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-sql-driver/mysql v1.9.1 h1:FrjNGn/BsJQjVRuSa8CBrM5BWA9BWoXXat3KrtSb/iI=
|
||||
github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
|
||||
github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/ircop/tclient v0.0.0-20180908074649-f30684f28b0f h1:p7j1sjVHXwjJpr8fYjzInUGTmK9rYXgcQPiXjpawl/c=
|
||||
github.com/ircop/tclient v0.0.0-20180908074649-f30684f28b0f/go.mod h1:d111ZaRuwWWPIw3+gL48/SD8Pj9P6qBS5scMGWFt6/I=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
|
||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pingcap/errors v0.11.5-0.20240311024730-e056997136bb h1:3pSi4EDG6hg0orE1ndHkXvX6Qdq2cZn8gAPir8ymKZk=
|
||||
github.com/pingcap/errors v0.11.5-0.20240311024730-e056997136bb/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg=
|
||||
github.com/pingcap/failpoint v0.0.0-20240528011301-b51a646c7c86 h1:tdMsjOqUR7YXHoBitzdebTvOjs/swniBTOLy5XiMtuE=
|
||||
github.com/pingcap/failpoint v0.0.0-20240528011301-b51a646c7c86/go.mod h1:exzhVYca3WRtd6gclGNErRWb1qEgff3LYta0LvRmON4=
|
||||
github.com/pingcap/log v1.1.1-0.20230317032135-a0d097d16e22 h1:2SOzvGvE8beiC1Y4g9Onkvu6UmuBBOeWRGQEjJaT/JY=
|
||||
github.com/pingcap/log v1.1.1-0.20230317032135-a0d097d16e22/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4=
|
||||
github.com/pingcap/tidb/pkg/parser v0.0.0-20241118164214-4f047be191be h1:t5EkCmZpxLCig5GQA0AZG47aqsuL5GTsJeeUD+Qfies=
|
||||
github.com/pingcap/tidb/pkg/parser v0.0.0-20241118164214-4f047be191be/go.mod h1:Hju1TEWZvrctQKbztTRwXH7rd41Yq0Pgmq4PrEKcq7o=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/reiver/go-oi v1.0.0 h1:nvECWD7LF+vOs8leNGV/ww+F2iZKf3EYjYZ527turzM=
|
||||
github.com/reiver/go-oi v1.0.0/go.mod h1:RrDBct90BAhoDTxB1fenZwfykqeGvhI6LsNfStJoEkI=
|
||||
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e h1:quuzZLi72kkJjl+f5AQ93FMcadG19WkS7MO6TXFOSas=
|
||||
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e/go.mod h1:+5vNVvEWwEIx86DB9Ke/+a5wBI464eDRo3eF0LcfpWg=
|
||||
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
|
||||
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07 h1:oI+RNwuC9jF2g2lP0u0cVEEZrc/AYBCuFdvwrLWM/6Q=
|
||||
github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07/go.mod h1:yFdBgwXP24JziuRl2NMUahT7nGLNOKi1SIiFxMttVD4=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/withlin/canal-go v1.1.2 h1:ugAjPPXB1g6sePQLei/l7eaZ57ioJSo87/+z4++H2hY=
|
||||
github.com/withlin/canal-go v1.1.2/go.mod h1:VlapEcKekyXd7luA6QzflxbisrYzSLAjpRqzLcgr+zk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
75
proxy/logger/logger.go
Normal file
75
proxy/logger/logger.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
formatter "github.com/antonfisher/nested-logrus-formatter"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"proxy/util/logger_conf"
|
||||
"proxy/util/logger_util"
|
||||
)
|
||||
|
||||
var (
|
||||
log *logrus.Logger
|
||||
AppLog *logrus.Entry
|
||||
InitLog *logrus.Entry
|
||||
CfgLog *logrus.Entry
|
||||
MysqlLog *logrus.Entry
|
||||
/*Bdtpolicylog *logrus.Entry
|
||||
PolicyAuthorizationlog *logrus.Entry
|
||||
AMpolicylog *logrus.Entry
|
||||
SMpolicylog *logrus.Entry
|
||||
Consumerlog *logrus.Entry
|
||||
UtilLog *logrus.Entry
|
||||
CallbackLog *logrus.Entry
|
||||
OamLog *logrus.Entry
|
||||
CtxLog *logrus.Entry
|
||||
ConsumerLog *logrus.Entry
|
||||
GinLog *logrus.Entry
|
||||
NotifyEventLog *logrus.Entry*/
|
||||
ProvLog *logrus.Entry
|
||||
RedisLog *logrus.Entry
|
||||
RestLog *logrus.Entry
|
||||
CanalLog *logrus.Entry
|
||||
)
|
||||
|
||||
const (
|
||||
FieldRemoteAddr string = "remote_addr"
|
||||
)
|
||||
|
||||
func init() {
|
||||
log = logrus.New()
|
||||
log.SetReportCaller(true)
|
||||
|
||||
log.Formatter = &formatter.Formatter{
|
||||
TimestampFormat: time.RFC3339,
|
||||
TrimMessages: true,
|
||||
NoFieldsSpace: true,
|
||||
HideKeys: true,
|
||||
FieldsOrder: []string{"component", "category", FieldRemoteAddr},
|
||||
}
|
||||
|
||||
free5gcLogHook, err := logger_util.NewFileHook(logger_conf.Free5gcLogFile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0o666)
|
||||
if err == nil {
|
||||
log.Hooks.Add(free5gcLogHook)
|
||||
}
|
||||
|
||||
AppLog = log.WithFields(logrus.Fields{"component": "proxy", "category": "App"})
|
||||
InitLog = log.WithFields(logrus.Fields{"component": "proxy", "category": "Init"})
|
||||
CfgLog = log.WithFields(logrus.Fields{"component": "proxy", "category": "Cfg"})
|
||||
MysqlLog = log.WithFields(logrus.Fields{"component": "proxy", "category": "Mysql"})
|
||||
RedisLog = log.WithFields(logrus.Fields{"component": "proxy", "category": "Redis"})
|
||||
RestLog = log.WithFields(logrus.Fields{"component": "proxy", "category": "Rest"})
|
||||
CanalLog = log.WithFields(logrus.Fields{"component": "proxy", "category": "Canal"})
|
||||
ProvLog = log.WithFields(logrus.Fields{"component": "proxy", "category": "Prov"})
|
||||
}
|
||||
|
||||
func SetLogLevel(level logrus.Level) {
|
||||
log.SetLevel(level)
|
||||
}
|
||||
|
||||
func SetReportCaller(set bool) {
|
||||
log.SetReportCaller(set)
|
||||
}
|
||||
147
proxy/main.go
Normal file
147
proxy/main.go
Normal file
@@ -0,0 +1,147 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"proxy/canal"
|
||||
config2 "proxy/config"
|
||||
"proxy/cron"
|
||||
"proxy/provision"
|
||||
_ "time"
|
||||
|
||||
l4g "github.com/sirupsen/logrus"
|
||||
mysql "proxy/Nmysql"
|
||||
rdb "proxy/Nredis"
|
||||
rest "proxy/Nrestful"
|
||||
tn "proxy/TelnetShellServer"
|
||||
"proxy/logger"
|
||||
)
|
||||
/*
|
||||
func initLog(cfg *rest.LogConf) {
|
||||
if strings.Compare("file", cfg.Output) != 0 {
|
||||
l4g.SetOutput(os.Stdout)
|
||||
} else {
|
||||
path := cfg.Path// "/var/log/pcf.log"
|
||||
// log rotate
|
||||
//`WithLinkName` 为最新的日志建立软连接
|
||||
//`WithRotationTime` 设置日志分割的时间,隔多久分割一次
|
||||
//WithMaxAge 和 WithRotationCount二者只能设置一个
|
||||
// `WithMaxAge` 设置文件清理前的最长保存时间
|
||||
// `WithRotationCount` 设置文件清理前最多保存的个数
|
||||
//
|
||||
// add a new log every 3 hours, with 30 days at most.
|
||||
writer, _ := rotatelogs.New(
|
||||
path+".%Y-%m-%d-%H:%M",
|
||||
rotatelogs.WithLinkName(path),
|
||||
//rotatelogs.WithMaxAge(time.Duration(cfg.MaxAge)*time.Hour),
|
||||
//rotatelogs.WithRotationTime(time.Duration(cfg.RotationTime)*time.Hour),
|
||||
rotatelogs.WithRotationTime(3 * time.Hour),
|
||||
rotatelogs.WithRotationCount(uint(cfg.MaxAge)),
|
||||
)
|
||||
l4g.SetOutput(writer)
|
||||
}
|
||||
|
||||
if strings.Compare("debug", cfg.Level) == 0 {
|
||||
l4g.SetLevel(l4g.DebugLevel)
|
||||
} else if strings.Compare("info", cfg.Level) == 0 {
|
||||
l4g.SetLevel(l4g.InfoLevel)
|
||||
} else if strings.Compare("warn", cfg.Level) == 0 {
|
||||
l4g.SetLevel(l4g.WarnLevel)
|
||||
} else if strings.Compare("error", cfg.Level) == 0 {
|
||||
l4g.SetLevel(l4g.ErrorLevel)
|
||||
}
|
||||
//l4g.SetReportCaller(true)// useless
|
||||
//l4g.SetFormatter(&l4g.TextFormatter{})
|
||||
}*/
|
||||
|
||||
func check(err error, message string) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
initLog.Debugf("%s", message)
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
var initLog *l4g.Entry
|
||||
func init() {
|
||||
initLog = logger.InitLog
|
||||
}
|
||||
|
||||
func setLogLevel(level string) {
|
||||
if level != "" {
|
||||
level, err := l4g.ParseLevel(level)
|
||||
if err != nil {
|
||||
initLog.Warnf("Log level [%s] is invalid, set to [info] level",
|
||||
level)
|
||||
logger.SetLogLevel(l4g.InfoLevel)
|
||||
} else {
|
||||
initLog.Infof("Log level is set to [%s] level", level)
|
||||
logger.SetLogLevel(level)
|
||||
}
|
||||
} else {
|
||||
initLog.Infoln("Log level not set. Default set to [info] level")
|
||||
logger.SetLogLevel(l4g.InfoLevel)
|
||||
}
|
||||
|
||||
logger.SetReportCaller(true)
|
||||
}
|
||||
// *********************************************************************************
|
||||
|
||||
//var cfgFile = flag.String("c", "", "selfcare proxy configure file.")
|
||||
func main() {
|
||||
// check if billing already running
|
||||
/*var output, errout string
|
||||
err, output, errout := rest.Shellout("pidof billing")
|
||||
if err != nil {
|
||||
fmt.Printf("Get pid of billing fail, err: %v\n", err)
|
||||
} else {
|
||||
ss := strings.Fields(output)
|
||||
if len(ss) >= 2 {
|
||||
fmt.Printf("Process billing is already running, pids[%s], exit!\n", output)
|
||||
os.Exit(0)
|
||||
} else {
|
||||
fmt.Printf("First process of billing, stdout[%s], stderr[%s]!\n", output, errout)
|
||||
}
|
||||
}*/
|
||||
|
||||
//flag.Parse()
|
||||
|
||||
// read config
|
||||
config := &config2.Config
|
||||
err := config2.ReadConfig()
|
||||
if err != nil {
|
||||
initLog.Errorf("open config file error: %s", err)
|
||||
return
|
||||
} else {
|
||||
initLog.Infof("config file: %v", config)
|
||||
}
|
||||
|
||||
//initLog(&config.Log)
|
||||
setLogLevel(config.Log.Level)
|
||||
|
||||
initLog.Infof("selfcare proxy start...\r\nconfig:[%v]", config)
|
||||
|
||||
if config.Rest.Enabled {
|
||||
go rest.Connect_ocs(config.Rest.LocRzIp, config.Rest.OcsRzIp, config.Rest.LocRzPort, config.Rest.OcsRzPort)
|
||||
go rest.StartHttpServer(config.Rest.HttpAddr)
|
||||
}
|
||||
|
||||
go tn.Server(config.TelnetServer.Addr)
|
||||
|
||||
// temp disable======================
|
||||
go rdb.NewRedisClient(config.RedisDb.NetType, config.RedisDb.Addr, config.RedisDb.Password, config.RedisDb.SentinelAddrs)
|
||||
|
||||
go mysql.OpenMysql(config.MysqlDb.Username, config.MysqlDb.Password, config.MysqlDb.Addr)
|
||||
if config.CanalServer.Enabled {
|
||||
go canal.CanalFsm(config.CanalServer.Addr, config.CanalServer.Username, config.CanalServer.Password)
|
||||
}
|
||||
//
|
||||
|
||||
if config.CronCfg.Enabled && (config.CronCfg.ClrExp != "" || config.CronCfg.NtfSms != "") {
|
||||
cron.CronStart(config.CronCfg.ClrExp, config.CronCfg.NtfSms)
|
||||
defer cron.CronStop()
|
||||
}
|
||||
|
||||
go provision.ProvisionFsm()
|
||||
|
||||
select {}
|
||||
}
|
||||
242
proxy/provision/provision.go
Normal file
242
proxy/provision/provision.go
Normal file
@@ -0,0 +1,242 @@
|
||||
package provision
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ircop/tclient"
|
||||
"proxy/MsgDef"
|
||||
"proxy/Nmysql"
|
||||
rds "proxy/Nredis"
|
||||
l4g "proxy/logger"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
. "proxy/config"
|
||||
)
|
||||
|
||||
func ProvisionFsm() {
|
||||
prov := &Config.Provision
|
||||
if !prov.Enabled {
|
||||
return
|
||||
}
|
||||
|
||||
interval := prov.Interval
|
||||
if interval <= 0 {
|
||||
interval = 8
|
||||
}
|
||||
ticker := time.NewTicker(time.Second * time.Duration(interval))
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
<-ticker.C // wait for next tick
|
||||
|
||||
CheckNewProvision()
|
||||
ProvisionBySmcli()
|
||||
}
|
||||
}
|
||||
|
||||
func TelnetClient() {
|
||||
client := tclient.New(5, "manager", "manager", "")
|
||||
err := client.Open("192.168.13.117", 4999)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// you can omit this, or do auth stuff manually by calling `ReadUntil` with login/password prompts
|
||||
/*out, err := client.Login("manager", "manager")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf(out)*/
|
||||
|
||||
out, err := client.Cmd("connect hlr -srvip 192.168.13.118 -passwd 123456")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf(out)
|
||||
|
||||
out, err = client.Cmd("connect auc -srvip 192.168.13.118 -passwd 123456")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf(out)
|
||||
|
||||
out, err = client.Cmd("connect vms -srvip 192.168.4.221 -passwd 123456")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf(out)
|
||||
|
||||
// smcli cmd
|
||||
|
||||
out, err = client.Cmd("disconnect hlr")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf(out)
|
||||
|
||||
out, err = client.Cmd("disconnect vms")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf(out)
|
||||
|
||||
//out, err = client.ReadUntil()
|
||||
}
|
||||
|
||||
func CheckNewProvision() {
|
||||
si, _ := Nmysql.QuerySyncMobileInfo()
|
||||
if si != nil {
|
||||
for _, v := range si {
|
||||
if v.OperType == 2 {// replace imsi
|
||||
oi, _ := Nmysql.QueryOldImsiInfo(v.ServiceNbr)
|
||||
if oi != nil {
|
||||
Nmysql.AddSmcliCmd2Mysql(Nmysql.CT_DISCONNECT_ACCOUNT, Nmysql.NT_HSS, strconv.Itoa(oi.PrdInstId), "delete subscriber -imsi " + v.Imsi)
|
||||
Nmysql.AddSmcliCmd2Mysql(Nmysql.CT_DISCONNECT_ACCOUNT, Nmysql.NT_AUC, strconv.Itoa(oi.PrdInstId),"delete aucSubscriber -imsi " + v.Imsi)
|
||||
Nmysql.UpdateSyncMobileState(oi.PreId, 6)
|
||||
|
||||
crtCmd := fmt.Sprintf("create subscriber -imsi %s -msisdn %s -eps_user_tpl def_eps -impi %s@ims.mnc010.mcc505.3gppnetwork.org",
|
||||
v.Imsi, v.ServiceNbr, v.Imsi)
|
||||
Nmysql.AddSmcliCmd2Mysql(Nmysql.CT_CREATE_SUB, Nmysql.NT_HSS, strconv.Itoa(v.PrdInstId), crtCmd)
|
||||
|
||||
if v.Opc == "" {
|
||||
crtCmd = fmt.Sprintf("create aucSubscriber -imsi %s -ki %s",
|
||||
v.Imsi, v.Ki)
|
||||
} else {
|
||||
crtCmd = fmt.Sprintf("create aucSubscriber -imsi %s -ki %s -opc %s",
|
||||
v.Imsi, v.Ki, v.Opc)
|
||||
}
|
||||
Nmysql.AddSmcliCmd2Mysql(Nmysql.CT_CREATE_SUB, Nmysql.NT_AUC, strconv.Itoa(v.PrdInstId), crtCmd)
|
||||
Nmysql.UpdateSyncMobileState(v.PreId, 2)
|
||||
}
|
||||
} else {
|
||||
crtCmd := fmt.Sprintf("create subscriber -imsi %s -msisdn %s -eps_user_tpl def_eps -impi %s@ims.mnc010.mcc505.3gppnetwork.org",
|
||||
v.Imsi, v.ServiceNbr, v.Imsi)
|
||||
Nmysql.AddSmcliCmd2Mysql(Nmysql.CT_CREATE_SUB, Nmysql.NT_HSS, strconv.Itoa(v.PrdInstId), crtCmd)
|
||||
|
||||
if v.Opc == "" {
|
||||
crtCmd = fmt.Sprintf("create aucSubscriber -imsi %s -ki %s",
|
||||
v.Imsi, v.Ki)
|
||||
} else {
|
||||
crtCmd = fmt.Sprintf("create aucSubscriber -imsi %s -ki %s -opc %s",
|
||||
v.Imsi, v.Ki, v.Opc)
|
||||
}
|
||||
Nmysql.AddSmcliCmd2Mysql(Nmysql.CT_CREATE_SUB, Nmysql.NT_AUC, strconv.Itoa(v.PrdInstId), crtCmd)
|
||||
|
||||
if v.VmsFlag > 0 {
|
||||
crtCmd := fmt.Sprintf("create vmsSubscriber -msisdn %s",
|
||||
v.ServiceNbr)
|
||||
Nmysql.AddSmcliCmd2Mysql(Nmysql.CT_CREATE_SUB, Nmysql.NT_VMS, strconv.Itoa(v.PrdInstId), crtCmd)
|
||||
}
|
||||
|
||||
// add ocs success
|
||||
crtCmd = fmt.Sprintf("create ppsSubscriber -msisdn %s -PRE_ID %d",
|
||||
v.ServiceNbr, v.PreId)
|
||||
Nmysql.AddSmcliCmdSucc2Mysql(Nmysql.CT_CREATE_SUB, Nmysql.NT_OCS, strconv.Itoa(v.PrdInstId), crtCmd)
|
||||
var synMobile = MsgDef.ChgSyncMobile{PreId: v.PreId, OperType: v.OperType, State: 1, ServiceNbr: v.ServiceNbr, CustId: v.CustId, AcctId: v.AcctId,
|
||||
PrdInstId: v.PrdInstId, MobileType: v.MobileType, BirthDate: v.BirthDate, Balance: v.Balance, BalanceExpDate: v.BalanceExpDate, OfrId: v.OfrId,
|
||||
Imsi: v.Imsi, Ki: v.Ki, Opc: v.Opc, VmsFlag: v.VmsFlag, ExpDate: v.ExpDate, CugId: v.CugId}
|
||||
rds.RdbSetCreateAcctRecord(&synMobile)
|
||||
|
||||
Nmysql.UpdateSyncMobileState(v.PreId, 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ProvisionBySmcli() {
|
||||
si, _ := Nmysql.QuerySyncCnCmd()
|
||||
if si != nil {
|
||||
prv := &Config.Provision
|
||||
SmcliClient := tclient.New(prv.ReadTimout, prv.Username, prv.Password, "")
|
||||
err := SmcliClient.Open(prv.EmsIp, prv.EmsPort)
|
||||
if err != nil {
|
||||
l4g.ProvLog.Errorf("Smcli Client Open fail: %v", err)
|
||||
return
|
||||
}
|
||||
defer SmcliClient.Close()
|
||||
|
||||
var out string
|
||||
if prv.ConnectHss != "" {
|
||||
out, err = SmcliClient.Cmd(prv.ConnectHss)
|
||||
if err != nil {
|
||||
l4g.ProvLog.Errorf("Smcli Client Cmd[%s] err: %v", prv.ConnectHss, err)
|
||||
return
|
||||
}
|
||||
l4g.ProvLog.Infof("Smcli Client Cmd[%s] output: %s", prv.ConnectHss, out)
|
||||
if !strings.Contains(out, "success") {// 0000:Command successful
|
||||
l4g.ProvLog.Warnf("Smcli Cmd[%s] not success", prv.ConnectHss)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if prv.ConnectAuc != "" {
|
||||
out, err = SmcliClient.Cmd(prv.ConnectAuc)
|
||||
if err != nil {
|
||||
l4g.ProvLog.Errorf("Smcli Client Cmd[%s] err: %v", prv.ConnectAuc, err)
|
||||
goto ReleaseConnnet
|
||||
}
|
||||
l4g.ProvLog.Infof("Smcli Client Cmd[%s] output: %s", prv.ConnectAuc, out)
|
||||
if !strings.Contains(out, "success") {// 0000:Command successful
|
||||
l4g.ProvLog.Warnf("Smcli Cmd[%s] not success", prv.ConnectAuc)
|
||||
goto ReleaseConnnet
|
||||
}
|
||||
}
|
||||
|
||||
if prv.ConnectVms != "" {
|
||||
out, err = SmcliClient.Cmd(prv.ConnectVms)
|
||||
if err != nil {
|
||||
l4g.ProvLog.Errorf("Smcli Client Cmd[%s] err: %v", prv.ConnectVms, err)
|
||||
goto ReleaseConnHss
|
||||
}
|
||||
l4g.ProvLog.Infof("Smcli Client Cmd[%s] output: %s", prv.ConnectVms, out)
|
||||
if !strings.Contains(out, "success") {// 0000:Command successful
|
||||
l4g.ProvLog.Warnf("Smcli Cmd[%s] not success", prv.ConnectVms)
|
||||
goto ReleaseConnHss
|
||||
}
|
||||
}
|
||||
|
||||
// smcli cmd
|
||||
for _, v := range si {
|
||||
if v.Command != "" {
|
||||
out, err = SmcliClient.Cmd(v.Command)
|
||||
if err != nil {
|
||||
l4g.ProvLog.Errorf("Smcli Client Cmd[%s] err: %v", v.Command, err)
|
||||
Nmysql.UpdateCnCmdResult(v.Id, 2, 2, "timeout")
|
||||
goto ReleaseConnnet
|
||||
}
|
||||
l4g.ProvLog.Infof("Smcli Client Cmd[%s] output: %s", v.Command, out)
|
||||
if !strings.Contains(out, "success") {// 0000:Command successful
|
||||
l4g.ProvLog.Warnf("Smcli Cmd[%s] not success", v.Command)
|
||||
Nmysql.UpdateCnCmdResult(v.Id, 2, 2, out)
|
||||
goto ReleaseConnnet
|
||||
} else {
|
||||
l4g.ProvLog.Infof("Smcli Cmd[%s] success", v.Command)
|
||||
Nmysql.UpdateCnCmdResult(v.Id, 2, 1, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseConnnet:
|
||||
if prv.DisconnectVms != "" {
|
||||
out, err = SmcliClient.Cmd(prv.DisconnectVms)
|
||||
if err != nil {
|
||||
l4g.ProvLog.Errorf("Smcli Client Cmd[%s] fail: %v", prv.DisconnectVms, err)
|
||||
return
|
||||
}
|
||||
l4g.ProvLog.Infof("Smcli Client Cmd[%s] output: %s", prv.DisconnectVms, out)
|
||||
}
|
||||
|
||||
ReleaseConnHss:
|
||||
if prv.DisconnectHss != "" {
|
||||
out, err = SmcliClient.Cmd(prv.DisconnectHss)
|
||||
if err != nil {
|
||||
l4g.ProvLog.Errorf("Smcli Client Cmd[%s] fail: %v", prv.DisconnectHss, err)
|
||||
return
|
||||
}
|
||||
l4g.ProvLog.Infof("Smcli Client Cmd[%s] output: %s", prv.DisconnectHss, out)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
237
proxy/redis/client.go
Normal file
237
proxy/redis/client.go
Normal file
@@ -0,0 +1,237 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
rds "github.com/go-redis/redis/v8"
|
||||
l4g "proxy/logger" //"github.com/sirupsen/logrus"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
//"strconv"
|
||||
//. "../MsgDef"
|
||||
)
|
||||
|
||||
var ctx = context.Background()
|
||||
|
||||
var rdb *rds.Client
|
||||
func NewRedisClient(netType, addr string) {
|
||||
rdb = rds.NewClient(&rds.Options{
|
||||
Network: netType,// The network type, either tcp or unix. Default is tcp.
|
||||
Addr: addr,// can be: /var/run/redis/redis-server.sock???
|
||||
Password: "", // no password set
|
||||
DB: 0, // use default DB
|
||||
PoolSize: 5,
|
||||
})
|
||||
|
||||
pong, err := rdb.Ping(ctx).Result()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("%v, err: %v", pong, err)// Output: PONG <nil>
|
||||
} else {
|
||||
l4g.RedisLog.Debugf("%v", pong)// Output: PONG <nil>
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type PcfUsrData struct {
|
||||
Msisdn string `redis:"msisdn"`
|
||||
PccRules string `redis:"pcc_rules"`
|
||||
}
|
||||
|
||||
func MmlAddPcfUser(params []string) (rsp string) {
|
||||
var imsi, msisdn, pccRules string
|
||||
|
||||
for _, val := range params {
|
||||
if strings.HasPrefix(val, "imsi=") {
|
||||
imsi = val[len("imsi="):]
|
||||
} else if strings.HasPrefix(val, "msisdn=") {
|
||||
msisdn = val[len("msisdn="):]
|
||||
} else if strings.HasPrefix(val, "pcc_rules=") {
|
||||
pccRules = val[len("pcc_rules="):]
|
||||
}
|
||||
}
|
||||
|
||||
err := rdb.HMSet(ctx, "pcfUser:"+imsi, "msisdn", msisdn, "pcc_rules", pccRules).Err()
|
||||
if err != nil {
|
||||
rsp = fmt.Sprintf("HMSet pcfUser:%s, err: %v", imsi, err)
|
||||
}
|
||||
|
||||
return rsp
|
||||
}
|
||||
|
||||
func MmlModPcfUser(params []string) (rsp string) {
|
||||
var imsi, msisdn, pccRules string
|
||||
|
||||
for _, val := range params {
|
||||
if strings.HasPrefix(val, "imsi=") {
|
||||
imsi = val[len("imsi="):]
|
||||
} else if strings.HasPrefix(val, "msisdn=") {
|
||||
msisdn = val[len("msisdn="):]
|
||||
} else if strings.HasPrefix(val, "pcc_rules=") {
|
||||
pccRules = val[len("pcc_rules="):]
|
||||
}
|
||||
}
|
||||
|
||||
err := rdb.HMSet(ctx, "pcfUser:"+imsi, "msisdn", msisdn, "pcc_rules", pccRules).Err()
|
||||
if err != nil {
|
||||
rsp = fmt.Sprintf("HMSet pcfUser:%s, err: %v", imsi, err)
|
||||
}
|
||||
|
||||
return rsp
|
||||
}
|
||||
|
||||
func MmlDelPcfUser(params []string) (rsp string) {
|
||||
var imsi string
|
||||
for _, val := range params {
|
||||
if strings.HasPrefix(val, "imsi=") {
|
||||
imsi = val[len("imsi="):]
|
||||
}
|
||||
}
|
||||
|
||||
err := rdb.Del(ctx, "pcfUser:"+imsi).Err()
|
||||
if err != nil {
|
||||
rsp = fmt.Sprintf("Del pcfUser:%s, err: %v", imsi, err)
|
||||
}
|
||||
|
||||
return rsp
|
||||
}
|
||||
|
||||
func MmlDspPcfUser(params []string) (rsp string) {
|
||||
var imsi string
|
||||
|
||||
for _, val := range params {
|
||||
if strings.HasPrefix(val, "imsi=") {
|
||||
imsi = val[len("imsi="):]
|
||||
}
|
||||
}
|
||||
|
||||
res := rdb.HGetAll(ctx, "pcfUser:"+imsi)
|
||||
err := res.Err()
|
||||
if err != nil {
|
||||
rsp = fmt.Sprintf("HGetAll pcfUser:%s, err: %v", imsi, err)
|
||||
return rsp
|
||||
}
|
||||
|
||||
// Scan the results into the struct.
|
||||
var usrData PcfUsrData
|
||||
if err = res.Scan(&usrData); err != nil {
|
||||
rsp = fmt.Sprintf("HGetAll Scan pcfUser:%s, err: %v", imsi, err)
|
||||
} else {
|
||||
rsp = fmt.Sprintf("pcfUser:imsi=%s, [%v]", imsi, usrData)
|
||||
}
|
||||
|
||||
return rsp
|
||||
}
|
||||
|
||||
func GetPcfUsrDataByImsi(imsi string) (usrData PcfUsrData, err error) {
|
||||
res := rdb.HGetAll(ctx, "pcfUser:"+imsi)
|
||||
err = res.Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll pcfUser:%s, err: %v", imsi, err)
|
||||
return
|
||||
}
|
||||
|
||||
// Scan the results into the struct.
|
||||
if err = res.Scan(&usrData); err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll Scan pcfUser:%s, err: %v", imsi, err)
|
||||
return
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func GetPcfUsrPccRulesByImsi(imsi string) (pccRules string, err error) {
|
||||
res := rdb.HGetAll(ctx, "pcfUser:"+imsi)
|
||||
err = res.Err()
|
||||
if err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll pcfUser:%s, err: %v", imsi, err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Scan the results into the struct.
|
||||
var usrData PcfUsrData
|
||||
if err = res.Scan(&usrData); err != nil {
|
||||
l4g.RedisLog.Errorf("HGetAll Scan pcfUser:%s, err: %v", imsi, err)
|
||||
return "", err
|
||||
} else {
|
||||
return usrData.PccRules, nil
|
||||
}
|
||||
}
|
||||
|
||||
func MmlBadPcfUser(params []string) (rsp string) {
|
||||
var pccRules string
|
||||
var startImsi, startMsisdn int64
|
||||
var subNum int64= 0
|
||||
|
||||
for _, val := range params {
|
||||
if strings.HasPrefix(val, "start_imsi=") {
|
||||
startImsi, _ = strconv.ParseInt(val[len("start_imsi="):], 10, 64)
|
||||
} else if strings.HasPrefix(val, "start_msisdn=") {
|
||||
startMsisdn, _ = strconv.ParseInt(val[len("start_msisdn="):], 10, 64)
|
||||
} else if strings.HasPrefix(val, "pcc_rules=") {
|
||||
pccRules = val[len("pcc_rules="):]
|
||||
} else if strings.HasPrefix(val, "sub_num=") {
|
||||
subNum, _ = strconv.ParseInt(val[len("sub_num="):], 10, 64)
|
||||
}
|
||||
}
|
||||
|
||||
var i int64= 0
|
||||
for i=0; i<subNum; i++ {
|
||||
var imsi, msisdn string
|
||||
imsi = fmt.Sprintf("imsi=%d", startImsi+i)
|
||||
msisdn = fmt.Sprintf("msisdn=%d", startMsisdn+i)
|
||||
mmlParams := []string{imsi, msisdn, pccRules}
|
||||
MmlAddPcfUser(mmlParams)
|
||||
}
|
||||
|
||||
rsp = "Command OK"
|
||||
return
|
||||
}
|
||||
|
||||
func MmlBdePcfUser(params []string) (rsp string) {
|
||||
var startImsi int64= 0
|
||||
var subNum int64= 0
|
||||
|
||||
for _, val := range params {
|
||||
if strings.HasPrefix(val, "imsi=") {
|
||||
startImsi, _ = strconv.ParseInt(val[len("start_imsi="):], 10, 64)
|
||||
} else if strings.HasPrefix(val, "sub_num=") {
|
||||
subNum, _ = strconv.ParseInt(val[len("sub_num="):], 10, 64)
|
||||
}
|
||||
}
|
||||
|
||||
var i int64= 0
|
||||
for i=0; i<subNum; i++ {
|
||||
var imsi string
|
||||
imsi = fmt.Sprintf("imsi=%d", startImsi+i)
|
||||
mmlParams := []string{imsi}
|
||||
MmlDelPcfUser(mmlParams)
|
||||
}
|
||||
|
||||
rsp = "Command OK"
|
||||
return
|
||||
}
|
||||
|
||||
func HandleMmlCmdRequest(cmd []string) string {
|
||||
paramStr := strings.TrimPrefix(cmd[1], "pcfuser:")
|
||||
params := strings.Split(paramStr, ",")
|
||||
|
||||
switch cmd[0] {
|
||||
case "add":
|
||||
return MmlAddPcfUser(params)
|
||||
case "mod":
|
||||
return MmlModPcfUser(params)
|
||||
case "del":
|
||||
return MmlDelPcfUser(params)
|
||||
case "dsp":
|
||||
return MmlDspPcfUser(params)
|
||||
case "bad":
|
||||
return MmlBadPcfUser(params)
|
||||
case "bde":
|
||||
return MmlBdePcfUser(params)
|
||||
default:
|
||||
return "Unkown MML CMD"
|
||||
}
|
||||
}
|
||||
|
||||
14
proxy/util/logger_conf/.gitignore
vendored
Normal file
14
proxy/util/logger_conf/.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Toolchain
|
||||
# Goland project folder
|
||||
.idea/
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
# emacs/vim
|
||||
GPATH
|
||||
GRTAGS
|
||||
GTAGS
|
||||
TAGS
|
||||
tags
|
||||
cscope.*
|
||||
# mac
|
||||
.DS_Store
|
||||
289
proxy/util/logger_conf/.golangci.yml
Normal file
289
proxy/util/logger_conf/.golangci.yml
Normal file
@@ -0,0 +1,289 @@
|
||||
# This file contains all available configuration options
|
||||
# with their default values.
|
||||
# options for analysis running
|
||||
run:
|
||||
# default concurrency is a available CPU number
|
||||
concurrency: 4
|
||||
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||
timeout: 1m
|
||||
# exit code when at least one issue was found, default is 1
|
||||
issues-exit-code: 1
|
||||
# include test files or not, default is true
|
||||
tests: false
|
||||
# list of build tags, all linters use it. Default is empty list.
|
||||
build-tags:
|
||||
# which dirs to skip: issues from them won't be reported;
|
||||
# can use regexp here: generated.*, regexp is applied on full path;
|
||||
# default value is empty list, but default dirs are skipped independently
|
||||
# from this option's value (see skip-dirs-use-default).
|
||||
# "/" will be replaced by current OS file path separator to properly work
|
||||
# on Windows.
|
||||
skip-dirs:
|
||||
# default is true. Enables skipping of directories:
|
||||
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
||||
skip-dirs-use-default: true
|
||||
# which files to skip: they will be analyzed, but issues from them
|
||||
# won't be reported. Default value is empty list, but there is
|
||||
# no need to include all autogenerated files, we confidently recognize
|
||||
# autogenerated files. If it's not please let us know.
|
||||
# "/" will be replaced by current OS file path separator to properly work
|
||||
# on Windows.
|
||||
skip-files:
|
||||
- "api_.*\\.go$"
|
||||
- "model_.*\\.go$"
|
||||
- "routers.go"
|
||||
- "client.go"
|
||||
- "configuration.go"
|
||||
- "nas.go"
|
||||
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
|
||||
# If invoked with -mod=readonly, the go command is disallowed from the implicit
|
||||
# automatic updating of go.mod described above. Instead, it fails when any changes
|
||||
# to go.mod are needed. This setting is most useful to check that go.mod does
|
||||
# not need updates, such as in a continuous integration and testing system.
|
||||
# If invoked with -mod=vendor, the go command assumes that the vendor
|
||||
# directory holds the correct copies of dependencies and ignores
|
||||
# the dependency descriptions in go.mod.
|
||||
#modules-download-mode: readonly|release|vendor
|
||||
# Allow multiple parallel golangci-lint instances running.
|
||||
# If false (default) - golangci-lint acquires file lock on start.
|
||||
allow-parallel-runners: true
|
||||
# output configuration options
|
||||
output:
|
||||
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
|
||||
format: colored-line-number
|
||||
# print lines of code with issue, default is true
|
||||
print-issued-lines: true
|
||||
# print linter name in the end of issue text, default is true
|
||||
print-linter-name: true
|
||||
# make issues output unique by line, default is true
|
||||
uniq-by-line: true
|
||||
# all available settings of specific linters
|
||||
linters-settings:
|
||||
errcheck:
|
||||
# report about not checking of errors in type assertions: `a := b.(MyStruct)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-type-assertions: false
|
||||
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-blank: true
|
||||
# [deprecated] comma-separated list of pairs of the form pkg:regex
|
||||
# the regex is used to ignore names within pkg. (default "fmt:.*").
|
||||
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
|
||||
#ignore: fmt:.*,io/ioutil:^Read.*
|
||||
# path to a file containing a list of functions to exclude from checking
|
||||
# see https://github.com/kisielk/errcheck#excluding-functions for details
|
||||
#exclude: /path/to/file.txt
|
||||
funlen:
|
||||
lines: 60
|
||||
statements: 40
|
||||
gocognit:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 10
|
||||
nestif:
|
||||
# minimal complexity of if statements to report, 5 by default
|
||||
min-complexity: 4
|
||||
goconst:
|
||||
# minimal length of string constant, 3 by default
|
||||
min-len: 3
|
||||
# minimal occurrences count to trigger, 3 by default
|
||||
min-occurrences: 3
|
||||
gocritic:
|
||||
# Which checks should be enabled; can't be combined with 'disabled-checks';
|
||||
# See https://go-critic.github.io/overview#checks-overview
|
||||
# To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
|
||||
# By default list of stable checks is used.
|
||||
enabled-checks:
|
||||
#- rangeValCopy
|
||||
# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
|
||||
disabled-checks:
|
||||
- regexpMust
|
||||
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
|
||||
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
|
||||
enabled-tags:
|
||||
- performance
|
||||
disabled-tags:
|
||||
- experimental
|
||||
settings: # settings passed to gocritic
|
||||
captLocal: # must be valid enabled check name
|
||||
paramsOnly: true
|
||||
rangeValCopy:
|
||||
sizeThreshold: 32
|
||||
gocyclo:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 10
|
||||
godox:
|
||||
# report any comments starting with keywords, this is useful for TODO or FIXME comments that
|
||||
# might be left in the code accidentally and should be resolved before merging
|
||||
keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting
|
||||
#- TODO
|
||||
- FIXME
|
||||
- BUG
|
||||
#- NOTE
|
||||
#- OPTIMIZE # marks code that should be optimized before merging
|
||||
#- HACK # marks hack-arounds that should be removed before merging
|
||||
- XXX # Fatal! Important problem
|
||||
gofmt:
|
||||
# simplify code: gofmt with `-s` option, true by default
|
||||
simplify: true
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: github.com/org/project
|
||||
golint:
|
||||
# minimal confidence for issues, default is 0.8
|
||||
min-confidence: 0.8
|
||||
gomnd:
|
||||
settings:
|
||||
mnd:
|
||||
# the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
|
||||
checks: argument,case,condition,operation,return,assign
|
||||
gomodguard:
|
||||
allowed:
|
||||
modules: # List of allowed modules
|
||||
# - gopkg.in/yaml.v2
|
||||
domains: # List of allowed module domains
|
||||
# - golang.org
|
||||
blocked:
|
||||
modules: # List of blocked modules
|
||||
# - github.com/uudashr/go-module: # Blocked module
|
||||
# recommendations: # Recommended modules that should be used instead (Optional)
|
||||
# - golang.org/x/mod
|
||||
# reason: "`mod` is the official go.mod parser library." # Reason why the recommended module should be used (Optional)
|
||||
versions: # List of blocked module version constraints
|
||||
# - github.com/mitchellh/go-homedir: # Blocked module with version constraint
|
||||
# version: "< 1.1.0" # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons
|
||||
# reason: "testing if blocked version constraint works." # Reason why the version constraint exists. (Optional)
|
||||
govet:
|
||||
# report about shadowed variables
|
||||
check-shadowing: true
|
||||
# settings per analyzer
|
||||
settings:
|
||||
printf: # analyzer name, run `go tool vet help` to see all analyzers
|
||||
funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
|
||||
# enable or disable analyzers by name
|
||||
enable:
|
||||
- atomicalign
|
||||
enable-all: false
|
||||
disable:
|
||||
- shadow
|
||||
disable-all: false
|
||||
depguard:
|
||||
list-type: blacklist
|
||||
include-go-root: false
|
||||
packages:
|
||||
- github.com/sirupsen/logrus
|
||||
packages-with-error-message:
|
||||
# specify an error message to output when a blacklisted package is used
|
||||
- github.com/sirupsen/logrus: "logging is allowed only by logutils.Log"
|
||||
lll:
|
||||
# max line length, lines longer will be reported. Default is 120.
|
||||
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
|
||||
line-length: 120
|
||||
# tab width in spaces. Default to 1.
|
||||
tab-width: 1
|
||||
maligned:
|
||||
# print struct with more effective memory layout or not, false by default
|
||||
suggest-new: true
|
||||
nakedret:
|
||||
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
|
||||
max-func-lines: 30
|
||||
testpackage:
|
||||
# regexp pattern to skip files
|
||||
skip-regexp: (export|internal)_test\.go
|
||||
unused:
|
||||
# treat code as a program (not a library) and report unused exported identifiers; default is false.
|
||||
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
whitespace:
|
||||
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
|
||||
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
|
||||
custom:
|
||||
# Each custom linter should have a unique name.
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- gofmt
|
||||
- govet
|
||||
- errcheck
|
||||
- staticcheck
|
||||
- unused
|
||||
- gosimple
|
||||
- structcheck
|
||||
- varcheck
|
||||
- ineffassign
|
||||
- deadcode
|
||||
- typecheck
|
||||
# Additional
|
||||
- lll
|
||||
- godox
|
||||
# - gomnd
|
||||
#- maligned
|
||||
#- nestif
|
||||
#- goconst
|
||||
#- gocognit
|
||||
- nakedret
|
||||
#disable-all: false
|
||||
fast: true
|
||||
issues:
|
||||
# List of regexps of issue texts to exclude, empty list by default.
|
||||
# But independently from this option we use default exclude patterns,
|
||||
# it can be disabled by `exclude-use-default: false`. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`
|
||||
exclude:
|
||||
# Excluding configuration per-path, per-linter, per-text and per-source
|
||||
exclude-rules:
|
||||
# Exclude some linters from running on tests files.
|
||||
# Independently from option `exclude` we use default exclude patterns,
|
||||
# it can be disabled by this option. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`.
|
||||
# Default value for this option is true.
|
||||
exclude-use-default: false
|
||||
# The default value is false. If set to true exclude and exclude-rules
|
||||
# regular expressions become case sensitive.
|
||||
exclude-case-sensitive: false
|
||||
# The list of ids of default excludes to include or disable. By default it's empty.
|
||||
include:
|
||||
#- EXC0002 # disable excluding of issues about comments from golint
|
||||
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
|
||||
#max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
#max-same-issues: 0
|
||||
# Show only new issues: if there are unstaged changes or untracked files,
|
||||
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
|
||||
# It's a super-useful option for integration of golangci-lint into existing
|
||||
# large codebase. It's not practical to fix all existing issues at the moment
|
||||
# of integration: much better don't allow issues in new code.
|
||||
# Default is false.
|
||||
new: false
|
||||
# Show only new issues created after git revision `REV`
|
||||
new-from-rev: ""
|
||||
# Show only new issues created in git patch with set file path.
|
||||
#new-from-patch: path/to/patch/file
|
||||
severity:
|
||||
# Default value is empty string.
|
||||
# Set the default severity for issues. If severity rules are defined and the issues
|
||||
# do not match or no severity is provided to the rule this will be the default
|
||||
# severity applied. Severities should match the supported severity names of the
|
||||
# selected out format.
|
||||
# - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
|
||||
# - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity
|
||||
# - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
|
||||
default-severity: error
|
||||
# The default value is false.
|
||||
# If set to true severity-rules regular expressions become case sensitive.
|
||||
case-sensitive: false
|
||||
# Default value is empty list.
|
||||
# When a list of severity rules are provided, severity information will be added to lint
|
||||
# issues. Severity rules have the same filtering capability as exclude rules except you
|
||||
# are allowed to specify one matcher per severity rule.
|
||||
# Only affects out formats that support setting severity information.
|
||||
rules:
|
||||
- linters:
|
||||
- gomnd
|
||||
severity: ignore
|
||||
202
proxy/util/logger_conf/LICENSE.txt
Normal file
202
proxy/util/logger_conf/LICENSE.txt
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2019 Communication Service/Software Laboratory, National Chiao Tung University
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
63
proxy/util/logger_conf/conf.go
Normal file
63
proxy/util/logger_conf/conf.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package logger_conf
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
//var Free5gcLogDir string = path_util.Free5gcPath("free5gc/log") + "/"
|
||||
var Free5gcLogDir string = "/var/log/"
|
||||
//var LibLogDir string = Free5gcLogDir + "lib/"
|
||||
//var NfLogDir string = Free5gcLogDir + "nf/"
|
||||
|
||||
var Free5gcLogFile string = Free5gcLogDir + "selfcareproxy.log"
|
||||
|
||||
func init() {//InitLoggerConf(dir, filename string) {//init() {
|
||||
//Free5gcLogDir = dir
|
||||
//Free5gcLogFile = dir + filename
|
||||
|
||||
/*if err := os.MkdirAll(LibLogDir, 0775); err != nil {
|
||||
log.Printf("Mkdir %s failed: %+v", LibLogDir, err)
|
||||
}
|
||||
if err := os.MkdirAll(NfLogDir, 0775); err != nil {
|
||||
log.Printf("Mkdir %s failed: %+v", NfLogDir, err)
|
||||
}*/
|
||||
|
||||
// Create log file or if it already exist, check if user can access it
|
||||
f, fileOpenErr := os.OpenFile(Free5gcLogFile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
|
||||
if fileOpenErr != nil {
|
||||
// user cannot access it.
|
||||
log.Printf("Cannot Open %s\n", Free5gcLogFile)
|
||||
} else {
|
||||
// user can access it
|
||||
if err := f.Close(); err != nil {
|
||||
log.Printf("File %s cannot been closed\n", Free5gcLogFile)
|
||||
}
|
||||
}
|
||||
|
||||
sudoUID, errUID := strconv.Atoi(os.Getenv("SUDO_UID"))
|
||||
sudoGID, errGID := strconv.Atoi(os.Getenv("SUDO_GID"))
|
||||
|
||||
if errUID == nil && errGID == nil {
|
||||
// if using sudo to run the program, errUID will be nil and sudoUID will get the uid who run sudo
|
||||
// else errUID will not be nil and sudoUID will be nil
|
||||
// If user using sudo to run the program and create log file, log will own by root,
|
||||
// here we change own to user so user can view and reuse the file
|
||||
if err := os.Chown(Free5gcLogDir, sudoUID, sudoGID); err != nil {
|
||||
log.Printf("Dir %s chown to %d:%d error: %v\n", Free5gcLogDir, sudoUID, sudoGID, err)
|
||||
}
|
||||
/*if err := os.Chown(LibLogDir, sudoUID, sudoGID); err != nil {
|
||||
log.Printf("Dir %s chown to %d:%d error: %v\n", LibLogDir, sudoUID, sudoGID, err)
|
||||
}
|
||||
if err := os.Chown(NfLogDir, sudoUID, sudoGID); err != nil {
|
||||
log.Printf("Dir %s chown to %d:%d error: %v\n", NfLogDir, sudoUID, sudoGID, err)
|
||||
}*/
|
||||
|
||||
if fileOpenErr == nil {
|
||||
if err := os.Chown(Free5gcLogFile, sudoUID, sudoGID); err != nil {
|
||||
log.Printf("File %s chown to %d:%d error: %v\n", Free5gcLogFile, sudoUID, sudoGID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
proxy/util/logger_util/.gitignore
vendored
Normal file
15
proxy/util/logger_util/.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Toolchain
|
||||
# Goland project folder
|
||||
.idea/
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
# emacs/vim
|
||||
GPATH
|
||||
GRTAGS
|
||||
GTAGS
|
||||
TAGS
|
||||
tags
|
||||
cscope.*
|
||||
# mac
|
||||
.DS_Store
|
||||
|
||||
289
proxy/util/logger_util/.golangci.yml
Normal file
289
proxy/util/logger_util/.golangci.yml
Normal file
@@ -0,0 +1,289 @@
|
||||
# This file contains all available configuration options
|
||||
# with their default values.
|
||||
# options for analysis running
|
||||
run:
|
||||
# default concurrency is a available CPU number
|
||||
concurrency: 4
|
||||
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||
timeout: 1m
|
||||
# exit code when at least one issue was found, default is 1
|
||||
issues-exit-code: 1
|
||||
# include test files or not, default is true
|
||||
tests: false
|
||||
# list of build tags, all linters use it. Default is empty list.
|
||||
build-tags:
|
||||
# which dirs to skip: issues from them won't be reported;
|
||||
# can use regexp here: generated.*, regexp is applied on full path;
|
||||
# default value is empty list, but default dirs are skipped independently
|
||||
# from this option's value (see skip-dirs-use-default).
|
||||
# "/" will be replaced by current OS file path separator to properly work
|
||||
# on Windows.
|
||||
skip-dirs:
|
||||
# default is true. Enables skipping of directories:
|
||||
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
||||
skip-dirs-use-default: true
|
||||
# which files to skip: they will be analyzed, but issues from them
|
||||
# won't be reported. Default value is empty list, but there is
|
||||
# no need to include all autogenerated files, we confidently recognize
|
||||
# autogenerated files. If it's not please let us know.
|
||||
# "/" will be replaced by current OS file path separator to properly work
|
||||
# on Windows.
|
||||
skip-files:
|
||||
- "api_.*\\.go$"
|
||||
- "model_.*\\.go$"
|
||||
- "routers.go"
|
||||
- "client.go"
|
||||
- "configuration.go"
|
||||
- "nas.go"
|
||||
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
|
||||
# If invoked with -mod=readonly, the go command is disallowed from the implicit
|
||||
# automatic updating of go.mod described above. Instead, it fails when any changes
|
||||
# to go.mod are needed. This setting is most useful to check that go.mod does
|
||||
# not need updates, such as in a continuous integration and testing system.
|
||||
# If invoked with -mod=vendor, the go command assumes that the vendor
|
||||
# directory holds the correct copies of dependencies and ignores
|
||||
# the dependency descriptions in go.mod.
|
||||
#modules-download-mode: readonly|release|vendor
|
||||
# Allow multiple parallel golangci-lint instances running.
|
||||
# If false (default) - golangci-lint acquires file lock on start.
|
||||
allow-parallel-runners: true
|
||||
# output configuration options
|
||||
output:
|
||||
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
|
||||
format: colored-line-number
|
||||
# print lines of code with issue, default is true
|
||||
print-issued-lines: true
|
||||
# print linter name in the end of issue text, default is true
|
||||
print-linter-name: true
|
||||
# make issues output unique by line, default is true
|
||||
uniq-by-line: true
|
||||
# all available settings of specific linters
|
||||
linters-settings:
|
||||
errcheck:
|
||||
# report about not checking of errors in type assertions: `a := b.(MyStruct)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-type-assertions: false
|
||||
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-blank: true
|
||||
# [deprecated] comma-separated list of pairs of the form pkg:regex
|
||||
# the regex is used to ignore names within pkg. (default "fmt:.*").
|
||||
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
|
||||
#ignore: fmt:.*,io/ioutil:^Read.*
|
||||
# path to a file containing a list of functions to exclude from checking
|
||||
# see https://github.com/kisielk/errcheck#excluding-functions for details
|
||||
#exclude: /path/to/file.txt
|
||||
funlen:
|
||||
lines: 60
|
||||
statements: 40
|
||||
gocognit:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 10
|
||||
nestif:
|
||||
# minimal complexity of if statements to report, 5 by default
|
||||
min-complexity: 4
|
||||
goconst:
|
||||
# minimal length of string constant, 3 by default
|
||||
min-len: 3
|
||||
# minimal occurrences count to trigger, 3 by default
|
||||
min-occurrences: 3
|
||||
gocritic:
|
||||
# Which checks should be enabled; can't be combined with 'disabled-checks';
|
||||
# See https://go-critic.github.io/overview#checks-overview
|
||||
# To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
|
||||
# By default list of stable checks is used.
|
||||
enabled-checks:
|
||||
#- rangeValCopy
|
||||
# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
|
||||
disabled-checks:
|
||||
- regexpMust
|
||||
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
|
||||
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
|
||||
enabled-tags:
|
||||
- performance
|
||||
disabled-tags:
|
||||
- experimental
|
||||
settings: # settings passed to gocritic
|
||||
captLocal: # must be valid enabled check name
|
||||
paramsOnly: true
|
||||
rangeValCopy:
|
||||
sizeThreshold: 32
|
||||
gocyclo:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 10
|
||||
godox:
|
||||
# report any comments starting with keywords, this is useful for TODO or FIXME comments that
|
||||
# might be left in the code accidentally and should be resolved before merging
|
||||
keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting
|
||||
#- TODO
|
||||
- FIXME
|
||||
- BUG
|
||||
#- NOTE
|
||||
#- OPTIMIZE # marks code that should be optimized before merging
|
||||
#- HACK # marks hack-arounds that should be removed before merging
|
||||
- XXX # Fatal! Important problem
|
||||
gofmt:
|
||||
# simplify code: gofmt with `-s` option, true by default
|
||||
simplify: true
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: github.com/org/project
|
||||
golint:
|
||||
# minimal confidence for issues, default is 0.8
|
||||
min-confidence: 0.8
|
||||
gomnd:
|
||||
settings:
|
||||
mnd:
|
||||
# the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
|
||||
checks: argument,case,condition,operation,return,assign
|
||||
gomodguard:
|
||||
allowed:
|
||||
modules: # List of allowed modules
|
||||
# - gopkg.in/yaml.v2
|
||||
domains: # List of allowed module domains
|
||||
# - golang.org
|
||||
blocked:
|
||||
modules: # List of blocked modules
|
||||
# - github.com/uudashr/go-module: # Blocked module
|
||||
# recommendations: # Recommended modules that should be used instead (Optional)
|
||||
# - golang.org/x/mod
|
||||
# reason: "`mod` is the official go.mod parser library." # Reason why the recommended module should be used (Optional)
|
||||
versions: # List of blocked module version constraints
|
||||
# - github.com/mitchellh/go-homedir: # Blocked module with version constraint
|
||||
# version: "< 1.1.0" # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons
|
||||
# reason: "testing if blocked version constraint works." # Reason why the version constraint exists. (Optional)
|
||||
govet:
|
||||
# report about shadowed variables
|
||||
check-shadowing: true
|
||||
# settings per analyzer
|
||||
settings:
|
||||
printf: # analyzer name, run `go tool vet help` to see all analyzers
|
||||
funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
|
||||
# enable or disable analyzers by name
|
||||
enable:
|
||||
- atomicalign
|
||||
enable-all: false
|
||||
disable:
|
||||
- shadow
|
||||
disable-all: false
|
||||
depguard:
|
||||
list-type: blacklist
|
||||
include-go-root: false
|
||||
packages:
|
||||
- github.com/sirupsen/logrus
|
||||
packages-with-error-message:
|
||||
# specify an error message to output when a blacklisted package is used
|
||||
- github.com/sirupsen/logrus: "logging is allowed only by logutils.Log"
|
||||
lll:
|
||||
# max line length, lines longer will be reported. Default is 120.
|
||||
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
|
||||
line-length: 120
|
||||
# tab width in spaces. Default to 1.
|
||||
tab-width: 1
|
||||
maligned:
|
||||
# print struct with more effective memory layout or not, false by default
|
||||
suggest-new: true
|
||||
nakedret:
|
||||
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
|
||||
max-func-lines: 30
|
||||
testpackage:
|
||||
# regexp pattern to skip files
|
||||
skip-regexp: (export|internal)_test\.go
|
||||
unused:
|
||||
# treat code as a program (not a library) and report unused exported identifiers; default is false.
|
||||
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
whitespace:
|
||||
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
|
||||
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
|
||||
custom:
|
||||
# Each custom linter should have a unique name.
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- gofmt
|
||||
- govet
|
||||
- errcheck
|
||||
- staticcheck
|
||||
- unused
|
||||
- gosimple
|
||||
- structcheck
|
||||
- varcheck
|
||||
- ineffassign
|
||||
- deadcode
|
||||
- typecheck
|
||||
# Additional
|
||||
- lll
|
||||
- godox
|
||||
# - gomnd
|
||||
#- maligned
|
||||
#- nestif
|
||||
#- goconst
|
||||
#- gocognit
|
||||
- nakedret
|
||||
#disable-all: false
|
||||
fast: true
|
||||
issues:
|
||||
# List of regexps of issue texts to exclude, empty list by default.
|
||||
# But independently from this option we use default exclude patterns,
|
||||
# it can be disabled by `exclude-use-default: false`. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`
|
||||
exclude:
|
||||
# Excluding configuration per-path, per-linter, per-text and per-source
|
||||
exclude-rules:
|
||||
# Exclude some linters from running on tests files.
|
||||
# Independently from option `exclude` we use default exclude patterns,
|
||||
# it can be disabled by this option. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`.
|
||||
# Default value for this option is true.
|
||||
exclude-use-default: false
|
||||
# The default value is false. If set to true exclude and exclude-rules
|
||||
# regular expressions become case sensitive.
|
||||
exclude-case-sensitive: false
|
||||
# The list of ids of default excludes to include or disable. By default it's empty.
|
||||
include:
|
||||
#- EXC0002 # disable excluding of issues about comments from golint
|
||||
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
|
||||
#max-issues-per-linter: 0
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
#max-same-issues: 0
|
||||
# Show only new issues: if there are unstaged changes or untracked files,
|
||||
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
|
||||
# It's a super-useful option for integration of golangci-lint into existing
|
||||
# large codebase. It's not practical to fix all existing issues at the moment
|
||||
# of integration: much better don't allow issues in new code.
|
||||
# Default is false.
|
||||
new: false
|
||||
# Show only new issues created after git revision `REV`
|
||||
new-from-rev: ""
|
||||
# Show only new issues created in git patch with set file path.
|
||||
#new-from-patch: path/to/patch/file
|
||||
severity:
|
||||
# Default value is empty string.
|
||||
# Set the default severity for issues. If severity rules are defined and the issues
|
||||
# do not match or no severity is provided to the rule this will be the default
|
||||
# severity applied. Severities should match the supported severity names of the
|
||||
# selected out format.
|
||||
# - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
|
||||
# - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity
|
||||
# - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
|
||||
default-severity: error
|
||||
# The default value is false.
|
||||
# If set to true severity-rules regular expressions become case sensitive.
|
||||
case-sensitive: false
|
||||
# Default value is empty list.
|
||||
# When a list of severity rules are provided, severity information will be added to lint
|
||||
# issues. Severity rules have the same filtering capability as exclude rules except you
|
||||
# are allowed to specify one matcher per severity rule.
|
||||
# Only affects out formats that support setting severity information.
|
||||
rules:
|
||||
- linters:
|
||||
- gomnd
|
||||
severity: ignore
|
||||
9
proxy/util/logger_util/CHANGELOG.md
Normal file
9
proxy/util/logger_util/CHANGELOG.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Change Log
|
||||
---
|
||||
2020-03-xx-xx
|
||||
---
|
||||
- Implemented enchacements:
|
||||
|
||||
- Fixed bugs:
|
||||
|
||||
- Closed issues:
|
||||
202
proxy/util/logger_util/LICENSE.txt
Normal file
202
proxy/util/logger_util/LICENSE.txt
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2019 Communication Service/Software Laboratory, National Chiao Tung University
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
42
proxy/util/logger_util/log_level.go
Normal file
42
proxy/util/logger_util/log_level.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package logger_util
|
||||
|
||||
type Logger struct {
|
||||
AMF *LogSetting `yaml:"AMF"`
|
||||
AUSF *LogSetting `yaml:"AUSF"`
|
||||
N3IWF *LogSetting `yaml:"N3IWF"`
|
||||
NRF *LogSetting `yaml:"NRF"`
|
||||
NSSF *LogSetting `yaml:"NSSF"`
|
||||
PCF *LogSetting `yaml:"PCF"`
|
||||
SMF *LogSetting `yaml:"SMF"`
|
||||
UDM *LogSetting `yaml:"UDM"`
|
||||
UDR *LogSetting `yaml:"UDR"`
|
||||
NEF *LogSetting `yaml:"NEF"`
|
||||
WEBUI *LogSetting `yaml:"WEBUI"`
|
||||
|
||||
Aper *LogSetting `yaml:"Aper"`
|
||||
CommonConsumerTest *LogSetting `yaml:"CommonConsumerTest"`
|
||||
FSM *LogSetting `yaml:"FSM"`
|
||||
MongoDBLibrary *LogSetting `yaml:"MongoDBLibrary"`
|
||||
NAS *LogSetting `yaml:"NAS"`
|
||||
NGAP *LogSetting `yaml:"NGAP"`
|
||||
OpenApi *LogSetting `yaml:"OpenApi"`
|
||||
NamfCommunication *LogSetting `yaml:"NamfCommunication"`
|
||||
NamfEventExposure *LogSetting `yaml:"NamfEventExposure"`
|
||||
NnssfNSSAIAvailability *LogSetting `yaml:"NnssfNSSAIAvailability"`
|
||||
NnssfNSSelection *LogSetting `yaml:"NnssfNSSelection"`
|
||||
NsmfEventExposure *LogSetting `yaml:"NsmfEventExposure"`
|
||||
NsmfPDUSession *LogSetting `yaml:"NsmfPDUSession"`
|
||||
NudmEventExposure *LogSetting `yaml:"NudmEventExposure"`
|
||||
NudmParameterProvision *LogSetting `yaml:"NudmParameterProvision"`
|
||||
NudmSubscriberDataManagement *LogSetting `yaml:"NudmSubscriberDataManagement"`
|
||||
NudmUEAuthentication *LogSetting `yaml:"NudmUEAuthentication"`
|
||||
NudmUEContextManagement *LogSetting `yaml:"NudmUEContextManagement"`
|
||||
NudrDataRepository *LogSetting `yaml:"NudrDataRepository"`
|
||||
PathUtil *LogSetting `yaml:"PathUtil"`
|
||||
PFCP *LogSetting `yaml:"PFCP"`
|
||||
}
|
||||
|
||||
type LogSetting struct {
|
||||
DebugLevel string `yaml:"debugLevel"`
|
||||
ReportCaller bool `yaml:"ReportCaller"`
|
||||
}
|
||||
174
proxy/util/logger_util/logger_util.go
Normal file
174
proxy/util/logger_util/logger_util.go
Normal file
@@ -0,0 +1,174 @@
|
||||
package logger_util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
|
||||
formatter "github.com/antonfisher/nested-logrus-formatter"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var(//const (
|
||||
maxLogFileSize int64= 1024*1024*128
|
||||
maxLogFile = 8
|
||||
)
|
||||
|
||||
func SetLoggerSizeAndNum(size, num int) {
|
||||
maxLogFileSize = 1024*1024*int64(size)
|
||||
maxLogFile = num
|
||||
}
|
||||
|
||||
type FileHook struct {
|
||||
file *os.File
|
||||
flag int
|
||||
chmod os.FileMode
|
||||
formatter *formatter.Formatter
|
||||
}
|
||||
|
||||
func renameFiles(file string) {
|
||||
var oldFileName, newFileName string
|
||||
var i int
|
||||
for i = maxLogFile-1; i > 0; i-- {
|
||||
if i > 1 {
|
||||
oldFileName = fmt.Sprintf("%s.%d",file, i-1)
|
||||
} else {
|
||||
oldFileName = file
|
||||
}
|
||||
if _, err := os.Stat(oldFileName); err == nil {
|
||||
newFileName = fmt.Sprintf("%s.%d", file, i)
|
||||
os.Rename(oldFileName, newFileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewFileHook(file string, flag int, chmod os.FileMode) (*FileHook, error) {
|
||||
plainFormatter := &formatter.Formatter{
|
||||
TimestampFormat: "2006-01-02 15:04:05.000",
|
||||
TrimMessages: true,
|
||||
NoColors: true,
|
||||
NoFieldsColors: true,
|
||||
NoFieldsSpace: true,
|
||||
HideKeys: true,
|
||||
FieldsOrder: []string{"component", "category", "remote_addr"},
|
||||
CallerFirst: true,
|
||||
CustomCallerFormatter: func(f *runtime.Frame) string {
|
||||
file := path.Base(f.File)
|
||||
if len(file) > 25 {
|
||||
file = file[len(file)-25:]
|
||||
}
|
||||
return fmt.Sprintf(" %15s:%04d", file, f.Line)
|
||||
},
|
||||
}
|
||||
|
||||
logFile, err := os.OpenFile(file, flag, chmod)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unable to write file on filehook %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &FileHook{logFile, flag, chmod, plainFormatter}, err
|
||||
}
|
||||
|
||||
// Fire event
|
||||
func (hook *FileHook) Fire(entry *logrus.Entry) error {
|
||||
var line string
|
||||
|
||||
info, err := hook.file.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.Size() > maxLogFileSize {
|
||||
fileInfo, err := os.Stat(hook.file.Name())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if fileInfo.Size() > maxLogFileSize {
|
||||
renameFiles(hook.file.Name())
|
||||
}
|
||||
hook.file.Close()
|
||||
if hook.file, err = os.OpenFile(hook.file.Name(), hook.flag, hook.chmod); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unable to write file on filehook %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if plainformat, err := hook.formatter.Format(entry); err != nil {
|
||||
log.Printf("Formatter error: %+v", err)
|
||||
return err
|
||||
} else {
|
||||
line = string(plainformat)
|
||||
}
|
||||
if _, err := hook.file.WriteString(line); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unable to write file on filehook(entry.String)%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *FileHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.PanicLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.ErrorLevel,
|
||||
logrus.WarnLevel,
|
||||
logrus.InfoLevel,
|
||||
logrus.DebugLevel,
|
||||
}
|
||||
}
|
||||
|
||||
// CustomResponseWriter
|
||||
type CustomResponseWriter struct {
|
||||
gin.ResponseWriter
|
||||
body *bytes.Buffer
|
||||
}
|
||||
|
||||
func (w CustomResponseWriter) Write(b []byte) (int, error) {
|
||||
w.body.Write(b)
|
||||
return w.ResponseWriter.Write(b)
|
||||
}
|
||||
|
||||
func (w CustomResponseWriter) WriteString(s string) (int, error) {
|
||||
w.body.WriteString(s)
|
||||
return w.ResponseWriter.WriteString(s)
|
||||
}
|
||||
//
|
||||
|
||||
//The Middleware will write the Gin logs to logrus.
|
||||
func ginToLogrus(log *logrus.Entry) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
path := c.Request.URL.Path
|
||||
raw := c.Request.URL.RawQuery
|
||||
|
||||
blw := &CustomResponseWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
|
||||
c.Writer = blw
|
||||
//
|
||||
|
||||
// Process request
|
||||
c.Next()
|
||||
|
||||
clientIP := c.ClientIP()
|
||||
method := c.Request.Method
|
||||
statusCode := c.Writer.Status()
|
||||
errorMessage := c.Errors.ByType(gin.ErrorTypePrivate).String()
|
||||
|
||||
if raw != "" {
|
||||
path = path + "?" + raw
|
||||
}
|
||||
|
||||
log.Infof("| %3d | %15s | %-7s | %s | %s",
|
||||
statusCode, clientIP, method, path, errorMessage)
|
||||
}
|
||||
}
|
||||
|
||||
//NewGinWithLogrus - returns an Engine instance with the ginToLogrus and Recovery middleware already attached.
|
||||
func NewGinWithLogrus(log *logrus.Entry) *gin.Engine {
|
||||
engine := gin.New()
|
||||
engine.Use(ginToLogrus(log), gin.Recovery())
|
||||
return engine
|
||||
}
|
||||
7
proxy/util/logger_util/version/version.go
Normal file
7
proxy/util/logger_util/version/version.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package version
|
||||
|
||||
var VERSION = "2020-03-31-01"
|
||||
|
||||
func GetVersion() (version string) {
|
||||
return VERSION
|
||||
}
|
||||
Reference in New Issue
Block a user