Skip to main content

Migrate to 6.2

This page describes the best strategy to upgrade to 6.2. Read the Release notes to get familiar with major changes for this release. This guide refers to changes in migration order. The Release notes refers to the changes based on their importance or significance. For this migration, an automated OpenRewrite migration recipe is provided. Run it at the specified step of the migration process.

Packaging changes

All the artifacts are available on JFrog Artifactory. There are two client-facing entrypoints: Read the download page to see how to configure those entry points. The channel mvn includes mvn-prod and also includes pre-release (alpha, beta, milestone, release candidate) and continuous builds. Visibility of Maven artifacts depends on the access rights of the account. Some artifacts, such as continuous build, may not be accessible if the required permissions are not granted. Atoti is not distributed on artifacts.activeviam.com.

Preparatory work

  • Upgrade to the latest 6.1
  • Check for use of avinternal/internal/private_ in imports and replace them. Do not hesitate to fill a support ticket to seek for an alternative
  • Fix Spring deprecations, follow Spring guide
  • Try building the project with JDK 25. Some dependencies may require an upgrade for the build to succeed — for example, Lombok must be upgraded to a JDK 25-compatible version (1.18.40+).
  • Check for use of removed features

Upgrade

  • Run the automated OpenRewrite migration recipe
  • Update the poms to the new Java version, Spring Boot version and Atoti version
  • Atoti Server 6.2 moves to Spring Boot 4, which brings Jackson 3 (com.fasterxml.jackson.*tools.jackson.*). Migrate your Jackson usage with OpenRewrite’s UpgradeJackson_2_3 recipe.
  • If you overrode the admin-ui.version Maven property to pin the Atoti Admin UI version, this property is removed: all Atoti UI artifacts (atoti-ui, atoti-ui-initial-content, atoti-admin-ui) are now versioned by the single atoti-ui.version property
  • Logging configuration
    • If JUL is used for logging, add a dependency to org.slf4j:slf4j-jdk14
    • If a different logging framework is used, remove the dependency to org.slf4j:jul-to-slf4j
  • Compile and test
If the code does not compile automatically after these steps, please file a ticket with the code that failed to be migrated, as it should have been handled by the migration recipes.

Post-upgrade

As part of the migration, the name of some loggers and JVM property may have changed. Warnings will be logged at runtime when using the legacy names in order to allow to identify the ones to migrate. Monitor the logs for these warnings.

Manual changes

The following changes are not handled by the automated recipe and must be applied manually.
  • IActivePivotContentServiceConfig is deprecated. If you implement this interface, the @Bean annotation is not inherited from the interface for activePivotContentService(). Add @Bean explicitly to your implementing method, or migrate to declaring IActivePivotContentService as a standalone @Bean.
  • Several methods of the Datastore transaction API (package com.activeviam.database.datastore.api.transaction) no longer declare throws DatastoreTransactionException, because they could never actually throw it. The affected methods are:
    • ITransactionalWriter#remove(String, Object...)
    • ITransactionalWriter#removeAll(String, Collection)
    • IOpenedTransaction#updateWhere(ISelection, ICondition, IUpdateWhereProcedure)
    • IOpenedTransaction#rollback()
    • ITransactionManager#rollbackTransaction()
    • ITransactionManager#stop()
    Since DatastoreTransactionException is a checked exception, a try block wrapping only calls to these methods with a catch (DatastoreTransactionException e) clause will no longer compile. Remove the now-dead catch clause, or the entire try if it was the only catch. In a multi-catch such as catch (DatastoreTransactionException | SomeOtherException e), remove only the DatastoreTransactionException alternative. Methods that still throw it, such as commitTransaction(), startTransaction(...) and removeWhere(...), are unaffected, so a catch that also wraps one of those stays as-is.
  • The String-based distributing level APIs have been removed. Replace usages as follows, converting each former String level name to a LevelIdentifier (constructed with dimension name, hierarchy name, and level name):
    • IApplicationDescriptionBuilderWithId#withDistributingFields(String...)withDistributingLevels(LevelIdentifier...)
    • QueryClusterDefinition.DistributedApplicationDefinition(String, List<String>)QueryClusterDefinition.DistributedApplicationDefinition(String, List<LevelIdentifier>)
  • IDistributedApplicationDefinition#getDistributingFields() has been removed. Use getDistributingLevels() instead, which returns a List<LevelIdentifier>.
  • com.activeviam.database.api.schema.DataTable has been removed. This change is not handled by the automated migration recipe — replace constructor calls manually with the description API matching your stack:
    • Datastore tables: new DataTable(name, keyFieldNames, fields) becomes StoreDescription.simpleBuilder().name(name).keyFieldNames(keyFieldNames).fields(fields).build(). The fields list should now contain IFieldDescription instances (from com.activeviam.database.datastore.api.description) instead of IDataTableField. Replace new DataTableField(...) with FieldDescription.builder()…build() from the same package.
    • DirectQuery tables: new DataTable(name, keyFieldNames, fields) becomes TableDescription.builder().externalTable(...).withSameLocalName().fields(fields).keyFieldNames(keyFieldNames).build(), supplying the appropriate ExternalTable. The fields list should now contain AFieldDescription instances (from com.activeviam.directquery.api.schema) instead of IDataTableField. Replace new DataTableField(...) with FieldDescription.builder()…build() from the same package.
  • IActivePivotBranchPermissionsManagerConfig has been deprecated and no longer carries @Configuration or @Bean. Implementing it no longer exposes a branch permissions manager bean. Stop implementing this interface and expose IBranchPermissionsManager as a @Bean from a @Configuration class directly.
  • IActivePivotConfig has been deprecated and no longer carries @Configuration or @Bean. Implementing it no longer exposes a branch permissions manager bean. Stop implementing this interface and expose IActivePivotManager as a @Bean from a @Configuration class directly.

Automated OpenRewrite Migration Recipe

The automated OpenRewrite migration recipe handles the following API changes from 6.1.20 to 6.2.0. Run it during the Upgrade step. The recipe is published to JFrog as the artifact com.activeviam.migration:6_1-to-6_2:<version>.

How to run

From your project root, preview the changes first:
mvn -U org.openrewrite.maven:rewrite-maven-plugin:5.45.0:dryRun \
  -Drewrite.recipeArtifactCoordinates=com.activeviam.migration:6_1-to-6_2:<version> \
  -Drewrite.activeRecipes=com.activeviam.migration.v6_1_to_6_2
Then apply them by replacing dryRun with run
mvn -U org.openrewrite.maven:rewrite-maven-plugin:5.45.0:run \
  -Drewrite.recipeArtifactCoordinates=com.activeviam.migration:6_1-to-6_2:<version> \
  -Drewrite.activeRecipes=com.activeviam.migration.v6_1_to_6_2

Running a subset of the migration

The aggregator recipe com.activeviam.migration.v6_1_to_6_2 runs everything. Each migration is split into three phases so you can adopt it gradually. Swap -Drewrite.activeRecipes= for one of the phase recipes instead of the aggregator:
PhaseRecipe nameWhen to run
Beforecom.activeviam.migration.v6_1_to_6_2_beforeOn the 6.1 code base, before upgrading. The old code still compiles.
Duringcom.activeviam.migration.v6_1_to_6_2_duringTogether with the upgrade to 6.2. The old code cannot accommodate these changes.
Aftercom.activeviam.migration.v6_1_to_6_2_afterOnce the project runs on 6.2, to clean up deprecated API usages.

Change of behavior

  • The query-service monitoring previously provided by the APM module is now built into Atoti Server: query counters are always recorded, and exceptions thrown during query processing are always logged. The single name=QueriesService,type=Monitoring MBean previously registered by the APM module is replaced by two MBeans: name=QueriesServiceStatistics,type=Monitoring (query counters) and name=QueriesServiceLogging,type=Monitoring (runtime logging toggles). The per-query report logs (query/result description, completion time, optional memory statistics) are now disabled by default. If you relied on the APM module to produce these logs, enable them with the activeviam.queries.service.logging=true application property (and optionally activeviam.queries.service.detailed-logging and activeviam.queries.service.log-memory-stats), or at runtime through the QueriesServiceLogging MBean. These logs are now emitted on the atoti.server.query.service logger.

Removed features

No longer supported

  • SnowflakeDialectSettings#SnowflakeDialectSettingsBuilder#arrayAggWrapperFunctionName(String) has been removed. The built-in SQL function from Snowflake is now faster.
  • DatabricksDialectSettings#DatabricksDialectSettingsBuilder#xxxNativeArrayUdafName(String) have been removed. Databricks has deprecated the use of Spark UDAFs. Review your database schema to use emulated vectors (multi-row or multi-column) instead.
  • The concealed measures feature has been removed from the distributed data cluster definition. The withConcealedMeasures(...) builder methods, IDataClusterDefinition#getConcealedMeasures/setConcealedMeasures, and the now-redundant withAllMeasures() builder step no longer exist. Remove any call to withAllMeasures() from data cluster definitions; the builder now goes straight from the hierarchy concealment step to branch concealment. Concealing hierarchies and branches remains available.

With alternatives

  • IApplicationDescriptionBuilderWithId#withoutDistributingFields() has been renamed to withoutDistributingLevels().
  • QueryClusterDefinition.DistributedApplicationDefinitionV2 has been renamed to QueryClusterDefinition.DistributedApplicationDefinition.
  • IJdbcSource has been removed. Replace all usages with the concrete JdbcSource class.
  • Deprecated method IQueryExecution#shouldBypassNonJitProviders has been removed. Use IQueryExecution#skipNonJitProviders instead.
  • Deprecated method IMultiVersionDistributedActivePivot#unloadMembersFromDataNode has been removed, along with the IMessengerDefinition#UNLOAD_MEMBERS_MESSAGE_TIMEOUT property and the distribution.unload_members_from_data_node.* metrics. Use IMultiVersionDataActivePivot#maskMembers instead.
  • ClickhouseProperties has been deprecated. Use ClickhousePropertiesV2 instead, as the ClickHouse connector has been upgraded to use a new client.
  • The Maven modules com.activeviam.activepivot:activepivot-impl and com.activeviam.activepivot:activepivot-intf have been merged into com.activeviam.activepivot:core, use it directly.
  • The empty Maven module com.activeviam.activepivot:activepivot-copper has been removed. Import com.activeviam.activepivot:core and optionally com.activeviam.activepivot:activepivot-dist-impl instead.
  • The empty Maven module com.activeviam.activepivot:activepivot-ext has been removed. Import com.activeviam.activepivot:core and optionally com.activeviam.activepivot:activepivot-dist-impl instead.
  • The empty Maven module com.activeviam.springboot:atoti-runtime-starter, kept as an alias since it was renamed in 6.1, has been removed. Use com.activeviam.springboot:atoti-server-application-starter instead.
  • Memory sampling (activated via the property “activeviam.mmap.tracking”, and triggered via JMX operations) has been removed. You should now rely on a JFR instead of JMX operations, as those include dedicated JFR events for memory operations. The associated properties “activeviam.mmap.sampling.depth”, “activeviam.mmap.sampling.start” and “activeviam.mmap.sampling.percent” have been removed.
  • MDXQuery is now immutable and the constructors should be used.
  • The activeviam.jwt.* application properties, deprecated since 6.1, have been removed. Use the atoti.jwt.* equivalents instead.
Previous nameNew name
activeviam.jwt.expirationatoti.jwt.expiration
activeviam.jwt.key.privateatoti.jwt.key.private
activeviam.jwt.key.publicatoti.jwt.key.public
activeviam.jwt.claim_key.authoritiesatoti.jwt.claim_key.authorities
activeviam.jwt.claim_key.principalatoti.jwt.claim_key.principal
activeviam.jwt.enabledatoti.jwt.enabled
activeviam.jwt.check_user_detailsatoti.jwt.check_user_details
The expiration property is now a Spring Duration. The available formats are described in Spring’s documentation. For this property, a unitless integer will represent Seconds. In 6.1, a unitless integer would represent:
  • milliseconds for atoti.jwt.expiration
  • seconds for activeviam.jwt.expiration
If you’re migrating to 6.2 and just changed from activeviam.jwt.expiration: int to atoti.jwt.expiration: int, you need to modify that value accordingly. Adding the unit suffix, such as atoti.jwt.expiration: 12000s is the safest way to configure this property.
  • The deprecated ActiveViam Property activeviam.contentService.nameGenerator.defaultSize has been removed, use activeviam.contentService.nameGenerator.size instead. See the Properties page for its definition.
  • Deprecated method StartBuilding.Builder#withEpochManager(IEpochManager) has been removed. Use StartBuilding.Builder#withEpochPolicy(IEpochManagementPolicy) instead, passing the epoch policy directly rather than wrapping it in an EpochManager.
  • Deprecated method PersistedBuilder#lockOptions(boolean) has been removed. Use PersistedBuilder#databaseLocks(LockOptions) instead. lockOptions(true) becomes databaseLocks(LockOptions.defaultOptions()) and lockOptions(false) needs no call.
  • The deprecated duplicate types under io.atoti.runtime.api.measures and io.atoti.server.common.api.plugins have been removed. Use the identically named types under com.activeviam.atoti.application.api.measures and com.activeviam.atoti.server.common.api.plugins. The automated recipe rewrites these package references.
  • The deprecated 4-argument constructor of ActivePivotTransactionCommittedEvent has been removed. Use the 6-argument constructor, passing -1, -1 for the start and commit timings when they are unknown.
  • The deprecated IGenericAggregationFunction.SUM_PRODUCT_FUNCTION_PLUGIN_KEY constant has been removed. Use IMultiSourceAggregationFunction.SUM_PRODUCT_FUNCTION_PLUGIN_KEY instead, which is the canonical home for the multi-source sum-product key. The automated recipe rewrites these references.
  • The deprecated integer and integer[] parser type keys (including sized and delimited variants such as integer[10] and integer[][:]) are no longer recognized. Replace them with the canonical int and int[] (and their sized and delimited variants).

API syntax changes

  • CsvParserConfiguration constructors are replaced by a new builder:
    • new CsvParserConfiguration()CsvParserConfiguration.builder().withColumnCount(0).build()
    • new CsvParserConfiguration(int)CsvParserConfiguration.builder().withColumnCount(n).build()
    • new CsvParserConfiguration(List<String>)CsvParserConfiguration.builder().withColumnNames(names).build()
    • new CsvParserConfiguration(Map<Integer, String>)CsvParserConfiguration.builder().withColumnNamesMapping(map).build()
    • Full constructors (7-param and 8-param) are migrated using the builder.
    • Setter calls (e.g. config.setSeparator(';')) are replaced by the corresponding builder methods (e.g. .separator(';')).
    • createCharset method has been removed

Mutable configuration passed as method argument

The OpenRewrite recipe cannot correctly migrate setter calls on a configuration object received as a method parameter. For example:
// Before
void configure(ICsvParserConfiguration config) {
    config.setSeparator(';');
}
The recipe will produce:
// After (INCORRECT — the new object is never returned or used)
void configure(CsvParserConfiguration config) {
    config = config.toBuilder().separator(';').build();
}
Because these configuration classes are now immutable, the reassignment to the local variable has no effect on the caller. Review such methods manually and refactor them to return the updated configuration instead:
// Correct
CsvParserConfiguration configure(CsvParserConfiguration config) {
    return config.toBuilder().separator(';').build();
}
  • CsvSourceFactory.create() static methods are replaced by ICsvSource.builder():
    • CsvSourceFactory.create()ICsvSource.builder().build()
    • CsvSourceFactory.create(name)ICsvSource.builder().name(name).build()
    • CsvSourceFactory.create(closeCallback)ICsvSource.builder().closeCallback(closeCallback).build()
    • CsvSourceFactory.create(name, closeCallback)ICsvSource.builder().name(name).closeCallback(closeCallback).build()
  • The ICsvParserConfiguration interface has been removed; replace all usages (return types, variable declarations, and parameter types) with the concrete CsvParserConfiguration class.
  • The IFileParserConfiguration interface has been removed; replace all usages (return types, variable declarations, and parameter types) with the concrete CsvParserConfiguration class.
  • The concrete FileParserConfiguration class has been removed; replace all usages (return types, variable declarations, and parameter types) with the concrete CsvParserConfiguration class.
  • CsvSourceConfiguration and CsvSourceConfigurationBuilder constructors are replaced by the builder:
    • new CsvSourceConfiguration(int, int, boolean, IComparator)CsvSourceConfiguration.builder().parserThreads(t).bufferSize(b).synchronousMode(s).fileComparator(c).build()
    • new CsvSourceConfigurationBuilder()CsvSourceConfiguration.builder()
    • CsvSourceConfigurationBuilder.DEFAULT_PARSER_THREADS is deprecated; use CsvSourceConfiguration.getDefaultParserThreads() instead.
  • The ICsvSourceConfiguration interface has been removed; replace all usages (return types, variable declarations, and parameter types) with the concrete CsvSourceConfiguration class.
  • SnowflakeProperties#SnowflakePropertiesBuilder#additionalOption(SFSession, String) is replaced by SnowflakeProperties#SnowflakePropertiesBuilder#additionalOption(String, String). Inline the former call using SFSession#getPropertyKey().
  • IParquetReaderFactory#create(InputFile, ReadSupport<IParquetRecord>, Configuration) is replaced by IParquetReaderFactory#create(InputFile, ReadSupport<IParquetRecord>, ParquetConfiguration). Wrap the former Configuration argument using new HadoopParquetConfiguration(configuration).
  • The three IParquetParser#parse overloads that take a Hadoop org.apache.hadoop.fs.Path have been removed:
    • parse(org.apache.hadoop.fs.Path, IStoreToParquetMapping, IStoreToParquetMapping...)parse(java.nio.file.Path, IStoreToParquetMapping, IStoreToParquetMapping...)
    • parse(org.apache.hadoop.fs.Path, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)parse(java.nio.file.Path, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)
    • parse(org.apache.hadoop.fs.Path, Configuration, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)parse(java.nio.file.Path, ParquetConfiguration, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...). Wrap the former Hadoop Configuration argument with new HadoopParquetConfiguration(configuration).
  • The factory parameter type in four IParquetParser#parse overloads changed from Function<ICloudEntityPath<EntityT>, ? extends SeekableByteChannel> to ICloudEntityChannelFactory<EntityT>. The affected overloads are:
    • parse(ICloudDirectory<EntityT>, Function<ICloudEntityPath<EntityT>, ? extends SeekableByteChannel>, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)
    • parse(ICloudDirectory<EntityT>, ParquetConfiguration, Function<ICloudEntityPath<EntityT>, ? extends SeekableByteChannel>, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)
    • parse(ICloudEntityPath<EntityT>, Function<ICloudEntityPath<EntityT>, ? extends SeekableByteChannel>, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)
    • parse(ICloudEntityPath<EntityT>, ParquetConfiguration, Function<ICloudEntityPath<EntityT>, ? extends SeekableByteChannel>, IParquetFieldParsers, IStoreToParquetMapping, IStoreToParquetMapping...)
  • IAgent no longer extends IExtendedPluginValue. Implementations of IAgent should now also explicitly implement IExtendedPluginValue if needed.
  • The three Logback conversion-rule converters have been moved out of the apm module into dedicated logging artifacts. Update the fully-qualified class names referenced in your logback.xml/logback-spring.xml <conversionRule> declarations:
    • com.activeviam.apm.api.logging.LogInstanceConvertercom.activeviam.tech.logging.logback.api.LogInstanceConverter (artifact com.activeviam.tech:logging-logback)
    • com.activeviam.apm.api.logging.LogThreadConvertercom.activeviam.tech.logging.logback.api.LogThreadConverter (artifact com.activeviam.tech:logging-logback)
    • com.activeviam.apm.api.logging.LogUserConvertercom.activeviam.tech.logging.logback.spring.api.LogUserConverter (artifact com.activeviam.tech:logging-logback-spring)
  • The IMultiVersionDataActivePivot interface has been moved from package com.activeviam.activepivot.dist.impl.api.cube to com.activeviam.activepivot.dist.datanode.impl.api.cube.
  • NoTransactionException has been moved in the public API, from package com.activeviam.database.datastore.internal to com.activeviam.database.datastore.api.transaction.
  • GetAggregatesQuery constructors are replaced by GetAggregatesQuery.builder(). Use the builder methods corresponding to the fields you were passing to the constructor, then call .build().
  • DrillthroughQuery constructors are replaced by DrillthroughQuery.builder(). Use the builder methods corresponding to the fields you were passing to the constructor, then call .build().