FilterS

FilterS are code blocks applied to generic events (hashmaps) in order to allow/deny further processing.

A Tenant will define multiple Filter profiles via .csv or API calls. The Filter profile ID is unique within a tenant but it can be repeated over multiple Tenants.

In order to be used in event processing, a Filter profile will be attached inside another subsystem profile definition, otherwise Filter profile will have no effect on it’s own.

A subsystem can use a Filter via FilterProfile or in-line (ad-hock in the same place where subsystem profile is defined).

Filter profile

Definition:

type Filter struct {
       Tenant             string
       ID                 string
       Rules              []*FilterRule
       ActivationInterval *utils.ActivationInterval
}

A Filter profile can be shared between multiple subsystem profile definitions.

A Filter profile can contain any number of Filter rules and each of them must pass in order for the filter profile to pass.

A Filter profile can be activated on specific interval, if multiple filters are used within a subsystem profile at least one needs to be active and passing in order for the subsystem profile to pass the event.

Filter rule

Definition:

type FilterRule struct {
       Type            string              // Filter type
       Element         string              // Name of the field providing us the Values to check (used in case of some )
       Values          []string            // Filter definition
}

The matching logic of each FilterRule is given by it’s type.

The following types are implemented:

*string*

Will match in full the Element with at least one value defined inside Values. Any of the values matching will have the FilterRule as matched.

*notstring

Is the negation of *string.

*prefix

Will match at beginning of Element one of the values defined inside Values.

*notprefix

Is the negation of *prefix.

*suffix

Will match at end of Element one of the values defined inside Values.

*notsuffix*

Is the negation of *suffix.

*empty

Will make sure that Element is empty or it does not exist in the event.

*notempty

Is the negation of *empty.

*exists

Will make sure that Element exists in the event.

*notexists

Is the negation of *exists.

*timings

Will compare the time contained in Element with one of the TimingIDs defined in Values.

*nottimings

Is the negation of *timings.

*destinations

Will make sure that the Element is a prefix contained inside one of the destination IDs as Values.

*notdestinations

Is the negation of *destinations.

*rsr

Will match the RSRRules defined in Values.

*notrsr*

Is the negation of *rsr.

*lt (less than), *lte (less than or equal), *gt (greather than), *gte (greather than or equal)

Are comparison operators and they pass if at least one of the values defined in Values are passing for the Element of event. The operators are able to compare string, float, int, time.Time, time.Duration, however both types need to be the same, otherwise the filter will raise incomparable as error.

Inline Filter

In order to facilitate quick filter definition (without the need of separate FilterProfile), one can define filters directly as FilterIDs following the special format.

Inline filter format:

filterType:fieldName:fieldValue

Example:

*string:WebsiteName:CGRateS.org

Subsystem profiles selection based on Filters

When a subsystem will process an event it will need to find fast enough (close to real-time and most preferably with constant speed) all the profiles having filters matching the event. For low number of profiles (tens of) we can go through all available profiles and check their filters but as soon as the number of profiles is growing, processing time will exponentially grow also. As an example, the AttributeS need to deal with 20 mil+ profiles in case of number portability implementation.

In order to guarantee constant processing time - O(1) - CGRateS will use internally a profile selection mechanism based on indexed filters which can be enabled within .json configuration file via indexed_selects. When indexed_selects is disabled, the indexes will not be used at all and profiles will be checked one by one. On the other hand, if indexed_selects is enabled, each FilterProfile needs to have at least one *string or *prefix type in order to be visible to the indexes (otherwise being completely ignored).

The following settings are further applied once indexed_selects is enabled:

string_indexed_fields

list of field names in the event which will be checked against string indexes (defaults to nil which means check all fields)

prefix_indexed_fields

list of field names in the event which will be checked against prefix indexes (default is empty, hence prefix matching is disabled inside indexes - small optimization since for prefixes there are multiple queries done for one field)