Merge branch 'master' into session

This commit is contained in:
Radu Ioan Fericean
2015-06-09 20:18:01 +03:00
17 changed files with 94 additions and 76 deletions

View File

@@ -271,6 +271,12 @@ func (self *CGRConfig) checkConfigSanity() error {
}
// SM-FreeSWITCH checks
if self.SmFsConfig.Enabled {
if self.SmFsConfig.Rater == "" {
return errors.New("Rater definition is mandatory!")
}
if self.SmFsConfig.Cdrs == "" {
return errors.New("Cdrs definition is mandatory!")
}
if self.SmFsConfig.Rater == utils.INTERNAL && !self.RaterEnabled {
return errors.New("Rater not enabled but requested by SM-FreeSWITCH component.")
}
@@ -280,6 +286,12 @@ func (self *CGRConfig) checkConfigSanity() error {
}
// SM-Kamailio checks
if self.SmKamConfig.Enabled {
if self.SmKamConfig.Rater == "" {
return errors.New("Rater definition is mandatory!")
}
if self.SmKamConfig.Cdrs == "" {
return errors.New("Cdrs definition is mandatory!")
}
if self.SmKamConfig.Rater == utils.INTERNAL && !self.RaterEnabled {
return errors.New("Rater not enabled but requested by SM-Kamailio component.")
}
@@ -289,6 +301,12 @@ func (self *CGRConfig) checkConfigSanity() error {
}
// SM-OpenSIPS checks
if self.SmOsipsConfig.Enabled {
if self.SmOsipsConfig.Rater == "" {
return errors.New("Rater definition is mandatory!")
}
if self.SmOsipsConfig.Cdrs == "" {
return errors.New("Cdrs definition is mandatory!")
}
if self.SmOsipsConfig.Rater == utils.INTERNAL && !self.RaterEnabled {
return errors.New("Rater not enabled but requested by SM-OpenSIPS component.")
}

View File

@@ -99,7 +99,7 @@ const CGRATES_CFG_JSON = `
"enabled": false, // start the CDR Server service: <true|false>
"extra_fields": [], // extra fields to store in CDRs for non-generic CDRs
"store_cdrs": true, // store cdrs in storDb
"rater": "", // address where to reach the Rater for cost calculation, empty to disable functionality: <""|internal|x.y.z.y:1234>
"rater": "internal", // address where to reach the Rater for cost calculation, empty to disable functionality: <""|internal|x.y.z.y:1234>
"cdrstats": "", // address where to reach the cdrstats service, empty to disable stats functionality<""|internal|x.y.z.y:1234>
"reconnects": 5, // number of reconnect attempts to rater or cdrs
"cdr_replication":[], // replicate the raw CDR to a number of servers
@@ -175,13 +175,14 @@ const CGRATES_CFG_JSON = `
}
},
"sm_freeswitch": {
"enabled": false, // starts SessionManager service: <true|false>
"rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
"cdrs": "", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
"cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
"reconnects": 5, // number of reconnect attempts to rater or cdrs
"compute_lcr": false, // when enabled it will compute and set cgr_lcr channel variable with least cost route ids
"cdr_extra_fields": [], // extra fields to store in CDRs in case of processing them
"create_cdr": false, // create CDR out of events and sends them to CDRS component
"cdr_extra_fields": [], // extra fields to store in CDRs when creating them
"debit_interval": "10s", // interval to perform debits on.
"min_call_duration": "0s", // only authorize calls with allowed duration higher than this
"max_call_duration": "3h", // maximum call duration a prepaid call can last
@@ -198,8 +199,9 @@ const CGRATES_CFG_JSON = `
"sm_kamailio": {
"enabled": false, // starts SessionManager service: <true|false>
"rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
"cdrs": "", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
"cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
"reconnects": 5, // number of reconnect attempts to rater or cdrs
"create_cdr": false, // create CDR out of events and sends them to CDRS component
"debit_interval": "10s", // interval to perform debits on.
"min_call_duration": "0s", // only authorize calls with allowed duration higher than this
"max_call_duration": "3h", // maximum call duration a prepaid call can last
@@ -213,13 +215,15 @@ const CGRATES_CFG_JSON = `
"enabled": false, // starts SessionManager service: <true|false>
"listen_udp": "127.0.0.1:2020", // address where to listen for datagram events coming from OpenSIPS
"rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
"cdrs": "", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
"cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
"reconnects": 5, // number of reconnects if connection is lost
"create_cdr": false, // create CDR out of events and sends them to CDRS component
"debit_interval": "10s", // interval to perform debits on.
"min_call_duration": "0s", // only authorize calls with allowed duration higher than this
"max_call_duration": "3h", // maximum call duration a prepaid call can last
"events_subscribe_interval": "60s", // automatic events subscription to OpenSIPS, 0 to disable it
"mi_addr": "127.0.0.1:8020", // address where to reach OpenSIPS MI to send session disconnects
"reconnects": 5, // number of reconnects if connection is lost
},

View File

@@ -140,7 +140,7 @@ func TestDfCdrsJsonCfg(t *testing.T) {
Enabled: utils.BoolPointer(false),
Extra_fields: utils.StringSlicePointer([]string{}),
Store_cdrs: utils.BoolPointer(true),
Rater: utils.StringPointer(""),
Rater: utils.StringPointer("internal"),
Cdrstats: utils.StringPointer(""),
Reconnects: utils.IntPointer(5),
Cdr_replication: &[]*CdrReplicationJsonCfg{},
@@ -306,9 +306,9 @@ func TestSmFsJsonCfg(t *testing.T) {
eCfg := &SmFsJsonCfg{
Enabled: utils.BoolPointer(false),
Rater: utils.StringPointer("internal"),
Cdrs: utils.StringPointer(""),
Cdrs: utils.StringPointer("internal"),
Reconnects: utils.IntPointer(5),
Compute_lcr: utils.BoolPointer(false),
Create_cdr: utils.BoolPointer(false),
Cdr_extra_fields: utils.StringSlicePointer([]string{}),
Debit_interval: utils.StringPointer("10s"),
Min_call_duration: utils.StringPointer("0s"),
@@ -335,8 +335,9 @@ func TestSmKamJsonCfg(t *testing.T) {
eCfg := &SmKamJsonCfg{
Enabled: utils.BoolPointer(false),
Rater: utils.StringPointer("internal"),
Cdrs: utils.StringPointer(""),
Cdrs: utils.StringPointer("internal"),
Reconnects: utils.IntPointer(5),
Create_cdr: utils.BoolPointer(false),
Debit_interval: utils.StringPointer("10s"),
Min_call_duration: utils.StringPointer("0s"),
Max_call_duration: utils.StringPointer("3h"),
@@ -359,13 +360,14 @@ func TestSmOsipsJsonCfg(t *testing.T) {
Enabled: utils.BoolPointer(false),
Listen_udp: utils.StringPointer("127.0.0.1:2020"),
Rater: utils.StringPointer("internal"),
Cdrs: utils.StringPointer(""),
Cdrs: utils.StringPointer("internal"),
Reconnects: utils.IntPointer(5),
Create_cdr: utils.BoolPointer(false),
Debit_interval: utils.StringPointer("10s"),
Min_call_duration: utils.StringPointer("0s"),
Max_call_duration: utils.StringPointer("3h"),
Events_subscribe_interval: utils.StringPointer("60s"),
Mi_addr: utils.StringPointer("127.0.0.1:8020"),
Reconnects: utils.IntPointer(5),
}
if cfg, err := dfCgrJsonCfg.SmOsipsJsonCfg(); err != nil {
t.Error(err)

View File

@@ -141,7 +141,7 @@ type SmFsJsonCfg struct {
Rater *string
Cdrs *string
Reconnects *int
Compute_lcr *bool
Create_cdr *bool
Cdr_extra_fields *[]string
Debit_interval *string
Min_call_duration *string
@@ -166,6 +166,7 @@ type SmKamJsonCfg struct {
Rater *string
Cdrs *string
Reconnects *int
Create_cdr *bool
Debit_interval *string
Min_call_duration *string
Max_call_duration *string
@@ -184,12 +185,13 @@ type SmOsipsJsonCfg struct {
Listen_udp *string
Rater *string
Cdrs *string
Reconnects *int
Create_cdr *bool
Debit_interval *string
Min_call_duration *string
Max_call_duration *string
Events_subscribe_interval *string
Mi_addr *string
Reconnects *int
}
// Represents one connection instance towards OpenSIPS

View File

@@ -60,7 +60,7 @@ type SmFsConfig struct {
Rater string
Cdrs string
Reconnects int
ComputeLcr bool
CreateCdr bool
CdrExtraFields []*utils.RSRField
DebitInterval time.Duration
MinCallDuration time.Duration
@@ -89,8 +89,8 @@ func (self *SmFsConfig) loadFromJsonCfg(jsnCfg *SmFsJsonCfg) error {
if jsnCfg.Reconnects != nil {
self.Reconnects = *jsnCfg.Reconnects
}
if jsnCfg.Compute_lcr != nil {
self.ComputeLcr = *jsnCfg.Compute_lcr
if jsnCfg.Create_cdr != nil {
self.CreateCdr = *jsnCfg.Create_cdr
}
if jsnCfg.Cdr_extra_fields != nil {
if self.CdrExtraFields, err = utils.ParseRSRFieldsFromSlice(*jsnCfg.Cdr_extra_fields); err != nil {
@@ -170,6 +170,7 @@ type SmKamConfig struct {
Rater string
Cdrs string
Reconnects int
CreateCdr bool
DebitInterval time.Duration
MinCallDuration time.Duration
MaxCallDuration time.Duration
@@ -193,6 +194,9 @@ func (self *SmKamConfig) loadFromJsonCfg(jsnCfg *SmKamJsonCfg) error {
if jsnCfg.Reconnects != nil {
self.Reconnects = *jsnCfg.Reconnects
}
if jsnCfg.Create_cdr != nil {
self.CreateCdr = *jsnCfg.Create_cdr
}
if jsnCfg.Debit_interval != nil {
if self.DebitInterval, err = utils.ParseDurationWithSecs(*jsnCfg.Debit_interval); err != nil {
return err
@@ -241,6 +245,7 @@ type SmOsipsConfig struct {
Rater string
Cdrs string
Reconnects int
CreateCdr bool
DebitInterval time.Duration
MinCallDuration time.Duration
MaxCallDuration time.Duration
@@ -262,6 +267,12 @@ func (self *SmOsipsConfig) loadFromJsonCfg(jsnCfg *SmOsipsJsonCfg) error {
if jsnCfg.Cdrs != nil {
self.Cdrs = *jsnCfg.Cdrs
}
if jsnCfg.Reconnects != nil {
self.Reconnects = *jsnCfg.Reconnects
}
if jsnCfg.Create_cdr != nil {
self.CreateCdr = *jsnCfg.Create_cdr
}
if jsnCfg.Debit_interval != nil {
if self.DebitInterval, err = utils.ParseDurationWithSecs(*jsnCfg.Debit_interval); err != nil {
return err
@@ -285,8 +296,6 @@ func (self *SmOsipsConfig) loadFromJsonCfg(jsnCfg *SmOsipsJsonCfg) error {
if jsnCfg.Mi_addr != nil {
self.MiAddr = *jsnCfg.Mi_addr
}
if jsnCfg.Reconnects != nil {
self.Reconnects = *jsnCfg.Reconnects
}
return nil
}

View File

@@ -26,8 +26,8 @@ import (
func TesSmFsConfigLoadFromJsonCfg(t *testing.T) {
smFsJsnCfg := &SmFsJsonCfg{
Enabled: utils.BoolPointer(true),
Compute_lcr: utils.BoolPointer(true),
Enabled: utils.BoolPointer(true),
Create_cdr: utils.BoolPointer(true),
Connections: &[]*FsConnJsonCfg{
&FsConnJsonCfg{
Server: utils.StringPointer("1.2.3.4:8021"),
@@ -42,7 +42,7 @@ func TesSmFsConfigLoadFromJsonCfg(t *testing.T) {
},
}
eSmFsConfig := &SmFsConfig{Enabled: true,
ComputeLcr: true,
CreateCdr: true,
Connections: []*FsConnConfig{
&FsConnConfig{Server: "1.2.3.4:8021", Password: "ClueCon", Reconnects: 5},
&FsConnConfig{Server: "1.2.3.4:8021", Password: "ClueCon", Reconnects: 5},

View File

@@ -6,30 +6,6 @@
// This file contains the default configuration hardcoded into CGRateS.
// This is what you get when you load CGRateS with an empty configuration file.
// Real-time Charging System for Telecom & ISP environments
// Copyright (C) ITsysCOM GmbH
//
// This file contains the default configuration hardcoded into CGRateS.
// This is what you get when you load CGRateS with an empty configuration file.
/*
Real-time Charging System for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH
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 <http://www.gnu.org/licenses/>
*/
//"general": {
// "http_skip_tls_veify": false, // if enabled Http Client will accept any TLS certificate
@@ -179,13 +155,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
// },
//},
//"sm_freeswitch": {
// "enabled": false, // starts SessionManager service: <true|false>
// "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
// "cdrs": "", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "reconnects": 5, // number of reconnect attempts to rater or cdrs
// "compute_lcr": false, // when enabled it will compute and set cgr_lcr channel variable with least cost route ids
// "cdr_extra_fields": [], // extra fields to store in CDRs in case of processing them
// "create_cdr": false, // create CDR out of events and sends them to CDRS component
// "cdr_extra_fields": [], // extra fields to store in CDRs when creating them
// "debit_interval": "10s", // interval to perform debits on.
// "min_call_duration": "0s", // only authorize calls with allowed duration higher than this
// "max_call_duration": "3h", // maximum call duration a prepaid call can last
@@ -202,8 +179,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
//"sm_kamailio": {
// "enabled": false, // starts SessionManager service: <true|false>
// "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
// "cdrs": "", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "reconnects": 5, // number of reconnect attempts to rater or cdrs
// "create_cdr": false, // create CDR out of events and sends them to CDRS component
// "debit_interval": "10s", // interval to perform debits on.
// "min_call_duration": "0s", // only authorize calls with allowed duration higher than this
// "max_call_duration": "3h", // maximum call duration a prepaid call can last
@@ -217,13 +195,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
// "enabled": false, // starts SessionManager service: <true|false>
// "listen_udp": "127.0.0.1:2020", // address where to listen for datagram events coming from OpenSIPS
// "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
// "cdrs": "", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "reconnects": 5, // number of reconnects if connection is lost
// "create_cdr": false, // create CDR out of events and sends them to CDRS component
// "debit_interval": "10s", // interval to perform debits on.
// "min_call_duration": "0s", // only authorize calls with allowed duration higher than this
// "max_call_duration": "3h", // maximum call duration a prepaid call can last
// "events_subscribe_interval": "60s", // automatic events subscription to OpenSIPS, 0 to disable it
// "mi_addr": "127.0.0.1:8020", // address where to reach OpenSIPS MI to send session disconnects
// "reconnects": 5, // number of reconnects if connection is lost
// "mi_addr": "127.0.0.1:8020", // address where to reach OpenSIPS MI to send session disconnects
//},

View File

@@ -179,6 +179,7 @@
"rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
"cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "reconnects": 5, // number of reconnect attempts to rater or cdrs
"create_cdr": true, // create CDR out of events and sends them to CDRS component
// "cdr_extra_fields": [], // extra fields to store in CDRs in case of processing them
"debit_interval": "5s", // interval to perform debits on.
// "min_call_duration": "0s", // only authorize calls with allowed duration higher than this
@@ -196,7 +197,7 @@
//"sm_kamailio": {
// "enabled": false, // starts SessionManager service: <true|false>
// "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
// "cdrs": "", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "reconnects": 5, // number of reconnect attempts to rater or cdrs
// "debit_interval": "10s", // interval to perform debits on.
// "min_call_duration": "0s", // only authorize calls with allowed duration higher than this
@@ -211,7 +212,7 @@
// "enabled": false, // starts SessionManager service: <true|false>
// "listen_udp": "127.0.0.1:2020", // address where to listen for datagram events coming from OpenSIPS
// "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
// "cdrs": "", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "debit_interval": "10s", // interval to perform debits on.
// "min_call_duration": "0s", // only authorize calls with allowed duration higher than this
// "max_call_duration": "3h", // maximum call duration a prepaid call can last

View File

@@ -224,6 +224,7 @@
// "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
"cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
// "reconnects": 5, // number of reconnect attempts to rater or cdrs
"create_cdr": true, // create CDR out of events and sends them to CDRS component
// "debit_interval": "10s", // interval to perform debits on.
// "min_call_duration": "0s", // only authorize calls with allowed duration higher than this
// "max_call_duration": "3h", // maximum call duration a prepaid call can last

View File

@@ -70,6 +70,7 @@
"listen_udp": "127.0.0.1:2020", // address where to listen for datagram events coming from OpenSIPS
"rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013>
"cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234>
"create_cdr": true, // create CDR out of events and sends them to CDRS component
"debit_interval": "2s", // interval to perform debits on.
"events_subscribe_interval": "60s", // automatic events subscription to OpenSIPS, 0 to disable it
"mi_addr": "127.0.0.1:8020", // address where to reach OpenSIPS MI to send session disconnects

View File

@@ -314,11 +314,10 @@ func (self *CdrServer) rateCDR(storedCdr *StoredCdr) error {
var err error
for i := 0; i < 4; i++ {
qryCC, errCost = self.getCostsFromDB(storedCdr.CgrId, storedCdr.MediationRunId)
if err == nil { //Connected so no need to reiterate
if err == nil { // Got our cost, no need to continue
break
}
time.Sleep(delay())
time.Sleep(delay() * time.Millisecond)
}
if err != nil { //calculate CDR as for pseudoprepaid
qryCC, errCost = self.getCostFromRater(storedCdr)

View File

@@ -26,8 +26,8 @@ import (
"github.com/cgrates/cgrates/utils"
_ "github.com/bmizerany/pq"
"github.com/cgrates/gorm"
_ "github.com/lib/pq"
)
type PostgresStorage struct {

View File

@@ -4,7 +4,7 @@ import os
import os.path
from subprocess import call
libs = ('github.com/bmizerany/pq',
libs = ('github.com/lib/pq',
'github.com/ugorji/go/codec',
'gopkg.in/mgo.v2',
'github.com/cgrates/fsock',
@@ -20,9 +20,9 @@ libs = ('github.com/bmizerany/pq',
if __name__ == "__main__":
go_path = os.path.join(os.environ['GOPATH'], 'src')
for lib in libs:
for lib in libs:
app_dir = os.path.abspath(os.path.join(go_path,lib))
if os.path.islink(app_dir): continue
git_path = os.path.join(app_dir, '.git')
bzr_path = os.path.join(app_dir, '.bzr')

View File

@@ -214,13 +214,15 @@ func (sm *FSSessionManager) onChannelPark(ev engine.Event, connId string) {
return
}
sm.setMaxCallDuration(ev.GetUUID(), connId, maxCallDur)
if sm.cfg.ComputeLcr {
/*if sm.cfg.ComputeLcr { // Fix here out of channel variable
if err := sm.setCgrLcr(ev, connId); err != nil {
engine.Logger.Err(fmt.Sprintf("<SM-FreeSWITCH> Could not set LCR for %s, error: %s", ev.GetUUID(), err.Error()))
sm.unparkCall(ev.GetUUID(), connId, ev.GetCallDestNr(utils.META_DEFAULT), SYSTEM_ERROR)
return
}
}
*/
sm.unparkCall(ev.GetUUID(), connId, ev.GetCallDestNr(utils.META_DEFAULT), AUTH_OK)
}
@@ -241,7 +243,7 @@ func (sm *FSSessionManager) onChannelHangupComplete(ev engine.Event) {
if ev.GetReqType(utils.META_DEFAULT) == utils.META_NONE { // Do not process this request
return
}
if sm.cdrs != nil {
if sm.cfg.CreateCdr {
go sm.ProcessCdr(ev.AsStoredCdr())
}
var s *Session

View File

@@ -221,7 +221,7 @@ func (self *KamailioSessionManager) Rater() engine.Connector {
}
func (self *KamailioSessionManager) ProcessCdr(cdr *engine.StoredCdr) error {
if self.cdrsrv == nil {
if !self.cfg.CreateCdr {
return nil
}
var reply string

View File

@@ -302,7 +302,7 @@ func (osm *OsipsSessionManager) callEnd(osipsEv *OsipsEvent) error {
// Records the event start in case of received so we can create CDR out of it
func (osm *OsipsSessionManager) processCdrStart(osipsEv *OsipsEvent) error {
if osm.cdrsrv == nil {
if !osm.cfg.CreateCdr {
return nil
}
if dialogId := osipsEv.DialogId(); dialogId == "" {

View File

@@ -1,19 +1,19 @@
#!/usr/bin/env sh
go get -v -u github.com/bmizerany/pq
go get -v -u github.com/ugorji/go/codec
go get -v -u gopkg.in/mgo.v2
go get -v -u github.com/cgrates/fsock
go get -v -u github.com/cgrates/kamevapi
go get -v -u github.com/cgrates/osipsdagram
go get -u -v github.com/go-sql-driver/mysql
go get -u -v github.com/hoisie/redis
go get -u -v github.com/howeyc/fsnotify
go get -u -v github.com/cgrates/liner
go get -u -v github.com/cgrates/rpcclient
go get -u -v github.com/cgrates/gorm
go get -u -v github.com/gorhill/cronexpr
go get -u -v github.com/cgrates/kamevapi
go get -v -u github.com/lib/pq
go get -v -u github.com/ugorji/go/codec
go get -v -u gopkg.in/mgo.v2
go get -u -v github.com/go-sql-driver/mysql
go get -u -v github.com/hoisie/redis
go get -u -v github.com/howeyc/fsnotify
go get -u -v github.com/gorhill/cronexpr
go get -u -v github.com/DisposaBoy/JsonConfigReader
go get -u -v golang.org/x/net/websocket
go get -u -v github.com/kr/pty