Skip to main content

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.

This page explains the changes required to migrate to the stated version of Atoti Sign-Off.

Migrate to 6.0.1

Upgrading from version 6.0.0 See Atoti Sign-Off 6.0.1 Release Notes.

Headline announcement

  • Persisting full scope paths: Full scope paths are persisted to the JPA layer to allow handling of scopes with slicing and non-slicing hierarchies.
  • Customized sign-off status feed: The sign-off status feed member for “in review” representation can be customized on the application server.

Using full scope paths in persisted data

Older versions of Atoti Sign-Off did not include the full scope path for definitions that were saved to the JPA layer. As of this version, full scope paths will be used. For example, if you have a definition on the slicing Book level, the old path would look like:
[Booking].[Books].[Book]=[BS_MGT_FX]
The new path will look like:
[Booking].[Books].[Book]=[AllMember].[BS_MGT_FX]
To migrate scope paths created before Atoti Sign-Off 6.1.0, we have added a migration endpoint. The reason for adding an endpoint rather than a script is that we need to connect with the application server to get the full scope path.
You only need to run the migration if you are using persisted data as your golden source of Atoti Sign-Off data. If you are using files as your golden source of data then you do not need to run the migration.
To run the migration, do the following:
  1. Start your application server.
  2. Start Atoti Sign-Off with the 6.0.1-migration Spring profile to include the endpoint and override default validation.
  3. Run the migration endpoint. You can do this via Swagger by executing the POST request at <base URL>/sign-off/rest/v2/migrate/sign-off-definition-scopes. The migration endpoint retrieves the full scope paths from the application server and updates the definitions if necessary.
  4. Restart the application server and Atoti Sign-Off as normal (without the 6.0.1-migration profile) to view your updated definitions and proceed as normal.

Configuration properties

Properties added

signoff-activeviam
Property NameCommentValue
sign-off.application.settings.feed-member-coordinate.memberDefines the members for the Sign-Off hierarchy.[TOTAL REVIEWABLE]

Configuration

Configuration properties

Properties added
signoff-activeviam module
PropertyDefault valueDescription
sign-off.workflow.approver-can-be-same-as-previous-userfalseWhen enabled, the approving user can be the same as the previous user in the workflow.
sign-off.application.overlapping-scopes.allowedfalseTrue if users are allowed to create definitions on overlapping scopes, false otherwise.

Configuration files

Files modified
RestApiProperties.java
Updated properties:
KeyCommentNew ValueOld Value
statusEndpointUpdated the default value./activeviam/pivot/rest/v9/ping/sign-off/enabled
UI settings
Updated properties:
KeyCommentNew ValueOld Value
availableApplicationServersCube-specific module settings are no longer needed.string[]{[serverName: string]: {[cubeName: string ]: {// Cube-specific module settings go here}}}
Deleted properties:
KeyComment
filteredApplicationCubesThis is fetched from the server and set in application.yml.
adjustmentCommentLevelUsed by dashboard widgets that have been removed.
adjustmentFiltersLevelUsed by dashboard widgets that have been removed.
adjustmentIdLevelUsed by dashboard widgets that have been removed.
adjustmentInputLevelUsed by dashboard widgets that have been removed.
adjustmentLiveFromLevelUsed by dashboard widgets that have been removed.
adjustmentLiveToLevelUsed by dashboard widgets that have been removed.
adjustmentReasonLevelUsed by dashboard widgets that have been removed.
adjustmentsServerNameLevelUsed by dashboard widgets that have been removed.
adjustmentStatusLevelUsed by dashboard widgets that have been removed.
adjustmentsWorkflowStatusLevelUsed by dashboard widgets that have been removed.
adjustmentTypeLevelUsed by dashboard widgets that have been removed.
adjustmentUserLevelUsed by dashboard widgets that have been removed.
adjustmentValidFromLevelUsed by dashboard widgets that have been removed.
adjustmentValidToLevelUsed by dashboard widgets that have been removed.
adjustmentCubeSettingsUsed by dashboard widgets that have been removed.
allowedStatusForArchiveAllowed actions are now fetched dynamically from the server.
allowedStatusForDeleteAllowed actions are now fetched dynamically from the server.
allowedStatusForEditAllowed actions are now fetched dynamically from the server.
allowedStatusForPublishAllowed actions are now fetched dynamically from the server.
areWorkflowButtonsHiddenAllowed actions are now fetched dynamically from the server.
availableRolesThis is fetched from the server and set in application.yml. See sign-off.workflow.roles.
failedStatusesUsed by dashboard widgets that have been removed.
fieldsThis is fetched from the server and set in application.yml.
isValidFromFieldDisabledForAdjustmentsThis is always disabled.
signOffButtonInformationThis is fetched from the server and set in application.yml. See workflow.configuration.
signOffInstanceAsOfDateDimensionNameUsed by dashboard widgets that have been removed.
signOffInstanceAsOfDateHierarchyNameUsed by dashboard widgets that have been removed.
signOffInstanceAsOfDateLevelNameUsed by dashboard widgets that have been removed.
signOffInstanceKeyDimensionNameUsed by dashboard widgets that have been removed.
signOffInstanceKeyHierarchyNameUsed by dashboard widgets that have been removed.
signOffInstanceStatusDimensionNameUsed by dashboard widgets that have been removed.
signOffInstanceStatusHierarchyNameUsed by dashboard widgets that have been removed.
signOffInstanceStatusLevelNameUsed by dashboard widgets that have been removed.
signOffRoleActionMapAllowed actions are now fetched dynamically from the server.
signOffStatusProgressUsed by dashboard widgets that have been removed.
signOffWorkFlowMapThis is fetched from the server and set in application.yml. See workflow.configuration.
startDailyProgressStatusUsed by dashboard widgets that have been removed.
taskDefinitionCategoryDimensionNameUsed by dashboard widgets that have been removed.
taskDefinitionCategoryHierarchyNameUsed by dashboard widgets that have been removed.
taskDefinitionCubeNameUsed by dashboard widgets that have been removed.
taskDefinitionNameDimensionNameUsed by dashboard widgets that have been removed.
taskDefinitionNameHierarchyNameUsed by dashboard widgets that have been removed.
taskDefinitionWorkflowStatusDimensionNameUsed by dashboard widgets that have been removed.
taskDefinitionWorkflowStatusHierarchyNameUsed by dashboard widgets that have been removed.
taskInstanceCubeNameUsed by dashboard widgets that have been removed.
application.yml
New properties:
Property NameCommentValue
activiti.datasource.properties.hibernate.default_schemaThe default schema used by the Activiti datasource.sign-off
application.datasource.properties.hibernate.default_schemaThe default schema used by the Application datasource.sign-off
application.rest-apis.MR.mdx-endpointA rest endpoint that can be called to execute MDX queries on the server. (MR)/activeviam/pivot/rest/v9/cube/query/mdx
application.rest-apis.MR.cubes.Var-ES Cube.as-of-date-levelThe full level used to determine the As-Of-Date of the VAR-ES Cube on the server. (MR).[Dates].[Date].[AsOfDate]
application.rest-apis.MR.cubes.VaR-ES Summary Cube.as-of-date-levelThe full level used to determine the As-Of-Date of the VaR-ES Summary Cube on the server. (MR).[Dates].[Date].[AsOfDate]
application.rest-apis.MR.cubes.Sensitivity Cube.as-of-date-levelThe full level used to determine the As-Of-Date of the Sensitivity Cube on the server. (MR).[Dates].[Date].[AsOfDate]
application.rest-apis.MR.cubes.Sensitivity Summary Cube.as-of-date-levelThe full level used to determine the As-Of-Date of the Sensitivity Summary Cube on the server. (MR).[Dates].[Date].[AsOfDate]
application.rest-apis.MR.cubes.PLCube.as-of-date-levelThe full level used to determine the As-Of-Date of the PLCube on the server. (MR).[Dates].[Date].[AsOfDate]
application.rest-apis.MR.cubes.PL Summary Cube.as-of-date-levelThe full level used to determine the As-Of-Date of the PL Summary Cube on the server. (MR).[Dates].[Date].[AsOfDate]
application.rest-apis.MR.cubes.MRCombinedCube.as-of-date-levelThe full level used to determine the As-Of-Date of the MRCombinedCube on the server. (MR).[Dates].[Date].[AsOfDate]
application.rest-apis.FRTB.mdx-endpointA rest endpoint that can be called to execute MDX queries on the server. (FRTB)/activeviam/pivot/rest/v9/cube/query/mdx
audit-log.datasource.properties.hibernate.default_schemaThe default schema used by the Activiti History datasource.sign-off
spring.h2.console.enabledWhen set to true, the H2 console is available. This is useful for investigating JDBC connections. Disabled by default.false
spring.application.nameSpring property for the application name. Used by the notification service to identify the source server for each notification.Atoti Sign-Off
spring.activiti.database-schemaThe schema used by the Activiti databases.sign-off
sign-off.workflow.rolesThe list of roles for workflow participantsUSERS,MANAGERS
Updated properties:
Old Property NameNew Property NameCommentNew ValueOld Value
activiti.datasource.urlactiviti.datasource.urlThe URL of the Activiti datasource.jdbc:h2:file:./sign-off-activiti;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS "sign-off";jdbc:h2:file:./sign-off-activiti;DB_CLOSE_DELAY=-1
application.datasource.urlapplication.datasource.urlThe URL of the Application datasource.jdbc:h2:file:./application-sign-off;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS "sign-off";jdbc:h2:file:./application-sign-off;DB_CLOSE_DELAY=-1
audit-log.datasource.urlaudit-log.datasource.urlThe URL of the Audit Log datasource.jdbc:h2:file:./audit-log;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS "sign-off";jdbc:h2:file:./audit-log;DB_CLOSE_DELAY=-1
workflow-typessign-off.workflow.configurationDescribes the workflows as a pair of key and approverse.g. [{"dummy-workflow": {"key": "sign-off-process-instance.dummy-workflow", "participants": "approvers"}}]e.g. [{"dummy-workflow": "sign-off-process-instance.dummy-workflow"}]

Datastores

Modified stores

ModificationStoreFieldTypeDescription
DeletedSignOffProcessDefinitionMEASURESlist of stringThis column has been removed because it is not used.

Other changes

Spring Boot compliance

Atoti Sign-Off now aligns more closely with Spring Boot best practices in our aim to move towards using Spring Boot Starters to ease migrations.
Configuration properties
Atoti Sign-Off now uses Spring Configuration Properties to help externalize configurations for users. You can see a full list of the provided properties in the Configuration Properties section.

Adjustments locations and input fields

These two adjustment fields are now Lists instead of Sets. This impacts the following classes and services that may affect your implementation: Workflow-related:
  • SignOffProcessInstanceWorkflowService.java
  • AuditableAdjustmentDefinitionDTO.java
  • AdjustmentExecutionDTO.java
JPA-related:
  • AdjustmentsDefinitionEntity.java
  • AdjustmentsFiltersConverter.java
  • AdjustmentsInputConverter.java
  • IAdjustmentDefinition.java
  • AdjustmentExecutionEntity.java
  • IAdjustmentExecution.java

Status manager service

The ISignOffWorkflowStatusManager lets you implement a service to define the statuses that relate to specific categories. Current methods with a default implementation in DefaultSignOffWorkflowStatusManager are:
  • getLiveDefinitionStatuses(): returns a list of definition status considered live.
  • getPendingApprovalTaskStatuses(): returns a list of task status considered pending.

Workflow task actions

A unique way is now used to execute common workflow task actions (e.g. approve, reject, request approval …) and custom actions. It allows greater flexibility and easier extension of current set of actions. To extend the task actions, see Adding Custom Workflow Tasks.

Using Atoti Sign-Off with older solutions

Atoti Sign-Off 6.0 is a major upgrade but can be compatible with older solutions with some adjustments. This section guides you through the steps to make your solution compatible with Atoti Sign-Off 6.0. We shall include sample changes specific to Atoti Market Risk version 5.4.2 and Atoti FRTB 5.3.4, but the general steps apply to any server that connects with Atoti Sign-Off.

Steps to use Atoti Sign-Off

The steps to use Atoti Sign-Off are the same as in the Getting started guide. Note that depending on the Atoti Server version of the solution you are running with Atoti Sign-Off, you may need to update the property application.rest-apis.<server>.mdx-endpoint in your application.yml file. If your Atoti Server version runs with a different version of the API than the default set in Atoti Sign-Off (/activeviam/pivot/rest/v9/cube/query/mdx) for Atoti Server 6.1, you will need to update this property. See the Atoti Server API documentation for the correct version.
Connecting with Atoti Market Risk 5.4.2 & Atoti FRTB 5.3.4
With Atoti Market Risk 5.4.2 and Atoti FRTB 5.3.4, which runs with Atoti Server 6.0, you need to update this property in Atoti Sign-Off:
application.rest-apis.MR.mdx-endpoint=/activeviam/pivot/rest/v8/cube/query/mdx

Steps to use the Atoti Solution

Migrate adjustments services
For UI compatibility, adjustments-services version 4.1 or higher is required. See Adjustments Services 4.1. You will need to:
  1. Update your dependency artifact’s groupId and version to com.activeviam.solutions and 4.1.0 respectively.
  2. Update your code to use a List in AdjustmentRequestDTO and SupportedAdjustmentDTO when setting yourfilters and input.
  3. Update your code to replace use of NamedValueDTOs from dependencies (e.g. com.activeviam.apps:shared also known as the common library).
Connecting Atoti Market Risk 5.4.2 & Atoti FRTB 5.3.4
In Atoti Market Risk 5.4.2 and Atoti FRTB 5.3.4, the dependency com.activeviam.apps:shared is using version 2.0.6-AS6.0 and 2.0.3-AS6.0 respectively which depend on adjustments-services version 4.0.0. Your code may call methods in dependencies that use NamedValueDTO which has changed in adjustments-services version 4.1.0. You should replace calls to ExecutionFunctionalComponents::parseInput with calls to a local method to your project to complete its purpose.
public static AdjustmentInputParser parseInput() {
    return (req, def) -> {
        Map<String, Object> inputMap = new HashMap<>();
        req.getInput().forEach(
                input -> {
                    String name = input.getName();
                    String value = input.getValue();
                    IParser<Object> parser = Registry.getPluginValue(IParser.class, def.typeOf(name));
                    inputMap.put(name, parser == null ? value : parser.parse(value));
                }
        );
        return inputMap;
    };
}
Atoti Market Risk 5.4.2 You may place this method in ExecutionFunctionalComponentsConfig for instance. Then you should replace the calls to ExecutionFunctionalComponents.java::parseInput with it in:
  • AdjustmentsExecutionVaRConfig
  • AdjustmentsExecutionPnLConfig
  • AdjustmentsExecutionSensiConfig
Atoti FRTB 5.3.4 You may place this method in AdjustmentExecutionConfig for instance and make it static. Then you should replace the calls to ExecutionFunctionalComponents::parseInput with it in this same class.
Migrate Sign-Off API
To ensure that the API contract between the Atoti solution and Atoti Sign-Off is respected, check that the Sign-Off API is upgraded to the version required by your Atoti Sign-Off version. You can find the correct version in the Dependency versions section of the Release notes. For Atoti Sign-Off 6.0.0 you need to upgrade to 4.2.0. See Sign-Off API 4.2. You will need to:
  1. Update your dependency artifact’s groupId, artifact and version to com.activeviam.solutions.signoff-api, signoff-api-lib and 4.2.0 respectively.
  2. Implement the ISignOffRestService::enabled method. This method is used to let Atoti Sign-Off know that the server is up and running.
  3. Remove calls to getMeasures in SignOffProcessInstanceExportDTO: The measures field has been removed in Sign-Off API 4.2.0.
Connecting with Atoti Market Risk 5.4.2 & Atoti FRTB 5.3.4
In Atoti Market Risk 5.4.2 and Atoti FRTB 5.3.4, you may remove calls to the getMeasures method in the SignOffProcessInstanceExportDTO class by extending the SignOffService with a CustomSignOffService class.
@Slf4j
public class CustomSignOffService extends SignOffService {
    public CustomSignOffService(IActivePivotManager manager, ILocalDataExtractionService dataExtractionService,
            ISignOffServiceParams serviceParams) {
        super(manager, dataExtractionService, serviceParams);
    }

    /**
     * Export the data related to the instance following the DEE templates
     *
     * @param instance The sign-off task definition that needs to be exported
     * @return The list of export names with the associated task ID
     */
    @Override
    public Map<String, String> export(SignOffProcessInstanceExportDTO instance) {
        validateRequest(instance);

        try {
            if (log.isInfoEnabled()) {
                log.info("[EXPORT][SERVICE] Received \"export\" call for {} for definition {}.", JacksonSerializer.serialize(instance),
                        JacksonSerializer.serialize(instance));
            }
        } catch (SerializerException e) {
            log.error("[EXPORT][SERVICE] Error serializing object", e);
        }

        IMultiVersionActivePivot pivot = manager.getActivePivots().get(instance.getDomain());
        if (pivot == null) {
            throw new BadRequestException("[EXPORT][SERVICE] Requested an export on the " + instance.getDomain() + " cube, which does not exist.");
        }

        List<IDeeOrder> templates = getTemplates(instance.getDomain());

        List<IDeeOrder> orders = new ArrayList<>();
        for (var template : templates) {
            orders.add(adjustDeeOrderToInstance(template, instance));
        }

        IDeeOrder order = new CompositeDeeOrder(orders);
        List<String> taskIds = dataExtractionService.submitLocalTask(order);

        Map<String, String> deeTasks = new HashMap<>();
        for (int i = 0; i < taskIds.size(); i++) {
            deeTasks.put(orders.get(i).getName(), taskIds.get(i));
        }
        return deeTasks;
    }

    /**
     * Get all the templates need to fulfill an export request
     *
     * @param domain   the selected cube
     * @return A list of export templates
     */
    protected List<IDeeOrder> getTemplates(String domain) {
        List<String> templatesName = serviceParams.getDomainTemplates(domain, List.of());
        if (templatesName == null) {
            return List.of();
        }
        return templatesName.stream().map(deeTemplates::get).filter(Objects::nonNull).map(DeeOrderStr::getDeeOrder).toList();
    }

    /**
     * Check that all the parameters are provided on the request
     *
     * @param instance The request
     * @throws BadRequestException when the request is not well filled
     */
    @Override
    protected void validateRequest(SignOffProcessInstanceExportDTO instance) {
        if (instance == null) {
            throw new BadRequestException("[EXPORT][SERVICE] DTO not provided.");
        }

        String domain = instance.getDomain();
        if (domain == null) {
            throw new BadRequestException("[EXPORT][SERVICE] The export request is missing a domain (cube).");
        }

        if (instance.getFilters() == null) {
            throw new BadRequestException("[EXPORT][SERVICE] The export request is missing filters.");
        }

        if (instance.getAsOfDate() == null) {
            throw new BadRequestException("[EXPORT][SERVICE] The export request is missing an as-of date.");
        }
    }
}
Alongside with an adapted SignOffServiceConfig.
@Configuration
public class SignOffServiceConfig {

    protected final CommonSignOffHierarchyProperties commonSignOffHierarchyProperties;

    protected final SignOffProperties signOffProperties;

    /**
     * The configuration property used to define the folder in which the DEE templates used for
     * the export of the sign-off are defined
     */
    public static final String EXPORT_TEMPLATE_FOLDER_PROP = "data.extraction.templates.base.dir.path";

    protected final String signOffDataExtractionTemplatesBaseDirPath;

    public SignOffServiceConfig(
            @Value("${" + EXPORT_TEMPLATE_FOLDER_PROP + "}") String signOffDataExtractionTemplatesBaseDirPath,
            CommonSignOffHierarchyProperties commonSignOffHierarchyProperties,
            SignOffProperties signOffProperties) {
        this.signOffDataExtractionTemplatesBaseDirPath = signOffDataExtractionTemplatesBaseDirPath;
        this.commonSignOffHierarchyProperties = commonSignOffHierarchyProperties;
        this.signOffProperties = signOffProperties;
    }

    @Bean
    public ISignOffService signOffService(IActivePivotManager manager, ILocalDataExtractionService dataExtractionService,
            @Qualifier(SP_QUALIFIER__TEMPLATES) Map<String, SignOffProperties.ExportFilenamesMdxTemplate> templatesFileName) {
        return new CustomSignOffService(manager, dataExtractionService, getSignOffServiceParams(templatesFileName));
    }

    @Bean
    @ConditionalOnVectorizedSensitivity
    @Deprecated(since = "5.4.0", forRemoval = true)
    @Qualifier(SP_QUALIFIER__TEMPLATES)
    protected Map<String, SignOffProperties.ExportFilenamesMdxTemplate> scalarTemplate() {
        return signOffProperties.getExtractionTemplates();
    }

    @Bean
    @ConditionalOnScalarSensitivity
    @Qualifier(SP_QUALIFIER__TEMPLATES)
    protected Map<String, SignOffProperties.ExportFilenamesMdxTemplate> vectorisedTemplate() {
        return signOffProperties.getExtractionTemplatesScalar();
    }

    protected ISignOffServiceParams getSignOffServiceParams(Map<String, SignOffProperties.ExportFilenamesMdxTemplate> templatesFileName) {
        Map<IPair<String, Set<String>>, List<String>> cubeToTemplates = new HashMap<>();
        for (var templatesFileNameValue : templatesFileName.values()) {
            var cubeName = templatesFileNameValue.getCubeName();
            Set<String> measuresAsSet = templatesFileNameValue.getMeasures();
            List<String> exportFileNames = templatesFileNameValue.getExportFileNames();
            cubeToTemplates.put(new Pair<>(cubeName, measuresAsSet), exportFileNames);
        }

        Map<String, LevelIdentifier> dateLevels = signOffProperties.getDateHierarchies();
        Map<String, LevelIdentifier> taskLevels = signOffProperties.getTaskLevels();

        return new ISignOffServiceParams() {
            @Override public String getKpiMdxTemplate() {
                return signOffProperties.getExportFilenamesMdxTemplate();
            }

            @Override public List<String> getDomainTemplates(String domain, List<String> measures) {
                Set<String> templates = new HashSet<>();
                templates.addAll(cubeToTemplates.getOrDefault(new Pair<>(domain, null), List.of()));
                templates.addAll(cubeToTemplates.getOrDefault(new Pair<>(DOMAIN_DEFAULT, null), List.of()));
                return new ArrayList<>(templates);
            }

            @Override public String getSignOffDataExtractionTemplatesBaseDirPath() {
                return signOffDataExtractionTemplatesBaseDirPath;
            }

            @Override public LevelIdentifier getDateLevel(String domain) {
                return dateLevels.getOrDefault(domain, dateLevels.get(DOMAIN_DEFAULT));
            }

            @Override public LevelIdentifier getSignOffLevel(String domain) {
                return taskLevels.getOrDefault(domain, taskLevels.get(DOMAIN_DEFAULT));
            }

            @Override public String getReviewableMember() {
                return commonSignOffHierarchyProperties.getLevelMembers().get(1);
            }
        };
    }
}
These changes will be used in the Atoti Market Risk solution when it is upgraded to be compatible with Atoti Sign-Off 6.0.x.