> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Migration guide 4.0

This guide explains the changes required to migrate to the stated version
of the Atoti Limits.

## Migrate to 4.0.4

### Summary

* **Recommended performance enhancement:** Disable scope hierarchies for large cardinalities of limit scopes.
* **Warning Threshold:** Intrepretation of the [warning threshold](#warning-threshold) limit has been updated.

#### Disabling scope hierarchies

The [scope level name](../../../user-ref/cube/scope-level-name) and [scope level member](../../../user-ref/cube/scope-level-member)
hierarchies can incur a performance cost when using Atoti Limits with limits with a high
cardinality of scopes. We recommend disabling scope hierarchies if you do not require these hierarchies to improve
the overall performance of Atoti Limits. This can be done by setting the property `limits.cube.scope-hierarchies-enabled=false`
in the `application.yml` file of your Atoti Limits application.

#### Warning threshold

In version 4.0.1, the interpretation of the warning threshold was updated. The new behavior, along with the
Atoti Limits and Atoti UI documentation, clarifies that the threshold is a direct percentage of the limit’s utilization.
If you updated a limit’s warning threshold or defined new warning thresholds using Atoti Limits in version
4.0.1-4.0.3, you may need to update your warning thresholds to ensure they are still aligned with your expectations.

##### Example

The following illustrates the updated behavior. Consider a limit with these
settings:

* **Rule**: GREATER\_THAN
* **Warning**: True (80%)
* **Absolute Value**: False
* **Limit Value**: 1000

The UI wording and warning range have changed as summarized in the following table:

<table><thead><tr><th /><th>Previous behavior<br />(4.0.1-4.0.3 )</th><th>New (and original) behavior<br />(pre 4.0.1 and 4.0.4+)</th></tr></thead><tbody><tr><td><strong>UI Wording</strong></td><td>“Warn when within % of limit value”</td><td>“Warn when utilization reaches % of a limit”</td></tr><tr><td><strong>Limit will warn in the range</strong></td><td>\[200, 1000]</td><td>\[800, 1000]</td></tr></tbody></table>

## Migrate to 4.0.3

### Summary

This is a maintenance release that includes bug fixes and performance improvements.

### Deprecations

#### `ILimitsActivitiAuthenticationManager`

The `ILimitsActivitiAuthenticationManager` interface is no longer used, has been deprecated and
marked for removal. This interface was previously used to authenticate requests to the Activiti
engine in
threads spawned by the DLC. It is no longer used and the authentication is now managed by
the `DelegatingSpringSecurityContextDataLoadController`.
It will be removed in the next minor release.

#### `IWebClientService`

The `getWithAuth(...)` methods in `IWebClientService` have been deprecated and marked for removal.
These are no
longer invoked and the default implementations of these methods in `WebClientService` now throw an
`UnsupportedOperationException`.

The `get(...)` methods are now used instead.

If you have custom code
that calls the `getWithAuth(...)` methods you will need to update it to use the `get(...)` methods
instead.

#### `ConnectedAtotiServer` and `ConnectedAtotiServersManager` deprecations

The following fields have been deprecated and marked for removal in `ConnectedAtotiServer`
and `ConnectedAtotiServersManager`. These are no longer required because the
`ILimitsRestClientBuilderProvider` is responsible for authenticating requests, so we don’t
need to pass these variables through the application.

`ConnectedAtotiServer` fields:

* `authentication`
* `limitsAuthentication`
* `servicePrincipal`
* `useJwtMachineToMachineAuth`

`ConnectedAtotiServersManager` fields:

* `contentServerAuth`
* `limitsAuth`
* `servicePrincipal`
* `useJwtMachineToMachineAuth`

### Configuration properties

#### Properties deprecated

##### [limits-integration-common module](../../../user-ref/properties/config-properties/limits-integration-common)

<table><thead><tr><th>Property Name</th><th>Comment</th></tr></thead><tbody><tr><td><code>limits.autoconfiguration.limits-authentication</code></td><td>This property has been deprecated and will be removed in the next minor release. It is currently used to configure Basic Authentication which will be replaced with JWT Authentication.</td></tr><tr><td><code>limits.autoconfiguration.authentication</code></td><td>This property has been deprecated and will be removed in the next minor release. It is currently used to configure Basic Authentication which will be replaced with JWT Authentication.</td></tr><tr><td><code>limits.autoconfiguration.content-server.authentication</code></td><td>This property has been deprecated and will be removed in the next minor release. It is currently used to configure Basic Authentication which will be replaced with JWT Authentication.</td></tr></tbody></table>

## Migrate to 4.0.2

### Summary

* [`WebClientService` changes](#webclientservice-changes)
* [Calculated measure location](#calculated-measure-location)

### `WebClientService` changes

If you previously extended `WebClientService`, update it to implement the new `IWebClientService`
interface. The methods are unchanged, but Atoti Limits now references `IWebClientService`
instead of `WebClientService`.

<Accordion title="IWebClientService">
  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  /**
   * <b>IWebClientService</b>
   *
   * <p>This service is used to send authenticated requests from the Atoti Limits Server to
   * application servers.
   *
   * @author ActiveViam
   */
  public interface IWebClientService {

    /**
     * Sends a POST request with the {@link RestClient} API.
     *
     * @param serverName - The target server for this {@link RestClient}'s Http requests
     * @param path - The path of the endpoint receiving the request
     * @param jsonBody - The POST request's payload body
     * @param errorMessage - A custom error message if an exception occurs
     * @return The POST response as a String
     */
    String post(String serverName, String path, String jsonBody, String errorMessage);

    /**
     * Sends a POST request with the {@link RestClient} API.
     *
     * @param serverName - The target server for this {@link RestClient}'s Http requests
     * @param path - The path of the endpoint receiving the request
     * @param jsonBody - The POST request's payload body
     * @param errorMessage - A custom error message if an exception occurs
     * @param extractResponseBody - If true, construct a {@link JsonErrorException}, else, throw a
     *     {@link LimitsWebClientServiceException}
     * @return The POST response as a String
     */
    String post(
        String serverName,
        String path,
        String jsonBody,
        String errorMessage,
        boolean extractResponseBody);

    /**
     * @param url - The {@code url} of the endpoint receiving the request
     * @param server - The target server for this {@link RestClient}'s Http requests
     * @param errorMessage - A custom error message if an exception occurs
     * @return The GET response as a String
     */
    String get(String url, String server, String errorMessage);

    /**
     * @param url - The {@code url} of the endpoint receiving the request
     * @param server - The target server for this {@link RestClient}'s Http requests
     * @param errorMessage - The custom error message if an exception occurs
     * @param extractResponseBody - If true, construct a {@link JsonErrorException}, else, throw a
     *     {@link LimitsWebClientServiceException}
     * @return The GET response as a String
     */
    String get(String url, String server, String errorMessage, boolean extractResponseBody);

    /**
     * @param url - The {@code url} of the endpoint receiving the request
     * @param authorization - The encoded {@code authorization} string
     * @param errorMessage - The custom error message if an exception occurs
     * @return The GET response as a string
     */
    String getWithAuth(String url, String authorization, String errorMessage);

    /**
     * Makes a GET request with the authentication already encoded. This method is called when sending
     * requests to the RemoteContentServer, which doesn't have a `serverName` but already has an
     * encodedAuth string.
     *
     * @param url - The {@code url} of the endpoint receiving the request
     * @param authorization - The encoded {@code authorization} string
     * @param errorMessage - A custom error message if an exception occurs
     * @param extractResponseBody - If true, construct a {@link JsonErrorException}, else, throw a
     *     {@link LimitsWebClientServiceException}
     * @return The GET response as a String
     */
    String getWithAuth(
        String url, String authorization, String errorMessage, boolean extractResponseBody);

    /**
     * Sends a PUT request with the {@link RestClient} API.
     *
     * @param serverName - The target server for this {@link RestClient}'s Http requests
     * @param path - The path of the endpoint receiving the request
     * @param body - The PUT request's payload body
     * @param responseType - The expected response type
     * @return The PUT response as a String
     */
    <T> ResponseEntity<T> put(String serverName, String path, Object body, Class<T> responseType);
  }
  ```
</Accordion>

### Calculated measure location

If you have limits on calculated measures, we expect that these calculated measures are saved in either
the `/pivot/entitlements/cm` folder of the content server (recommended) **OR** in the `ui/calculated_measures`
folder (not recommended). If you have limits on calculated measures that exist in both folders, then
those in `ui/calculated_measures` should be moved to `/pivot/entitlements/cm`, otherwise these limits
won’t be created. The `ui/calculated_measures` folder is the location for calculated measures that
were saved via ActiveUI 4, so we do not expect most users will need to migrate.

### Configuration files

#### Files Modified

##### Properties added

###### [limits-activeviam module](../../../user-ref/properties/config-properties/limits-activeviam)

<table><thead><tr><th>Property</th><th>Default value</th><th>Description</th></tr></thead><tbody><tr><td>limits.autoconfiguration.use-jwt-machine-to-machine-auth</td><td><code>false</code></td><td>True if JWT Authentication should be used when sending requests from Atoti Limits to connected Atoti Servers. If false, Basic Authentication will be used by default unless you implement your own <code>ILimitsRestClientBuilderProvider</code> bean.</td></tr><tr><td>limits.autoconfiguration.service-principal</td><td /><td>The name of the user authenticated to perform machine-to-machine requests from Atoti Limits to connected Atoti Servers, if using JWT Authentication.</td></tr></tbody></table>

## Migrate to 4.0.1

Upgrading from version *4.0.0*, see
the [Atoti Limits 4.0.1 Release Notes](../../release-notes#401).

### Summary

* **Disable Scope Hierarchies**: We have added a property `limits.cube.scope-hierarchies-enabled` that can
  be used to disable scope hierarchies to improve loading performance for large cardinalities of limit
  scopes.
* **Roles**: `ROLE_USER` no longer required in Atoti Limits.

### Configuration files

#### Files Modified

##### Properties added

###### [limits-activeviam module](../../../user-ref/properties/config-properties/limits-activeviam)

<table><thead><tr><th>Property</th><th>Default value</th><th>Description</th></tr></thead><tbody><tr><td>limits.autoconfiguration.use-jwt-machine-to-machine-auth</td><td><code>false</code></td><td>True if JWT Authentication should be used when sending requests from the Atoti Server to Atoti Limits. If false, Basic Authentication will be used by default unless you implement your own <code>ILimitsRestClientProvider</code> or <code>ILimitsRestTemplateProvider</code> bean.</td></tr><tr><td>limits.autoconfiguration.service-principal</td><td /><td>The name of the user authenticated to perform machine-to-machine requests from the Atoti Server to Atoti Limits, if using JWT Authentication.</td></tr></tbody></table>

### Other changes

#### `ROLE_USER` no longer required in Atoti Limits

`ROLE_USER` is no longer a required role for all users in Atoti Limits. Previously, this role was required
because it was hardcoded as the `owner`/`reader` of KPIs created by Atoti Limits. Now, the role set as the
`owner`/`reader` of KPIs created by Atoti Limits is auto-configured, or can be overridden using the
`limits.autoconfiguration.content-server.limits-created-measures-owners` property. Users will need to have this
auto-configured (or overridden) role, or a [data access role](../../../dev/roles/data-access-permissions), to view KPIs created
by Atoti Limits, including the calculated members related to the KPIS.

## Migrate to 4.0.0

Upgrading from version *3.3.0*, see
the [Atoti Limits 4.0.0 Release Notes](../../release-notes#400).

Atoti Limits is using Atoti Server 6.1.1 and Atoti UI 5.2.x.

For new features and fixes included in these releases, please see
the [Atoti UI documentation](https://docs.activeviam.com/products/atoti/ui/5.2/)
and [Atoti UI Migration Notes](https://docs.activeviam.com/products/atoti/ui/5.2/docs/changelog), and
the [release notes for Atoti Server](https://docs.activeviam.com/products/atoti/server/6.1.1/docs/release/changelog/index.).

<Warning>
  Please note that Atoti Server version 5.11 is now out-of-support. Therefore, we
  will no longer support connections
  to servers of this version as of this release of Atoti Limits.
</Warning>

### Summary

* **Atoti Server upgrade**: Atoti Limits has been upgraded to Atoti Server 6.1.1. For the required changes, see [Atoti Server upgrade](#atoti-server-upgrade).
* **Atoti UI upgrade**: Atoti UI has been upgraded to version 5.2.0. For the required changes,
  see the [Atoti UI migration guide](https://docs.activeviam.com/products/atoti/ui/latest/docs/migration/5.1-to-5.2/).
* **Maven Artifact group ID changes**: The `groupID`s for maven artifacts have been updated from `com.activeviam.limits`
  to `com.activeviam.solutions.limits` to align with other ActiveViam Business Solutions.
  Please update your `groupID`s when importing Atoti Limits artifacts. This change does not affect package names.
* **Improvements to the auto-configuration modules**: These improvements require you to update
  dependencies and properties.
* **Simplified scopes migration script**: We have added an optional script for migrating CSV files to use the simplified scope notation. See [CSV migrations to 4.0.0](#csv-migrations-to-400).

### Breaking changes

* **Starter changes**: Multiple classes have been removed from the starter module. See [Starter changes](#starter-changes) for more details.
* **Removal of DTO suffix**: The “DTO” suffix has been removed from Java objects that were not pure data transfer objects. See the full list of changes [below](./migrate-4.0#removal-of-dto-suffix).
* **Manual configuration removal**: Manual configuration has been removed in favor of
  auto-configuration.

#### Atoti Server upgrade

For details on migrating your code to Atoti Server 6.1.1,
see [the Atoti Server migration notes](https://docs.activeviam.com/products/atoti/server/6.1.1/docs/release/migration_notes/).

<Tip>
  There is a [java-api-migration-tool](https://github.com/activeviam/java-api-migration-tool) available to help you migrate your code.
  We highly recommend that you use this tool.
</Tip>

Here are the main changes you need to make to your Atoti Limits code:

##### Java 21

Update your Java version to Java 21 or later in order to run Atoti Limits.

##### Atoti Spring Boot Starter changes

Atoti Server now ships with a suite of [Spring Boot Starters](https://docs.activeviam.com/products/atoti/server/6.1.1/docs/starters/starters_directory/).
These dependencies auto-configure default imports required by Atoti Server, that you may override at runtime.

If you do not use the out-of-the-box `limits-starter`, import these starter dependencies and remove any explicit import of classes that are now auto-configured.
If you do use the out-of-the-box `limits-starter`, no further changes are required.

The following core classes have been removed in `limits-activeviam` or `limits-starter` as they are now inherited from starters:

* `ActivePivotServicesConfig.class`
* `ActivePivotWebSocketServicesConfig.class`
* `ActivePivotWithDatastoreConfig.class`
* `ActivePivotXmlaServletConfig.class`
* `ActiveViamRestServicesConfig.class`
* `AdminUIResourceServerConfig.class`
* `AtotiServerWebMvcConfigurer.class`
* `ContentServerWebSocketServicesConfig.class`
* `FullAccessBranchPermissionsManagerConfig.class`
* `JwtConfig.class`
* `LocalI18nConfig.class`
* `NoSecurityDatabaseServiceConfig.class`
* `TracingConfig.class`

##### Security configuration changes

The upgrade to Atoti Server 6.1.1 includes changes to
the security configuration.
We expect you to implement your own security, but we provide a sample configuration in
the `com.activeviam.limits.starter.cfg.security` package.

<Warning>
  This is not a production grade sample.
</Warning>

For details on how to implement your own security, please see
the [Atoti Server documentation](https://docs.activeviam.com/products/atoti/server/6.1.1/docs/starters/atoti_starter/#stock-security).

#### Starter changes

Most of the `limits-starter` module has been moved into `limits-activeviam`. The goal of these changes is
ultimately to improve the developer experience when migrating, particularly in the context of client
customizations. Please see the [Getting Started guide](../../../dev/getting-started) for more details on how to structure your project.

To this end, we have made the following changes:

* We have added a new `LimitsCoreAutoConfiguration` class in `limits-activeviam`. This is a base configuration class for the imports required by Atoti Limits and is auto-configured on startup.
  * Most of `LimitsAppConfig` has been moved to `LimitsCoreAutoConfiguration`.
* `LimitsApplicationConfigurationPropertiesConfig` has been removed and the properties have been moved into the `@EnableConfigurationProperties` annotation in `LimitsCoreAutoConfiguration`.
* We have added a new `LimitsRestServicesAutoConfiguration` class to import all the REST services required by Atoti Limits.
* `LimitsProcessExceptionHandler` has been removed and the exception handlers it contained have been merged into `RestExceptionHandlerControllerAdvice`.

We have converted many of the `*Config` classes explicitly imported in `LimitsAppConfig` to `*AutoConfiguration` classes and moved them to the `com.activeviam.limits.autoconfigure` package in `limits-activeviam`.
These new classes will be automatically registered via [Spring Auto-configuration](https://docs.spring.io/spring-boot/reference/using/auto-configuration.), so there is no more need to explicitly import them.
The beans that were exposed by these classes are now annotated with `@ConditionalOnMissingBean`, so you can define your own implementations of the interfaces to override the default beans.
The following classes have been affected by this change:

<table><thead><tr><th>Old <code>\*Config</code> class</th><th>New <code>\*AutoConfiguration</code> class</th><th>Description</th></tr></thead><tbody><tr><td><code>DefaultManagedObjectIdentityGeneratorConfig</code></td><td><code>ManagedObjectIdentityGeneratorAutoConfiguration</code></td><td>Configuration for the ID generators.</td></tr><tr><td><code>EvaluationServiceConfig</code></td><td><code>LimitsEvaluationServicesAutoConfiguration</code></td><td>Configuration for the services used when evaluating limits.</td></tr><tr><td><code>LimitsContentConfig</code></td><td><code>ContentServiceAutoConfiguration</code></td><td>Configurations for the content service.</td></tr><tr><td><code>LimitsDatastoreConfig</code></td><td><code>LimitsDatastoreAutoConfiguration</code></td><td>Configuration for the datastores.</td></tr><tr><td><code>LimitsValidationConfig</code></td><td><code>LimitsValidationAutoConfiguration</code></td><td>Configuration for the validation API.</td></tr><tr><td><code>LimitsWorkflowConfig</code></td><td><code>LimitsWorkflowAutoConfiguration</code></td><td>Configurations for the workflow.</td></tr><tr><td><code>PivotConfig</code></td><td><code>LimitsManagerAutoConfiguration</code></td><td>Configuration for the services used when evaluating limits.</td></tr></tbody></table>

The following classes have been moved from `LimitsAppConfig` to `LimitsCoreAutoConfiguration`:

* `LimitsActivitiAuthenticationManager`,
* `LimitsDataProperties`
* `LimitsDimensionsConfig`
* `LimitsCubeConfig`
* `LimitsAsOfDateLoader`
* `DataLoadControllerConfig`
* `CSVSourceConfig`
* `LimitsProcessEngineMailConfig`
* `ConnectedAtotiServersManager` (previously `RemoteAtotiServersProperties`)
* `LimitsManagerConfig` (previously `PivotConfig`)

The following classes have been moved from `LimitsAppConfig` to the
new `LimitsRestServicesAutoConfiguration` class:

* `AutoConfigRestService`
* `DataLoadControllerRestServiceConfig`
* `IncidentRestController`
* `IncidentsSseController`
* `KPICrudRestService`
* `LimitsAsOfDateRestService`
* `LimitsDefinitionCrudRestService`
* `LimitsEvaluationRestService`
* `LimitsServerSettingsRestController`
* `RemoteCubeRestService`
* `RestExceptionHandlerControllerAdvice`
* `ScopeRetrievalRestService`
* `UploadCsv`

The following classes have been moved from `LimitsAppConfig` to the new `LimitsDatastoreAutoConfiguration` class:

* `AtotiServerWithDatastoreConfig`
* `DatastoreConfiguratorSetup`
* `LimitsDatastoreService`
* `LimitsDatastoreVersionService`
* `LimitsDefinitionDatastoreConfig`
* `LimitsProcessInstanceDatastoreConfig`
* `LimitsSchema`
* `ScopeTupleGenerator`
* `TuplePublisherConfig`

The following classes have been moved from `LimitsAppConfig` to the
new `LimitsCrudServicesAutoConfiguration` class:

* `IncidentCrudService`
* `KpiCrudService`
* `LimitsCrudService`
* `LimitsRetrievalService`

The following classes have been moved from `LimitsAppConfig` to the
new `LimitsEvaluationServicesAutoConfiguration` class:

* `DefaultEvaluationService`
* `DefaultEvaluationTaskManager`
* `EvaluationErrorHandler`

The following classes have been moved from `LimitsAppConfig` to the
new `LimitsJpaAutoConfiguration` class:

* `LimitsJpaConfig`
* `LimitsProcessJpaConfig`

The following classes have been moved from `LimitsAppConfig` to the
new `LimitsPersistenceServicesAutoConfiguration` class:

* `DefaultLimitsAppCrudService`
* `DefaultLimitsAppDatastoreCrudService`

The following classes have been renamed:

<table><thead><tr><th>Old class name</th><th>New class name</th></tr></thead><tbody><tr><td><code>PivotManager</code></td><td><code>LimitsManagerDescriptionConfig</code></td></tr></tbody></table>

#### Improvements to the auto-configuration modules

Although we do not intend for these modules to be extended, we have made improvements to the
auto-configuration modules that are breaking.

You won’t need to update code, but you’ll need to update dependencies and properties.
For more information see [the connected server section](../../../dev/integration/java).

##### Changes requiring action

<table><thead><tr><th>Breaking change</th><th>Action required</th></tr></thead><tbody><tr><td>The <code>limits-auto-config-ap\<ATOTI\_SERVER\_VERSION\_PREFIX></code> artifacts have been renamed to <code>limits-auto-config-\<ATOTI\_SERVER\_VERSION\_PREFIX></code>.</td><td>Update your dependency import.</td></tr><tr><td>The <code>limits-auto-config</code> modules are now true auto-configuration modules, meaning you now only have to import the dependency, not the classes.</td><td>Remove the previous import of <code>LimitsAutoConfig</code>.</td></tr><tr><td>The <a href="https://docs.activeviam.com/products/modules/limits/3.3/online-help/user-ref/properties/config-properties/limits-integration-common.html">old autoconfiguration properties</a> have been replaced with <a href="../../../user-ref/properties/config-properties/limits-integration-common">new properties</a>.</td><td>Update your properties accordingly.<br /><note><p>Only four properties are marked as REQUIRED.</p></note></td></tr></tbody></table>

##### Changes not requiring action

* `LimitsAutoConfig` has been renamed to `LimitsConnector`.
* `RemoteAtotiServersProperties` was used in the past to store the connected servers in Atoti Limits and as a configuration source for the manual configuration. As we have removed the
  manual configuration, it has been renamed to `ConnectedAtotiServersManager`.
* The `com.activeviam.limits.autconfig.*` packages have been renamed
  to `com.activeviam.limits.autoconfigure.*`.
* The `com.activeviam.limits.integration.common.*` packages have been renamed
  to `com.activeviam.limits.autoconfigure.common.*`.
* The `limits-auto-config-ap<ATOTI_SERVER_VERSION_PREFIX>` artifacts have been renamed
  to `limits-auto-config-<ATOTI_SERVER_VERSION_PREFIX>`.
* The `lookup-post-processor-ap<ATOTI_SERVER_VERSION_PREFIX>` artifacts have been renamed
  to `lookup-post-processor-<ATOTI_SERVER_VERSION_PREFIX>`.

#### Artifact changes

We have reorganized the artifacts used by the connected server to connect with Atoti Limits.

<Note>
  We do not expect users to have to modify their code to accommodate these changes,
  but we shall provide them nonetheless for clarity.
</Note>

This includes artifacts for connecting with instances of Atoti Server on
version `6.0.x` using Java 11, in addition to the already supported `6.0.x-sb3` version using Java 17.

The `limits-shared-properties` module has been renamed to `limits-common` and the `limits-lookup-postprocessors`
modules have been merged into the `limits-integration` and `limits-common` modules. This helps:

* reduce the number of modules in the project,
* simplify the usage of Spring in the `LookUpPostProcessor`,
* facilitate future improvements by having more reusable code across Atoti Server
  version-specific modules.

The artifact structure is as follows:

* **limits**
  * **limits-activeviam** - Source code for the services required by Atoti Limits.
  * **limits-atoti-server** - An Atoti Server sandbox used for **testing** Atoti Limits. **Not intended for production.**
    * **limits-atoti-server-60** - Atoti Server sandbox running on `6.0.X`.
    * **limits-atoti-server-60-sb3** - Atoti Server sandbox running on `6.0.X-sb3`.
    * **limits-atoti-server-61** - Atoti Server sandbox running on `6.1.X`.
  * **limits-integration** - Code to integrate Atoti Server with Atoti Limits.
    * **limits-auto-config-60** - Code to integrate Atoti Server with Atoti Limits `6.0.X`.
    * **limits-auto-config-60-sb3** - Code to integrate Atoti Server with Atoti Limits `6.0.X-sb3`.
    * **limits-auto-config-61** - Code to integrate Atoti Server with Atoti Limits `6.1.X`.
  * **limits-migrations** - Scripts to migrate Atoti Limits.
  * **limits-common** - Code common to both `limits-activeviam` and `limits-integration` modules.
  * **limits-starter** - Lightweight Spring Boot application used to get Atoti Limits up and running quickly.

The artifact changes from the previous release are as follows:

<table><thead><tr><th>Old Name</th><th>New Name</th><th>Comment</th></tr></thead><tbody><tr><td><code>limits-shared-properties</code></td><td><code>limits-common</code></td><td>The old artifact has been renamed.</td></tr><tr><td><code>limits-common-lookup</code></td><td><code>limits-common</code></td><td>The old artifact has been merged into the new artifact.</td></tr><tr><td><code>lookup-post-processor-ap60</code></td><td><code>limits-auto-config-60-sb3</code></td><td>The old artifact has been merged into the new artifact and requires Java 17.</td></tr><tr><td>N/A</td><td><code>limits-auto-config-60</code></td><td>This new artifact is compatible with Java 11.</td></tr><tr><td><code>limits-auto-config-ap60</code></td><td><code>limits-auto-config-60-sb3</code></td><td>The old artifact has been renamed and requires Java 17.</td></tr><tr><td><code>limits-atoti-server-60</code></td><td><code>limits-atoti-server-60-sb3</code></td><td>The old artifact has been renamed and requires Java 17.</td></tr><tr><td>N/A</td><td><code>limits-atoti-server-60</code></td><td>This new artifact is compatible with Java 11.</td></tr></tbody></table>

#### Removal of DTO suffix

We have removed the “DTO” suffix from classes that were not pure data transfer objects. Please update any references to these classes in your custom code:

* `LimitDTO.java`
* `LimitStructureDTO.java`
* `IncidentDTO.java`
* `LimitsProcessInstanceDTO.java`
* `HistoricalClassDifferenceDTO.java`
* `HistoricalFieldDifferenceDTO.java`
* `CalculatedMeasureDTO.java`
* `CalculatedMeasuresDTO.java`
* `ContentServerElementDTO.java`
* `ContentServerEntryDTO.java`

#### CSV migrations to 4.0.0

The migration script migrates the `limits.csv` files from Atoti Limits 3.3.0 to 4.0.0 by converting the scope value
to the new simplified notation.

<Warning>
  Migrating the `limits.csv` files from Atoti Limits 3.3.0 to 4.0.0 is NOT a required migration. Scopes in the old format
  will still work in Atoti Limits 4.0.0.
</Warning>

##### How it works

This script expects the following program arguments (in this order):

1. The target version of Atoti Limits (should be `4.0.0`).
2. The source limits input file path.
3. The target limits output file path.

##### Steps

1. Run `mvn clean install` on `limits-migrations`.
2. Run `java -jar path/to/limits-migrator-tool-exec.jar 4.0 path/to/source/limits.csv path/to/target/limits.csv path/to/properties/folder`.
   Your files are now converted to the new format and can be found in the target directory.

<Note>
  The output directory must already exist, but the file will be created.
</Note>

#### Changes to `ILimitsRetrievalService`

The `ILimitsRetrievalService` interface has been updated and the default implementation, `LimitsRetrievalService`, has
been significantly changed to improve performance. If you have implemented a custom version of
this service, you will need to make the following method changes:

<table><thead><tr><th>Old signature</th><th>New Signature</th><th>Note</th></tr></thead><tbody><tr><td><code>ILimitsDatastoreVersionService getLimitsDatastoreVersionService();</code></td><td>N/A</td><td>This method has been removed.</td></tr><tr><td><code>IDatabaseVersion getDatastoreVersion(LimitsQueryPayload limitsQueryPayload);</code></td><td><code>IDatabaseVersion getDatastoreVersion(String branchName);</code></td><td>This method has been modified to accept a string argument specifying the name of the branch on which to execute the query.</td></tr><tr><td><code>Integer getPendingApprovalsForLimitStructure(String limitStructureId);</code></td><td><code>Map\<String, Integer> getPendingApprovalsForLimitStructure(Set\<String> limitStructureIds);</code></td><td>This method has been updated to accept a set of limit structure IDs and return a map of those IDs to the number of pending approvals. This improves performance for UI requests on the <a href="../../../user-ref/using-limits/limits-inventory">Inventory screen</a>.</td></tr></tbody></table>

#### Removing manual configuration

The manual configuration has been removed from Atoti Limits. Please see the [removed
properties table](#properties-deleted) for the properties you
should remove.

### Validator API changes

Several API changes have been made to the `IValidator` interface:

* The `ILimitValidator`, `ILimitStructureValidator`, and `IIncidentValidator` interfaces have been moved to the `com.activeviam.limits.model.validation.function.intf` package.
* The `getInvalidObjects()` method has been removed since it was not used.
* The `reset(boolean throwException)` method has been updated to an empty default implementation and is overridden by the abstract class, `AValidator`. To override the `reset` method, see the [custom validator](../../../dev/dev-extensions/custom-validation/custom-validators) page for more information.

### Removing Between and Not Between KPI types

The `Between` and `Not Between` Kpi types have been removed as valid KPI types since they were never supported by Atoti Limits.

### Configuration

#### Configuration properties

##### Files Modified

###### [limits-integration-common module](../../../user-ref/properties/config-properties/limits-integration-common)

All properties have been replaced. Please see the [new properties](../../../user-ref/properties/config-properties/limits-integration-common) for the updated list.

##### [limits-activeviam module](../../../user-ref/properties/config-properties/limits-activeviam)

###### Properties added

###### [limits-activeviam module](../../../user-ref/properties/config-properties/limits-activeviam)

<table><thead><tr><th>Property</th><th>Default value</th><th>Description</th></tr></thead><tbody><tr><td>limits.cube.format.kpi-goal</td><td>#,##0.#</td><td>Format value for KPI Goal values.</td></tr><tr><td>limits.cube.kpi-filters-enabled</td><td>true</td><td>True if cube filters are enabled for Limits KPIs, false otherwise.</td></tr><tr><td>limits.data-access-control.servers.<server name="">.role-permissions</server></td><td /><td>Defines the permissions available to each role.</td></tr><tr><td>limits.data-access-control.servers.<server name="">.default-scope-match-mode</server></td><td>MATCH\_ALL</td><td>Sets the match mode to use for scope permissions when it is omitted.</td></tr><tr><td>limits.autoconfiguration.content-server.limits-created-measures-owners</td><td /><td>The roles that will be the owner/reader for the calculated members that were created based on the KPIs. The value should be auto-configured from the KPI owners in the content server.</td></tr><tr><td>limits.workflow\.workflow-status-fetched-with-limit</td><td>true</td><td>When set to true, retrieving limit structures also updates the limit status with the current workflow status.</td></tr></tbody></table>

#### Property files

No changes.

### Datastores

#### Modified stores

<table><thead><tr><th>Modification</th><th>Store</th><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>Added</td><td><a href="../../../user-ref/datastore/limits-store">Limits</a></td><td>Alive</td><td>Boolean</td><td>This field indicates whether the limit is still alive (not deleted or expired). For more details, see <a href="./migrate-4.0"><code>Alive</code> field in Limits store</a>.</td></tr></tbody></table>

### Cube schema

#### Added

<table><thead><tr><th>Cube</th><th>Dimension</th><th>Hierarchy</th><th>Levels</th><th>Datastore fields</th><th>Details</th></tr></thead><tbody><tr><td>Limits</td><td>Limit</td><td><a href="../../../user-ref/cube/scope-level-name">Scope Level Name</a></td><td>Scope Level Name</td><td>ScopeKeys</td><td>The level name of a limit’s scope, for example <code>Book\@Books\@Booking</code>.</td></tr><tr><td>Limits</td><td>Limit</td><td><a href="../../../user-ref/cube/scope-level-member">Scope Level Member</a></td><td>Scope Level Member</td><td>ScopeValues</td><td>The level member of a scope, for example <code>Book 1</code>.</td></tr></tbody></table>

### Measures

No changes.

### Other changes

#### Independent retrieval of limit status

`/limits/rest/v2/limitDefinition/limits/status/get` retrieves status of Limits based on their id.
This completes the server setting `workflow-status-fetched-with-limit` to omit status when fetching limits structures with `/limits/rest/v2/limitDefinition/structure/get`.

This helps loading the limits viewer screen in the Atoti UI when the amount of Limits in a structure is relatively large.
If a long time is experienced when fetching the Limits in the UI (more than a few seconds) this aims at retrieving the Limits faster by decoupling the retrieval of each Limit’s status.

#### `Alive` field in `Limits` store

Due to the [independent retrieval of limit status](#independent-retrieval-of-limit-status), a field has been added to the [Limits store](../../../user-ref/datastore/limits-store) to keep track of whether a limit is alive (not expired or deleted).
This was previously based on the status of the limit, which was stored in the Limits store.
However, the status is now exclusively retrieved through the workflow, so information on whether a limit is alive is now independent of the status, so it can be retrieved at a later stage.

This store field defaults to `true` and cannot be set via CSV source as we expect any limit loaded from file existing at its creation.
To access a deleted or expired limit, it should be persisted in the audit trail.

#### `ROLE_LIMITS` is no longer a required role

The `ROLE_LIMITS` role is no longer required for all users of Atoti Limits. This role has been repurposed as the [full-access role](../../../dev/roles/limits-roles#role_limits-full-access) in the permission roles to maintain backward compatibility.
Users with this role will continue having full access to all actions in the UI as they previously did.

<Note>
  `ROLE_LIMITS` is still used to tag KPIs created by the module, but user access to the KPIs is controlled by the `ROLE_USER` role, which is still [required](../../../dev/roles/limits-roles#role_user).
</Note>
