Adding New Data Loading or Unloading Topics
This page provides a description of how to load a new file into a new store within Atoti FRTB. The techniques employed are generic examples that can be extended, adapted and repeated for any use case that are needed. In all cases, we make minimal changes to the Reference Implementation.
Step 1 - Move data to the relevant directory
In this step, we want to bring any custom data into an appropriate folder inside:
/frtb-starter/src/test/resources/data/
For this example we will be bringing our file named Custom.csv within the 2018-09-26
folder and setting up our topic configuration so that we can load the
same format file for each AsOfDate. Below is a sample file for reference.
AsOfDate | RiskClass | CustomProjected |
---|---|---|
2018-09-26 | Commodity | -6640.633693 |
2018-09-26 | GIRR | 14020.37649 |
2018-09-26 | CSR Sec CTP | 8386.767854 |
2018-09-26 | CSR Sec non-CTP | 19218.3336 |
2018-09-26 | Equity | 8274.302903 |
2018-09-26 | FX | 2150.845785 |
2018-09-26 | CSR non-Sec | -25353.39868 |
2018-09-26 | DRC Sec non-CTP | 11319.08548 |
2018-09-26 | DRC non-Sec | 17134.37517 |
Step 2 - Create the datastore definition we want to populate
To add a new datastore, we will need to navigate to the
addModifications()
method inside of the
DatastoreCustomisationsConfig
class.
frtb-starter/src/main/java/com/activeviam/frtb/starter/cfg/impl/
In this method we can append the following to create our datastore description.
@Override
public void addModifications(IDatastoreConfigurator configurator) {
mergingDuplicateKeyHandlerCustomisations(configurator);
customizationForDrc(configurator);
if (extraDatastoreConfigs != null) {
extraDatastoreConfigs.forEach(config -> config.accept(configurator));
}
// Here we add our modification
// In this method we can append the following to create our datastore description.
IStoreDescription storeDescription = StoreDescription.builder()
.withStoreName(CUSTOM_STORE)
.withField(StoreFieldNames.AS_OF_DATE, ILiteralType.LOCAL_DATE).asKeyField()
.withField(StoreFieldNames.RISK_CLASS, ILiteralType.STRING).asKeyField()
.withField("CustomProjected", ILiteralType.DOUBLE)
// You can customize your datastore with any number of fields, as well as define partitioning, duplicate key handlers, and indexing configurations
.build();
configurator.addStore(FRTBConstants.FRTB_SCHEMA, storeDescription);
// Here, we can also add a reference if needed:
IReferenceDescription referenceDescription = configurator.referenceBuilder(FRTBConstants.FRTB_SCHEMA)
.fromStore(SADatastoreConfig.TRADE_BASE_STORE_NAME)
.toStore(CUSTOM_STORE)
.withName(SADatastoreConfig.TRADE_BASE_STORE_NAME + "To" + CUSTOM_STORE)
.withMapping(SADatastoreConfig.TRADE_BASE_STORE_RISK_CLASS, SADatastoreConfig.TRADE_BASE_STORE_RISK_CLASS)
.withMapping(SADatastoreConfig.AS_OF_DATE, SADatastoreConfig.AS_OF_DATE)
.build();
configurator.addReference(FRTBConstants.FRTB_SCHEMA, referenceDescription);
}
If we want to organize our customizations into a separate class for instance ClientCustomisations
, we can create a new class as outlined here.
See Datastore Helper documentation for more information on potential datastore modifications.
Step 3 - Create ChannelParameters for our data loading topic
- Create a class which auto wires the desired source configuration class
- Create the ChannelParameters bean which includes the store name, topic name, and file pattern. We must qualify our bean with a unique qualifier. To wire ChannelParameters bean properly, we must use the appropriate ChannelParameters Bean Annotation. For more information, see ChannelParameters Bean Annotations.
- Ensure that a file pattern property is defined within
frtb-starter/src/main/resources/frtb-data-load.properties
ascustom.file-pattern=**/*Custom*.csv
. Wildcards can be appended as needed, for instance to be able to includeCustom_1.csv
.
public class CustomChannelParameters {
@Autowired
ASourceConfig sourceConfig;
private static final String CUSTOM_STORE = "CustomStore";
public static final String FILE_PATTERN_PROP = "custom.file-pattern";
public static final String TOPIC_CUSTOM = "Custom_TOPIC";
public static final String SP_QUALIFIER__CUSTOM_STORE_CHANNEL_PARAMETER = "customStoreChannelParameter";
@SourceConfigChannelParametersBean
@Qualifier(SP_QUALIFIER__CUSTOM_STORE_CHANNEL_PARAMETER)
public ACSVSourceConfig.ChannelParameters customStoreChannelParameter() {
return sourceConfig.channelParametersBuilder(TOPIC_CUSTOM, CUSTOM_STORE, FILE_PATTERN_PROP).build();
}
}
Step 4 - Include our new topic in initialDataLoad
Find InitialDataLoadConfig
in frtb-starter/src/main/java/com/activeviam/frtb/starter/cfg/impl/
and modify initialDataLoad
method to include our topic as desired.
In this example, we want to load our new file for each asOfDate.
public class InitialDataLoadConfig {
@Bean
@DependsOn(value = { "startManager", "initialConfigDataLoad"})
public Void initialDataLoad(
@Qualifier("initialLoadAsOfDates") List<LocalDate> initialLoadAsOfDates,
@Qualifier("initialLoadHistory") boolean initialLoadHistory
) throws IOException {
/* ... */
for (final LocalDate date : initialLoadAsOfDates) {
/* ... */
controller.execute(
new DataLoadControllerRequest(
LoadDataTxControllerTask.PLUGIN_KEY,
Arrays.asList(CustomChannelParameters.TOPIC_CUSTOM),
fetchScope)
);
}
/* ... */
}
}
Step 5 - Ensure FRTBConfig picks up our modifications
To ensure that our customisations are picked up, be sure to include CustomChannelParameters
and ClientCustomisations
classes in FRTBConfig
located
in /frtb-starter/src/main/java/com/activeviam/frtb/starter/cfg/impl/
When using DirectQuery
When using DirectQuery, we must perform Step 2 and configure our datastore correctly. Then we have to modify our remote database to include the new Table / Fields. When doing so we must ensure we follow the naming convention of our Name Mapper.
Our database only needs to contain the new fields and or stores. When the application starts, the Datastore description will be converted into a database description. The remote database needs to contain the modifications before we start the application.
Adding a Field with DirectQuery
When adding a new field, we must add it to the datastore description as outlined in step 2 and also ensure the field exists in our database in the correct table.
Then when the application starts, the datastore description (containing the custom field) will be converted into a DirectQuery database description and the field can be used for Hierarchies or treated the same as other DirectQuery fields.
note
When using custom fields with DirectQuery it is important to remember that datastore queries and getByKey queries are not recommended due to the performance overhead.
Adding a new Table with DirectQuery
When adding a new table, we first need to ensure we have properly completed step 2 and have defined our table on our remote database. Once complete, we can then
add our new table to our DirectQuery database configuration (class extending ADirectQueryDatabaseSchema
).
In this example we want to add a table with the name “MyCustomTable” in our Datastore config.
First we create a CustomDirectQueryDatabaseConfig
marked as @Primary
which extends the reference DirectQueryDatabaseConfig
class. We add our table
to the getDirectQueryTableDescriptions()
method as follows:
@Primary
public class CustomDirectQueryDatabaseConfig extends DirectQueryDatabaseConfig {
@Override
public List<Table> getDirectQueryTableDescriptions() {
// Get all default tables from the parent
List<Table> existingTables = super.getDirectQueryTableDescriptions();
existingTables.add(getMyCustomTable());
return existingTables;
}
public Table getMyCustomTable(){
// Convert our datastore description into a database description
return migrator.migrateToDirectQueryTable(
getStoreDescriptionFor(
"MyCustomTable"
)
);
}
}
Then we just add our DirectQueryDatabaseConfig
class to our application configuration and the extra table will exist in the Atoti instance.
warning
The DirectQuery and InMemory Atoti servers must be configured identically. There must not be any hierarchies in the DirectQuery data node that do not exist in the InMemory one.
Suggested further reading
Enriching File Fields by Adding Column Calculators
Add and Load a New Column to Existing File