mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 10:06:24 +05:00
Make Charger Profiles storable in MySQL and Postgres
This commit is contained in:
committed by
Dan Christian Bogos
parent
d78f34bdc5
commit
eda80242eb
@@ -86,11 +86,11 @@ func TestChargersIT(t *testing.T) {
|
||||
case utils.MetaMongo:
|
||||
chargersConfigDIR = "apis_chargers_mongo"
|
||||
case utils.MetaRedis:
|
||||
t.SkipNow()
|
||||
chargersConfigDIR = "apis_chargers_redis"
|
||||
case utils.MetaMySQL:
|
||||
chargersConfigDIR = "apis_chargers_mysql"
|
||||
case utils.MetaPostgres:
|
||||
t.SkipNow()
|
||||
chargersConfigDIR = "apis_chargers_postgres"
|
||||
default:
|
||||
t.Fatal("Unknown Database type")
|
||||
}
|
||||
|
||||
@@ -130,6 +130,8 @@ const CGRATES_CFG_JSON = `
|
||||
"*ip_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*ip_allocations": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*action_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*versions": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*charger_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
|
||||
// compatible db types: <*internal|*redis|*mongo>
|
||||
"*actions": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
@@ -142,10 +144,8 @@ const CGRATES_CFG_JSON = `
|
||||
"*filters": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*route_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*attribute_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*charger_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*rate_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*load_ids": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*versions": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "*default"},
|
||||
"*resource_filter_indexes" : {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate": false, "dbConn": "*default"},
|
||||
"*ip_filter_indexes" : {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate": false, "dbConn": "*default"},
|
||||
"*stat_filter_indexes" : {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate": false, "dbConn": "*default"},
|
||||
|
||||
@@ -1061,7 +1061,8 @@ func (cfg *CGRConfig) checkConfigSanity() error {
|
||||
utils.Internal, utils.Redis, utils.Mongo}
|
||||
|
||||
if item != utils.MetaAccounts && item != utils.MetaIPProfiles &&
|
||||
item != utils.MetaIPAllocations && item != utils.MetaActionProfiles {
|
||||
item != utils.MetaIPAllocations && item != utils.MetaActionProfiles &&
|
||||
item != utils.MetaChargerProfiles {
|
||||
if item == utils.MetaCDRs {
|
||||
if !slices.Contains(storDBTypes, cfg.dbCfg.DBConns[val.DBConn].Type) {
|
||||
return fmt.Errorf("<%s> db item can only be of types <%v>, got <%s>", item,
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
"*cdrs": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"}
|
||||
"*cdrs": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"},
|
||||
"*charger_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
54
data/conf/samples/apis_chargers_postgres/cgrates.json
Normal file
54
data/conf/samples/apis_chargers_postgres/cgrates.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
|
||||
"general": {
|
||||
"reply_timeout": "50s"
|
||||
},
|
||||
|
||||
"logger": {
|
||||
"level": 7
|
||||
},
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080"
|
||||
},
|
||||
|
||||
"db": {
|
||||
"db_conns": {
|
||||
"*default": {
|
||||
"db_type": "redis",
|
||||
"db_host": "127.0.0.1",
|
||||
"db_port": 6379,
|
||||
"db_name": "10",
|
||||
"db_user": "cgrates"
|
||||
},
|
||||
"StorDB": { // The id of the DB connection
|
||||
"db_type": "postgres", // db type: <internal|redis|mysql|mongo|postgres>
|
||||
"db_host": "127.0.0.1",
|
||||
"db_port": 5432, // db port to reach the database
|
||||
"db_name": "cgrates", // the host to connect to
|
||||
"db_user": "cgrates",
|
||||
"db_password": "CGRateS.org" // password to use when connecting to the database
|
||||
},
|
||||
},
|
||||
"items": {
|
||||
"*cdrs": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"},
|
||||
"*charger_profiles": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"}
|
||||
}
|
||||
},
|
||||
|
||||
"attributes": {
|
||||
"enabled": true
|
||||
},
|
||||
|
||||
"chargers": {
|
||||
"enabled": true,
|
||||
"attributes_conns": ["*internal"]
|
||||
},
|
||||
|
||||
"admins": {
|
||||
"enabled": true
|
||||
}
|
||||
|
||||
}
|
||||
53
data/conf/samples/apis_chargers_redis/cgrates.json
Normal file
53
data/conf/samples/apis_chargers_redis/cgrates.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
|
||||
"general": {
|
||||
"reply_timeout": "50s"
|
||||
},
|
||||
|
||||
"logger": {
|
||||
"level": 7
|
||||
},
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080"
|
||||
},
|
||||
|
||||
"db": {
|
||||
"db_conns": {
|
||||
"*default": {
|
||||
"db_type": "redis",
|
||||
"db_host": "127.0.0.1",
|
||||
"db_port": 6379,
|
||||
"db_name": "10",
|
||||
"db_user": "cgrates"
|
||||
},
|
||||
"StorDB": {
|
||||
"db_type": "mysql",
|
||||
"db_host": "127.0.0.1",
|
||||
"db_port": 3306,
|
||||
"db_name": "cgrates",
|
||||
"db_user": "cgrates",
|
||||
"db_password": "CGRateS.org"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
"*cdrs": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"}
|
||||
}
|
||||
},
|
||||
|
||||
"attributes": {
|
||||
"enabled": true
|
||||
},
|
||||
|
||||
"chargers": {
|
||||
"enabled": true,
|
||||
"attributes_conns": ["*internal"]
|
||||
},
|
||||
|
||||
"admins": {
|
||||
"enabled": true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,7 +36,7 @@
|
||||
},
|
||||
},
|
||||
"items": {
|
||||
"*cdrs": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"},
|
||||
"*cdrs": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
},
|
||||
"items": {
|
||||
"*cdrs": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"},
|
||||
"*accounts": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"},
|
||||
"*accounts": {"limit": -1, "ttl": "", "static_ttl": false, "remote":false, "replicate":false, "dbConn": "StorDB"}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -44,4 +44,15 @@ CREATE TABLE action_profiles (
|
||||
PRIMARY KEY (`pk`),
|
||||
UNIQUE KEY unique_tenant_id (`tenant`, `id`)
|
||||
);
|
||||
CREATE UNIQUE INDEX action_profiles_idx ON action_profiles (`id`);
|
||||
CREATE UNIQUE INDEX action_profiles_idx ON action_profiles (`id`);
|
||||
|
||||
DROP TABLE IF EXISTS charger_profiles;
|
||||
CREATE TABLE charger_profiles (
|
||||
`pk` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`tenant` VARCHAR(40) NOT NULL,
|
||||
`id` VARCHAR(64) NOT NULL,
|
||||
`charger_profile` JSON NOT NULL,
|
||||
PRIMARY KEY (`pk`),
|
||||
UNIQUE KEY unique_tenant_id (`tenant`, `id`)
|
||||
);
|
||||
CREATE UNIQUE INDEX charger_profiles_idx ON charger_profiles (`id`);
|
||||
@@ -43,3 +43,14 @@ CREATE TABLE action_profiles (
|
||||
UNIQUE (tenant, id)
|
||||
);
|
||||
CREATE UNIQUE INDEX action_profiles_idx ON action_profiles ("id");
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS charger_profiles;
|
||||
CREATE TABLE charger_profiles (
|
||||
pk SERIAL PRIMARY KEY,
|
||||
tenant VARCHAR(40) NOT NULL,
|
||||
id VARCHAR(64) NOT NULL,
|
||||
charger_profile JSONB NOT NULL,
|
||||
UNIQUE (tenant, id)
|
||||
);
|
||||
CREATE UNIQUE INDEX charger_profiles_idx ON charger_profiles ("id");
|
||||
|
||||
@@ -426,3 +426,14 @@ type ActionProfileJSONMdl struct {
|
||||
func (ActionProfileJSONMdl) TableName() string {
|
||||
return utils.TBLActionProfilesJSON
|
||||
}
|
||||
|
||||
type ChargerProfileMdl struct {
|
||||
PK uint `gorm:"primary_key"`
|
||||
Tenant string `index:"0" re:".*"`
|
||||
ID string `index:"1" re:".*"`
|
||||
ChargerProfile utils.JSONB `gorm:"type:jsonb" index:"2" re:".*"`
|
||||
}
|
||||
|
||||
func (ChargerProfileMdl) TableName() string {
|
||||
return utils.TBLChargerProfilesJSON
|
||||
}
|
||||
|
||||
@@ -106,6 +106,8 @@ func (sqls *SQLStorage) GetKeysForPrefix(ctx *context.Context, prefix string) (k
|
||||
keys, err = sqls.getAllKeysMatchingTenantID(ctx, utils.TBLIPAllocations, tntID)
|
||||
case utils.ActionProfilePrefix:
|
||||
keys, err = sqls.getAllKeysMatchingTenantID(ctx, utils.TBLActionProfilesJSON, tntID)
|
||||
case utils.ChargerProfilePrefix:
|
||||
keys, err = sqls.getAllKeysMatchingTenantID(ctx, utils.TBLChargerProfilesJSON, tntID)
|
||||
default:
|
||||
err = fmt.Errorf("unsupported prefix in GetKeysForPrefix: %q", prefix)
|
||||
}
|
||||
@@ -534,8 +536,7 @@ func (sqls *SQLStorage) GetActionProfileDrv(ctx *context.Context, tenant, id str
|
||||
if len(result) == 0 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
ap, err = utils.MapStringInterfaceToActionProfile(result[0].ActionProfile)
|
||||
return
|
||||
return utils.MapStringInterfaceToActionProfile(result[0].ActionProfile)
|
||||
}
|
||||
|
||||
func (sqls *SQLStorage) SetActionProfileDrv(ctx *context.Context, ap *utils.ActionProfile) (err error) {
|
||||
@@ -570,6 +571,51 @@ func (sqls *SQLStorage) RemoveActionProfileDrv(ctx *context.Context, tenant, id
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sqls *SQLStorage) GetChargerProfileDrv(_ *context.Context, tenant, id string) (cp *utils.ChargerProfile, err error) {
|
||||
var result []*ChargerProfileMdl
|
||||
if err := sqls.db.Model(&ChargerProfileMdl{}).Where(&ChargerProfileMdl{Tenant: tenant,
|
||||
ID: id}).Find(&result).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(result) == 0 {
|
||||
return nil, utils.ErrNotFound
|
||||
}
|
||||
|
||||
return utils.MapStringInterfaceToChargerProfile(result[0].ChargerProfile)
|
||||
}
|
||||
|
||||
func (sqls *SQLStorage) SetChargerProfileDrv(_ *context.Context, cp *utils.ChargerProfile) (err error) {
|
||||
tx := sqls.db.Begin()
|
||||
mdl := &ChargerProfileMdl{
|
||||
Tenant: cp.Tenant,
|
||||
ID: cp.ID,
|
||||
ChargerProfile: cp.AsMapStringInterface(),
|
||||
}
|
||||
if err := tx.Model(&ChargerProfileMdl{}).Where(
|
||||
ChargerProfileMdl{Tenant: mdl.Tenant, ID: mdl.ID}).Delete(
|
||||
ChargerProfileMdl{}).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
if err := tx.Save(mdl).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sqls *SQLStorage) RemoveChargerProfileDrv(_ *context.Context, tenant, id string) (err error) {
|
||||
tx := sqls.db.Begin()
|
||||
if err := tx.Model(&ChargerProfileMdl{}).Where(&ChargerProfileMdl{Tenant: tenant, ID: id}).
|
||||
Delete(&ChargerProfileMdl{}).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddLoadHistory DataDB method not implemented yet
|
||||
func (sqls *SQLStorage) AddLoadHistory(ldInst *utils.LoadInstance,
|
||||
loadHistSize int, transactionID string) error {
|
||||
@@ -807,21 +853,6 @@ func (sqls *SQLStorage) RemoveAttributeProfileDrv(ctx *context.Context, tenant,
|
||||
return utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
// DataDB method not implemented yet
|
||||
func (sqls *SQLStorage) GetChargerProfileDrv(_ *context.Context, tenant, id string) (r *utils.ChargerProfile, err error) {
|
||||
return nil, utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
// DataDB method not implemented yet
|
||||
func (sqls *SQLStorage) SetChargerProfileDrv(_ *context.Context, r *utils.ChargerProfile) (err error) {
|
||||
return utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
// DataDB method not implemented yet
|
||||
func (sqls *SQLStorage) RemoveChargerProfileDrv(_ *context.Context, tenant, id string) (err error) {
|
||||
return utils.ErrNotImplemented
|
||||
}
|
||||
|
||||
// GetStorageType returns the storage type that is being used
|
||||
func (sqls *SQLStorage) GetStorageType() string {
|
||||
return utils.MetaMySQL
|
||||
|
||||
@@ -173,3 +173,38 @@ type ChargerProfileWithAPIOpts struct {
|
||||
*ChargerProfile
|
||||
APIOpts map[string]any
|
||||
}
|
||||
|
||||
// AsMapStringInterface converts ChargerProfile struct to map[string]any
|
||||
func (cp *ChargerProfile) AsMapStringInterface() map[string]any {
|
||||
if cp == nil {
|
||||
return nil
|
||||
}
|
||||
return map[string]any{
|
||||
Tenant: cp.Tenant,
|
||||
ID: cp.ID,
|
||||
FilterIDs: cp.FilterIDs,
|
||||
Weights: cp.Weights,
|
||||
Blockers: cp.Blockers,
|
||||
RunID: cp.RunID,
|
||||
AttributeIDs: cp.AttributeIDs,
|
||||
}
|
||||
}
|
||||
|
||||
// MapStringInterfaceToChargerProfile converts map[string]any to ChargerProfile struct
|
||||
func MapStringInterfaceToChargerProfile(m map[string]any) (cp *ChargerProfile, err error) {
|
||||
cp = &ChargerProfile{}
|
||||
if v, ok := m[Tenant].(string); ok {
|
||||
cp.Tenant = v
|
||||
}
|
||||
if v, ok := m[ID].(string); ok {
|
||||
cp.ID = v
|
||||
}
|
||||
cp.FilterIDs = InterfaceToStringSlice(m[FilterIDs])
|
||||
cp.Weights = InterfaceToDynamicWeights(m[Weights])
|
||||
cp.Blockers = InterfaceToDynamicBlockers(m[Blockers])
|
||||
if v, ok := m[RunID].(string); ok {
|
||||
cp.RunID = v
|
||||
}
|
||||
cp.AttributeIDs = InterfaceToStringSlice(m[AttributeIDs])
|
||||
return cp, nil
|
||||
}
|
||||
|
||||
@@ -1897,28 +1897,29 @@ const (
|
||||
|
||||
// Table Name
|
||||
const (
|
||||
TBLTPResources = "tp_resources"
|
||||
TBLTPStats = "tp_stats"
|
||||
TBLTPRankings = "tp_rankings"
|
||||
TBLTPTrends = "tp_trends"
|
||||
TBLTPThresholds = "tp_thresholds"
|
||||
TBLTPFilters = "tp_filters"
|
||||
SessionCostsTBL = "session_costs"
|
||||
CDRsTBL = "cdrs"
|
||||
TBLTPRoutes = "tp_routes"
|
||||
TBLTPAttributes = "tp_attributes"
|
||||
TBLTPChargers = "tp_chargers"
|
||||
TBLVersions = "versions"
|
||||
TBLAccounts = "accounts"
|
||||
TBLIPProfiles = "ip_profiles"
|
||||
TBLIPAllocations = "ip_allocations"
|
||||
TBLActionProfilesJSON = "action_profiles"
|
||||
OldSMCosts = "sm_costs"
|
||||
TBLTPDispatchers = "tp_dispatcher_profiles"
|
||||
TBLTPDispatcherHosts = "tp_dispatcher_hosts"
|
||||
TBLTPRateProfiles = "tp_rate_profiles"
|
||||
TBLTPActionProfiles = "tp_action_profiles"
|
||||
TBLTPAccounts = "tp_accounts"
|
||||
TBLTPResources = "tp_resources"
|
||||
TBLTPStats = "tp_stats"
|
||||
TBLTPRankings = "tp_rankings"
|
||||
TBLTPTrends = "tp_trends"
|
||||
TBLTPThresholds = "tp_thresholds"
|
||||
TBLTPFilters = "tp_filters"
|
||||
SessionCostsTBL = "session_costs"
|
||||
CDRsTBL = "cdrs"
|
||||
TBLTPRoutes = "tp_routes"
|
||||
TBLTPAttributes = "tp_attributes"
|
||||
TBLTPChargers = "tp_chargers"
|
||||
TBLVersions = "versions"
|
||||
TBLAccounts = "accounts"
|
||||
TBLIPProfiles = "ip_profiles"
|
||||
TBLIPAllocations = "ip_allocations"
|
||||
TBLActionProfilesJSON = "action_profiles"
|
||||
TBLChargerProfilesJSON = "charger_profiles"
|
||||
OldSMCosts = "sm_costs"
|
||||
TBLTPDispatchers = "tp_dispatcher_profiles"
|
||||
TBLTPDispatcherHosts = "tp_dispatcher_hosts"
|
||||
TBLTPRateProfiles = "tp_rate_profiles"
|
||||
TBLTPActionProfiles = "tp_action_profiles"
|
||||
TBLTPAccounts = "tp_accounts"
|
||||
)
|
||||
|
||||
// Cache Name
|
||||
|
||||
Reference in New Issue
Block a user