diff --git a/apier/v1/auth.go b/apier/v1/auth.go index 0b548da60..847917927 100644 --- a/apier/v1/auth.go +++ b/apier/v1/auth.go @@ -28,6 +28,9 @@ import ( // Returns MaxUsage (for calls in seconds), -1 for no limit func (self *ApierV1) GetMaxUsage(usageRecord engine.UsageRecord, maxUsage *float64) error { + if err := usageRecord.LoadUserProfile(); err != nil { + return err + } if usageRecord.TOR == "" { usageRecord.TOR = utils.VOICE } diff --git a/apier/v1/debit.go b/apier/v1/debit.go index 321dab63a..f70ea0572 100644 --- a/apier/v1/debit.go +++ b/apier/v1/debit.go @@ -27,6 +27,10 @@ func (self *ApierV1) DebitUsage(usageRecord engine.UsageRecord, reply *string) e if missing := utils.MissingStructFields(&usageRecord, []string{"Account", "Destination", "Usage"}); len(missing) != 0 { return utils.NewErrMandatoryIeMissing(missing...) } + if err := usageRecord.LoadUserProfile(); err != nil { + *reply = err.Error() + return err + } if usageRecord.TOR == "" { usageRecord.TOR = utils.VOICE } diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index 88d700249..40d41de96 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -541,7 +541,7 @@ func main() { return } } - //engine.SetPubSub(users) + engine.SetUserService(users) }() wg.Wait() diff --git a/engine/calldesc.go b/engine/calldesc.go index 45d3c4289..417f3c0f6 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -68,7 +68,7 @@ var ( globalRoundingDecimals = 10 historyScribe history.Scribe pubSubServer PublisherSubscriber - //historyScribe, _ = history.NewMockScribe() + userService UserService ) // Exported method to set the storage getter. @@ -108,6 +108,10 @@ func SetPubSub(ps PublisherSubscriber) { pubSubServer = ps } +func SetUserService(us UserService) { + userService = us +} + func Publish(event CgrEvent) { if pubSubServer != nil { var s string diff --git a/engine/storedcdr.go b/engine/storedcdr.go index ad7c17e73..580fd1d73 100644 --- a/engine/storedcdr.go +++ b/engine/storedcdr.go @@ -20,6 +20,7 @@ package engine import ( "encoding/json" + "log" "math" "net/url" "strconv" @@ -681,3 +682,53 @@ func (self *UsageRecord) AsCallDescriptor() (*CallDescriptor, error) { TimeEnd: startTime.Add(usage), }, nil } + +func (self *UsageRecord) LoadUserProfile() error { + up := &UserProfile{ + Tenant: self.Tenant, + Profile: map[string]string{ + "TOR": self.TOR, + "ReqType": self.ReqType, + "Direction": self.Direction, + "Tenant": self.Tenant, + "Category": self.Category, + "Account": self.Account, + "Subject": self.SetupTime, + "Destination": self.Destination, + "SetupTime": self.SetupTime, + "AnswerTime": self.AnswerTime, + "Usage": self.Usage, + }, + } + // clean *user fields + if up.Tenant == utils.USERS { + up.Tenant = "" + } + for key, value := range up.Profile { + if value == utils.USERS { + delete(up.Profile, key) + } + } + log.Print("UP: ", up.Profile) + ups := make([]*UserProfile, 0) + if err := userService.GetUsers(*up, &ups); err != nil { + return err + } + if len(ups) > 0 { + up = ups[0] // take the first matched user profile + self.TOR = up.Profile["TOR"] + self.ReqType = up.Profile["ReqType"] + self.Direction = up.Profile["Direction"] + self.Tenant = up.Tenant + self.Category = up.Profile["Category"] + self.Account = up.Profile["Account"] + self.Subject = up.Profile["Subject"] + self.Destination = up.Profile["Destination"] + self.SetupTime = up.Profile["SetupTime"] + self.AnswerTime = up.Profile["AnswerTime"] + self.Usage = up.Profile["Usage"] + } else { + return utils.ErrNotFound + } + return nil +} diff --git a/engine/storedcdr_test.go b/engine/storedcdr_test.go index 3163f851a..d6602de14 100644 --- a/engine/storedcdr_test.go +++ b/engine/storedcdr_test.go @@ -549,3 +549,48 @@ func TestUsageReqAsCD(t *testing.T) { t.Errorf("Expected: %+v, received: %+v", eCD, cd) } } + +func TestStoredCDRGetUserProfile(t *testing.T) { + userService = &UserMap{ + table: map[string]map[string]string{ + "test:user": map[string]string{"TOR": "01", "ReqType": "1", "Direction": "*out", "Category": "c1", "Account": "dan", "Subject": "0723", "Destination": "+401", "SetupTime": "s1", "AnswerTime": "t1", "Usage": "10"}, + ":user": map[string]string{"TOR": "02", "ReqType": "2", "Direction": "*out", "Category": "c2", "Account": "ivo", "Subject": "0724", "Destination": "+402", "SetupTime": "s2", "AnswerTime": "t2", "Usage": "11"}, + "test:": map[string]string{"TOR": "03", "ReqType": "3", "Direction": "*out", "Category": "c3", "Account": "elloy", "Subject": "0725", "Destination": "+403", "SetupTime": "s3", "AnswerTime": "t3", "Usage": "12"}, + "test1:user1": map[string]string{"TOR": "04", "ReqType": "4", "Direction": "*out", "Category": "call", "Account": "rif", "Subject": "0726", "Destination": "+404", "SetupTime": "s4", "AnswerTime": "t4", "Usage": "13"}, + }, + index: make(map[string]map[string]bool), + } + + ur := &UsageRecord{ + TOR: utils.USERS, + ReqType: utils.USERS, + Direction: "*out", + Tenant: utils.USERS, + Category: "call", + Account: utils.USERS, + Subject: utils.USERS, + Destination: utils.USERS, + SetupTime: utils.USERS, + AnswerTime: utils.USERS, + Usage: "13", + } + if err := ur.LoadUserProfile(); err != nil { + t.Error("Error loading user profile: ", err) + } + expected := &UsageRecord{ + TOR: "04", + ReqType: "4", + Direction: "*out", + Tenant: "test1", + Category: "call", + Account: "rif", + Subject: "0726", + Destination: "+404", + SetupTime: "s4", + AnswerTime: "t4", + Usage: "13", + } + if !reflect.DeepEqual(ur, expected) { + t.Errorf("Expected: %+v got: %+v", expected, ur) + } +} diff --git a/utils/consts.go b/utils/consts.go index 1c69ac9b1..7300cfcc1 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -83,6 +83,7 @@ const ( ROUNDING_DOWN = "*down" ANY = "*any" ASAP = "*asap" + USERS = "*users" COMMENT_CHAR = '#' CSV_SEP = ',' FALLBACK_SEP = ';'