> ## 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 notes 5.11

# Migrate to 5.11

### Spring

Spring was updated to version 2.6. As a result of the necessary configuration changes, the class
`com.activeviam.cfg.SpringRestServiceInitializer` must be added to your Spring configuration,
unless you already import `com.qfs.server.cfg.impl.ActiveViamRestServicesConfig` or
`com.qfs.content.cfg.impl.StandaloneContentServerRestConfig` to configure the REST services.

### Copper

The performances of the calculations defined in Copper have been improved. The transient memory generated
at query time will be reduced by limiting the boxing phenomenon. (The use, for instance, of `java.lang.Integer` instead of `int`)

As a consequence, multiple methods are now deprecated.
We strongly advise users to migrate out of any deprecated methods, as these changes are strictly brought
to users for transient memory performance purposes.

* Combining multiple `CopperElements` through `Copper.combine(...)` to create a new measure is no longer done with
  `CopperMeasure map(SerializableFunction<IRecordReader, Object> mapper)`. The method is now called `mapToObject`
  to follow the changes brought to other methods.
  For instance,
  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  Copper.combine(Copper.sum(RISK__PNL), Copper.member(City))
    .mapToInt(reader -> {
      if (reader.read(1).equals("NYC") {
        return 0;
      } else {
        return reader.readDouble(0) > 0 ? 1 : -1;
      }
    })
  ```

* Combining multiple `CopperMeasure` through `Copper.combine(...)` to create a new measure is no longer done with
  `CopperMeasure map(SerializableFunction<IRecordReader, Object> mapper)`. Instead, the new method's output type will
  dictate the method that should be used. For instance, if these measures are combined into a measure that outputs `int`,
  one should use `CopperMeasure mapToInt(SerializableToIntFunction<IArrayReader> mapper)`.
  For instance,
  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  Copper.combine(Copper.sum(RISK__PNL), Copper.constant(0d).withName(PNL_LIMIT))
    .mapToInt(a -> a.readDouble(0) >= a.readDouble(1) ? 1 : -1)
  ```

* Modifying a measure follows the same rule: `Copper.sum(RISK__PNL).mapToDouble(reader -> reader.readDouble(0) * 2d)`

* The aforementioned changes make `CopperMeasure#withType()` relatively redundant: it is removed for measures that have
  already specified it through the choice of mapping method.

* Contrary to the specialized implementations like `mapToInt(SerializableToIntFunction<IArrayReader>)`, `mapToDouble(SerializableToDoubleFunction<IArrayReader>`, etc...
  The method `mapToObject` takes as argument a `SerializableBiConsumer<IArrayReader, IWritableCell>`. The provided cell must be used to write the result:
  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  Copper.sum(RISK__PNL).mapToObject((reader, cell) -> {
    if (reader.readDouble(0) <= 1) {
      cell.writeDouble(reader.readDouble(0));
    }
  });
  ```

* From now on, only two types of measures support setting a specific output type: when using the various `mapToDouble`/`mapToLong` methods and the new `map`, or right after a `plus`/`minus`/etc. using `withType`.

### Post Processors

To also reduce the memory consumption of `IPostProcessor`s and `IEvaluator`s, we added new implementations
of these components.

> `AAdvancedPostProcessor<outputType>` becomes `AAdvancedPostProcessorV2` and does not declare a generic output type.
> All Post Processors must now receive the property `outputType` in their initialization properties.

* `IEvaluatorV2`'s evaluation method is `void evaluate(ILocation location, IRecordReader aggregatedMeasures, IWritableCell resultCell)`.
  Instead of reading underlying values from an `Object[]`, one now needs to read them from the given `IRecordReader`,
  using the appropriate specialized method, and write the result of the evaluation into the `resultCell`.
  For instance,
  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  @Override
  public Double evaluate(ILocation location, Object[] measures) {
      if (measures[0] == null) {
          return null;
      } else {
          return 10D + ((Number) measures[0]).doubleValue();
      }
  }
  ```
  becomes
  ```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
  @Override
  public void evaluate(ILocation location, IRecordReader aggregatedMeasures, IWritableCell resultCell) {
      if (!aggregatedMeasures.isNull(0)) {
          resultCell.writeDouble(10D + aggregatedMeasures.readDouble(0));
      }
  }
  ```

* In a similar fashion, all abstract implementations of `ITransformProcedure` are now deprecated. It is now necessary to directly implement the interface.
  As before, one can now either implement the method `transform` or the method `doTransform`, depending on the
  expected behavior.

* Similarly, the method `evaluateLeaf` of the `ADynamicAggregationPostProcessor` was reworked to provide a cell in `ADynamicAggregationPostProcessorV2`

* The method `IPostProcessor#init(Properties)` has been completely reworked, with clear methods to implement or override for each of the most important parts
  of the post processor.

### Distribution

Now, cubes within a distributed cluster have a unique identifier that will be used to expose their remote addresses through
the query cube they are related to.
This introduces a breaking change in the distributed messenger constructors: `ADistributedMessenger` now include `CubeEndPointInfo`
in its constructor, a data structure holding information regarding cube addresses and identifiers. These data are solely resolved by core ActivePivot,
thus one has just to include the new field in any subsequent messenger.

### Analysis Hierarchies

The implementations of Analysis Hierarchies have been cleaned as part of 5.11. Users are expected to extend and override `AAnalysisHierarchyV2`.<br />
Most users should not see a difference because Analysis Hierarchies were mostly populated with static members.

The contract between the two classes has been better described. There is now a clear separation between static members and members generated from the ActivePivot Schema.<br />
Static members are still created by `AAnalysisHierarchyV2#buildDiscriminatorPaths`.<br />
However, to process introspected members, the new method is `#processIntrospectedMember`, replacing a judicious override of `#contributeMember`.
Instead of consuming a member and having to call the `super` method to do the contribution, users receive the introspected members and their counts, as well a consumer function.
It is up to the function to generate as many members as it wants and to pass each one of them to the consumer to publish them.

As before, `AAnalysisHierarchyV2` sources are available for inspection and inspiration.

### Datastore

* To create datastore queries one should now give a `SelectionField` instead of a `String` which was the path to the field.
* `ReferencedField` was renamed `ReachableField`.
* `ISelectionField` was removed. It is replaced by `SelectionField`.
* `SelectionField.getName()` was renamed `getAlias()`.

> `getMostRecentVersion()` should never be used by a project. It is an internal method. Replace all calls
> to `getMostRecentVersion()` by a call to `getHead()`.

### Vectors

All methods in `IVectorBinding` were changed from:
`void methodName(IVector source, IVector destination)`
to:
`void methodName(IVector left, IVector right)`

This change is performed to align all the vector APIs together.
For instance, doing `vectorA.minus(vectorB)` is now, under the hood, calling `binding.minus(vectorA, vectorB)`, keeping the arguments in their initial order.
This should better prevent mistakes in the implementations of methods such as `IVectorBinding.applyAsDouble(left, right, DoubleBinaryOperator)`.

Users writing their own vector implementations and their own bindings for these vectors will probably need to ensure their bindings are in order.

### Content Service UI

`ContentServerResourceServerConfig` is replaced by `AdminUIResourceServerConfig` and `content-server-ui.jar` is replaced by `admin-ui.jar`.

### Content Server and ActiveMonitor Database

#### Migrating H2 to v2

The dependency version of h2 for ActivePivot and ActiveMonitor was upgraded from 1.4.200 to 2.1.214. This version change
makes h2-generated `.db` files incompatible between 6.0 and the prior versions.

Unwanted `.db` files can simply be deleted, or restoring the entries of your current database can be attempted using the [h2 migration notes](https://www.h2database.com/html/migration-to-v2.html).

### SOAP

We no longer return a full `ActivePivotManagerDescription` in our webservices with `retrieveManagerDescription` but instead return a lighter description
called `SoapActivePivotDiscovery` in `retrieveActivePivotDiscovery`. This discovery will contain all the information
you previously wanted from an `ActivePivotManagerDescription` including a list of Catalogs and a list of Cubes
(And in each cube, its measures, dimensions, hierarchies and levels).

`retrieveActivePivotDescription` also no longer return a `IActivePivotDescription` but a `SoapCubeDiscovery` which is a lighter
description of your ActivePivot.

`retrieveSchemaDescription` no longer exists in our webservices.

### XML

Building ActivePivot from an XML description file is no longer available. Users are invited to use our fluent builder API using `StartBuilding`.

### ActiveviamProperties

The options for the ActiveViam Property `-Dactiveviam.chunkAllocatorClass` were moved to specialized packages. See the Javadoc of the property `CHUNK_ALLOCATOR_CLASS_PROPERTY`.
