From e703c3f4317a10ce0320eb43bedbe7c1b1c664d1 Mon Sep 17 00:00:00 2001 From: DanB Date: Tue, 11 Jun 2013 13:25:57 +0200 Subject: [PATCH] Adding Apier, Apier.GetTPID initial implementation --- apier/.apier.go.swp | Bin 0 -> 12288 bytes apier/.tpid.go.swp | Bin 0 -> 12288 bytes apier/apier.go | 23 ++++++++ apier/tpid.go | 43 +++++++++++++++ cmd/cgr-rater/cgr-rater.go | 2 + utils/coreutils.go | 20 +++++++ utils/map.go | 62 +++++++++++++++++++++ utils/slice.go | 44 +++++++++++++++ utils/struct.go | 108 +++++++++++++++++++++++++++++++++++++ 9 files changed, 302 insertions(+) create mode 100644 apier/.apier.go.swp create mode 100644 apier/.tpid.go.swp create mode 100644 apier/apier.go create mode 100644 apier/tpid.go create mode 100644 utils/map.go create mode 100644 utils/slice.go create mode 100644 utils/struct.go diff --git a/apier/.apier.go.swp b/apier/.apier.go.swp new file mode 100644 index 0000000000000000000000000000000000000000..7fa2acbe6af2d3fa5add5b1775805ca1cbb1cfdb GIT binary patch literal 12288 zcmeI2&5jdC5XXz0A>rc?2_;ei7g#Nx{WuU2gc!{3GSYrHW1H0;+n%Lj1+HA+1-QW*@FW}(FHgu=WG=9(oQvfMVz#v;nO{YtS!Hv(G2& zcLBXLAs_^VfDjM@LO=)z0U;m+guwqo;3@I4rJh%OuuhG2D@BE}?=A*UDay~xns4zoadelJQr6XIj&uv{~oU5s3r-#~1b;gQ^wwkjY!MWz0{XXyLQae>} zryjro?;blL`u8~=S;rIWG-o;}Q}`C`ZKdsp@qRD9pX?^RBZk3t(%awac6s|C<(NBh z+DqE~-8kh=KkXcJw~$a5i69Ib)PWC^-ot}_kK_F#K8({8&W?UxV6d3gQ(Z11Hj}C_ z$YZ9QQ)Or}AykY1gNgA7=)oB{g`GKGmRrCNxe9CooE8NSG}m5_>SC4XI^NH1?bueq z*zyLea?S!=CIFGITBWWhsK;=DgYXi`>X7A+1fGov|C8+X8& zaUS@3`vz~Ut#5MD^K;)m*dvtF8(ct)f}Y@ny&0F-JJ=<%1=B}1>2Moofa~n}(7Ga{ HXoda;FKRMQ literal 0 HcmV?d00001 diff --git a/apier/.tpid.go.swp b/apier/.tpid.go.swp new file mode 100644 index 0000000000000000000000000000000000000000..a511e76758dbdaa0f31a42ddbf430c6cb6b40443 GIT binary patch literal 12288 zcmeI2&u<$=6vtm8E~XR^+>nqS;gSU7O&Xz!KoG`FQcL+^Y^PC@D;N3)zyS&F9QYqNap8c(ch+_*fgoxn4wYu5uO_qe=FNMbH$K>TgN-}w zL%!MAB0Mh>E!Q4?d~J#7+t-LklLC)mU?DsBl*4Q5|#S!|Q%=jit55!g~~Pcb0dRs3;0E zROsc6d7@m($o+09t&(w_wVbeT?PaBTD3FdxSdMcy^;Rejpv;1+4UEZ{8NLsNJui5Y zN|#E@E>*?c1;$jesFGo$rFR+&C*lFsd?dA5)ZT|T#0faf39FKX^9PFNdP=R!(;KXoqOj-ttA(irKoVeBZ%)KKaIJrZXWfUAGHtK z{WFHaUb}y^+w1Y(ahIFiX?FYV*2zJ$%bk;M=eW0vgnCE>XlYP7K5h4JAD{HOd3467 z&2AUY&fcpq7_7<*sb^If=NYa7PlUBXqwppnbc+`}$He$ER=#p@3Om%)7cVs^l}m+V z<=`~Scp$kfWKw2ze4WJmsVOa++$p2iSm-HdxPq21q%H8OLEg)rMZi6iIGm1|DK+j3 zR_iQL^2gS^wE#S)SqBip$=FccLBt~MxL8>I2Wo-Ld|`?d$qc6d$TjgH74wj`eHQp& zXw>^L1fR0daa0v8R>_p8g*#x?D8&_Qt?`YG%`I;Ci)qn1J|wi$ b+nG7Cis>EG?r;k=z^yI#)YvShXr2B7o+ic& literal 0 HcmV?d00001 diff --git a/apier/apier.go b/apier/apier.go new file mode 100644 index 000000000..d9a9792de --- /dev/null +++ b/apier/apier.go @@ -0,0 +1,23 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package apier + + +type Apier struct { +} diff --git a/apier/tpid.go b/apier/tpid.go new file mode 100644 index 000000000..1d722663d --- /dev/null +++ b/apier/tpid.go @@ -0,0 +1,43 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package apier + +import ( + "github.com/cgrates/cgrates/utils" +) + + +type TPID struct{ + TPid string // the id of tariff plan + Active bool // Marks whether this tpid is the active one in datadb +} + + +// Return TPid associated with id queried, new tpid in case of empty id +func (self *Apier) GetTPID( reqAttr string, reply *TPID) error { + *reply = TPID{Active:false} + if reqAttr == "" { + reply.TPid = utils.NewTPid() + } else { + reply.TPid = reqAttr + } + return nil +} + + diff --git a/cmd/cgr-rater/cgr-rater.go b/cmd/cgr-rater/cgr-rater.go index 1d03e6955..e892902aa 100644 --- a/cmd/cgr-rater/cgr-rater.go +++ b/cmd/cgr-rater/cgr-rater.go @@ -30,6 +30,7 @@ import ( "github.com/cgrates/cgrates/scheduler" "github.com/cgrates/cgrates/sessionmanager" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/cgrates/apier" "io" "net" "net/rpc" @@ -74,6 +75,7 @@ func listenToRPCRequests(rpcResponder interface{}, rpcAddress string, rpc_encodi rater.Logger.Info(fmt.Sprintf(" Listening for incomming RPC requests on %v", l.Addr())) rpc.Register(rpcResponder) + rpc.Register(&apier.Apier{}) var serveFunc func(io.ReadWriteCloser) if rpc_encoding == JSON { serveFunc = jsonrpc.ServeConn diff --git a/utils/coreutils.go b/utils/coreutils.go index 37999a8f0..a6f36b5a8 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -21,6 +21,8 @@ package utils import ( "crypto/sha1" "fmt" + "encoding/hex" + "crypto/rand" ) // Returns first non empty string out of vals. Useful to extract defaults @@ -38,3 +40,21 @@ func FSCgrId(uuid string) string { hasher.Write([]byte(uuid)) return fmt.Sprintf("%x", hasher.Sum(nil)) } + +func NewTPid() string { + hasher := sha1.New() + uuid,_ := GenUUID() + hasher.Write([]byte(uuid)) + return fmt.Sprintf("%x", hasher.Sum(nil)) +} + +func GenUUID() (string, error) { + uuid := make([]byte, 16) + n, err := rand.Read(uuid) + if n != len(uuid) || err != nil { + return "", err + } + uuid[8] = 0x80 + uuid[4] = 0x40 + return hex.EncodeToString(uuid), nil +} diff --git a/utils/map.go b/utils/map.go new file mode 100644 index 000000000..6dd371188 --- /dev/null +++ b/utils/map.go @@ -0,0 +1,62 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + + +package utils + +// Converts map[string]string into map[string]interface{} +func ConvertMapValStrIf(inMap map[string]string) map[string]interface{} { + outMap := make(map[string]interface{}) + for field, val := range inMap { + outMap[field] = val + } + return outMap +} + +// Mirrors key/val +func MirrorMap(mapIn map[string]string) (map[string]string, error) { + mapOut := make(map[string]string) + for key, val := range mapIn { + mapOut[val] = key + } + return mapOut, nil +} + +// Returns mising keys in a map +func MissingMapKeys(inMap map[string]string, requiredKeys []string) []string { + missingKeys := []string{} + for _, reqKey := range requiredKeys { + if val, hasKey := inMap[reqKey]; !hasKey { + missingKeys = append(missingKeys, reqKey) + } else if val == "" { + missingKeys = append(missingKeys, reqKey) + } + } + return missingKeys +} + +// Return map keys +func MapKeys(m map[string]string) []string { + n := make([]string, len(m)) + i := 0 + for k := range m { + n[i] = k + i++ + } + return n +} diff --git a/utils/slice.go b/utils/slice.go new file mode 100644 index 000000000..7bc6c017e --- /dev/null +++ b/utils/slice.go @@ -0,0 +1,44 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + + +package utils + +import ( + "sort" + "strings" +) + +// Binary string search in slice +func IsSliceMember(ss []string, s string) bool { + sort.Strings(ss) + if i := sort.SearchStrings(ss, s); i < len(ss) && ss[i] == s { + return true + } + return false +} + +//Iterates over slice members and returns true of one starts with prefix +func SliceMemberHasPrefix(ss []string, prfx string) bool { + for _, mbr := range ss { + if strings.HasPrefix(mbr, prfx) { + return true + } + } + return false +} diff --git a/utils/struct.go b/utils/struct.go new file mode 100644 index 000000000..172115f74 --- /dev/null +++ b/utils/struct.go @@ -0,0 +1,108 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ +package utils + +import ( + "reflect" + "strconv" +) + +// Detects missing field values based on mandatory field names, s should be a pointer to a struct +func MissingStructFields(s interface{}, mandatories []string) []string { + missing := []string{} + for _, fieldName := range mandatories { + fld := reflect.ValueOf(s).Elem().FieldByName(fieldName) + if (fld.Kind() == reflect.String && fld.String() == "") || + ((fld.Kind() == reflect.Slice || fld.Kind() == reflect.Map) && fld.Len() == 0) || + (fld.Kind() == reflect.Int && fld.Int() == 0) { + missing = append(missing, fieldName) + } + } + return missing +} + +// Detects nonempty struct fields, s should be a pointer to a struct +// Useful to not overwrite db fields with non defined params in api +func NonemptyStructFields(s interface{}) map[string]interface{} { + fields := make(map[string]interface{}) + for i := 0; i < reflect.ValueOf(s).Elem().NumField(); i++ { + fld := reflect.ValueOf(s).Elem().Field(i) + switch fld.Kind() { + case reflect.Bool: + fields[reflect.TypeOf(s).Elem().Field(i).Name] = fld.Bool() + case reflect.Int: + fieldVal := fld.Int() + if fieldVal != 0 { + fields[reflect.TypeOf(s).Elem().Field(i).Name] = fieldVal + } + case reflect.String: + fieldVal := fld.String() + if fieldVal != "" { + fields[reflect.TypeOf(s).Elem().Field(i).Name] = fieldVal + } + } + } + return fields +} + +// Converts a struct to map +func StrucToMap(s interface{}) map[string]interface{} { + mp := make(map[string]interface{}) + for i := 0; i < reflect.ValueOf(s).Elem().NumField(); i++ { + fld := reflect.ValueOf(s).Elem().Field(i) + switch fld.Kind() { + case reflect.Bool: + mp[reflect.TypeOf(s).Elem().Field(i).Name] = fld.Bool() + case reflect.Int: + mp[reflect.TypeOf(s).Elem().Field(i).Name] = fld.Int() + case reflect.String: + mp[reflect.TypeOf(s).Elem().Field(i).Name] = fld.String() + } + } + return mp +} + +// Update struct with map fields, returns not matching map keys, s is a struct to be updated +func UpdateStructWithStrMap(s interface{}, m map[string]string) []string { + notMatched := []string{} + for key, val := range m { + fld := reflect.ValueOf(s).Elem().FieldByName(key) + if fld.IsValid() { + switch fld.Kind() { + case reflect.Bool: + if valBool, err := strconv.ParseBool(val); err != nil { + notMatched = append(notMatched, key) + } else { + fld.SetBool(valBool) + } + case reflect.Int: + if valInt, err := strconv.ParseInt(val, 10, 64); err != nil { + notMatched = append(notMatched, key) + } else { + fld.SetInt(valInt) + } + case reflect.String: + fld.SetString(val) + } + } else { + notMatched = append(notMatched, key) + } + } + return notMatched +} +