Implementing User Config


Configuring Liberator

User Config uses a number of StreamLink subjects to request configuration for users. Which subjects are used depends on the asset classes you have enabled.

The config subjects for asset classes you have enabled must be included in your Liberator config using object mapping. If you do not do this, Liberator will return a READ_DENIED error for those subjects.

Object mapping example
# Non-asset-specific config
object-map	"/PRIVATE/CONFIG"                   "/PRIVATE/%u/CONFIG"

# FX config
object-map	"/PRIVATE/FX/CONFIG"                "/PRIVATE/%u/FX/CONFIG"

# MM (Money Markets) config
object-map	"/PRIVATE/MM/CONFIG"                "/PRIVATE/%u/MM/CONFIG"

# Commodities config

You must also include the relevant config subjects in your Liberator config using add-data-service::include-pattern inside the add-data-service block for your Configuration Service created in the next section.

Finally, ensure that the config subjects are added to your Keymaster permissions.

Creating a Configuration Service

Creating a Configuration Service allows you to integrate any downstream permissioning system with our User Config feature-switch mechanism.

By creating Config Providers designed to provide config for the different asset classes (FX, MM, Commodities) and user types (regular, sales, TOBO), you can serve a full range of feature configuration for different asset classes, features, and users.

Config Adapters

The FX Integration API supplies a number of Config Adapter classes, which you can use to register Config Providers that provide the User Config.

There is a pre-made Config Adapter for each of the asset classes (FX, MM, Commodities) as well as for non-asset-specific User Config. Each of them have one or more registration helper functions for different user types (regular, sales, TOBO).

A combination of the asset class and user type you want to supply config for informs you which Config Adapter and registration helper function you need to use.

For a full reference to the available Config Adapters and their registration helper functions, see User Config Adapters.

See below an ExampleAdapter which showcases the registration of a number of Config Providers for the various asset classes and user types.

public class ExampleAdapter {
    public void start() {
        // ...

        UserConfigAdapter.registerConfigProvider(dataSource, new UserConfigProvider());
        UserConfigAdapter.registerSalesTOBOConfigProvider(dataSource, new UserTOBOConfigProvider());

        FXConfigAdapter.registerConfigProvider(dataSource, new FXConfigProvider());
        FXConfigAdapter.registerSalesConfigProvider(dataSource, new FXSalesConfigProvider());
        FXConfigAdapter.registerSalesTOBOConfigProvider(dataSource, new FXTOBOConfigProvider());

        MMConfigAdapter.registerConfigProvider(dataSource, new MMConfigProvider());
        MMConfigAdapter.registerSalesConfigProvider(dataSource, new MMSalesConfigProvider());
        MMConfigAdapter.registerSalesTOBOConfigProvider(dataSource, new MMTOBOConfigProvider());

        CommoditiesConfigAdapter.registerConfigProvider(dataSource, new CommoditiesConfigProvider());

        // ...

Config Providers

By creating Config Providers for each of the config subjects, you can generate and supply User Config based on data held in downstream services such as a database or permissioning system, meaning you don’t have to redeploy anything when User Config changes.

This all hinges on the onRequest callback of the Config Providers, supplied by the CachedObjectProvider interface.

CachedObjectProvider interface
public interface CachedObjectProvider<S, T extends SubjectInfo> {
    void onRequest(T subjectInfo, SubjectConsumer<S> publishObject);
    void onDiscard(T subjectInfo);

The User Config is published for streaming back to the client application by calling the SubjectConsumer.onNext method as in the example below.

Example FXSalesConfigProvider
public class FXSalesConfigProvider implements CachedObjectProvider<FXSalesConfig, ConfigSubjectInfo> {

	public void onRequest(
			final ConfigSubjectInfo subjectInfo,
			final SubjectConsumer<FXSalesConfig> publishObject
	) {
		// Here you'd look up the user's config - we're just using an empty configuration object.
		publishObject.onNext(new FXSalesConfig());

	public void onDiscard(final ConfigSubjectInfo subject) {


Refer to the Example Adapter in the FX Integration API kit for examples on how Config Providers are created and registered with Config Adapters.

For a reference on the available feature configuration of each User Config object, see User Config API reference.


How do I restrict the subjects a user can subscribe and contribute to?

Continue to use Liberator authorisation to protect subjects, as before:

  • Users may only subscribe to subjects they have been permitted to subscribe to.

  • Users may not subscribe or contribute to the channels of other users. Liberator maps channel subjects to internal subject names that include an identifier, usually a username or group name. Users may not subscribe to the internal subjects directly, only indirectly via Liberator’s object mapping or a mapping message from an adapter.

It is good practice for your adapters to verify that a user’s subject request is permitted before serving it:

  • If a subject request is not permitted, the adapter should respond with READ_DENIED.

  • If a contribution is not permitted, the adapter should respond with WRITE_DENIED.

  • If a contribution is a message in a trade-model workflow, then the adapter should send a Reject or Error message with a reason.

How do I enable specific tenors and settlement dates for a user?

Use the FXCalendarAdapter to enable specific tenors and settlement dates for a user.

Enabling specific tenors and settlement dates for a TOBO user
public class ExampleAdapter {
    public void start() throws IOException {
      // ...

      final FXCalendarAdapter fxCalendarAdapter = new FXCalendarAdapter(dataSource);

      final SettlementDateRequestListener<ToboSettlementDateSubjectInfo> toboSettlementDateRequestListener = new SettlementDateRequestListener<>(ToboSettlementDateSubjectInfo::getToboUsername);


      final DateRequestListener<ToboTenorDateSubjectInfo> toboTenorDateRequestListener = new DateRequestListener<>(ToboTenorDateSubjectInfo::getToboUsername);

      final TenorDateProvider<ToboTenorDateSubjectInfo> toboTenorDateProvider =


      // ...

Refer to the FX Integration API kit’s Example Adapter for a full example, including how to enable tenors and settlement dates for regular users as well as TOBO users.

See also: