Getting started

This section provides guidance on developing with the Limits Module.

Provided is a minimalist ActivePivot project built with Spring Boot for you to edit, customize, and use as a base for your ActivePivot projects.


Details

This project aims to be an example of how to run the Limits Module with an ActivePivot Spring Boot application.

This project is a starting point for your own projects and implementations. You should be able to take this, customize it, and get a cube up and running in a few minutes.

📦 Installation

Requirements

Distribution

Limits backend source

To access the Limits backend source zip folder, click here.

Unzip this repository and run mvn clean install. This will generate a JAR file, which can be run using standard java commands.

Limits UI

💻 Usage

The Limits Module can be integrated with any ActivePivot instance with the same AP version. For more information, see How to Integrate Limits to Atoti+.

As Of Date

The file as_of_date.csv sets the asOfDate for the limits application. This asOfDate is used for evaluating limits against connected accelerators.

Limit definitions

The files limits_approve_frtb.csv and limits_approve_mra.csv load the LimitsDefinition store, and can be found in src/test/resources/data-samples/data/. Limit definitions which have the same Name, CubeName, and ServerName fields create a single KPI on a connected server via REST calls.

For more information on the Limits approve files, see Limits approve.

note

Currently, limits_approve_mra.csv is being ignored because the ETL will skip un-configured accelerators. To load MRA limits, modify acc.url.map prop in src/main/resources/properties/limits.properties to include MRA. ( Example: {'MRA': 'http://localhost:10010/risk-activepivot/pivot/rest/v5/cube', 'FRTB': 'http://localhost:8080/frtb-starter/pivot/rest/v5/cube'} )

AlertTasks and Alert Definitions store

AlertTasks are created for each limit definition in the LimitsDefinition store, which evaluates whether a limit is in breach or warning state. The PollingFrequency field of a limit definition determines how often an AlertTask is run. When limits are in breach or warning status the AlertTask writes to a file named alert.csv. You can find this file in today’s date folder inside the directory src/test/resources/data-damples/data/alert. The files generated here will populate the AlertsDefinition store via a listening topic.

Limit workflow

In the resources/processes folder, the following Activiti workflow bpmn files can be found out of box.

Limit Scopes

Limit definition Scope matching

A Limit Scope is a list of Level Name to Level Value pairs. The Scope represents one or many locations in the Cube where the Limit should be applied. For example, for a Limit to apply when “Trade1” is expressed for the “Trade” dimension, the Value/Pair “Trade=Trade1” can be defined as the Limit’s Scope.

A Scope needs to be specific enough so that its definition only matches one Member in the Cube, to avoid Ambiguous Scopes. The Scope can consist of multiple Level definitions within the format: key=value|key=value|key=value. Each individual Scope is separated by a pipe ‘|’ character.

A Scope is broken up into two main components:

  1. Scope Key: Specifies a Level in the Cube. Can be provided in one of 3 ways:
    • LevelName - (Minimum required): Only specifies the Level Name.
    • LevelName@HierarchyName - (Optional): Specifies the Level in a specific Hierarchy.
    • LevelName@HierarchyName@DimensionName - (Optional): Specifies the Level in a specific Hierarchy in a specific Dimension.
  2. Scope Value: Member within the provided Level to apply the Limit.

note

If a level could not be provided for a “LevelName@HierarchyName” or “LevelName@HierarchyName@DimensionName” then we will invert the ordering and try to find the level again. If we are able to find the inverse level description then we will log a warning notifying that the input data may be in the incorrect format.

A Scope can only be defined once for each Level of the Cube. To define a Limit for multiple Level Members of one Cube Level, you need to define multiple Limit Definitions, each with a different Level Member value in the scope.

A Scope can consist of both explicit and wildcard Scopes.

Explicit Scopes

An explicit Scope value is one where the Cube Level and Level Member are explicitly defined.

For example:

ID=1

AllMember Scope

Multiple Explicit Scopes

A Scope can have multiple Explicit values.

For Example:

Vertex=1d|Vertex=1m|Vertex=1w

AllMember Scope

Wildcard Scopes

A Scope’s Level Value can also be applied to all Level Members of a given Cube Level. This is done by specifying a Scope where the Cube Level Member is a ("*") wildcard. This will match all Members of the given Cube Level. An example of a wildcard scope is defined below:

ID=*

AllMember Scope

«!–#### Parent Child Scopes

A Parent-Child scope is a scope defined on Parent-Child hierarchy, which is a multi-level hierarchy where a parent/child relationship exists between the hierarchy’s levels. For example, the BookHierarchy, in FRTB, hierarchy consists of levels Level 1, Level 2, Level 3,…, Level 15 and each level has a parent/child relationship with the next level (Level 1 is a parent to Level 2, etc.).

In order to create valid Parent-Child scope’s via initial CSV loading, the property parent-child.levels must be set, declaring all Parent-Child hierarchies. The format of the property value is: @=@

An example:

parent-child.levels=FRTB@StandardisedApproachCube=BookHierarchy@Organization—>

All Member Scopes

A Scope’s Level Value can also be applied to the AllMember Level of a given Cube Level. This is done by specifying a Scope where the Cube Level Member is a (“AllMember”). This will match the Total / AllMember of the given Cube Level. An example of an AllMember scope is defined below:

Book=AllMember

AllMember Scope

Ambiguous Scopes

A Scope can be ambiguous if the Level or Level Member specified exists in multiple Hierarchies.

Ambiguous Level Name

Assuming we have the following Cube Structure:

Dimension Hierarchy Levels
Calendar Days Year, Month, Day
Calendar Leap Years Year

If we specify a Scope Year=2022 then Limits will throw an exception as Year is ambiguous and relates to two Levels in the Cube Year of the Days Hierarchy and Year of the Leap Years Hierarchy. To fix this, we will need to specify that we want the year of the Leap Years Hierarchy: Year@Leap Years=2022.

Ambiguous Level Path

A Level Member is Ambiguous if it’s a part of a Multi-Level Hierarchy and there are multiple paths through the Hierarchies 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 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 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 one of the other Months.

With the handling of ambiguous paths, we have the following properties to change the default handling of ambiguous scopes:

scope.force-unambiguous-level-paths

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=January|Year=2021 then the scope is no longer ambiguous, as there is no other path back to the root.February.

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.

scope.autofill-unambiguous-level-paths

This property allows a Limit’s Scope to be modified at load time. IFF the Level Member provided of a Scope is unambiguous, we add all un-specified Level Members to the Scope as well. This will lock this Limit’s Scope location so if new data comes in, we won’t have to worry about the Scope becoming ambiguous and apply 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 the 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 were to be 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.

note

If autofill is turned on and multiple Paths are found for a Level Member, an exception will be thrown as a Scope can only be on one path of a Multi-Level Hierarchy.

Limit lookup

Because this can potentially cause multiple Limit Definitions to be applied to any location in the cube, Limit definition collisions are resolved by the following logic:

We take the Limit Definition that has:

  1. A higher precedence
  2. Matches a location with more explicit scope matches.
  3. Matches a location with more wildcard scope matches.
  4. Has a lesser value.

Other

note

If running as a JAR file, the limits_approve.csv file may not be found, and you will need to explicitly point to it.

  • ActiveUI, ActiveViam’s user interface for exploring the cube, will be available from http://localhost:9090/ui

The default security credentials are admin:admin, but can be modified in the SecurityConfig class (we use Spring Security).