mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-14 12:49:54 +05:00
Updated routes APIs
This commit is contained in:
committed by
Dan Christian Bogos
parent
37e5481307
commit
eab2338360
@@ -3592,26 +3592,26 @@ func testV1FIdxSetRouteSProfileWithFltr(t *testing.T) {
|
||||
}
|
||||
|
||||
//we will set a RouteProfile with our filter and check the indexes
|
||||
rtPrf := &RouteWithAPIOpts{
|
||||
RouteProfile: &engine.RouteProfile{
|
||||
rtPrf := &engine.APIRouteProfileWithAPIOpts{
|
||||
APIRouteProfile: &engine.APIRouteProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ROUTE_1",
|
||||
FilterIDs: []string{"fltr_for_attr",
|
||||
"*string:~*req.Account:1001"},
|
||||
Sorting: utils.MetaWeight,
|
||||
Routes: []*engine.Route{
|
||||
Routes: []*engine.ExternalRoute{
|
||||
{
|
||||
ID: "local",
|
||||
RateProfileIDs: []string{"RP_LOCAL"},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
},
|
||||
{
|
||||
ID: "mobile",
|
||||
RateProfileIDs: []string{"RP_MOBILE"},
|
||||
Weights: utils.DynamicWeights{{Weight: 30}},
|
||||
Weights: ";30",
|
||||
},
|
||||
},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
},
|
||||
}
|
||||
if err := tFIdxRpc.Call(context.Background(), utils.AdminSv1SetRouteProfile,
|
||||
@@ -3690,27 +3690,27 @@ func testV1FIdxSetRouteSMoreFltrsMoreIndexing(t *testing.T) {
|
||||
t.Error("Unexpected reply result", reply)
|
||||
}
|
||||
// update our RoutesProfile with our filters
|
||||
rtPrf := &RouteWithAPIOpts{
|
||||
RouteProfile: &engine.RouteProfile{
|
||||
rtPrf := &engine.APIRouteProfileWithAPIOpts{
|
||||
APIRouteProfile: &engine.APIRouteProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ROUTE_1",
|
||||
FilterIDs: []string{"fltr_for_attr",
|
||||
"fltr_for_attr2", "fltr_for_attr3",
|
||||
"*string:~*req.Account:1001"},
|
||||
Sorting: utils.MetaWeight,
|
||||
Routes: []*engine.Route{
|
||||
Routes: []*engine.ExternalRoute{
|
||||
{
|
||||
ID: "local",
|
||||
RateProfileIDs: []string{"RP_LOCAL"},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
},
|
||||
{
|
||||
ID: "mobile",
|
||||
RateProfileIDs: []string{"RP_MOBILE"},
|
||||
Weights: utils.DynamicWeights{{Weight: 30}},
|
||||
Weights: ";30",
|
||||
},
|
||||
},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
},
|
||||
}
|
||||
if err := tFIdxRpc.Call(context.Background(), utils.AdminSv1SetRouteProfile,
|
||||
@@ -3800,38 +3800,38 @@ func testV1FIdxRouteSProfileComputeIndexes(t *testing.T) {
|
||||
|
||||
func testV1FIdxRouteSMoreProfilesForFltrs(t *testing.T) {
|
||||
// will add more routes with our filters for matching indexes
|
||||
rtPrf1 := &RouteWithAPIOpts{
|
||||
RouteProfile: &engine.RouteProfile{
|
||||
rtPrf1 := &engine.APIRouteProfileWithAPIOpts{
|
||||
APIRouteProfile: &engine.APIRouteProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ROUTE_2",
|
||||
FilterIDs: []string{"fltr_for_attr2", "fltr_for_attr3",
|
||||
"*string:~*req.Account:1001"},
|
||||
Sorting: utils.MetaWeight,
|
||||
Routes: []*engine.Route{
|
||||
Routes: []*engine.ExternalRoute{
|
||||
{
|
||||
ID: "route1",
|
||||
RateProfileIDs: []string{"RP_LOCAL"},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
},
|
||||
},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
},
|
||||
}
|
||||
rtPrf2 := &RouteWithAPIOpts{
|
||||
RouteProfile: &engine.RouteProfile{
|
||||
rtPrf2 := &engine.APIRouteProfileWithAPIOpts{
|
||||
APIRouteProfile: &engine.APIRouteProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ROUTE_3",
|
||||
FilterIDs: []string{"fltr_for_attr",
|
||||
"*string:~*req.Account:1001"},
|
||||
Sorting: utils.MetaWeight,
|
||||
Routes: []*engine.Route{
|
||||
Routes: []*engine.ExternalRoute{
|
||||
{
|
||||
ID: "route2",
|
||||
RateProfileIDs: []string{"RP_LOCAL"},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
},
|
||||
},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
},
|
||||
}
|
||||
var reply string
|
||||
|
||||
@@ -799,22 +799,22 @@ func testLoadersGetRouteProfile(t *testing.T) {
|
||||
t.Errorf("expected: <%+v>, \nreceived: <%+v>", expIDs, rtIDs)
|
||||
}
|
||||
|
||||
expRtPrf := engine.RouteProfile{
|
||||
expRtPrf := engine.APIRouteProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "ROUTE_ACNT_1001",
|
||||
FilterIDs: []string{"FLTR_ACCOUNT_1001"},
|
||||
Sorting: utils.MetaWeight,
|
||||
SortingParameters: []string{},
|
||||
Routes: []*engine.Route{
|
||||
Routes: []*engine.ExternalRoute{
|
||||
{
|
||||
ID: "route1",
|
||||
Weights: utils.DynamicWeights{{Weight: 20}},
|
||||
Weights: ";20",
|
||||
},
|
||||
},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
}
|
||||
|
||||
var rplyRtPrf engine.RouteProfile
|
||||
var rplyRtPrf engine.APIRouteProfile
|
||||
if err := ldrRPC.Call(context.Background(), utils.AdminSv1GetRouteProfile,
|
||||
utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
@@ -1116,7 +1116,7 @@ func testLoadersGetRouteProfileAfterRemove(t *testing.T) {
|
||||
t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err)
|
||||
}
|
||||
|
||||
var rplyRtPrf engine.RouteProfile
|
||||
var rplyRtPrf engine.APIRouteProfile
|
||||
if err := ldrRPC.Call(context.Background(), utils.AdminSv1GetRouteProfile,
|
||||
utils.TenantID{
|
||||
Tenant: "cgrates.org",
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
// GetRouteProfile returns a Route configuration
|
||||
func (adms *AdminSv1) GetRouteProfile(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *engine.RouteProfile) error {
|
||||
func (adms *AdminSv1) GetRouteProfile(ctx *context.Context, arg *utils.TenantIDWithAPIOpts, reply *engine.APIRouteProfile) error {
|
||||
if missing := utils.MissingStructFields(arg, []string{utils.ID}); len(missing) != 0 { //Params missing
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
@@ -35,7 +35,7 @@ func (adms *AdminSv1) GetRouteProfile(ctx *context.Context, arg *utils.TenantIDW
|
||||
if rp, err := adms.dm.GetRouteProfile(ctx, tnt, arg.ID, true, true, utils.NonTransactional); err != nil {
|
||||
return utils.APIErrorHandler(err)
|
||||
} else {
|
||||
*reply = *rp
|
||||
*reply = *engine.NewAPIRouteProfile(rp)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -81,20 +81,19 @@ func (adms *AdminSv1) GetRouteProfileCount(ctx *context.Context, args *utils.Ten
|
||||
return nil
|
||||
}
|
||||
|
||||
type RouteWithAPIOpts struct {
|
||||
*engine.RouteProfile
|
||||
APIOpts map[string]interface{}
|
||||
}
|
||||
|
||||
//SetRouteProfile add a new Route configuration
|
||||
func (adms *AdminSv1) SetRouteProfile(ctx *context.Context, args *RouteWithAPIOpts, reply *string) error {
|
||||
if missing := utils.MissingStructFields(args.RouteProfile, []string{utils.ID}); len(missing) != 0 {
|
||||
func (adms *AdminSv1) SetRouteProfile(ctx *context.Context, args *engine.APIRouteProfileWithAPIOpts, reply *string) error {
|
||||
if missing := utils.MissingStructFields(args.APIRouteProfile, []string{utils.ID}); len(missing) != 0 {
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
if args.Tenant == utils.EmptyString {
|
||||
args.Tenant = adms.cfg.GeneralCfg().DefaultTenant
|
||||
}
|
||||
if err := adms.dm.SetRouteProfile(ctx, args.RouteProfile, true); err != nil {
|
||||
rp, err := args.AsRouteProfile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := adms.dm.SetRouteProfile(ctx, rp, true); err != nil {
|
||||
return utils.APIErrorHandler(err)
|
||||
}
|
||||
//generate a loadID for CacheRouteProfiles and store it in database
|
||||
@@ -103,7 +102,7 @@ func (adms *AdminSv1) SetRouteProfile(ctx *context.Context, args *RouteWithAPIOp
|
||||
}
|
||||
//handle caching for SupplierProfile
|
||||
if err := adms.CallCache(ctx, utils.IfaceAsString(args.APIOpts[utils.CacheOpt]), args.Tenant, utils.CacheRouteProfiles,
|
||||
args.TenantID(), &args.FilterIDs, args.APIOpts); err != nil {
|
||||
rp.TenantID(), &args.FilterIDs, args.APIOpts); err != nil {
|
||||
return utils.APIErrorHandler(err)
|
||||
}
|
||||
*reply = utils.OK
|
||||
|
||||
@@ -43,15 +43,16 @@ func TestRoutesSetGetRemRouteProfile(t *testing.T) {
|
||||
ID: "routeID",
|
||||
},
|
||||
}
|
||||
var result engine.RouteProfile
|
||||
var result engine.APIRouteProfile
|
||||
var reply string
|
||||
|
||||
rtPrf := &RouteWithAPIOpts{
|
||||
RouteProfile: &engine.RouteProfile{
|
||||
rtPrf := &engine.APIRouteProfileWithAPIOpts{
|
||||
APIRouteProfile: &engine.APIRouteProfile{
|
||||
Tenant: "cgrates.org",
|
||||
ID: "routeID",
|
||||
FilterIDs: []string{"*string:~*req.Account:1001"},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
Routes: []*engine.ExternalRoute{{}},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -63,9 +64,9 @@ func TestRoutesSetGetRemRouteProfile(t *testing.T) {
|
||||
|
||||
if err := adms.GetRouteProfile(context.Background(), arg, &result); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(result, *rtPrf.RouteProfile) {
|
||||
} else if !reflect.DeepEqual(result, *rtPrf.APIRouteProfile) {
|
||||
t.Errorf("\nexpected: <%+v>, \nreceived: <%+v>",
|
||||
utils.ToJSON(rtPrf.RouteProfile), utils.ToJSON(result))
|
||||
utils.ToJSON(rtPrf.APIRouteProfile), utils.ToJSON(result))
|
||||
}
|
||||
|
||||
var rtPrfIDs []string
|
||||
@@ -112,7 +113,7 @@ func TestRoutesGetRouteProfileCheckErrors(t *testing.T) {
|
||||
cfg: cfg,
|
||||
dm: dm,
|
||||
}
|
||||
var rcv engine.RouteProfile
|
||||
var rcv engine.APIRouteProfile
|
||||
experr := "MANDATORY_IE_MISSING: [ID]"
|
||||
|
||||
if err := adms.GetRouteProfile(context.Background(), &utils.TenantIDWithAPIOpts{
|
||||
@@ -145,8 +146,10 @@ func TestRoutesSetRouteProfileCheckErrors(t *testing.T) {
|
||||
dm: dm,
|
||||
}
|
||||
|
||||
rtPrf := &RouteWithAPIOpts{
|
||||
RouteProfile: &engine.RouteProfile{},
|
||||
rtPrf := &engine.APIRouteProfileWithAPIOpts{
|
||||
APIRouteProfile: &engine.APIRouteProfile{
|
||||
Routes: []*engine.ExternalRoute{{}},
|
||||
},
|
||||
}
|
||||
|
||||
var reply string
|
||||
@@ -219,11 +222,12 @@ func TestRoutesRemoveRouteProfileCheckErrors(t *testing.T) {
|
||||
dm: dm,
|
||||
}
|
||||
|
||||
rtPrf := &RouteWithAPIOpts{
|
||||
RouteProfile: &engine.RouteProfile{
|
||||
rtPrf := &engine.APIRouteProfileWithAPIOpts{
|
||||
APIRouteProfile: &engine.APIRouteProfile{
|
||||
ID: "TestRoutesRemoveRouteProfileCheckErrors",
|
||||
Tenant: "cgrates.org",
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
Routes: []*engine.ExternalRoute{{}},
|
||||
},
|
||||
}
|
||||
var reply string
|
||||
@@ -249,7 +253,7 @@ func TestRoutesRemoveRouteProfileCheckErrors(t *testing.T) {
|
||||
cancel()
|
||||
|
||||
adms.cfg.GeneralCfg().DefaultCaching = utils.MetaNone
|
||||
var rcv engine.RouteProfile
|
||||
var rcv engine.APIRouteProfile
|
||||
|
||||
if err := adms.GetRouteProfile(context.Background(), &utils.TenantIDWithAPIOpts{
|
||||
TenantID: &utils.TenantID{
|
||||
|
||||
@@ -180,7 +180,7 @@ func testCgrLdrGetSubsystemsNotLoadedLoad(t *testing.T) {
|
||||
}
|
||||
|
||||
// routesPrf
|
||||
var replyRts *engine.RouteProfile
|
||||
var replyRts *engine.APIRouteProfile
|
||||
if err := cgrLdrBIRPC.Call(context.Background(), utils.AdminSv1GetRouteProfile,
|
||||
&utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ROUTE_ACNT_1001"}},
|
||||
&replyRts); err == nil || err.Error() != utils.ErrNotFound.Error() {
|
||||
@@ -534,25 +534,25 @@ func testCgrLdrGetResourceAfterLoad(t *testing.T) {
|
||||
}
|
||||
|
||||
func testCgrLdrGetRouteProfileAfterLoad(t *testing.T) {
|
||||
expRoutePrf := &engine.RouteProfile{
|
||||
expRoutePrf := &engine.APIRouteProfile{
|
||||
ID: "ROUTE_ACNT_1001",
|
||||
Tenant: "cgrates.org",
|
||||
FilterIDs: []string{"FLTR_ACCOUNT_1001"},
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
Sorting: utils.MetaWeight,
|
||||
SortingParameters: []string{},
|
||||
Routes: []*engine.Route{
|
||||
Routes: []*engine.ExternalRoute{
|
||||
{
|
||||
ID: "route1",
|
||||
Weights: utils.DynamicWeights{{Weight: 20}},
|
||||
Weights: ";20",
|
||||
},
|
||||
{
|
||||
ID: "route2",
|
||||
Weights: utils.DynamicWeights{{Weight: 10}},
|
||||
Weights: ";10",
|
||||
},
|
||||
},
|
||||
}
|
||||
var replyRts *engine.RouteProfile
|
||||
var replyRts *engine.APIRouteProfile
|
||||
if err := cgrLdrBIRPC.Call(context.Background(), utils.AdminSv1GetRouteProfile,
|
||||
&utils.TenantIDWithAPIOpts{TenantID: &utils.TenantID{Tenant: "cgrates.org", ID: "ROUTE_ACNT_1001"}},
|
||||
&replyRts); err != nil {
|
||||
|
||||
@@ -60,6 +60,6 @@ func (self *CmdGetRoute) PostprocessRpcParams() error {
|
||||
}
|
||||
|
||||
func (self *CmdGetRoute) RpcResult() interface{} {
|
||||
var atr engine.RouteProfile
|
||||
var atr engine.APIRouteProfile
|
||||
return &atr
|
||||
}
|
||||
|
||||
@@ -320,3 +320,97 @@ type RouteWithWeight struct {
|
||||
Weight float64
|
||||
lazyCheckRules []*FilterRule
|
||||
}
|
||||
|
||||
// ExternalRoute the attribute for external profile
|
||||
type ExternalRoute struct {
|
||||
ID string // RouteID
|
||||
FilterIDs []string
|
||||
AccountIDs []string
|
||||
RateProfileIDs []string // used when computing price
|
||||
ResourceIDs []string // queried in some strategies
|
||||
StatIDs []string // queried in some strategies
|
||||
Weights string
|
||||
Blocker bool // do not process further route after this one
|
||||
RouteParameters string
|
||||
}
|
||||
|
||||
// APIRouteProfile used by APIs
|
||||
type APIRouteProfile struct {
|
||||
Tenant string
|
||||
ID string // LCR Profile ID
|
||||
FilterIDs []string
|
||||
Sorting string // Sorting strategy
|
||||
SortingParameters []string
|
||||
Routes []*ExternalRoute
|
||||
Weights string
|
||||
}
|
||||
|
||||
type APIRouteProfileWithAPIOpts struct {
|
||||
*APIRouteProfile
|
||||
APIOpts map[string]interface{}
|
||||
}
|
||||
|
||||
func NewAPIRouteProfile(attr *RouteProfile) (ext *APIRouteProfile) {
|
||||
ext = &APIRouteProfile{
|
||||
Tenant: attr.Tenant,
|
||||
ID: attr.ID,
|
||||
FilterIDs: attr.FilterIDs,
|
||||
Sorting: attr.Sorting,
|
||||
SortingParameters: attr.SortingParameters,
|
||||
Routes: make([]*ExternalRoute, len(attr.Routes)),
|
||||
Weights: attr.Weights.String(utils.InfieldSep, utils.ANDSep),
|
||||
}
|
||||
for i, r := range attr.Routes {
|
||||
ext.Routes[i] = &ExternalRoute{
|
||||
ID: r.ID,
|
||||
FilterIDs: r.FilterIDs,
|
||||
AccountIDs: r.AccountIDs,
|
||||
RateProfileIDs: r.RateProfileIDs,
|
||||
ResourceIDs: r.ResourceIDs,
|
||||
StatIDs: r.StatIDs,
|
||||
Weights: r.Weights.String(utils.InfieldSep, utils.ANDSep),
|
||||
Blocker: r.Blocker,
|
||||
RouteParameters: r.RouteParameters,
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AsAttributeProfile converts the external attribute format to the actual AttributeProfile
|
||||
func (ext *APIRouteProfile) AsRouteProfile() (rp *RouteProfile, err error) {
|
||||
if len(ext.Routes) == 0 {
|
||||
return nil, utils.NewErrMandatoryIeMissing("Routes")
|
||||
}
|
||||
rp = &RouteProfile{
|
||||
Tenant: ext.Tenant,
|
||||
ID: ext.ID,
|
||||
FilterIDs: ext.FilterIDs,
|
||||
Sorting: ext.Sorting,
|
||||
SortingParameters: ext.SortingParameters,
|
||||
Routes: make([]*Route, len(ext.Routes)),
|
||||
}
|
||||
if ext.Weights != utils.EmptyString {
|
||||
if rp.Weights, err = utils.NewDynamicWeightsFromString(ext.Weights, utils.InfieldSep, utils.ANDSep); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
for i, extR := range ext.Routes {
|
||||
rp.Routes[i] = &Route{
|
||||
ID: extR.ID,
|
||||
FilterIDs: extR.FilterIDs,
|
||||
AccountIDs: extR.AccountIDs,
|
||||
RateProfileIDs: extR.RateProfileIDs,
|
||||
ResourceIDs: extR.ResourceIDs,
|
||||
StatIDs: extR.StatIDs,
|
||||
Blocker: extR.Blocker,
|
||||
RouteParameters: extR.RouteParameters,
|
||||
}
|
||||
if extR.Weights != utils.EmptyString {
|
||||
if rp.Routes[i].Weights, err = utils.NewDynamicWeightsFromString(extR.Weights, utils.InfieldSep, utils.ANDSep); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
err = rp.Compile()
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user