> ## 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.

# Atoti What-If Implementation Example

# Implementing Atoti What-If simulations

This section provides a detailed example of using Atoti What-If to implement what-if scenarios through simulations.

## Importing the library in your project

To use Atoti What-If, import the Spring Boot Starter in your Maven configuration:

```xml theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
<dependency>
    <groupId>com.activeviam.apps</groupId>
    <artifactId>atoti-what-if-spring-boot-starter</artifactId>
    <version>5.0.0-AS6.1</version>
</dependency>
```

Released versions of Atoti What-If are built using a specific version of Atoti Server but will work with any non-breaking patch version of the core library.

## Using the Spring Boot Starter (recommended)

The Spring Boot Starter auto-configures all What-If components. You only need to provide two beans:

1. **`IDatabaseService`** — provided by your Atoti Server application
2. **`IWhatIfPersistenceProperties`** — provides Hibernate configuration for persistence

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Bean
public IWhatIfPersistenceProperties whatIfPersistenceProperties(
        @Value("classpath:hibernate.properties") Resource resource) throws IOException {
    Properties props = new Properties();
    props.load(resource.getInputStream());
    return () -> props.entrySet().stream()
        .collect(Collectors.toMap(
            e -> String.valueOf(e.getKey()),
            e -> String.valueOf(e.getValue())
        ));
}
```

The starter automatically creates and wires:

* `DatabaseSimulationEngine`
* `IUniqueIdGenerator`
* `ISimulationPersistenceManager`
* `IDatabaseSimulationsSecurityManager`
* `DatabaseSimulationsWorkflow`
* `DatabaseSimulationsRestService`

For distributed environments, enable distributed mode and specify the query node name:

```yaml theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
atoti:
  what-if:
    distribution:
      enabled: true
      query-node-name: "MyQueryNodeName"
```

See the [configuration reference](./configuration-reference) for all available properties, and [how to set up the Spring Boot Starter](./setup-spring-boot-starter) for more details.

## Manual configuration (advanced)

To enable the creation of Atoti What-If simulations within your project, you need to create several objects.

### The `IDatabaseService` implementation

All Atoti Server applications will contain an `IDatabaseService` implementation, which will be suitable for Atoti What-If in most cases. Distributed environments are a special case, where the query node requires a custom `IDatabaseService` with access to the data nodes.

We provide a `RestDistributedDatabaseService` implementation for this scenario, which would typically be used as follows:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Bean
@ConditionalOnQueryNode
@ConditionalOnMissingBean
public AddressSupplier addressSupplier() {
    return () -> mvPivot.getClusterMembersRestAddresses().values().stream()
            // for backwards compatibility, add protocol if missing
            .map(addr -> addr.regionMatches(true, 0, "http", 0, 4) ? addr : ("http://" + addr))
            .collect(Collectors.toSet());
}

@Bean
@ConditionalOnQueryNode
@ConditionalOnMissingBean
public AuthenticatorSupplier authenticatorSupplier(IJwtService jwtService) {
    return () -> new JwtAuthenticator(jwtService);
}

@Bean
@Primary
@ConditionalOnQueryNode
public IDatabaseService restRemoteService(AddressSupplier addressSupplier, AuthenticatorSupplier authenticatorSupplier) {
    return new RestDistributedDatabaseService(addressSupplier, authenticatorSupplier, () -> mvPivot);
}
```

In this example, we rely on an `IMultiVersionDistributedActivePivot` object to retrieve the addresses of the cluster members (data nodes). These addresses will be used internally to forward simulation executions and merge the results.

We also need to create an `AAuthenticator` supplier which will provide the security context of the thread executing a request to the `RemoteDatabaseService` connection. This ensures access to the data node databases is secured through built-in authentication and authorization.

### The persistence manager

Simulation persistence is enabled through the creation of an `ISimulationPersistenceManager` object:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Bean
public ISimulationPersistenceManager persistenceManager(WhatIfHibernateProperties whatIfHibernateProperties) {
    var configuration = new org.hibernate.cfg.Configuration();
    var properties = new Properties();
    properties.putAll(whatIfHibernateProperties.getPersistence());
    configuration.addProperties(properties);
    configuration.addAnnotatedClass(DatabaseSimulationJPA.class);
    var sessionFactory = configuration.buildSessionFactory();

    HibernateSimulationPersistenceManager<DatabaseSimulationJPA> persistenceManager = HibernateSimulationPersistenceManager.of(DatabaseSimulationJPA.class);
    persistenceManager.setSessionFactory(sessionFactory);
    return persistenceManager;
}
```

This example uses a non-auditable Hibernate persistence manager. The following implementations of a persistence manager are available in the Atoti What-If library:

<table><thead><tr><th>Manager</th><th>Description</th></tr></thead><tbody><tr><td>HibernateSimulationPersistenceManager</td><td>Persists simulations in an SQL database, using Hibernate.</td></tr><tr><td>HibernateAuditablePersistenceManager</td><td>Persists simulations in an SQL database, using Hibernate. Adds audit capabilities to the persistence layer.</td></tr></tbody></table>

### The security manager

To handle simulation permissioning, the following implementations of `IDatabaseSimulationsSecurityManager` are provided:

<table><thead><tr><th>Manager</th><th>Description</th></tr></thead><tbody><tr><td>SpringDatabaseSimulationsSecurityManager</td><td>A security manager that uses Spring security to retrieve user authentication and authorization.</td></tr><tr><td>NoOpDatabaseSimulationsSecurityManager</td><td>A security manager that allows all actions to be performed by all users.</td></tr></tbody></table>

The configuration class should use the appropriate implementation:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Bean
public IDatabaseSimulationsSecurityManager securityManager(ISimulationPersistenceManager persistenceManager, IBranchPermissionsManager branchPermissionsManager) {
    return new SpringDatabaseSimulationsSecurityManager(persistenceManager, branchPermissionsManager);
}
```

### The simulation engine

An instance of `DatabaseSimulationEngine` has to be created, and the associated `DatabaseSimulationsUtils` class should use the same `IDatabaseService` instance:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Bean
public DatabaseSimulationEngine simulationEngine(IDatabaseService databaseService) {
    DatabaseSimulationEngine engine = new DatabaseSimulationEngine();
    engine.setDatabaseService(databaseService);
    DatabaseSimulationsUtils.setDatabaseService(databaseService);
    return engine;
}
```

### The unique ID generator

An implementation of `IUniqueIdGenerator` is required for the workflow to correctly assign IDs to simulation executions. The Atoti What-If library contains the `IncrementalUniqueIdGenerator`, providing an incremental counter starting from the Epoch second.

Alternatively, we can use a custom implementation:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
private static class UniqueIdGenerator implements IUniqueIdGenerator {
    private final AtomicLong generator = new AtomicLong(0);

    @Override
    public Long generateId() {
        synchronized (generator) {
            return generator.getAndIncrement();
        }
    }
}

@Bean
public IUniqueIdGenerator simulationIdGenerator() {
    return new UniqueIdGenerator();
}
```

### The simulation workflow

An instance of `DatabaseSimulationsWorkflow` will then use the objects defined in our configuration:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Bean
public DatabaseSimulationsWorkflow simulationWorkflow(
        DatabaseSimulationEngine engine,
        ISimulationPersistenceManager manager,
        IDatabaseSimulationsSecurityManager securityManager,
        IDatabaseService databaseService,
        IUniqueIdGenerator idGenerator) {
    return new DatabaseSimulationsWorkflow(
            engine,
            manager,
            securityManager,
            databaseService,
            idGenerator);
}
```

### The simulation REST service

Finally, to enable UI interactions with the workflow and persistence, create a `DatabaseSimulationsRestService`:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Bean
public DatabaseSimulationsRestService simulationsService(
        ISimulationPersistenceManager manager,
        DatabaseSimulationsWorkflow workflow,
        IDatabaseService databaseService) {
    return new DatabaseSimulationsRestService(manager, workflow, databaseService);
}
```

## Creating definition implementations

Definition implementations are use-case specific implementations of the `IDatabaseSimulationDefinition` interface, with specific required parameters, logic for creating `JsonDatabaseAction` objects and a method for the retrieval of before/after values for a specific instance of the definition.

### The IDatabaseSimulationDefinition interface and ADatabaseSimulationDefinition abstract class

The `IDatabaseSimulationDefinition` interface is an extension of the core `IExtendedPluginValue` containing the following methods:

<table><thead><tr><th>Method</th><th>Return type</th><th>Description</th></tr></thead><tbody><tr><td><code>getParameters()</code></td><td><code>Map\<String, String></code></td><td>The implementation should return a map of the definition instance parameters as Name -> Serialized value.</td></tr><tr><td><code>toJsonDatabaseEdit()</code></td><td><code>JsonDatabaseEdit</code></td><td>The implementation should transform the parameters of the definition instance into a <code>JsonDatabaseEdit</code> to be sent to the <code>IDatabaseService</code>. This method will be called by the <code>DatabaseSimulationEngine</code>.</td></tr><tr><td><code>getDescription()</code></td><td><code>String</code></td><td>The implementation should return the description of the definition.</td></tr><tr><td><code>getDiffs(IDatabaseService databaseService)</code></td><td><code>List\<DatabaseSimulationDiffDTO></code></td><td>The implementation should provide a mechanism to retrieve a list of <code>DatabaseSimulationDiffDTO</code> from a database service.</td></tr></tbody></table>

The `ADatabaseSimulationDefinition` class is an abstract class providing a skeleton implementation of the `IDatabaseSimulationDefinition` interface.

Abstract methods are:

<table><thead><tr><th>Method</th><th>Return type</th><th>Description</th></tr></thead><tbody><tr><td><code>getAllParameterNames()</code></td><td><code>Set\<String></code></td><td>A method for retrieving all the relevant parameter names, for instantiating the parameters <code>Map\<String, String></code>.</td></tr><tr><td><code>generateDatabaseActions()</code></td><td><code>JsonDatabaseAction\[]</code></td><td>A method for generating an array of <code>JsonDatabaseAction</code> to use in a <code>JsonDatabaseEdit</code>.</td></tr></tbody></table>

Implemented or stubbed methods are:

<table><thead><tr><th>Method</th><th>Description</th></tr></thead><tbody><tr><td><code>getParameters()</code></td><td>Returns a stored <code>Map\<String, String></code> of parameters.</td></tr><tr><td><code>addParameter(String key, Object value)</code></td><td>Adds a parameter to the parameters <code>Map\<String, String></code>.</td></tr><tr><td><code>getParameter(String key)</code></td><td>Returns the <code>String</code> representation of the requested parameter, from the parameters <code>Map\<String, String</code>>.</td></tr><tr><td><code>getParameter(String key, TypeReference\<T> type)</code></td><td>Returns a deserialized parameter object from the parameters <code>Map\<String, String></code>, using a Jackson <code>TypeReference</code>. Intended to be used with <code>Collections</code> types.</td></tr><tr><td><code>getParameter(String key, Class\<T> class)</code></td><td>Returns a deserialized parameter object from the parameters <code>Map\<String, String></code> using the class object passed in.</td></tr><tr><td><code>toJsonDatabaseEdit()</code></td><td>Implementation of the interface method that wraps the <code>generateDatabaseActions()</code> result in a <code>JsonDatabaseEdit</code> object.</td></tr><tr><td><code>getDiffs(IDatabaseService databaseService)</code></td><td>Stub implementation of the interface method which returns a list containing a <code>DatabaseSimulationDiffDTO</code> with all fields set to “N/A”.</td></tr></tbody></table>

### Required constructors

As all `IDatabaseSimulationDefinition` instances are also `IExtendedPluginValue` objects that are instantiated by the Atoti Server Registry, a specialized constructor is provided in the `ADatabaseSimulationDefinition` class.

<Warning>
  While completely custom implementations of `IDatabaseSimulationDefinition` can be created, it is strongly recommended to extend the `ADatabaseSimulationDefinition` class. The specialized constructor of the custom implementation can then be:
</Warning>

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
public MyCustomSimulationDefinition(Map<String, Object> parameters) {
    super(parameters);
}
```

<Warning>
  Without a constructor accepting `Map<String, Object> parameters` as an input, the Registry will not be able to instantiate the definitions.
</Warning>

Custom constructors can then be implemented to take any input and be passed through to the `getParameters()` method.

### Creating concrete definitions for a given use-case

Starting from the `ADatabaseSimulationDefinition` abstract class detailed above, and taking into account the required constructors, a typical definition implementation would be:

#### Class annotations

The concrete class is annotated to be an extended plugin value, with an associated plugin key:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@QuartetExtendedPluginValue(intf = IDatabaseSimulationDefinition.class, key = PnLArithmeticSimulationDefinition.PLUGIN_KEY)
public class PnLArithmeticSimulationDefinition extends ADatabaseSimulationDefinition {
    public static final String PLUGIN_KEY = "PnLBookScalingSimulationDefinition";

    ...

    @Override
    public String getType() {
        return PLUGIN_KEY;
    }
}
```

#### Constructors

The two constructors for this implementation are:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
public PnLArithmeticSimulationDefinition(Map<String, Object> parameters) {
    super(parameters);
}

public PnLArithmeticSimulationDefinition(BranchAwareAdjustmentRequestDTO dto, boolean isAbsolute) {
    super(Map.of(
        DTO, dto,
        IS_ABSOLUTE, isAbsolute
    ));
}
```

In this example, the `BranchAwareAdjustmentRequestDTO` is a DTO containing all the relevant information related to the simulation parameters. The second constructor isn’t required, as the `Map<String, Object>` can be created externally and passed to the mandatory constructor.

#### The JsonDatabaseAction generation method

The definition in this example will use the input parameters to create a single action that applies an arithmetic operation to a field in a database table:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Override
protected JsonDatabaseAction[] generateDatabaseActions() {
    BranchAwareAdjustmentRequestDTO dto = getParameter(DTO, BranchAwareAdjustmentRequestDTO.class);
    boolean isAbsolute = getParameter(IS_ABSOLUTE, Boolean.class);

    JsonNode conditionNode = DatabaseSimulationsUtils.baseConditionToJsonNode((IBaseCondition) convertToCondition(dto));

    JsonDatabaseAction[] actions = List.of(
            DatabaseSimulationsUtils.newUpdateDatabaseAction(
                    TRADE_PNL_STORE_NAME,
                    conditionNode,
                    ArithmeticUpdateProcedureFactory.generateProcedureAsJsonNode(
                            PNL_VECTOR,
                            isAbsolute ? ArithmeticUpdateProcedureFactory.Operation.PLUS : ArithmeticUpdateProcedureFactory.Operation.SCALE,
                            Double.valueOf(dto.valueOfInput(StoreFieldConstants.SENSITIVITY_VALUES))
                    )
            )
    ).toArray(JsonDatabaseAction[]::new);

    return actions;
}
```

Any `JsonDatabaseAction` type can be implemented within this method.

### Helper methods for creating JsonDatabaseAction objects

To simplify the creation of `JsonDatabaseAction` objects, several helper methods are provided in the `DatabaseSimulationsUtils` utility class.

#### General helper methods

We include methods for converting to and from `JsonNode` objects as used by the database service APIs.

<table><thead><tr><th>Method</th><th>Return type</th><th>Description</th></tr></thead><tbody><tr><td><code>baseConditionToJsonNode(IBaseCondition condition)</code></td><td><code>JsonNode</code></td><td>Converts an <code>IBaseCondition</code> object into a <code>JsonNode</code>.</td></tr><tr><td><code>stringToJsonNode(String string)</code></td><td><code>JsonNode</code></td><td>Converts a <code>String</code> to a <code>JsonNode</code>.</td></tr><tr><td><code>jsonNodeToString(JsonNode node)</code></td><td><code>String</code></td><td>Converts a <code>JsonNode</code> to a <code>String</code>.</td></tr><tr><td><code>mapToJsonNode(Map\<String, Object> map)</code></td><td><code>JsonNode</code></td><td>Converts a <code>Map\<String, Object></code> to a <code>JsonNode</code>.</td></tr></tbody></table>

#### Actions by type

Type-specific methods are included for all `JsonDatabaseAction` types:

<table><thead><tr><th>Method</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>newAddDatabaseAction(String baseTable, String\[]\[] tuples)</code></td><td><code>JsonDatabaseAction</code> for inserting new tuples.</td><td>Creates a <code>JsonDatabaseAction</code> for the insertion of the given tuples (as an array of <code>String\[]</code>) into the specified table.</td></tr><tr><td><code>newRemoveDatabaseAction(String baseTable, JsonNode condition)</code></td><td><code>JsonDatabaseAction</code> for deleting rows from a table.</td><td>Creates a <code>JsonDatabaseAction</code> that removes rows matching the condition from the specified table.</td></tr><tr><td><code>newUpdateDatabaseAction(String baseTable, JsonNodeCondition condition, JsonNode updateProcedure)</code></td><td><code>JsonDatabaseAction</code> for executing an update procedure on rows in a table.</td><td>Creates a <code>JsonDatabaseAction</code> that executes an update procedure on the rows in the specified table that match the given condition.</td></tr><tr><td><code>newDuplicateDatabaseAction(String baseTable, JsonNode condition, String branch, Map\<String, String> suffixes)</code></td><td><code>JsonDatabaseAction</code> for duplicating rows in a table.</td><td>Retrieves rows in the given table for the branch, adds the specified suffixes to the appropriate fields and generates a <code>JsonDatabaseAction</code> that inserts the resulting tuples into the table.</td></tr><tr><td><code>newDuplicateDatabaseAction(String baseTable, JsonNode condition, String branch, Map\<String, String> suffixes, Map\<String, Function\<Object, Object>> overrides)</code></td><td><code>JsonDatabaseAction</code> for duplicating rows in a table.</td><td>Retrieves rows in the given table for the branch, applies any defined overrides, adds the specified suffixes to the appropriate fields and generates a <code>JsonDatabaseAction</code> that inserts the resulting tuples into the table.</td></tr></tbody></table>

#### IUpdateWhereProcedureFactory implementations

For the `newUpdateDatabaseAction(String baseTable, JsonNodeCondition condition, JsonNode updateProcedure)` method, we provide several implementations of the `IUpdateWhereProcedureFactory` interface, for use as the update procedure, through the following methods:

<table><thead><tr><th>Factory</th><th>Method</th><th>Description</th></tr></thead><tbody><tr><td><code>ArithmeticUpdateProcedureFactory</code></td><td><code>generateProcedureAsJsonNode(String field, Operation operation, Double operator)</code></td><td>Generates a <code>JsonNode</code> update-where procedure that applies the given operation (<code>PLUS</code>, <code>MINUS</code> or <code>SCALE</code>) to a field, with the given value.</td></tr><tr><td><code>ArithmeticUpdateProcedureFactory</code></td><td><code>generateProcedureAsJsonNode(String field, Operation operation, Double operator, List\<Integer> indicesInVector)</code></td><td>Generates a <code>JsonNode</code> update-where procedure that applies the given operation (<code>PLUS</code>, <code>MINUS</code> or <code>SCALE</code>) to a field, with the given value. Optionally, a list of vector indices for which the operation applies can be supplied.</td></tr><tr><td><code>UpdateWithFieldValuesProcedureFactory</code></td><td><code>generateProcedureAsJsonNode(Map\<String, Object> fieldsToUpdate)</code></td><td>Generates a <code>JsonNode</code> update-where procedure that changes the value of a field to a set value.</td></tr><tr><td><code>UpdateWithListOfValuesProcedureFactory</code></td><td><code>generateProcedureAsJsonNode(Set\<String> keys, List\<Map\<String, Object>> rowsToUpdate)</code></td><td>Generates a <code>JsonNode</code> update-where procedure that selects records based on keys and fills in the remaining fields from the matched entry in the list of rows expressed as <code>Map\<String, Object></code>. Allows for a larger degree of flexibility than the <code>UpdateWithFieldValuesProcedureFactory</code>, as the field changes can be different for each key.</td></tr></tbody></table>

### The DTOs

External data transfer is handled through DTO objects wrapping the definitions, simulations and diff objects within the simulation workflow. All DTO objects provide getters and setters for the instance parameters within the object.

#### The DatabaseSimulationDiffDTO

<table><thead><tr><th>Field</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>store</td><td><code>String</code></td><td>The store for which the before and after values are retrieved.</td></tr><tr><td>filters</td><td><code>Map\<String, String></code></td><td>A map of field values used for the conditional retrieval of before and after values.</td></tr><tr><td>beforeValue</td><td><code>String</code></td><td>The value before the simulation has been executed, serialized into a <code>String</code>.</td></tr><tr><td>afterValue</td><td><code>String</code></td><td>The value after the simulation has been executed, serialized into a <code>String</code>.</td></tr></tbody></table>

#### The DatabaseSimulationDefinitionDTO

| Field                 | Type                  | Description                                                            |
| --------------------- | --------------------- | ---------------------------------------------------------------------- |
| definitionType        | `String`              | The plugin type of the definition instance.                            |
| definitionParameters  | `Map<String, String>` | The parameters used in the definition instance, as a serialized `Map`. |
| definitionDescription | `String`              | A description of the definition instance.                              |

The `DatabaseSimulationDefinitionDTO` also offers conversion methods:

<table><thead><tr><th>Method</th><th>Return type</th><th>Description</th></tr></thead><tbody><tr><td><code>from(String serialized)</code></td><td><code>DatabaseSimulationDefinitionDTO</code></td><td>Conversion method from a serialized <code>String</code> into a concrete object.</td></tr><tr><td><code>from(Map\<String, Object> serialized)</code></td><td><code>DatabaseSimulationDefinitionDTO</code></td><td>Conversion method from a serialized <code>Map</code> into a concrete object.</td></tr><tr><td><code>toDefinition()</code></td><td><code>IDatabaseSimulationDefinition</code></td><td>Conversion from the DTO into the exact simulation definition instance.</td></tr></tbody></table>

#### The DatabaseSimulationDTO

| Field                 | Type                  | Description                                                                                    |
| --------------------- | --------------------- | ---------------------------------------------------------------------------------------------- |
| simulationId          | `Long`                | The ID of the simulation.                                                                      |
| simulationName        | `String`              | The name of the simulation.                                                                    |
| createdBy             | `String`              | The user who created the simulation instance.                                                  |
| creationDate          | `String`              | The date of the creation of the simulation instance.                                           |
| executedBy            | `String`              | The user who executed the simulation instance.                                                 |
| executionDate         | `String`              | The date of the execution of the simulation instance.                                          |
| status                | `String`              | The status of the simulation.                                                                  |
| branchName            | `String`              | The name of the branch on which the simulation has been executed.                              |
| parentBranchName      | `String`              | The parent branch of the simulation execution.                                                 |
| definitionType        | `String`              | The plugin type of the definition instance used in this simulation.                            |
| definitionParameters  | `Map<String, String>` | The parameters used in the definition instance used in this simulation, as a serialized `Map`. |
| definitionDescription | `String`              | A description of the definition instance used in this simulation.                              |

The `DatabaseSimulationDTO` also offers a conversion method:

<table><thead><tr><th>Method</th><th>Return type</th><th>Description</th></tr></thead><tbody><tr><td><code>toDatabaseSimulation()</code></td><td><code>IDatabaseSimulation</code></td><td>Conversion from the DTO into the exact simulation instance.</td></tr></tbody></table>

### Custom REST services

If the generic endpoints available in `DatabaseSimulationsRestService` are not enough, a REST service handling specific simulation types can be created:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@RestController
@RequestMapping(REST_API_URL_PREFIX)
public class TradeRescaleRestServiceController {

	private static final String NAMESPACE = "services/"+ RestPrefixExtractor.REST_NAMESPACE + "/whatif";
	public static final String REST_API_URL_PREFIX = "/" + NAMESPACE + "/tradescale";

	@Autowired
	private DatabaseSimulationsWorkflow workflow;

	protected static final Logger LOGGER = LoggerFactory.getLogger(TradeRescaleRestServiceController.class);

	@PostMapping(value = "/scaleTrade")
	public DatabaseSimulationStatus scaleTrade(@RequestBody TradeRescaleDTO dto) {
		LOGGER.info("[TRADE_RESCALING] Attempting to rescale trades: {}.", dto.getTradeID());
		IDatabaseSimulationDefinition definition = new TradeDuplicateAndRescaleSimulationDefinition(
				List.of(TradeDuplicateAndRescaleSimulationDefinition.RESCALE_SA, TradeDuplicateAndRescaleSimulationDefinition.RESCALE_IMA), dto);

		IDatabaseSimulation simulation = workflow.execute(new DatabaseSimulation(dto.getTitle(), definition, dto.getUserName(), dto.getBranch()));

		DatabaseSimulationStatus status = simulation.getStatus();

		if (DatabaseSimulationStatus.FAILED.equals(status)) {
			LOGGER.warn("[TRADE_RESCALING] Execution failed for Simulation ID: {}", simulation.getSimulationId());
		}
		if (DatabaseSimulationStatus.UNAUTHORISED.equals(status)) {
			LOGGER.warn("[TRADE_RESCALING] Execution unauthorized for user: {}", simulation.getCreatedBy());
		}
		LOGGER.info("[TRADE_RESCALING] Successfully rescaled trades: {}.", dto.getTradeID());
		return status;
	}
}
```

In this example, we expose a single endpoint for the creation and execution of an `IDatabaseSimulation`. The service creates an `IDatabaseSimulationDefinition` from a custom implementation, executes it through the `DatabaseSimulationsWorkflow` and returns the status object.
