Implementing the Configuration Service

Back-end requirements

The Configuration Service is available from version 3.49 of the FX Integration API.

Dependant front-end features

The following application features depend on an implementation of the Configuration Service:

Application Version Feature

FX Sales

2.14+

Historic Search

FX Professional

3.22+

Historic Search

Implementing the Configuration Service (versions 3.55+)

For FX Integration API 3.55+, follow the instructions in the sections below:

The string 'Tobo' in type names was renamed to 'TOBO' in version 3.58 of the FX Integration API. The type names below reflect this change.

Configure subject routing

Follow the steps below to include subject-routing configuration in your adapter for Liberator:

  1. Add the following object mapping to your adapter project’s blade/Liberator/etc/rttpd.conf file:

    object-map  "/PRIVATE/FX/CONFIG" "/PRIVATE/%u/FX/CONFIG"
    object-map  "/PRIVATE/FX/SALES/CONFIG/TOBOUSER/%1" "/PRIVATE/FX/SALES/CONFIG/TOBOUSER/%u/%1"
    object-map  "/PRIVATE/FX/SALES/CONFIG" "/PRIVATE/FX/%u/SALES/CONFIG"
  2. Add the following include patterns to the add-data-service block in your adapter project’s blade/Liberator/etc/rttpd.conf file:

    add-data-service
      ...
      include-pattern  "^/PRIVATE/[^/]+/FX/CONFIG"
      include-pattern  "^/PRIVATE/FX/[^/]+/SALES/CONFIG"
      include-pattern  "^/PRIVATE/FX/SALES/CONFIG/TOBOUSER/[^/]+/[^/]+"
      ...
    end-data-service

Grant permissions

To permit users to view the configuration subjects, add the following permissions to the global namespace:

Permission
Field Description

Action

VIEW

Product

^/PRIVATE/%u/FX/CONFIG

Namespace

Authorisation

ALLOW

Permission
Field Description

Action

VIEW

Product

^/PRIVATE/FX/[^/]+/SALES/CONFIG

Namespace

Authorisation

ALLOW

Permission
Field Description

Action

VIEW

Product

^/PRIVATE/FX/SALES/CONFIG/TOBOUSER/[^/]+/[^/]+

Namespace

Authorisation

ALLOW

For more information on permissioning, see:

Register configuration providers

Configuration is served by three providers, registered with the FXConfigAdapter class:

com.caplin.motif.datasourcecom.caplin.motif.fx.configCachedObjectProviderS, T extends SubjectInfoonRequest(subject : T, publishObject : Consumer)onDiscard(subject : T)FXConfigAdapterregisterConfigProvider(provider)registerSalesConfigProvider(provider)registerSalesTOBOConfigProvider(provider)MyConfigProviderConfig,ConfigSubjectInfoonRequest(subject : ConfigSubjectInfo, publishObject : Consumer<Config>)onDiscard(subject : ConfigSubjectInfo)MySalesConfigProviderSalesConfig,ConfigSubjectInfoonRequest(subject : ConfigSubjectInfo, publishObject : Consumer<SalesConfig>)onDiscard(subject : ConfigSubjectInfo)MyTOBOConfigProviderTOBOConfig,SalesTOBOConfigSubjectInfoonRequest(subject : SalesTOBOConfigSubjectInfo, publishObject : Consumer<TOBOConfig>)onDiscard(subject : SalesTOBOConfigSubjectInfo)registersregistersregisters

Which providers you need to register depends on the applications your adapter serves:

  • Adapter serves Caplin FX Professional:

    • FXConfigAdapter.registerConfigProvider()

  • Adapter serves Caplin FX Sales:

    • FXConfigAdapter.registerSalesConfigProvider()

    • FXConfigAdapter.registerTOBOConfigProvider()

The providers serve configuration implemented in the Config, SalesConfig, and TOBOConfig classes respectively:

com.caplin.motif.fx.configConfiggetFeatures() : FeaturessetFeatures(features : Features)SalesConfiggetCurrencyPairs() : Map<String, CurrencyPair>getFeatures() : FeaturessetCurrencyPairs(currencyPairs : Map<String, CurrencyPair>)setFeatures(features: Features)TOBOConfiggetAccounts() : List<Account>getCurrencyPairs() : Map<String, CurrencyPair>getFeatures() : FeaturesgetUserInfo() : UserInfosetAccounts(accounts : List<Account>)setCurrencyPairs(currencyPairs : Map<String, CurrencyPair>)setFeatures(features : Features)setUserInfo(userInfo : UserInfo)

Search field configuration for Historic Search is implemented in the Features class:

com.caplin.motif.fx.config.definitionsFeaturesgetHistoricSearch() : HistoricSearchsetHistoricSearch(historicSearch : HistoricSearch)HistoricSearchgetExecution() : HistoricSearchExecutionsetExecution(execution : HistoricSearchExecution)HistoricSearchExecutiongetSearchFields() : List<HistoricSearchField>setSearchFields(List<HistoricSearchFields> searchFields)HistoricSearchFieldgetDisplayName() : StringgetField() : StringgetOptions() : List<HistoricSearchDropdownOption>getType() : HistoricSearchSearchTypesetDisplayName(displayName : String)setField(field : String)setOptions(options : List<HistoricSearchDropdownOption>)setType(type : HistoricSearchSearchType)providesprovides

Follow the steps below to implement configuration for the Historic Search feature in Caplin FX Sales:

  1. Create implementations of CachedObjectProvider for SalesConfig and TOBOConfig:

    Implement CachedObjectProvider for SalesConfig object
    public class MySalesConfigProvider
        implements CachedObjectProvider<SalesConfig, ConfigSubjectInfo>
    {
      @Override
      public void onRequest(ConfigSubjectInfo subject, Consumer<SalesConfig> publishObject)
      {
        List<HistoricSearchField> searchFields = Arrays.asList(
                new HistoricSearchField()
                        .displayName("Trade ID")
                        .field("TradeId")
                        .type(HistoricSearchSearchType.TEXT),
                new HistoricSearchField()
                        .displayName("Amount")
                        .field("Amount")
                        .type(HistoricSearchSearchType.TEXT),
                new HistoricSearchField()
                        .displayName("Currency Pair")
                        .field("CurrencyPair")
                        .type(HistoricSearchSearchType.TEXT)
        );
    
        HistoricSearchExecution hse = new HistoricSearchExecution();
        hse.setSearchFields(searchFields);
    
        HistoricSearch hs = new HistoricSearch();
        hs.setExecution(hse);
    
        Features features = new Features();
        features.setHistoricSearch(hs);
    
        SalesConfig salesConfig = new SalesConfig();
        salesConfig.setFeatures(features);
    
        publishObject.accept(salesConfig);
      }
    
      @Override
      public void onDiscard(ConfigSubjectInfo subject)
      {
        //
      }
    }

    In the onRequest method of your CachedObjectProvider implementation for SalesConfig, instantiate a new SalesConfig object. Apply your Historic Search configuration to it, where each HistoricSearchField object represents a field in the Historic Search query builder. Publish the configured SalesConfig object using the Consumer instance passed to onRequest.

    Implement CachedObjectProvider for TOBOConfig object
    public class MyTOBOConfigProvider
        implements CachedObjectProvider<TOBOConfig, SalesTOBOConfigSubjectInfo>
    {
      @Override
      public void onRequest(SalesTOBOConfigSubjectInfo subject, Consumer<TOBOConfig> publishObject)
      {
        List<HistoricSearchField> searchFields = Arrays.asList(
                new HistoricSearchField()
                        .displayName("Trade ID")
                        .field("TradeId")
                        .type(HistoricSearchSearchType.TEXT),
                new HistoricSearchField()
                        .displayName("Amount")
                        .field("Amount")
                        .type(HistoricSearchSearchType.TEXT),
                new HistoricSearchField()
                        .displayName("Currency Pair")
                        .field("CurrencyPair")
                        .type(HistoricSearchSearchType.TEXT)
        );
    
        HistoricSearchExecution hse = new HistoricSearchExecution();
        hse.setSearchFields(searchFields);
    
        HistoricSearch hs = new HistoricSearch();
        hs.setExecution(hse);
    
        Features features = new Features();
        features.setHistoricSearch(hs);
    
        TOBOConfig toboConfig = new TOBOConfig();
        toboConfig.setFeatures(features);
    
        publishObject.accept(toboConfig);
      }
    
      @Override
      public void onDiscard(SalesTOBOConfigSubjectInfo subject)
      {
        //
      }
    }

    In the onRequest method of your CachedObjectProvider implementation for TOBOConfig, instantiate a new TOBOConfig object. Apply your Historic Search configuration to it, where each HistoricSearchField object represents a field in the Historic Search query builder. Publish the configured TOBOConfig object using the Consumer instance passed to onRequest.

  2. In the constructor of your config adapter, register new instances of MySalesConfigProvider and MyTOBOConfigProvider with your adapter’s FXConfigAdapter instance:

    public class MyConfigAdapter
    {
      private MyConfigAdapter(DataSource dataSource) throws IOException
      {
        final FXConfigAdapter fxAdapter = new FXConfigAdapter(dataSource);
    
        // Register sales configuration provider
        fxAdapter.registerSalesConfigProvider(new MySalesConfigProvider());
    
        // Register TOBO configuration provider
        fxAdapter.registerSalesTOBOConfigProvider(new MyTOBOConfigProvider());
    
        // ... other provider registrations
      }
    
      public static void main(final String[] args) throws IOException
      {
        final DataSource dataSource = DataSource.fromArgs(args);
        new MyConfigAdapter(dataSource);
        dataSource.start();
      }
    }

For a working example of a config adapter, see the Novo Config Adapter example in the FX Integration API Kit 3.55+.

Implementing the Configuration Service (version 3.54)

For FX Integration API 3.54, follow the instructions in the sections below:

Configure subject routing

Follow the steps below to include subject-routing configuration in your adapter for Liberator:

  1. Add the following object mapping to your adapter project’s blade/Liberator/etc/rttpd.conf file:

    object-map  "/PRIVATE/FX/CONFIG" "/PRIVATE/%u/FX/CONFIG"
    object-map  "/PRIVATE/FX/SALES/CONFIG/TOBOUSER/%1" "/PRIVATE/FX/SALES/CONFIG/TOBOUSER/%u/%1"
    object-map  "/PRIVATE/FX/SALES/CONFIG" "/PRIVATE/FX/%u/SALES/CONFIG"
  2. Add the following include patterns to the add-data-service block in your adapter project’s blade/Liberator/etc/rttpd.conf file:

    add-data-service
      ...
      include-pattern  "^/PRIVATE/[^/]+/FX/CONFIG"
      include-pattern  "^/PRIVATE/FX/[^/]+/SALES/CONFIG"
      include-pattern  "^/PRIVATE/FX/SALES/CONFIG/TOBOUSER/[^/]+/[^/]+"
      ...
    end-data-service

Grant permissions

To permit users to view the configuration subjects, add the following permissions to the global namespace:

Permission
Field Description

Action

VIEW

Product

^/PRIVATE/%u/FX/CONFIG

Namespace

Authorisation

ALLOW

Permission
Field Description

Action

VIEW

Product

^/PRIVATE/FX/[^/]+/SALES/CONFIG

Namespace

Authorisation

ALLOW

Permission
Field Description

Action

VIEW

Product

^/PRIVATE/FX/SALES/CONFIG/TOBOUSER/[^/]+/[^/]+

Namespace

Authorisation

ALLOW

For more information on permissioning, see:

Implement and register configuration providers

Configuration is served by three providers, registered with the FXConfigAdapter class:

com.caplin.motif.datasourcecom.caplin.motif.fx.configCachedObjectProviderS, T extends SubjectInfoonRequest(subject : T, publishObject : Consumer)onDiscard(subject : T)FXConfigAdapterregisterConfigProvider(provider)registerSalesConfigProvider(provider)registerSalesToboConfigProvider(provider)MyConfigProviderConfig,ConfigSubjectInfoonRequest(subject : ConfigSubjectInfo, publishObject : Consumer<Config>)onDiscard(subject : ConfigSubjectInfo)MySalesConfigProviderSalesConfig,ConfigSubjectInfoonRequest(subject : ConfigSubjectInfo, publishObject : Consumer<SalesConfig>)onDiscard(subject : ConfigSubjectInfo)MyToboConfigProviderToboConfig,SalesToboConfigSubjectInfoonRequest(subject : SalesToboConfigSubjectInfo, publishObject : Consumer<ToboConfig>)onDiscard(subject : SalesToboConfigSubjectInfo)registersregistersregisters

Which providers you need to register depends on the applications your adapter serves:

  • Adapter serves Caplin FX Professional:

    • FXConfigAdapter.registerConfigProvider()

  • Adapter serves Caplin FX Sales:

    • FXConfigAdapter.registerSalesConfigProvider()

    • FXConfigAdapter.registerToboConfigProvider()

The providers serve implementations of Config, SalesConfig, and ToboConfig respectively:

com.caplin.motif.fx.configConfiggetFeatures() : FeaturesSalesConfiggetFeatures() : FeaturesgetCurrencyPairs() : Map<String, CurrencyPair>ToboConfiggetAccounts() : List<Account>getFeatures() : FeaturesgetCurrencyPairs() : Map<String, CurrencyPair>getUserInfo() : UserInfoMyConfiggetFeatures() : FeaturesMySalesConfiggetFeatures() : FeaturesgetCurrencyPairs() : Map<String, CurrencyPair>MyToboConfiggetAccounts() : List<Account>getFeatures() : FeaturesgetCurrencyPairs() : Map<String, CurrencyPair>getUserInfo() : UserInfo

Search field configuration for Historic Search is implemented in the Features class:

com.caplin.motif.fx.config.definitionsFeaturesgetHistoricSearch() : HistoricSearchsetHistoricSearch(historicSearch : HistoricSearch)HistoricSearchgetExecution() : HistoricSearchExecutionsetExecution(execution : HistoricSearchExecution)HistoricSearchExecutiongetSearchFields() : List<HistoricSearchField>setSearchFields(List<HistoricSearchFields> searchFields)HistoricSearchFieldgetDisplayName() : StringgetField() : StringgetOptions() : List<HistoricSearchDropdownOption>getType() : HistoricSearchSearchTypesetDisplayName(displayName : String)setField(field : String)setOptions(options : List<HistoricSearchDropdownOption>)setType(type : HistoricSearchSearchType)providesprovides

Follow the steps below to implement configuration for the Historic Search feature in Caplin FX Sales:

  1. Create implementations of com.caplin.motif.fx.config.SalesConfig and com.caplin.motif.fx.config.ToboConfig:

    Implement SalesConfig
    public class MySalesConfig implements SalesConfig
    {
      @Override
      public Map<String, CurrencyPair> getCurrencyPairs()
      {
        return null;
      }
    
      @Override
      public Features getFeatures()
      {
        List<HistoricSearchField> searchFields = Arrays.asList(
          new HistoricSearchField()
            .displayName("Trade ID")
            .field("TradeId")
            .type(HistoricSearchSearchType.TEXT),
          new HistoricSearchField()
            .displayName("Amount")
            .field("Amount")
            .type(HistoricSearchSearchType.TEXT),
          new HistoricSearchField()
            .displayName("Currency Pair")
            .field("CurrencyPair")
            .type(HistoricSearchSearchType.TEXT)
        );
    
        HistoricSearchExecution hse = new HistoricSearchExecution();
        hse.setSearchFields(searchFields);
    
        HistoricSearch hs = new HistoricSearch();
        hs.setExecution(hse);
    
        Features features = new Features();
        features.setHistoricSearch(hs);
    
        return features;
      }
    }
    Implement ToboConfig
    public class MyToboConfig implements ToboConfig
    {
      @Override
      public List<Account> getAccounts()
      {
        return null;
      }
    
      @Override
      public Map<String, CurrencyPair> getCurrencyPairs()
      {
        return null;
      }
    
      @Override
      public Features getFeatures()
      {
        List<HistoricSearchField> searchFields = Arrays.asList(
          new HistoricSearchField()
            .displayName("Trade ID")
            .field("TradeId")
            .type(HistoricSearchSearchType.TEXT),
          new HistoricSearchField()
            .displayName("Amount")
            .field("Amount")
            .type(HistoricSearchSearchType.TEXT),
          new HistoricSearchField()
            .displayName("Currency Pair")
            .field("CurrencyPair")
            .type(HistoricSearchSearchType.TEXT)
        );
    
        HistoricSearchExecution hse = new HistoricSearchExecution();
        hse.setSearchFields(searchFields);
    
        HistoricSearch hs = new HistoricSearch();
        hs.setExecution(hse);
    
        Features features = new Features();
        features.setHistoricSearch(hs);
    
        return features;
      }
    
      @Override
      public UserInfo getUserInfo()
      {
        return null;
      }
    }

    Each HistoricSearchField object represents a field in the Historic Search query builder.

  2. Create implementations of CachedObjectProvider for SalesConfig and ToboConfig:

    Implement CachedObjectProvider for SalesConfig object
    public class MySalesConfigProvider
        implements CachedObjectProvider<SalesConfig, ConfigSubjectInfo>
    {
    
      @Override
      public void onRequest(ConfigSubjectInfo subject, Consumer<SalesConfig> publishObject)
      {
        publishObject.accept(new MySalesConfig());
      }
    
      @Override
      public void onDiscard(ConfigSubjectInfo subject)
      {
        //
      }
    }
    Implement CachedObjectProvider for ToboConfig object
    public class MyToboConfigProvider
        implements CachedObjectProvider<ToboConfig, SalesToboConfigSubjectInfo>
    {
      @Override
      public void onRequest(SalesToboConfigSubjectInfo subject, Consumer<ToboConfig> publishObject)
      {
        publishObject.accept(new MyToboConfig());
      }
    
      @Override
      public void onDiscard(SalesToboConfigSubjectInfo subject)
      {
        //
      }
    }
  3. In the constructor of your config adapter, register new instances of MySalesConfigProvider and MyToboConfigProvider with your adapter’s FXConfigAdapter instance:

    public class MyConfigAdapter
    {
      private MyConfigAdapter(DataSource dataSource) throws IOException
      {
        final FXConfigAdapter fxAdapter = new FXConfigAdapter(dataSource);
    
        // Register sales configuration provider
        fxAdapter.registerSalesConfigProvider(new MySalesConfigProvider());
    
        // Register TOBO configuration provider
        fxAdapter.registerSalesToboConfigProvider(new MyToboConfigProvider());
    
        // ... other provider registrations
      }
    
      public static void main(final String[] args) throws IOException
      {
        final DataSource dataSource = DataSource.fromArgs(args);
        new MyConfigAdapter(dataSource);
        dataSource.start();
      }
    }

For a working example of a config adapter, see the Novo Config Adapter example in the FX Integration API Kit 3.54.

Implementing the Configuration Service (versions 3.49–3.53)

For FX Integration API 3.49–3.53, follow the instructions in the sections below:

Configure subject routing

Follow the steps below to include subject-routing configuration in your adapter for Liberator:

  1. Add the following object mapping to your adapter project’s blade/Liberator/etc/rttpd.conf file:

    object-map "/PRIVATE/FX/CONFIG" "/PRIVATE/%u/FX/CONFIG"
  2. Add the following include pattern to the add-data-service block in your adapter project’s blade/Liberator/etc/rttpd.conf file:

    add-data-service
      ...
      include-pattern "^/PRIVATE/[^/]+/FX/CONFIG"
      ...
    end-data-service

Grant permissions

To permit users to view the configuration subject, add the following permission to the global namespace:

Permission
Field Description

Action

VIEW

Product

^/PRIVATE/%u/FX/CONFIG

Namespace

Authorisation

ALLOW

For more information on permissioning, see:

Implement and register configuration providers

In the FX Integration API versions 3.49–3.53, the Configuration Service provider is registered with the FXTradeAdapter class:

com.caplin.motif.datasourcecom.caplin.motif.fx.configcom.caplin.motif.fx.searchcom.caplin.motif.fx.tradingCachedObjectProviderS, T extends SubjectInfoinitialise(publisher : ObjectPublisher)onRequest(subject : S)onDiscard(subject : S)ConfiggetExecutionSearchConfig() : SearchConfigSearchConfigSearchConfig(searchFields : List<SearchField>)getSearchFields() : List<SearchField>SearchFieldgetDisplayName() : StringgetField() : StringgetOptions() : List<SearchDropdownOption>getType() : SearchTypesFXTradeAdapterregisterConfigProvider(provider)MyConfigProviderConfig,ConfigSubjectInfopublisher : ObjectPublisher<Config>initialise(publisher : ObjectPublisher<Config>)onRequest(subject : ConfigSubjectInfo)onDiscard(subject : ConfigSubjectInfo)MyConfiggetExecutionSearchConfig() : SearchConfigpublishesregistersprovides1*

Follow the steps below:

  1. Create an implementation of the com.caplin.motif.fx.config.Config interface:

    public class MyConfig implements Config
    {
      @Override
      public SearchConfig getExecutionSearchConfig()
      {
        return new SearchConfig(
          Arrays.asList(
            new SearchField("Trade ID", "TradeId", TEXT),
            new SearchField("Amount", "Amount", TEXT),
            new SearchField("Currency Pair", "CurrencyPair", TEXT)
          )
        );
      }
    }

    In MyConfig.getExecutionSearchConfig(), instantiate and return a new a SearchConfig object. Pass the SearchConfig constructor a java.util.List of SearchField objects, where each SearchField object represents a field in the Historic Search query builder.

  2. Create an implementation of the CachedObjectProvider interface:

    public class MyConfigProvider
        implements CachedObjectProvider<Config, ConfigSubjectInfo>
    {
      private ObjectPublisher<Config> publisher;
    
      @Override
      public void initialise(ObjectPublisher<Config> publisher)
      {
        this.publisher = publisher;
      }
    
      @Override
      public void onRequest(ConfigSubjectInfo subject)
      {
        publisher.publish(subject.getSubject(), new MyConfig());
      }
    
      @Override
      public void onDiscard(ConfigSubjectInfo subject)
      {
        //
      }
    }

    In MyConfigProvider.onRequest, publish an instance of MyConfig.

  3. In the constructor of your trade adapter, register a new instance of MyConfigProvider with your adapter’s FXTradeAdapter instance:

    public class MyTradeAdapter
    {
      private MyTradeAdapter(DataSource dataSource) throws IOException
      {
        final FXTradeAdapter fxAdapter = new FXTradeAdapter(dataSource);
    
        // Register configuration provider
        fxAdapter.registerConfigProvider(new MyConfigProvider());
    
        // ... other provider registrations
      }
    
      public static void main(final String[] args) throws IOException
      {
        final DataSource dataSource = DataSource.fromArgs(args);
        new MyTradeAdapter(dataSource);
        dataSource.start();
      }
    }

For a working example of a trade adapter with a registered config provider, see the Novo Trading Adapter example in the FX Integration API Kit 3.50–3.53.


See also: