Migration notes 4.1

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

Migrate to 4.1.0

Upgrading from version 4.0.3, see the Atoti Limits 4.1.0 Release Notes.

Atoti Limits is using Atoti Server 6.1.3 and Atoti UI ~5.2.6.

For new features and fixes included in these releases, please see the Atoti UI documentation and Atoti UI Migration Notes, and the release notes for Atoti Server.

Summary

  • Authentication: JWT is now the default authentication for machine-to-machine communication. Basic authentication has been removed.
  • Removal: limits-activeviam and /limits/rest/v2/limitDefinition/limitsDefinitionStoreQuery have been removed.
  • Interface changes: Several interfaces have been updated or removed (IAuthenticatedLimitUserService, IEvaluationService, IValidationError), custom implementations may need updates.
  • “Save” operation changes: Atoti Limits now strictly enforces create vs. update logic based on the presence and existence of IDs.
  • Temporary limits: sourceLimitId is now validated. Temporary limits are grouped under their official source limits in API responses.
  • Security filtering: @PostFilter and @PostAuthorize are now applied in ILimitsRetrievalService to enforce user-based result filtering.
  • Auto-configuration: Now uses @ConditionalOnMissingBean to simplify custom bean injection and avoid needing @Primary.

Breaking changes

  • Endpoint removal: Removed the /limits/rest/v2/limitDefinition/limitsDefinitionStoreQuery endpoint used when evaluating in favor of using the ILimitCacheService.
  • Module removal: The limits-activeviam module has been removed from the released source files.
  • Authentication changes: JWT is now the default machine-to-machine (MtM) authentication. This will require property changes in your Atoti Server and Atoti Limits.
  • IAuthenticatedLimitUserService changes: With the removal of Basic authentication, some methods in IAuthenticatedLimitUserService are no longer required and have been removed.
  • Evaluation service change: There is a new method in IEvaluationService, which you will need to implement if you have a custom implementation of this interface.
  • Validation error changes: The IValidationError interface has been modified. If you have any custom validation errors you will need to update them accordingly.

Module removal

The limits-activeviam module has been removed from the released source files. This is to enforce best practices that will ultimately improve the developer experience. Providing a clean separation between source code and custom code makes migrations easier.

note

The source code and javadoc of limits-activeviam is still available for download from the ActiveViam internal Maven repository. We have only excluded it from the reference starter project that we distribute with our releases.

We don’t recommend that you modify the source code of limits-activeviam. Instead, use Spring injection to add to or modify the default behavior of the core code. You can find examples of this in the Extending the module section of our documentation.

If you have modified the source code of limits-activeviam, you need to extract your changes into the limits-starter module and use Spring to inject the changes. If you can’t use Spring injection, please raise a Jira ticket in order for us to provide the appropriate hooks.

In the meantime, you can override the limits-activeviam code in limits-starter by adding your code with the same class and package name as in limits-activeviam.

JWT is now the default machine-to-machine (MtM) authentication

Atoti Limits now uses JWT authentication for machine-to-machine communication. This is the default authentication method for Atoti Limits and your Atoti Server. Therefore, you need to set the limits.autoconfiguration.service-principal property on both the Atoti Limits and your Atoti Server to communicate between servers. This service-principal user should have sufficient rights to perform all limit related operations.

You should remove the following unused properties in your Atoti Server:

  • limits.autoconfiguration.authentication
  • limits.autoconfiguration.content-server.authentication
  • limits.autoconfiguration.limits-authentication
IAuthenticatedLimitUserService changes

The following methods were required to support Basic authentication which has been removed in favor of JWT authentication. They have been removed from IAuthenticatedLimitUserService:

  • runWithAuthentication
  • decodeBase64EncodedAuthentication

If you have a custom implementation of IAuthenticatedLimitUserService that overrides the default interface implementation of these methods, you can safely remove them from your code.

Functional Interface changes

The beans used for MtM authentication have been updated to return only builders and have been renamed. These changes provide more consistency and better flexibility. If you have customized the MtM authentication, you will need to update your code accordingly.

The following interfaces have been updated:

Old Interface Name New Interface Name Applicable Server Old method signature New method signature
ILimitsRestTemplateProvider ILimitsRestTemplateBuilder Connected servers on Atoti Server version 6.0.x RestTemplate getLimitsRestTemplate() RestTemplateBuilder getRestTemplateBuilder()
ILimitsRestClientProvider ILimitsRestClientBuilder Connected servers on Atoti Server version 6.0.x-sb3 or 6.1.x RestClient getLimitsRestClient() RestClient.Builder getRestClientBuilder()
ILimitsRestClientBuilderProvider ILimitsRestClientBuilder Atoti Limits RestClient.Builder getLimitsRestClientBuilder() RestClient.Builder getRestClientBuilder()

Additional Method in IEvaluationService

An overloaded version of the evaluateLimits method has been added to the IEvaluationService interface that allows you to control whether a notification is sent when the evaluation is complete:

Collection<Incident> evaluateLimits(Collection<LimitEvaluationTask> limitEvaluationTasks, boolean sendNotification);

If you have a custom implementation of IEvaluationService, you will need to add this method to your implementation.

Validation error changes

The structure of validation errors has been streamlined to improve readability and usability. These changes impact the error objects themselves, as well as the error handlers. If you have custom validation errors or error handlers in your project, you’ll need to migrate them accordingly.

IValidationError changes
  • new method added: String getFieldName() - returns the name of the field containing the error.
  • method getLineNumber() was renamed to getIndex().
  • method getColumnIndex() was removed (replaced by getFieldName()).
  • method getSource() was removed.
IValidationErrorHandler changes
  • The handleValidationFailure and handleValidationError methods no longer take a source argument, since the source isn’t stored on the validation error.

Input file formats

No changes.

Configuration

Configuration properties

Properties added
limits-activeviam module
Property Default Value Description
limits.cube.scope-hierarchies-enabled true True if scope hierarchies are enabled. You may disable this if you don’t require the scope hierarchies and have a high cardinality of scopes defined in your limits, as it may impact performance on load.
limits.notification.server-started-notification-user-role ROLE_ADMIN The role required to receive the server started notification.
limits.notification.evaluation-completed-notification-user-role The role required to receive the evaluation completed notification. No role is set by default, so the notification will be sent to all users.
limits.workflow.file-attachments-are-read-only true When set to true, the file attachments in the workflow are set to read-only on the file system. You may disable this if you encounter difficulties uploading file.
limits.workflow.allowed-file-upload-extensions pdf, jpeg, png, csv, xls, xlsx, doc, docx, txt, ppt, pptx, eml, msg The file types allowed to be uploaded as attachments in the workflow.
Properties deleted
Property Name Comment
limits.autoconfiguration.use-jwt-machine-to-machine-auth JWT authentication is now the default machine-to-machine authentication. Basic authentication was removed.
limits.autoconfiguration.limits-authentication This property was used for basic machine-to-machine authentication to connect with Atoti Limits.
limits.autoconfiguration.authentication This property was used for basic machine-to-machine authentication to connect with the connected Atoti Server.
limits.autoconfiguration.content-server.authentication This property was used for basic machine-to-machine authentication to connect with the connected Atoti Server’s Content server.

Configuration files

Files Modified
application.yml

New properties:

Property Name Comment Value
activeviam.apps.inter-server-event-service.issuer.target-servers[0].name The name of the server to send events to (ConnectedAcc). ConnectedAcc
activeviam.apps.inter-server-event-service.issuer.target-servers[0].url The URL of the server to send events to (ConnectedAcc). http://localhost:7070
activeviam.apps.inter-server-event-service.issuer.target-servers[1].name The name of the server to send events to (FRTB). FRTB
activeviam.apps.inter-server-event-service.issuer.target-servers[1].url The URL of the server to send events to (FRTB). http://localhost:8080/frtb-starter
spring.application.name Spring property for the application name. Used by the notification service to identify the source server for each notification. Atoti Limits
limits.autoconfiguration.service-principal The name of the user authenticated to perform machine-to-machine requests from Atoti Limits to the connected Atoti Servers. admin

Datastores

No changes.

Databases

No changes.

Cube schema

No changes.

Measures

No changes.

Context values

No changes.

Other changes

@PostFilter and @PostAuthorize in ILimitsRetrievalService

The methods of ILimitsRetrievalService have been updated to use the Spring @PostFilter and @PostAuthorize annotations to filter the results based on the user’s roles. This change is applied at the interface level for all methods, so all implementations of this interface will be affected. For custom internal calls that should not filter the results, you can use the methods that accept a LimitsQueryPayload argument and set checkUserPermissions to false. Please keep in mind that any user-facing invocations of these methods should always have checkUserPermissions set to true to ensure users only see the limits they are authorized to access.

The @PostFilter annotation applies to methods that return java Collections. The @PostAuthorize annotation applies to methods that return a single object.

Behavior change for “save” methods/endpoints

The default behavior of the “save” methods and endpoints in Atoti Limits has changed. Previously, “save” operations attempted to update the existing object if the incoming object had the same ID as an existing object. Otherwise it was treated as creation. If the incoming object did not have an ID or had an ID that did not match an existing object, a new object was created.

Now, the “save” methods and endpoints follow these rules:

  • “save” a single object:
    • If the incoming object does not have an ID, it will be treated as a create operation that will fail if an object with that ID already exists.
    • If the incoming object has an ID, it will be treated as an update operation that will fail if no object with that ID exists.
  • “save” a collection of objects:
    • If any of the incoming objects are missing an ID, all objects are treated as create operations that will fail if any contain an ID that already exists.
    • If all incoming objects have an ID, all are treated as update operations that will fail if any of the IDs do not exist.

The following methods and endpoints are affected by this change:

  • DefaultLimitsAppCrudService.java:
    • saveLimitStructure
    • saveLimitStructures
    • saveLimit
    • saveLimits
    • saveIncident
    • saveIncidents
  • LimitsDefinitionCrudRestService.java:
    • /structure/save
    • /structures/save
    • /limit/save
    • /limits/save

note

These changes do not impact the “create” or “update” specific methods or endpoints. If you previously used the “save” methods or endpoints to create objects with pre-defined IDs, you will need to update your code to use the “create” methods or endpoints instead.

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, to view KPIs created by Atoti Limits, including the calculated members related to the KPIS.

If users have trouble accessing KPIs and calculated measures after upgrading to this version, you may need to manually delete them from the content server so Atoti Limits can recreate them with the correct owner/reader role(s).

Temporary limits changes

The following changes have been made involving temporary limits:

1. sourceLimitId field is now validated for temporary limits

The sourceLimitId field links a temporary limit to its source limit. This field is now validated to ensure that the source limit exists and is an official limit. Please ensure that the sourceLimitId field is correctly set when creating temporary limits.

warning

Prior to this change, creating temporary limits with another temporary limit as the source limit was blocked via the UI, but wasn’t validated by the server so it was possible to create such limits via the REST API. This was an unintended behavior which we don’t expect clients to do, and is now blocked.

2. Temporary limits are now grouped under official limits

Limits retrieved via REST now have temporary limits grouped under the official limit indicated in the temporary limit’s sourceLimitId field. If you are using the Atoti Limits REST API to retrieve limits, please note that you may need to update your code to account for this change. Temporary limits are stored in the temporaryLimits field of the corresponding official limit.

Auto-configuration changes

We have updated some of our @Autoconfiguration classes to not explicitly @Import Spring beans and to instead use the @ConditionalOnMissingBean annotation to check for the presence of the beans. This makes it easier for users to inject beans into Atoti Limits and prevents the need to mark a bean as @Primary when multiple beans are present.

The following @AutoConfiguration classes have had explicit imports removed:

  • LimitsCoreAutoconfiguration
  • LimitsEvaluationServicesAutoConfiguration

The following beans are now @ConditionalOnMissingBean:

  • DefaultUtilizationMeasureCalculator which implements IUtilizationCalculator
  • LimitsCopperMeasureBuilder which implements ILimitsCopperMeasureBuilder
  • DefaultEvaluationService which implements IEvaluationService

If you have any custom implementations of these interfaces then you can remove the @Primary annotation.