diff --git a/apier/.apier.go.swp b/apier/.apier.go.swp
new file mode 100644
index 000000000..7fa2acbe6
Binary files /dev/null and b/apier/.apier.go.swp differ
diff --git a/apier/.tpid.go.swp b/apier/.tpid.go.swp
new file mode 100644
index 000000000..a511e7675
Binary files /dev/null and b/apier/.tpid.go.swp differ
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
+}
+