Scope properties
Scope Properties
This page outlines the different properties that can be enabled to modify how Scopes are applied in the cube and to control the normalization that is performed on incomplete Scope definitions. Modifying the Scope properties increases complexity and usability of Scopes and can cause previously valid Scopes to become invalid.
There are three Scope properties, two of which are for handling Ambiguous Level Paths for Scopes on Multi-Level Hierarchies:
Property name | Out-of-the-box value |
---|---|
limits.scope.force-unambiguous-level-paths | False |
limits.scope.autofill-unambiguous-level-paths | True |
limits.scope.is-using-explicit-scope-matching | True |
The properties can be added in the application.yml file, located in limits-starter\src\main\resources.
Ambiguous Level Path
A Level Member is ambiguous if it’s part of a Multi-Level Hierarchy and there are multiple paths through the Hierarchy Levels to get to this specific Level Member. This can be explained easier with an example:
Assuming we have the following Cube Structure:
Dimension | Hierarchy | Levels |
---|---|---|
Calendar | Days | Year, Month, Day |
With the below data for the Levels of the Days
Hierarchy.
Year | Month | Day | Number Of Days |
---|---|---|---|
2021 | |||
January | 31 | ||
First | 1 | ||
Second | 1 | ||
February | 28 | ||
First | 1 | ||
Second | 1 | ||
2022 | 366 | ||
January | 31 | ||
First | 1 | ||
Second | 1 | ||
February | 29 | ||
First | 1 | ||
Second | 1 | ||
Third | 1 |
If we specify a scope Month=February
, we either get a warning or an exception, depending on the value of limits.scope.force-unambiguous-level-paths, as the Level Member does not have an absolute path back to the root. What this means is that there are two ways to get to the month February within the Days Hierarchy: [2021/February
, 2022/February
]. To fix this, we need to specify the Levels back to the root. Our scope will now look like: Month=February|Year=2022
.
If we specify a scope Day=Third
, there is no ambiguity, as there’s only one path to the Day Third: 2022/February/Third
.
If we specify a scope on Day=Third
, we can optionally store the values for Month
and Year
if limits.scope.autofill-unambiguous-level-paths is enabled. This results in an internal Scope of: Day=Third|Month=February|Year=2022
. This way, if more data is loaded in later, the Day=Third
could become ambiguous, especially if a value Third
is loaded for another month.
limits.scope.force-unambiguous-level-paths
By default, this property is set to false.
This property only applies when a scope is defined with an Ambiguous Level Path.
This property forces that a level be Unambiguous at load time. This means that for the provided Level Member there is only one path back to the Root Level Member. For instance, the scope Month=February
is ambiguous, since there are two paths to February. If we specify Month=February|Year=2021
then the scope is no longer ambiguous, as there is no other path back to the root.
Enabling this property will not allow any data to be loaded if more than one path exists back to the root.
Disabling this property will allow our scope of Month=February
. Our limit in this case will apply to all Years.
note
The path is data dependent: new data can cause an unambiguous Level Member to become ambiguous later on.
limits.scope.autofill-unambiguous-level-paths
By default, this property is set to true.
This property only applies when a scope is defined with an Ambiguous Level Path.
This property allows Atoti Limits to automatically fill in missing parent levels with Wildcards. If the limits.scope.force-unambiguous-level-paths
is also enabled, the missing parent levels will only be added if only one possible path exists back to the root.
This property allows a limit’s Scope to be modified at load time. If the Level Member provided for a Scope is unambiguous, we add all unspecified Level Members to the Scope too. Otherwise, if the Scope is ambiguous, we add Wildcards for the missing parent levels. This locks the limit’s Scope location, so if new data comes in, we won’t have to worry about the Scope becoming ambiguous and applying to other locations.
For example, if we specify the scope Day=Third
, there is only one path back to the root: 2022/February/Third
. So we will add these values to our scope. In the end, our scope will be: Year=2022|Month=February|Day=Third
. In this case, if a Third
day is loaded for another month, our scope will still only apply to the 2022/February/Third
location as it did when we initially loaded the limit.
limits.scope.is-using-explicit-scope-matching
By default, this property is set to true.
When enabled, limits will only be shown and applied to the exact location their Scope is defined on. If we try to drill down below the limit’s Scope definition, the limit will not apply.
If we have a Limit with Scope ID=*
, we can see how the Explicit Scope matching only displays the Scope at the exact Level it was defined on:
When disabled, we can drill down on a level and view the limit below the level it was defined on. We can see that the limit is displayed below the ID level that it was defined on.
This is only a visual difference and doesn’t affect how we evaluate limits for a breach.
Property Matrix
The following property compatibility matrix outlines how setting each property affects the ability to load ambiguous Scopes on Multi-Level Hierarchies, and auto-filling parent levels.
force-unambiguous- level-paths |
autofill-unambiguous- level-paths |
isUsingExplicit ScopeMatching |
Can load Ambiguous-Scope |
What do we do | Out-of-the-box configuration |
---|---|---|---|---|---|
TRUE | TRUE | TRUE | Yes - If only one path to root exists | Fill in explicit path to root | |
TRUE | TRUE | FALSE | Yes - If only one path to root exists | Fill in explicit Path | |
TRUE | FALSE | TRUE | No - Cannot fill Scope | ||
TRUE | FALSE | FALSE | No - Cannot fill Scope | ||
FALSE | TRUE | TRUE | Yes | Fill in implicit path | Yes |
FALSE | TRUE | FALSE | Yes | Fill in implicit path | |
FALSE | FALSE | TRUE | No - Cannot fill Scope | ||
FALSE | FALSE | FALSE | Yes | Fill in implicit path |