Documentation for a newer release is available. View Latest

Create Settings

The following is an example of how to add a setting, in this case a DpsSampleSetting, that will be managed by the platform. You need to configure a domain project.

Domain Project Setup

In order to add a setting to be managed by the Dynamic Processing Settings Platform you need to create the following:

  • Setting Definition

  • Domain Object

  • Search Fields for the setting

Setting Definition

Specifies how to calculate the logical unique key for the setting and associates all the other components (domain object and search fields) to the setting concept

    @Bean
    public SettingDefinition<DpsSampleSetting> dpsSampleSettingDefinition() {
        return SettingDefinition.<DpsSampleSetting>builder()
                .settingType(DpsSampleSetting.SETTING_TYPE) (1)
                .collectionName("setting-" + DpsSampleSetting.SETTING_TYPE) (2)
                .idFunction(setting -> setting.getProcessingEntity() + "-" + setting.getPayload().getFullName()) (3)
                .historyEnabled(true) (4)
                .notificationsEnabled(false) (5)
                .payloadClass(DpsSampleSetting.class) (6)
                .payloadExample(payloadExample()) (7)
                .searchableFieldsClass(DpsSampleSettingSearchableFields.class) (8)
                .searchableFieldsExample(dpsSampleSettingQueryExample()) (9)
                .build();
    }

Setting definition can be described by using the following attributes:

1 setting type - (mandatory) defines setting type that must be unique across all settings. e.g. ibanplus
2 collection name - (mandatory) defines a collection name in which dynamic settings of this setting type will be stored
3 ID function - (mandatory) derives a logical unique key for a setting within the collection
4 history enabled - (optional) whether to track history for the setting changes or not. It’s enabled by default.
5 notifications enabled - (optional) whether to send Kafka notifications when setting is created, updated or deleted. It’s off by default as DPSv1 didn’t have this functionality.
6 payload class - (mandatory) describes the payload (structure) of this setting type
7 payload example - (mandatory) gives an example of the payload
8 search fields class - (optional) provides a lit of the searchable fields
9 searchable fields example - (conditionally mandatory) if search fields class is provided, examples must be provided too.

Domain Object

This will be the payload of a setting object and should contain all the relevant attributes for the setting you wish to define.

@Data
@Builder(toBuilder = true)
public class DpsSampleSetting {
    public static final SettingType SETTING_TYPE = SettingType.of("sample");

    @NotEmpty
    private String description;
    @NotBlank
    private String fullName;
    @NotNull
    @Pattern(regexp = "[0-9A-Z]{3}")
    private String statusPattern;

    @Min(5)
    @Max(50)
    private String stringWithMinMax;
    @Min(5)
    private String stringWithMin;
    @Max(50)
    private String stringWithMax;
    @Size(min = 6, max = 60)
    private String stringWithSize;
    @Size(min = 6)
    private String stringWithSizeMin;
    @Size(max = 60)
    private String stringWithSizeMax;

    @Min(5)
    @Max(50)
    private Integer numberWithMinMax;
    @Min(5)
    private Integer numberWithMin;
    @Max(50)
    private Integer numberWithMax;
    @Size(min = 6, max = 60)
    private Integer numberWithSize;
    @Size(min = 6)
    private Integer numberWithSizeMin;
    @Size(max = 60)
    private Integer numberWithSizeMax;
    @Valid
    private Limit defaultLimit;
    @Valid
    private List<Limit> limits;
    @Valid
    @Size(max = 10)
    private List<@Pattern(regexp = "[0-9A-Z]{3}") String> paymentTypeAllowedList;
    @Size(min = 1)
    @Valid
    private List<OnUsCurrency> onUsCurrencyList;
    private ParticipantType participantType;

    @Data
    @Builder
    public static class SuspenseAccount {
        @Size(max = 3, min = 3)
        private String currency;
    }

    @Data
    @Builder
    public static class OnUsCurrency {
        @Size(max = 3, min = 3)
        private String currency;
    }

    @Data
    @Builder
    public static class Limit {
        String id;
        LimitType limitType;
        Amount amount;
    }

    @Data
    @Builder
    public static class Amount {
        BigDecimal amountValue;
        @Size(min = 3, max = 3)
        String currency;
    }

    public enum LimitType {
        MAX_TRANSACTION_VALUE("MaxTransactionValue"),
        MIN_TRANSACTION_VALUE("MinTransactionValue");

        private final String label;

        LimitType(String label) {
            this.label = label;
        }
    }

    public enum ParticipantType {
        DIRECT, INDIRECT
    }
}

Searchable Fields

Each setting definition can be searched by common and setting-specific searchable fields. To see more about common searchable fields, go to Common Searchable Fields

Setting-specific searchable fields are defined via the SearchField and SearchableFields implementation.

The SearchField implementation contains a mapping between the searchable field constant and the path of the field in the domain object. The path must represent the exact position of the field in the domain object.

e.g.
DpsSampleSetting contains filed defaultLimit of type Limit.
Limit contains field amount of type Amount.
Amount contains field amountValue of type BigDecimal

This is why constant for searchable field DEFAULT_LIMIT_AMOUNT_VALUE has value: defaultLimit.amount.amountValue

package com.iconsolutions.ipf.demo.setting.sample.search;

import com.iconsolutions.ipf.dynamicsettings.v2.search.SearchField;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public enum DpsSampleSettingSearchFields implements SearchField {
    DESCRIPTION("description"),
    FULL_NAME("fullName"),
    DEFAULT_LIMIT_ID("defaultLimit.id"),
    DEFAULT_LIMIT_TYPE("defaultLimit.limitType"),
    DEFAULT_LIMIT_AMOUNT_VALUE("defaultLimit.amount.amountValue"),
    DEFAULT_LIMIT_AMOUNT_CURRENCY("defaultLimit.amount.currency"),
    LIMIT_TYPE("limits.limitType"),
    LIMIT_AMOUNT_VALUE("limits.amount.amountValue"),
    LIMIT_AMOUNT_CURRENCY("limits.amount.currency"),
    PARTICIPANT_TYPE("participantType"),
    ON_US_CURRENCY("onUsCurrencyList.currency"),
    LIMITS("limits"),
    LIMIT_TYPE("limitType"),
    AMOUNT("amount");

    private final String name;

    @Override
    public String getName() {
        return name;
    }
}

The SearchableFields implementation should extend CommonSearchableFields. This allows the setting to be searched by common searchable fields as well.

SearchableFields defines which query operator is used for each searchable field through Criterion build. Criterion is then converted to a database-specific query format.

@Data
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
public class DpsSampleSettingSearchableFields extends CommonSearchableFields {
    private String description;
    private String fullName;
    private String defaultLimitId;
    private DpsSampleSetting.LimitType defaultLimitType;
    private BigDecimal defaultLimitAmountValue;
    private String defaultLimitAmountCurrency;
    private DpsSampleSetting.LimitType limitType;
    private BigDecimal limitAmountValue;
    private String limitAmountCurrency;
    private DpsSampleSetting.ParticipantType participantType;
    private String onUsCurrency;

    @Override
    public List<Criterion> criteria() {
        final List<Criterion> criteria = new ArrayList<>(super.criteria());
        if (description != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.DESCRIPTION, description));
        }
        if (fullName != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.FULL_NAME, fullName));
        }
        if (defaultLimitId != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.DEFAULT_LIMIT_ID, defaultLimitId));
        }
        if (defaultLimitType != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.DEFAULT_LIMIT_TYPE, defaultLimitType));
        }
        if (defaultLimitAmountValue != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.DEFAULT_LIMIT_AMOUNT_VALUE, defaultLimitAmountValue));
        }
        if (defaultLimitAmountCurrency != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.DEFAULT_LIMIT_AMOUNT_CURRENCY, defaultLimitAmountCurrency));
        }
        if (limitType != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.LIMIT_TYPE, limitType));
        }
        if (limitAmountValue != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.LIMIT_AMOUNT_VALUE, limitAmountValue));
        }
        if (limitAmountCurrency != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.LIMIT_AMOUNT_CURRENCY, limitAmountCurrency));
        }
        if (participantType != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.PARTICIPANT_TYPE, participantType));
        }
        if (onUsCurrency != null) {
            criteria.add(Criterion.equalTo(DpsSampleSettingSearchFields.ON_US_CURRENCY, onUsCurrency));
        }
        if (limitType != null && amount != null) {
            criteria.add(Criterion.elemMatch(DpsSampleSettingSearchFields.LIMITS, List.of(
                    Criterion.equalTo(DpsSampleSettingSearchFields.LIMIT_TYPE, limitType),
                    Criterion.equalTo(DpsSampleSettingSearchFields.AMOUNT, amount)
            )));
        }
        return criteria;
    }
}