package cdr import ( "fmt" "net/http" "strings" "be.ems/lib/config" "be.ems/lib/core/ctx" "be.ems/lib/dborm" "be.ems/lib/log" "be.ems/lib/services" neService "be.ems/src/modules/network_element/service" wsService "be.ems/src/modules/ws/service" ) var ( UriCDREvent = config.DefaultUriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrEvent" UriCDRFile = config.DefaultUriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrFile" CustomUriCDREvent = config.UriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrEvent" CustomUriCDRFile = config.UriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrFile" ) // CDREvent CDR数据表格结构体 type CDREvent struct { NeType string `json:"neType" xorm:"ne_type"` NeName string `json:"neName" xorm:"ne_name"` RmUID string `json:"rmUID" xorm:"rm_uid"` Timestamp int `json:"timestamp" xorm:"timestamp"` CDR map[string]any `json:"CDR" xorm:"cdr_json"` TenantID string `json:"tenantID" xorm:"tenant_id"` } // PostCDREventFrom 接收CDR数据请求 func PostCDREventFrom(w http.ResponseWriter, r *http.Request) { log.Info("PostCDREventFrom processing... ") neType := ctx.GetParam(r, "elementTypeValue") var cdrEvent CDREvent if err := ctx.ShouldBindJSON(r, &cdrEvent); err != nil { services.ResponseInternalServerError500ProcessError(w, err) return } neTypeLower := strings.ToLower(cdrEvent.NeType) if neType == "" || neType != neTypeLower { services.ResponseInternalServerError500ProcessError(w, fmt.Errorf("inconsistent network element types")) return } // for multi-tenancy switch neTypeLower { case "ims", "smsc": if v, ok := cdrEvent.CDR["callerParty"]; ok { where := fmt.Sprintf("'%v' like msisdn", v) tenantID, err := dborm.XormGetSingleColStringByWhere("u_sub_user", "tenant_id", where) if err != nil { log.Errorf("failed to get tenant_id:%v", err) } if tenantID != "" { cdrEvent.TenantID = tenantID } } case "smf": if v, ok := cdrEvent.CDR["subscriberIdentifier"]; ok { subscriptionIDData := v.(map[string]any)["subscriptionIDData"] where := fmt.Sprintf("'%v' like imsi or '%v' like msisdn", subscriptionIDData, subscriptionIDData) tenantID, err := dborm.XormGetSingleColStringByWhere("u_sub_user", "tenant_id", where) if err != nil { log.Errorf("failed to get tenant_id:%v", err) } if tenantID != "" { cdrEvent.TenantID = tenantID } } } tableName := fmt.Sprintf("cdr_event_%s", neTypeLower) affected, err := dborm.XormInsertTableOne(tableName, cdrEvent) if err != nil && affected <= 0 { log.Error("Failed to insert "+tableName, err) services.ResponseInternalServerError500ProcessError(w, err) return } // 发送到匹配的网元 neInfo := neService.NewNeInfo.SelectNeInfoByRmuid(cdrEvent.RmUID) if neInfo.RmUID == cdrEvent.RmUID { // 推送到ws订阅组 switch neInfo.NeType { case "IMS": if v, ok := cdrEvent.CDR["recordType"]; ok && (v == "MOC" || v == "MTSM") { wsService.NewWSSend.ByGroupID(wsService.GROUP_IMS_CDR+"_"+neInfo.NeId, cdrEvent) } case "SMF": wsService.NewWSSend.ByGroupID(wsService.GROUP_SMF_CDR+"_"+neInfo.NeId, cdrEvent) case "SMSC": wsService.NewWSSend.ByGroupID(wsService.GROUP_SMSC_CDR+"_"+neInfo.NeId, cdrEvent) case "SGWC": wsService.NewWSSend.ByGroupID(wsService.GROUP_SGWC_CDR+"_"+neInfo.NeId, cdrEvent) } } services.ResponseStatusOK204NoContent(w) }