diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index 6caa32909..57c039277 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -600,8 +600,7 @@ func startChargerService(internalChargerSChan chan rpcclient.RpcClientConnection return } } - cS, err := engine.NewChargerService(dm, filterS, attrSConn, - cfg.ChargerSCfg().StringIndexedFields, cfg.ChargerSCfg().PrefixIndexedFields) + cS, err := engine.NewChargerService(dm, filterS, attrSConn, cfg) if err != nil { utils.Logger.Crit( fmt.Sprintf("<%s> Could not init, error: %s", diff --git a/engine/chargers.go b/engine/chargers.go index 084e430b0..f1de985df 100644 --- a/engine/chargers.go +++ b/engine/chargers.go @@ -21,37 +21,24 @@ package engine import ( "fmt" + "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" "github.com/cgrates/rpcclient" ) -// ChargerProfile is the config for one Charger -type ChargerProfile struct { - Tenant string - ID string - FilterIDs []string - ActivationInterval *utils.ActivationInterval // Activation interval - RunID string - AttributeIDs []string // perform data aliasing based on these Attributes - Weight float64 -} - func NewChargerService(dm *DataManager, filterS *FilterS, attrS rpcclient.RpcClientConnection, - strgIdxFlds, prfxIdxFlds *[]string) (*ChargerService, error) { + cfg *config.CGRConfig) (*ChargerService, error) { return &ChargerService{dm: dm, filterS: filterS, - attrS: attrS, - strgIdxFlds: strgIdxFlds, - prfxIdxFlds: prfxIdxFlds}, nil + attrS: attrS, cfg: cfg}, nil } // ChargerService is performing charging type ChargerService struct { - dm *DataManager - filterS *FilterS - attrS rpcclient.RpcClientConnection - strgIdxFlds *[]string - prfxIdxFlds *[]string + dm *DataManager + filterS *FilterS + attrS rpcclient.RpcClientConnection + cfg *config.CGRConfig } // ListenAndServe will initialize the service @@ -69,6 +56,45 @@ func (cS *ChargerService) Shutdown() (err error) { return } +// matchingChargingProfilesForEvent returns ordered list of matching chargers which are active by the time of the function call +func (cS *ChargerService) matchingChargingProfilesForEvent(cgrEv *utils.CGREvent) (cPs ChargerProfiles, err error) { + cpIDs, err := matchingItemIDsForEvent(cgrEv.Event, + cS.cfg.ChargerSCfg().StringIndexedFields, cS.cfg.ChargerSCfg().PrefixIndexedFields, + cS.dm, utils.CacheChargerFilterIndexes, cgrEv.Tenant, cS.cfg.FilterSCfg().IndexedSelects) + if err != nil { + return nil, err + } + matchingCPs := make(map[string]*ChargerProfile) + for cpID := range cpIDs { + cP, err := cS.dm.GetChargerProfile(cgrEv.Tenant, cpID, false, utils.NonTransactional) + if err != nil { + if err == utils.ErrNotFound { + continue + } + return nil, err + } + if cP.ActivationInterval != nil && cgrEv.Time != nil && + !cP.ActivationInterval.IsActiveAtTime(*cgrEv.Time) { // not active + continue + } + if pass, err := cS.filterS.Pass(cgrEv.Tenant, cP.FilterIDs, + NewNavigableMap(cgrEv.Event)); err != nil { + return nil, err + } else if !pass { + continue + } + matchingCPs[cpID] = cP + } + cPs = make(ChargerProfiles, len(matchingCPs)) + i := 0 + for _, cP := range matchingCPs { + cPs[i] = cP + i++ + } + cPs.Sort() + return +} + func (cS *ChargerService) processEvent(cgrEv *utils.CGREvent) (cgrEvs []*utils.CGREvent, err error) { return } diff --git a/engine/libchargers.go b/engine/libchargers.go new file mode 100644 index 000000000..d3609e4d2 --- /dev/null +++ b/engine/libchargers.go @@ -0,0 +1,48 @@ +/* +Real-time Online/Offline Charging System (OCS) 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 +*/ + +package engine + +import ( + "sort" + + "github.com/cgrates/cgrates/utils" +) + +// ChargerProfile is the config for one Charger +type ChargerProfile struct { + Tenant string + ID string + FilterIDs []string + ActivationInterval *utils.ActivationInterval // Activation interval + RunID string + AttributeIDs []string // perform data aliasing based on these Attributes + Weight float64 +} + +func (cP *ChargerProfile) TenantID() string { + return utils.ConcatenatedKey(cP.Tenant, cP.ID) +} + +// ChargerProfiles is a sortable list of Charger profiles +type ChargerProfiles []*ChargerProfile + +// Sort is part of sort interface, sort based on Weight +func (cps ChargerProfiles) Sort() { + sort.Slice(cps, func(i, j int) bool { return cps[i].Weight > cps[j].Weight }) +}