From d709713f9978a4e50ed8ce6eaf6695c52cca9eff Mon Sep 17 00:00:00 2001 From: TeoV Date: Fri, 8 Dec 2017 14:01:28 +0200 Subject: [PATCH] Add ReverseIndex to ReqFilterIndexer --- engine/filterindexer.go | 84 +++++- engine/storage_map.go | 4 +- engine/suppliers_test.go | 2 +- engine/tp_reader.go | 110 ++++---- utils/consts.go | 547 ++++++++++++++++++++------------------- 5 files changed, 419 insertions(+), 328 deletions(-) diff --git a/engine/filterindexer.go b/engine/filterindexer.go index fd8d0c361..5bf133c63 100644 --- a/engine/filterindexer.go +++ b/engine/filterindexer.go @@ -22,36 +22,51 @@ import ( "github.com/cgrates/cgrates/utils" ) -func NewReqFilterIndexer(dm *DataManager, dbKey string) (*ReqFilterIndexer, error) { - indexes, err := dm.GetReqFilterIndexes(dbKey) +func NewReqFilterIndexer(dm *DataManager, itemType, dbKeySuffix string) (*ReqFilterIndexer, error) { + indexes, err := dm.GetReqFilterIndexes(GetDBIndexKey(itemType, dbKeySuffix, false)) if err != nil && err != utils.ErrNotFound { return nil, err } if indexes == nil { indexes = make(map[string]map[string]utils.StringMap) } - return &ReqFilterIndexer{dm: dm, dbKey: dbKey, - indexes: indexes, chngdIndxKeys: make(utils.StringMap)}, nil + reverseIndexes, err := dm.GetReqFilterIndexes(GetDBIndexKey(itemType, dbKeySuffix, true)) + if err != nil && err != utils.ErrNotFound { + return nil, err + } + if reverseIndexes == nil { + reverseIndexes = make(map[string]map[string]utils.StringMap) + } + return &ReqFilterIndexer{dm: dm, itemType: itemType, dbKeySuffix: dbKeySuffix, + indexes: indexes, reveseIndex: reverseIndexes, chngdIndxKeys: make(utils.StringMap), + chngdRevIndxKeys: make(utils.StringMap)}, nil } // ReqFilterIndexer is a centralized indexer for all data sources using RequestFilter // retrieves and stores it's data from/to dataDB // not thread safe, meant to be used as logic within other code blocks type ReqFilterIndexer struct { - indexes map[string]map[string]utils.StringMap // map[fieldName]map[fieldValue]utils.StringMap[resourceID] - dm *DataManager - dbKey string // get/store the result from/into this key - chngdIndxKeys utils.StringMap // keep record of the changed fieldName:fieldValue pair so we can re-cache wisely + indexes map[string]map[string]utils.StringMap // map[fieldName]map[fieldValue]utils.StringMap[itemID] + reveseIndex map[string]map[string]utils.StringMap // map[itemID]map[fieldName]utils.StringMap[fieldValue] + dm *DataManager + itemType string + dbKeySuffix string // get/store the result from/into this key + chngdIndxKeys utils.StringMap // keep record of the changed fieldName:fieldValue pair so we can re-cache wisely + chngdRevIndxKeys utils.StringMap // keep record of the changed itemID:fieldName pair so we can re-cache wisely } // ChangedKeys returns the changed keys from original indexes so we can reload wisely -func (rfi *ReqFilterIndexer) ChangedKeys() utils.StringMap { +func (rfi *ReqFilterIndexer) ChangedKeys(reverse bool) utils.StringMap { + if reverse { + return rfi.chngdRevIndxKeys + } return rfi.chngdIndxKeys } // IndexFilters parses reqFltrs, adding itemID in the indexes and marks the changed keys in chngdIndxKeys func (rfi *ReqFilterIndexer) IndexFilters(itemID string, reqFltrs []*RequestFilter) { var hasMetaString bool + rfi.reveseIndex[itemID] = make(map[string]utils.StringMap) for _, fltr := range reqFltrs { if fltr.Type != MetaString { continue @@ -60,21 +75,30 @@ func (rfi *ReqFilterIndexer) IndexFilters(itemID string, reqFltrs []*RequestFilt if _, hastIt := rfi.indexes[fltr.FieldName]; !hastIt { rfi.indexes[fltr.FieldName] = make(map[string]utils.StringMap) } + if _, hastIt := rfi.reveseIndex[itemID][fltr.FieldName]; !hastIt { + rfi.reveseIndex[itemID][fltr.FieldName] = make(utils.StringMap) + } for _, fldVal := range fltr.Values { if _, hasIt := rfi.indexes[fltr.FieldName][fldVal]; !hasIt { rfi.indexes[fltr.FieldName][fldVal] = make(utils.StringMap) } rfi.indexes[fltr.FieldName][fldVal][itemID] = true + rfi.reveseIndex[itemID][fltr.FieldName][fldVal] = true rfi.chngdIndxKeys[utils.ConcatenatedKey(fltr.FieldName, fldVal)] = true } + rfi.chngdRevIndxKeys[utils.ConcatenatedKey(itemID, fltr.FieldName)] = true } if !hasMetaString { if _, hasIt := rfi.indexes[utils.NOT_AVAILABLE]; !hasIt { rfi.indexes[utils.NOT_AVAILABLE] = make(map[string]utils.StringMap) } + if _, hastIt := rfi.reveseIndex[itemID][utils.NOT_AVAILABLE]; !hastIt { + rfi.reveseIndex[itemID][utils.NOT_AVAILABLE] = make(utils.StringMap) + } if _, hasIt := rfi.indexes[utils.NOT_AVAILABLE][utils.NOT_AVAILABLE]; !hasIt { rfi.indexes[utils.NOT_AVAILABLE][utils.NOT_AVAILABLE] = make(utils.StringMap) } + rfi.reveseIndex[itemID][utils.NOT_AVAILABLE][utils.NOT_AVAILABLE] = true rfi.indexes[utils.NOT_AVAILABLE][utils.NOT_AVAILABLE][itemID] = true // Fields without real field index will be located in map[NOT_AVAILABLE][NOT_AVAILABLE][rl.ID] } return @@ -83,6 +107,7 @@ func (rfi *ReqFilterIndexer) IndexFilters(itemID string, reqFltrs []*RequestFilt // IndexFilters parses reqFltrs, adding itemID in the indexes and marks the changed keys in chngdIndxKeys func (rfi *ReqFilterIndexer) IndexTPFilter(tpFltr *utils.TPFilter, itemID string) { var hasMetaString bool + rfi.reveseIndex[itemID] = make(map[string]utils.StringMap) for _, fltr := range tpFltr.Filters { if fltr.Type != MetaString { continue @@ -91,27 +116,64 @@ func (rfi *ReqFilterIndexer) IndexTPFilter(tpFltr *utils.TPFilter, itemID string if _, hastIt := rfi.indexes[fltr.FieldName]; !hastIt { rfi.indexes[fltr.FieldName] = make(map[string]utils.StringMap) } + if _, hastIt := rfi.reveseIndex[itemID][fltr.FieldName]; !hastIt { + rfi.reveseIndex[itemID][fltr.FieldName] = make(utils.StringMap) + } for _, fldVal := range fltr.Values { if _, hasIt := rfi.indexes[fltr.FieldName][fldVal]; !hasIt { rfi.indexes[fltr.FieldName][fldVal] = make(utils.StringMap) } rfi.indexes[fltr.FieldName][fldVal][itemID] = true + rfi.reveseIndex[itemID][fltr.FieldName][fldVal] = true rfi.chngdIndxKeys[utils.ConcatenatedKey(fltr.FieldName, fldVal)] = true } + rfi.chngdRevIndxKeys[utils.ConcatenatedKey(itemID, fltr.FieldName)] = true } if !hasMetaString { if _, hasIt := rfi.indexes[utils.NOT_AVAILABLE]; !hasIt { rfi.indexes[utils.NOT_AVAILABLE] = make(map[string]utils.StringMap) } + if _, hastIt := rfi.reveseIndex[itemID][utils.NOT_AVAILABLE]; !hastIt { + rfi.reveseIndex[itemID][utils.NOT_AVAILABLE] = make(utils.StringMap) + } if _, hasIt := rfi.indexes[utils.NOT_AVAILABLE][utils.NOT_AVAILABLE]; !hasIt { rfi.indexes[utils.NOT_AVAILABLE][utils.NOT_AVAILABLE] = make(utils.StringMap) } + rfi.reveseIndex[itemID][utils.NOT_AVAILABLE][utils.NOT_AVAILABLE] = true rfi.indexes[utils.NOT_AVAILABLE][utils.NOT_AVAILABLE][itemID] = true // Fields without real field index will be located in map[NOT_AVAILABLE][NOT_AVAILABLE][rl.ID] } return } // StoreIndexes handles storing the indexes to dataDB -func (rfi *ReqFilterIndexer) StoreIndexes() error { - return rfi.dm.SetReqFilterIndexes(rfi.dbKey, rfi.indexes) +func (rfi *ReqFilterIndexer) StoreIndexes() (err error) { + if err = rfi.dm.SetReqFilterIndexes(GetDBIndexKey(rfi.itemType, rfi.dbKeySuffix, false), rfi.indexes); err != nil { + return + } + return rfi.dm.SetReqFilterIndexes(GetDBIndexKey(rfi.itemType, rfi.dbKeySuffix, true), rfi.reveseIndex) +} + +func GetDBIndexKey(itemType, dbKeySuffix string, reverse bool) (dbKey string) { + var idxPrefix, rIdxPrefix string + switch itemType { + case utils.ThresholdProfilePrefix: + idxPrefix = utils.ThresholdStringIndex + rIdxPrefix = utils.ThresholdStringRevIndex + case utils.ResourceProfilesPrefix: + idxPrefix = utils.ResourceProfilesStringIndex + rIdxPrefix = utils.ResourceProfilesStringRevIndex + case utils.StatQueueProfilePrefix: + idxPrefix = utils.StatQueuesStringIndex + rIdxPrefix = utils.StatQueuesStringRevIndex + case utils.SupplierProfilePrefix: + idxPrefix = utils.SupplierProfilesStringIndex + rIdxPrefix = utils.SupplierProfilesStringRevIndex + case utils.AliasProfilePrefix: + idxPrefix = utils.AliasProfilesStringIndex + rIdxPrefix = utils.AliasProfilesStringRevIndex + } + if reverse { + return rIdxPrefix + dbKeySuffix + } + return idxPrefix + dbKeySuffix } diff --git a/engine/storage_map.go b/engine/storage_map.go index d6bda37be..171a925b5 100755 --- a/engine/storage_map.go +++ b/engine/storage_map.go @@ -1176,7 +1176,6 @@ func (ms *MapStorage) SetReqFilterIndexesDrv(dbKey string, indexes map[string]ma func (ms *MapStorage) MatchReqFilterIndexDrv(dbKey, fldName, fldVal string) (itemIDs utils.StringMap, err error) { ms.mu.RLock() defer ms.mu.RUnlock() - // Not found in cache, check in DB values, ok := ms.dict[dbKey] if !ok { return nil, utils.ErrNotFound @@ -1188,6 +1187,9 @@ func (ms *MapStorage) MatchReqFilterIndexDrv(dbKey, fldName, fldVal string) (ite if _, hasIt := indexes[fldName]; hasIt { itemIDs = indexes[fldName][fldVal] } + if len(itemIDs) == 0 { + return nil, utils.ErrNotFound + } return } diff --git a/engine/suppliers_test.go b/engine/suppliers_test.go index 37966d273..03e7f0424 100644 --- a/engine/suppliers_test.go +++ b/engine/suppliers_test.go @@ -273,7 +273,7 @@ func TestSuppliersPopulateSupplierService(t *testing.T) { for _, spr := range sprsmatch { dmspl.DataDB().SetSupplierProfileDrv(spr) } - ref, err := NewReqFilterIndexer(dmspl, utils.SupplierProfilesStringIndex+"cgrates.org") + ref, err := NewReqFilterIndexer(dmspl, utils.SupplierProfilePrefix, "cgrates.org") if err != nil { t.Errorf("Error: %+v", err) } diff --git a/engine/tp_reader.go b/engine/tp_reader.go index 48b990a8f..a7f1a6226 100755 --- a/engine/tp_reader.go +++ b/engine/tp_reader.go @@ -1623,7 +1623,6 @@ func (tpr *TpReader) LoadResourceProfilesFiltered(tag string) (err error) { } tpr.resProfiles = mapRsPfls for tntID, res := range mapRsPfls { - resIndxrKey := utils.ResourceProfilesStringIndex + tntID.Tenant if has, err := tpr.dm.HasData(utils.ResourcesPrefix, tntID.TenantID()); err != nil { return err } else if !has { @@ -1631,7 +1630,7 @@ func (tpr *TpReader) LoadResourceProfilesFiltered(tag string) (err error) { } // index resource for filters if _, has := tpr.resIndexers[tntID.Tenant]; !has { - if tpr.resIndexers[tntID.Tenant], err = NewReqFilterIndexer(tpr.dm, resIndxrKey); err != nil { + if tpr.resIndexers[tntID.Tenant], err = NewReqFilterIndexer(tpr.dm, utils.ResourceProfilesPrefix, tntID.Tenant); err != nil { return } } @@ -1670,7 +1669,6 @@ func (tpr *TpReader) LoadStatsFiltered(tag string) (err error) { } tpr.sqProfiles = mapSTs for tntID, sq := range mapSTs { - sqpIndxrKey := utils.StatQueuesStringIndex + tntID.Tenant if has, err := tpr.dm.HasData(utils.StatQueuePrefix, tntID.TenantID()); err != nil { return err } else if !has { @@ -1678,7 +1676,7 @@ func (tpr *TpReader) LoadStatsFiltered(tag string) (err error) { } // index statQueues for filters if _, has := tpr.sqpIndexers[tntID.Tenant]; !has { - if tpr.sqpIndexers[tntID.Tenant], err = NewReqFilterIndexer(tpr.dm, sqpIndxrKey); err != nil { + if tpr.sqpIndexers[tntID.Tenant], err = NewReqFilterIndexer(tpr.dm, utils.StatQueueProfilePrefix, tntID.Tenant); err != nil { return } } @@ -1717,7 +1715,6 @@ func (tpr *TpReader) LoadThresholdsFiltered(tag string) (err error) { } tpr.thProfiles = mapTHs for tntID, th := range mapTHs { - thdIndxrKey := utils.ThresholdStringIndex + tntID.Tenant if has, err := tpr.dm.HasData(utils.ThresholdPrefix, tntID.TenantID()); err != nil { return err } else if !has { @@ -1725,7 +1722,7 @@ func (tpr *TpReader) LoadThresholdsFiltered(tag string) (err error) { } // index thresholds for filters if _, has := tpr.thdsIndexers[tntID.Tenant]; !has { - if tpr.thdsIndexers[tntID.Tenant], err = NewReqFilterIndexer(tpr.dm, thdIndxrKey); err != nil { + if tpr.thdsIndexers[tntID.Tenant], err = NewReqFilterIndexer(tpr.dm, utils.ThresholdProfilePrefix, tntID.Tenant); err != nil { return } } @@ -1781,15 +1778,14 @@ func (tpr *TpReader) LoadSupplierProfilesFiltered(tag string) (err error) { } tpr.sppProfiles = mapRsPfls for tntID, res := range mapRsPfls { - resIndxrKey := utils.SupplierProfilesStringIndex + tntID.Tenant if has, err := tpr.dm.HasData(utils.SupplierProfilePrefix, tntID.TenantID()); err != nil { return err } else if !has { tpr.suppliers = append(tpr.suppliers, &utils.TenantID{Tenant: tntID.Tenant, ID: tntID.ID}) } - // index lcr profile for filters + // index supplier profile for filters if _, has := tpr.sppIndexers[tntID.Tenant]; !has { - if tpr.sppIndexers[tntID.Tenant], err = NewReqFilterIndexer(tpr.dm, resIndxrKey); err != nil { + if tpr.sppIndexers[tntID.Tenant], err = NewReqFilterIndexer(tpr.dm, utils.SupplierProfilePrefix, tntID.Tenant); err != nil { return } } @@ -1828,7 +1824,6 @@ func (tpr *TpReader) LoadAliasProfilesFiltered(tag string) (err error) { } tpr.aliasProfiles = mapRsPfls for tntID, res := range mapRsPfls { - resIndxrKey := utils.AliasProfilesStringIndex + tntID.Tenant if has, err := tpr.dm.HasData(utils.AliasProfilePrefix, tntID.TenantID()); err != nil { return err } else if !has { @@ -1836,7 +1831,7 @@ func (tpr *TpReader) LoadAliasProfilesFiltered(tag string) (err error) { } // index alias profile for filters if _, has := tpr.aliasIndexers[tntID.Tenant]; !has { - if tpr.aliasIndexers[tntID.Tenant], err = NewReqFilterIndexer(tpr.dm, resIndxrKey); err != nil { + if tpr.aliasIndexers[tntID.Tenant], err = NewReqFilterIndexer(tpr.dm, utils.AliasProfilePrefix, tntID.Tenant); err != nil { return } } @@ -2334,52 +2329,79 @@ func (tpr *TpReader) WriteToDatabase(flush, verbose, disable_reverse bool) (err return err } } + } + if verbose { + log.Print("Indexing resource profiles") + } + for tenant, fltrIdxer := range tpr.resIndexers { + if err := fltrIdxer.StoreIndexes(); err != nil { + return err + } if verbose { - log.Print("Indexing resource profiles") + log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys(false).Slice()) } - for tenant, fltrIdxer := range tpr.resIndexers { - if err := fltrIdxer.StoreIndexes(); err != nil { - return err - } - if verbose { - log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys().Slice()) - } + if verbose { + log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys(true).Slice()) } + } + if verbose { + log.Print("StatQueue filter indexes:") + } + for tenant, fltrIdxer := range tpr.sqpIndexers { + if err := fltrIdxer.StoreIndexes(); err != nil { + return err + } if verbose { - log.Print("StatQueue filter indexes:") + log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys(false).Slice()) } - for tenant, fltrIdxer := range tpr.sqpIndexers { - if err := fltrIdxer.StoreIndexes(); err != nil { - return err - } - if verbose { - log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys().Slice()) - } + if verbose { + log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys(true).Slice()) } + } + if verbose { + log.Print("Threshold filter indexes:") + } + for tenant, fltrIdxer := range tpr.thdsIndexers { + if err := fltrIdxer.StoreIndexes(); err != nil { + return err + } if verbose { - log.Print("Threshold filter indexes:") + log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys(false).Slice()) } - for tenant, fltrIdxer := range tpr.thdsIndexers { - if err := fltrIdxer.StoreIndexes(); err != nil { - return err - } - if verbose { - log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys().Slice()) - } + if verbose { + log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys(true).Slice()) } + } - if verbose { - log.Print("Indexing Supplier Profiles") + if verbose { + log.Print("Indexing Supplier Profiles") + } + for tenant, fltrIdxer := range tpr.sppIndexers { + if err := fltrIdxer.StoreIndexes(); err != nil { + return err } - for tenant, fltrIdxer := range tpr.sppIndexers { - if err := fltrIdxer.StoreIndexes(); err != nil { - return err - } - if verbose { - log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys().Slice()) - } + if verbose { + log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys(false).Slice()) + } + if verbose { + log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys(true).Slice()) + } + } + + if verbose { + log.Print("Indexing Alias Profiles") + } + for tenant, fltrIdxer := range tpr.aliasIndexers { + if err := fltrIdxer.StoreIndexes(); err != nil { + return err + } + if verbose { + log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys(false).Slice()) + } + if verbose { + log.Printf("Tenant: %s, keys %+v", tenant, fltrIdxer.ChangedKeys(true).Slice()) } } return diff --git a/utils/consts.go b/utils/consts.go index 85bc5cc0e..a5870a8a2 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -71,277 +71,282 @@ var ( ) const ( - CGRateS = "CGRateS" - VERSION = "0.9.1~rc8" - GitLastLogFileName = ".git_lastlog.txt" - DIAMETER_FIRMWARE_REVISION = 918 - REDIS_MAX_CONNS = 10 - POSTGRES = "postgres" - MYSQL = "mysql" - MONGO = "mongo" - REDIS = "redis" - MAPSTOR = "mapstor" - LOCALHOST = "127.0.0.1" - FSCDR_FILE_CSV = "freeswitch_file_csv" - FSCDR_HTTP_JSON = "freeswitch_http_json" - NOT_IMPLEMENTED = "not implemented" - PREPAID = "prepaid" - META_PREPAID = "*prepaid" - POSTPAID = "postpaid" - META_POSTPAID = "*postpaid" - PSEUDOPREPAID = "pseudoprepaid" - META_PSEUDOPREPAID = "*pseudoprepaid" - META_RATED = "*rated" - META_NONE = "*none" - META_NOW = "*now" - TBLTPTimings = "tp_timings" - TBLTPDestinations = "tp_destinations" - TBLTPRates = "tp_rates" - TBLTPDestinationRates = "tp_destination_rates" - TBLTPRatingPlans = "tp_rating_plans" - TBLTPRateProfiles = "tp_rating_profiles" - TBLTPSharedGroups = "tp_shared_groups" - TBLTPCdrStats = "tp_cdr_stats" - TBLTPLcrs = "tp_lcr_rules" - TBLTPActions = "tp_actions" - TBLTPActionPlans = "tp_action_plans" - TBLTPActionTriggers = "tp_action_triggers" - TBLTPAccountActions = "tp_account_actions" - TBLTPDerivedChargers = "tp_derived_chargers" - TBLTPUsers = "tp_users" - TBLTPAliases = "tp_aliases" - TBLTPResources = "tp_resources" - TBLTPStats = "tp_stats" - TBLTPThresholds = "tp_thresholds" - TBLTPFilters = "tp_filters" - SMCostsTBL = "sm_costs" - CDRsTBL = "cdrs" - TBLTPSuppliers = "tp_suppliers" - TBLTPAlias = "tp_alias" - TBLVersions = "versions" - TIMINGS_CSV = "Timings.csv" - DESTINATIONS_CSV = "Destinations.csv" - RATES_CSV = "Rates.csv" - DESTINATION_RATES_CSV = "DestinationRates.csv" - RATING_PLANS_CSV = "RatingPlans.csv" - RATING_PROFILES_CSV = "RatingProfiles.csv" - SHARED_GROUPS_CSV = "SharedGroups.csv" - LCRS_CSV = "LcrRules.csv" - ACTIONS_CSV = "Actions.csv" - ACTION_PLANS_CSV = "ActionPlans.csv" - ACTION_TRIGGERS_CSV = "ActionTriggers.csv" - ACCOUNT_ACTIONS_CSV = "AccountActions.csv" - DERIVED_CHARGERS_CSV = "DerivedChargers.csv" - CDR_STATS_CSV = "CdrStats.csv" - USERS_CSV = "Users.csv" - ALIASES_CSV = "Aliases.csv" - ResourcesCsv = "Resources.csv" - StatsCsv = "Stats.csv" - ThresholdsCsv = "Thresholds.csv" - FiltersCsv = "Filters.csv" - SuppliersCsv = "Suppliers.csv" - AliasCsv = "Alias.csv" - ROUNDING_UP = "*up" - ROUNDING_MIDDLE = "*middle" - ROUNDING_DOWN = "*down" - ANY = "*any" - UNLIMITED = "*unlimited" - ZERO = "*zero" - ASAP = "*asap" - USERS = "*users" - COMMENT_CHAR = '#' - CSV_SEP = ',' - FALLBACK_SEP = ';' - INFIELD_SEP = ";" - MetaPipe = "*|" - FIELDS_SEP = "," - InInFieldSep = ":" - STATIC_HDRVAL_SEP = "::" - REGEXP_PREFIX = "~" - FILTER_VAL_START = "(" - FILTER_VAL_END = ")" - JSON = "json" - GOB = "gob" - MSGPACK = "msgpack" - CSV_LOAD = "CSVLOAD" - CGRID = "CGRID" - TOR = "ToR" - ORDERID = "OrderID" - ACCID = "OriginID" - InitialOriginID = "InitialOriginID" - OriginIDPrefix = "OriginIDPrefix" - CDRSOURCE = "Source" - CDRHOST = "OriginHost" - REQTYPE = "RequestType" - DIRECTION = "Direction" - TENANT = "Tenant" - CATEGORY = "Category" - ACCOUNT = "Account" - SUBJECT = "Subject" - DESTINATION = "Destination" - SETUP_TIME = "SetupTime" - ANSWER_TIME = "AnswerTime" - USAGE = "Usage" - LastUsed = "LastUsed" - PDD = "PDD" - SUPPLIER = "Supplier" - MEDI_RUNID = "RunID" - COST = "Cost" - COST_DETAILS = "CostDetails" - RATED = "rated" - RATED_FLD = "Rated" - PartialField = "Partial" - DEFAULT_RUNID = "*default" - META_DEFAULT = "*default" - STATIC_VALUE_PREFIX = "^" - CSV = "csv" - FWV = "fwv" - PartialCSV = "partial_csv" - DRYRUN = "dry_run" - META_COMBIMED = "*combimed" - MetaInternal = "*internal" - ZERO_RATING_SUBJECT_PREFIX = "*zero" - OK = "OK" - CDRE_FIXED_WIDTH = "fwv" - XML_PROFILE_PREFIX = "*xml:" - CDRE = "cdre" - CDRC = "cdrc" - MASK_CHAR = "*" - CONCATENATED_KEY_SEP = ":" - FORKED_CDR = "forked_cdr" - UNIT_TEST = "UNIT_TEST" - HDR_VAL_SEP = "/" - MONETARY = "*monetary" - SMS = "*sms" - MMS = "*mms" - GENERIC = "*generic" - DATA = "*data" - VOICE = "*voice" - MAX_COST_FREE = "*free" - MAX_COST_DISCONNECT = "*disconnect" - HOURS = "hours" - MINUTES = "minutes" - NANOSECONDS = "nanoseconds" - SECONDS = "seconds" - OUT = "*out" - IN = "*in" - META_OUT = "*out" - META_ANY = "*any" - MetaExists = "*exists" - CDR_IMPORT = "cdr_import" - CDR_EXPORT = "cdr_export" - ASR = "ASR" - ACD = "ACD" - FILTER_REGEXP_TPL = "$1$2$3$4$5" - TASKS_KEY = "tasks" - ACTION_PLAN_PREFIX = "apl_" - AccountActionPlansPrefix = "aap_" - ACTION_TRIGGER_PREFIX = "atr_" - REVERSE_ACTION_TRIGGER_PREFIX = "rtr_" - RATING_PLAN_PREFIX = "rpl_" - RATING_PROFILE_PREFIX = "rpf_" - ACTION_PREFIX = "act_" - SHARED_GROUP_PREFIX = "shg_" - ACCOUNT_PREFIX = "acc_" - DESTINATION_PREFIX = "dst_" - REVERSE_DESTINATION_PREFIX = "rds_" - LCR_PREFIX = "lcr_" - DERIVEDCHARGERS_PREFIX = "dcs_" - CDR_STATS_QUEUE_PREFIX = "csq_" - PUBSUB_SUBSCRIBERS_PREFIX = "pss_" - USERS_PREFIX = "usr_" - ALIASES_PREFIX = "als_" - REVERSE_ALIASES_PREFIX = "rls_" - ResourcesPrefix = "res_" - ResourceProfilesStringIndex = "rsi_" - ResourceProfilesPrefix = "rsp_" - StatQueuesStringIndex = "ssi_" - ThresholdPrefix = "thd_" - ThresholdStringIndex = "tsi_" - TimingsPrefix = "tmg_" - FilterPrefix = "ftr_" - FilterIndex = "fti_" - CDR_STATS_PREFIX = "cst_" - TEMP_DESTINATION_PREFIX = "tmp_" - LOG_CALL_COST_PREFIX = "cco_" - LOG_ACTION_TIMMING_PREFIX = "ltm_" - LOG_ACTION_TRIGGER_PREFIX = "ltr_" - VERSION_PREFIX = "ver_" - LOG_ERR = "ler_" - LOG_CDR = "cdr_" - LOG_MEDIATED_CDR = "mcd_" - StatQueueProfilePrefix = "sqp_" - SupplierProfilePrefix = "spp_" - SupplierProfilesStringIndex = "spi_" - AliasProfilePrefix = "alp_" - AliasProfilesStringIndex = "ali_" - ThresholdProfilePrefix = "thp_" - StatQueuePrefix = "stq_" - LOADINST_KEY = "load_history" - SESSION_MANAGER_SOURCE = "SMR" - MEDIATOR_SOURCE = "MED" - CDRS_SOURCE = "CDRS" - SCHED_SOURCE = "SCH" - RATER_SOURCE = "RAT" - CREATE_CDRS_TABLES_SQL = "create_cdrs_tables.sql" - CREATE_TARIFFPLAN_TABLES_SQL = "create_tariffplan_tables.sql" - TEST_SQL = "TEST_SQL" - DESTINATIONS_LOAD_THRESHOLD = 0.1 - META_CONSTANT = "*constant" - META_FILLER = "*filler" - META_HANDLER = "*handler" - META_HTTP_POST = "*http_post" - MetaHTTPjson = "*http_json" - MetaHTTPjsonCDR = "*http_json_cdr" - META_HTTP_JSONRPC = "*http_jsonrpc" - MetaHTTPjsonMap = "*http_json_map" - MetaAMQPjsonCDR = "*amqp_json_cdr" - MetaAMQPjsonMap = "*amqp_json_map" - NANO_MULTIPLIER = 1000000000 - CGR_AUTHORIZE = "CGR_AUTHORIZE" - CONFIG_DIR = "/etc/cgrates/" - CGR_ACCOUNT = "cgr_account" - CGR_SUPPLIER = "cgr_supplier" - CGR_DESTINATION = "cgr_destination" - CGR_SUBJECT = "cgr_subject" - CGR_CATEGORY = "cgr_category" - CGR_REQTYPE = "cgr_reqtype" - CGR_TENANT = "cgr_tenant" - CGR_TOR = "cgr_tor" - CGR_ACCID = "cgr_accid" - CGR_HOST = "cgr_host" - CGR_PDD = "cgr_pdd" - DISCONNECT_CAUSE = "DisconnectCause" - CGR_DISCONNECT_CAUSE = "cgr_disconnectcause" - CGR_COMPUTELCR = "cgr_computelcr" - CGR_SUPPLIERS = "cgr_suppliers" - CGRFlags = "cgr_flags" - KAM_FLATSTORE = "kamailio_flatstore" - OSIPS_FLATSTORE = "opensips_flatstore" - MAX_DEBIT_CACHE_PREFIX = "MAX_DEBIT_" - REFUND_INCR_CACHE_PREFIX = "REFUND_INCR_" - REFUND_ROUND_CACHE_PREFIX = "REFUND_ROUND_" - GET_SESS_RUNS_CACHE_PREFIX = "GET_SESS_RUNS_" - GET_DERIV_MAX_SESS_TIME = "GET_DERIV_MAX_SESS_TIME_" - LOG_CALL_COST_CACHE_PREFIX = "LOG_CALL_COSTS_" - LCRCachePrefix = "LCR_" - ALIAS_CONTEXT_RATING = "*rating" - NOT_AVAILABLE = "N/A" - MetaEmpty = "*empty" - CALL = "call" - EXTRA_FIELDS = "ExtraFields" - META_SURETAX = "*sure_tax" - SURETAX = "suretax" - DIAMETER_AGENT = "diameter_agent" - COUNTER_EVENT = "*event" - COUNTER_BALANCE = "*balance" - EVENT_NAME = "EventName" - COMPUTE_LCR = "ComputeLcr" - CGR_AUTHORIZATION = "CgrAuthorization" - CGR_SESSION_START = "CgrSessionStart" - CGR_SESSION_UPDATE = "CgrSessionUpdate" - CGR_SESSION_END = "CgrSessionEnd" - CGR_LCR_REQUEST = "CgrLcrRequest" + CGRateS = "CGRateS" + VERSION = "0.9.1~rc8" + GitLastLogFileName = ".git_lastlog.txt" + DIAMETER_FIRMWARE_REVISION = 918 + REDIS_MAX_CONNS = 10 + POSTGRES = "postgres" + MYSQL = "mysql" + MONGO = "mongo" + REDIS = "redis" + MAPSTOR = "mapstor" + LOCALHOST = "127.0.0.1" + FSCDR_FILE_CSV = "freeswitch_file_csv" + FSCDR_HTTP_JSON = "freeswitch_http_json" + NOT_IMPLEMENTED = "not implemented" + PREPAID = "prepaid" + META_PREPAID = "*prepaid" + POSTPAID = "postpaid" + META_POSTPAID = "*postpaid" + PSEUDOPREPAID = "pseudoprepaid" + META_PSEUDOPREPAID = "*pseudoprepaid" + META_RATED = "*rated" + META_NONE = "*none" + META_NOW = "*now" + TBLTPTimings = "tp_timings" + TBLTPDestinations = "tp_destinations" + TBLTPRates = "tp_rates" + TBLTPDestinationRates = "tp_destination_rates" + TBLTPRatingPlans = "tp_rating_plans" + TBLTPRateProfiles = "tp_rating_profiles" + TBLTPSharedGroups = "tp_shared_groups" + TBLTPCdrStats = "tp_cdr_stats" + TBLTPLcrs = "tp_lcr_rules" + TBLTPActions = "tp_actions" + TBLTPActionPlans = "tp_action_plans" + TBLTPActionTriggers = "tp_action_triggers" + TBLTPAccountActions = "tp_account_actions" + TBLTPDerivedChargers = "tp_derived_chargers" + TBLTPUsers = "tp_users" + TBLTPAliases = "tp_aliases" + TBLTPResources = "tp_resources" + TBLTPStats = "tp_stats" + TBLTPThresholds = "tp_thresholds" + TBLTPFilters = "tp_filters" + SMCostsTBL = "sm_costs" + CDRsTBL = "cdrs" + TBLTPSuppliers = "tp_suppliers" + TBLTPAlias = "tp_alias" + TBLVersions = "versions" + TIMINGS_CSV = "Timings.csv" + DESTINATIONS_CSV = "Destinations.csv" + RATES_CSV = "Rates.csv" + DESTINATION_RATES_CSV = "DestinationRates.csv" + RATING_PLANS_CSV = "RatingPlans.csv" + RATING_PROFILES_CSV = "RatingProfiles.csv" + SHARED_GROUPS_CSV = "SharedGroups.csv" + LCRS_CSV = "LcrRules.csv" + ACTIONS_CSV = "Actions.csv" + ACTION_PLANS_CSV = "ActionPlans.csv" + ACTION_TRIGGERS_CSV = "ActionTriggers.csv" + ACCOUNT_ACTIONS_CSV = "AccountActions.csv" + DERIVED_CHARGERS_CSV = "DerivedChargers.csv" + CDR_STATS_CSV = "CdrStats.csv" + USERS_CSV = "Users.csv" + ALIASES_CSV = "Aliases.csv" + ResourcesCsv = "Resources.csv" + StatsCsv = "Stats.csv" + ThresholdsCsv = "Thresholds.csv" + FiltersCsv = "Filters.csv" + SuppliersCsv = "Suppliers.csv" + AliasCsv = "Alias.csv" + ROUNDING_UP = "*up" + ROUNDING_MIDDLE = "*middle" + ROUNDING_DOWN = "*down" + ANY = "*any" + UNLIMITED = "*unlimited" + ZERO = "*zero" + ASAP = "*asap" + USERS = "*users" + COMMENT_CHAR = '#' + CSV_SEP = ',' + FALLBACK_SEP = ';' + INFIELD_SEP = ";" + MetaPipe = "*|" + FIELDS_SEP = "," + InInFieldSep = ":" + STATIC_HDRVAL_SEP = "::" + REGEXP_PREFIX = "~" + FILTER_VAL_START = "(" + FILTER_VAL_END = ")" + JSON = "json" + GOB = "gob" + MSGPACK = "msgpack" + CSV_LOAD = "CSVLOAD" + CGRID = "CGRID" + TOR = "ToR" + ORDERID = "OrderID" + ACCID = "OriginID" + InitialOriginID = "InitialOriginID" + OriginIDPrefix = "OriginIDPrefix" + CDRSOURCE = "Source" + CDRHOST = "OriginHost" + REQTYPE = "RequestType" + DIRECTION = "Direction" + TENANT = "Tenant" + CATEGORY = "Category" + ACCOUNT = "Account" + SUBJECT = "Subject" + DESTINATION = "Destination" + SETUP_TIME = "SetupTime" + ANSWER_TIME = "AnswerTime" + USAGE = "Usage" + LastUsed = "LastUsed" + PDD = "PDD" + SUPPLIER = "Supplier" + MEDI_RUNID = "RunID" + COST = "Cost" + COST_DETAILS = "CostDetails" + RATED = "rated" + RATED_FLD = "Rated" + PartialField = "Partial" + DEFAULT_RUNID = "*default" + META_DEFAULT = "*default" + STATIC_VALUE_PREFIX = "^" + CSV = "csv" + FWV = "fwv" + PartialCSV = "partial_csv" + DRYRUN = "dry_run" + META_COMBIMED = "*combimed" + MetaInternal = "*internal" + ZERO_RATING_SUBJECT_PREFIX = "*zero" + OK = "OK" + CDRE_FIXED_WIDTH = "fwv" + XML_PROFILE_PREFIX = "*xml:" + CDRE = "cdre" + CDRC = "cdrc" + MASK_CHAR = "*" + CONCATENATED_KEY_SEP = ":" + FORKED_CDR = "forked_cdr" + UNIT_TEST = "UNIT_TEST" + HDR_VAL_SEP = "/" + MONETARY = "*monetary" + SMS = "*sms" + MMS = "*mms" + GENERIC = "*generic" + DATA = "*data" + VOICE = "*voice" + MAX_COST_FREE = "*free" + MAX_COST_DISCONNECT = "*disconnect" + HOURS = "hours" + MINUTES = "minutes" + NANOSECONDS = "nanoseconds" + SECONDS = "seconds" + OUT = "*out" + IN = "*in" + META_OUT = "*out" + META_ANY = "*any" + MetaExists = "*exists" + CDR_IMPORT = "cdr_import" + CDR_EXPORT = "cdr_export" + ASR = "ASR" + ACD = "ACD" + FILTER_REGEXP_TPL = "$1$2$3$4$5" + TASKS_KEY = "tasks" + ACTION_PLAN_PREFIX = "apl_" + AccountActionPlansPrefix = "aap_" + ACTION_TRIGGER_PREFIX = "atr_" + REVERSE_ACTION_TRIGGER_PREFIX = "rtr_" + RATING_PLAN_PREFIX = "rpl_" + RATING_PROFILE_PREFIX = "rpf_" + ACTION_PREFIX = "act_" + SHARED_GROUP_PREFIX = "shg_" + ACCOUNT_PREFIX = "acc_" + DESTINATION_PREFIX = "dst_" + REVERSE_DESTINATION_PREFIX = "rds_" + LCR_PREFIX = "lcr_" + DERIVEDCHARGERS_PREFIX = "dcs_" + CDR_STATS_QUEUE_PREFIX = "csq_" + PUBSUB_SUBSCRIBERS_PREFIX = "pss_" + USERS_PREFIX = "usr_" + ALIASES_PREFIX = "als_" + REVERSE_ALIASES_PREFIX = "rls_" + ResourcesPrefix = "res_" + ResourceProfilesStringIndex = "rsi_" + ResourceProfilesStringRevIndex = "rsr_" + ResourceProfilesPrefix = "rsp_" + StatQueuesStringIndex = "ssi_" + StatQueuesStringRevIndex = "ssr_" + ThresholdPrefix = "thd_" + ThresholdStringIndex = "tsi_" + ThresholdStringRevIndex = "tsr_" + TimingsPrefix = "tmg_" + FilterPrefix = "ftr_" + FilterIndex = "fti_" + CDR_STATS_PREFIX = "cst_" + TEMP_DESTINATION_PREFIX = "tmp_" + LOG_CALL_COST_PREFIX = "cco_" + LOG_ACTION_TIMMING_PREFIX = "ltm_" + LOG_ACTION_TRIGGER_PREFIX = "ltr_" + VERSION_PREFIX = "ver_" + LOG_ERR = "ler_" + LOG_CDR = "cdr_" + LOG_MEDIATED_CDR = "mcd_" + StatQueueProfilePrefix = "sqp_" + SupplierProfilePrefix = "spp_" + SupplierProfilesStringIndex = "spi_" + SupplierProfilesStringRevIndex = "spr_" + AliasProfilePrefix = "alp_" + AliasProfilesStringIndex = "ali_" + AliasProfilesStringRevIndex = "alr_" + ThresholdProfilePrefix = "thp_" + StatQueuePrefix = "stq_" + LOADINST_KEY = "load_history" + SESSION_MANAGER_SOURCE = "SMR" + MEDIATOR_SOURCE = "MED" + CDRS_SOURCE = "CDRS" + SCHED_SOURCE = "SCH" + RATER_SOURCE = "RAT" + CREATE_CDRS_TABLES_SQL = "create_cdrs_tables.sql" + CREATE_TARIFFPLAN_TABLES_SQL = "create_tariffplan_tables.sql" + TEST_SQL = "TEST_SQL" + DESTINATIONS_LOAD_THRESHOLD = 0.1 + META_CONSTANT = "*constant" + META_FILLER = "*filler" + META_HANDLER = "*handler" + META_HTTP_POST = "*http_post" + MetaHTTPjson = "*http_json" + MetaHTTPjsonCDR = "*http_json_cdr" + META_HTTP_JSONRPC = "*http_jsonrpc" + MetaHTTPjsonMap = "*http_json_map" + MetaAMQPjsonCDR = "*amqp_json_cdr" + MetaAMQPjsonMap = "*amqp_json_map" + NANO_MULTIPLIER = 1000000000 + CGR_AUTHORIZE = "CGR_AUTHORIZE" + CONFIG_DIR = "/etc/cgrates/" + CGR_ACCOUNT = "cgr_account" + CGR_SUPPLIER = "cgr_supplier" + CGR_DESTINATION = "cgr_destination" + CGR_SUBJECT = "cgr_subject" + CGR_CATEGORY = "cgr_category" + CGR_REQTYPE = "cgr_reqtype" + CGR_TENANT = "cgr_tenant" + CGR_TOR = "cgr_tor" + CGR_ACCID = "cgr_accid" + CGR_HOST = "cgr_host" + CGR_PDD = "cgr_pdd" + DISCONNECT_CAUSE = "DisconnectCause" + CGR_DISCONNECT_CAUSE = "cgr_disconnectcause" + CGR_COMPUTELCR = "cgr_computelcr" + CGR_SUPPLIERS = "cgr_suppliers" + CGRFlags = "cgr_flags" + KAM_FLATSTORE = "kamailio_flatstore" + OSIPS_FLATSTORE = "opensips_flatstore" + MAX_DEBIT_CACHE_PREFIX = "MAX_DEBIT_" + REFUND_INCR_CACHE_PREFIX = "REFUND_INCR_" + REFUND_ROUND_CACHE_PREFIX = "REFUND_ROUND_" + GET_SESS_RUNS_CACHE_PREFIX = "GET_SESS_RUNS_" + GET_DERIV_MAX_SESS_TIME = "GET_DERIV_MAX_SESS_TIME_" + LOG_CALL_COST_CACHE_PREFIX = "LOG_CALL_COSTS_" + LCRCachePrefix = "LCR_" + ALIAS_CONTEXT_RATING = "*rating" + NOT_AVAILABLE = "N/A" + MetaEmpty = "*empty" + CALL = "call" + EXTRA_FIELDS = "ExtraFields" + META_SURETAX = "*sure_tax" + SURETAX = "suretax" + DIAMETER_AGENT = "diameter_agent" + COUNTER_EVENT = "*event" + COUNTER_BALANCE = "*balance" + EVENT_NAME = "EventName" + COMPUTE_LCR = "ComputeLcr" + CGR_AUTHORIZATION = "CgrAuthorization" + CGR_SESSION_START = "CgrSessionStart" + CGR_SESSION_UPDATE = "CgrSessionUpdate" + CGR_SESSION_END = "CgrSessionEnd" + CGR_LCR_REQUEST = "CgrLcrRequest" // action trigger threshold types TRIGGER_MIN_EVENT_COUNTER = "*min_event_counter" TRIGGER_MIN_BALANCE_COUNTER = "*min_balance_counter"