Skip to main content

Introduction

In Atoti, it is possible to restrict the view of a cube by granting access to a specific set of members. This is achieved using:
  • Atoti entitlements: They provide a way to configure ISubCubeProperties context values characterizing the resources an authenticated user can access (see Atoti Security section for more details).
  • Cube Filters: They represent filters that can hide members of an Atoti cube for a given query.
In this article, we explain the use case behind cube filters and detail how these objects can be manipulated to reach the wanted result.
Query filters generation is closely tied to the original MDX. Nevertheless, for the sake of clarity this topic is out of this article’s scope. More details can be found in the MDX Filtering page.

Post-Processors and CubeFilters

Editing filters can be very handy, especially when working in an environment relying on automated MDX generation through a UI or using a third-party component that may not offer the possibility of editing the final MDX. An MDX generated filter may result in hiding the very members you want to do calculations on, thus producing confusing results. Atoti Server allows post-processors to manipulate ICubeFilters to remove such member restrictions. This can be done using the Prefetcher API of the post-processors. PrefetchRequests are requests emitted by post-processors to notify the core product to prefetch the given aggregates on a given location with a defined scope expressed using an ICubeFilter. Those requests are typically created by the IPrefetcher of a post-processor. IPrefetchRequests also hold a context that can be used to store computations made in the prefetcher, so that they can be used within the post-processor’s compute() method.
Note: When building a Prefetch Request, the ILocation corresponding to the required data for the post-processor computation can be different from the one from the query. One should make sure to provide all the required locations to the IPrefetchRequest.
In a post-processors chain, filters are propagated along the chain. This mean that each post-processor may edit the cube filter it received and pass it along to the underlying post-processors.

Use Case

A classic example would be the calculation of day-to-day differences. The following query calculates the differences of contributors.COUNT between each day and the day before.
The above query yields the following result:
Now let us change the initial MDX by selecting only the 24th and 25th of September.
The result becomes:
Filtering introduced a result change for the 24th of September. This is because the previous day has been hidden by the Subselect, and so is not accessible through the top SELECT. While it is possible to rewrite the MDX query without filtering to get the expected result, it can’t be done by pure UI interactions. Even worse, the user may be completely stuck if the UI does not provide a way to edit the underlying MDX query (Excel, for example). For such use cases, the ICubeFilter API provides the capability to directly edit the resulting Cube Filters, ignoring the query filter when needed and allowing more granular control over the queried space.

Building CubeFilters

ICubeFilters are immutable objects that once built cannot be modified. An ICubeFilter can only be obtained by calling the ICubeFilterBuilder.build() method. There are two approaches for building a Cube Filter:
  • From scratch using CubeFilter.builder(). This call will provide an ICubeFilterBuilder with no access restrictions by default.
  • From an existing ICubeFilter using ICubeFilter.edit(). This will provide a builder including a copy of the permissions of the input ICubeFilter.
The fluent ICubeFilterBuilder API allows you to:
  • Specify access to some measure with ICubeFilterBuilder.includeMeasure(String measureName).
  • Grant or deny access to some members with various ICubeFilterBuilder.includeMembers(...) methods or ICubeFilterBuilder.excludeMembers(...) methods, respectively. The input of these methods specify the dimension, hierarchy, and the member path of the required members. Alternatively, ICubeFilterBuilder.includeMembersWithConditions(...) methods and ICubeFilterBuilder.excludeMembersWithConditions(...) support, on top of the member path specification, ICondition conditions to express more complex filtering rules.
  • Intersect a given filter with another pre-existing filter with ICubeFilterBuilder.intersect(ICubeFilter filter).
  • Clear restrictions on a given hierarchy using ICubeFilter.clear(...) methods.
The final ICubeFilter instance can be obtained by calling the ICubeFilterBuilder.build() method.
If the path to the members to grant access to is incomplete, then all members below are granted.
Examples:
Creates a filter that has access to measures with a member path “AllMember/DeskA/Book3”.
Creates a filter that has access to measures of members that do not correspond to “DeskA”.

TrendPostProcessor Example

The following example illustrates the usage of the CubeFilter API in a Trend post-processor. The CubeFilter built when defining the IPrefetcher relative to the post-processor (see init() and createPrefetchers()) will dynamically allow access to the correct dates through the filter created in computeFilter(). The computeLocation() method will include the location of all the data needed for performing the post-processor’s computations.