Crear Configuraciones

A continuación se presenta un ejemplo de cómo agregar una configuración, en este caso un DpsSampleSetting, que será gestionada por la plataforma. Debe configurar un proyecto de dominio.

Configuración del Proyecto de Dominio

Para añadir una configuración que sea gestionada por el Dynamic Processing Settings Plataforma que necesita crear lo siguiente:

  • Definición de Configuración

  • Objeto de Dominio

  • Campos de búsqueda para la configuración

Definición de Configuración

Especifica cómo calcular la clave lógica única para la configuración y asocia todos los demás componentes (objeto de dominio y campos de búsqueda) al concepto de configuración.

    @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();
    }

La definición de configuración puede ser descrita utilizando los siguientes atributos:

1 tipo de configuración-(mandatorio) define el tipo de configuración que debe ser único en todas las configuraciones. p. ej. ibanplus
2 nombre de la colección-(mandatorio) define un nombre de colección en el que dynamic settings de este tipo de configuración se almacenará
3 Función de ID-(mandatorio) deriva una clave única lógica para una configuración dentro de la colección
4 historia habilitada-(opcional) si se debe rastrear el historial de los cambios de configuración o no. Está habilitado por defecto.
5 notifications habilitado-(opcional) si enviar Kafka notifications cuando se crea, actualiza o elimina una configuración. Está desactivado por defecto ya que DPSv1 no contaba con esta funcionalidad.
6 clase de carga útil-(mandatorio) describe la carga útil (estructura) de este tipo de configuración
7 ejemplo de carga útil-(mandatorio) proporciona un ejemplo de la carga útil
8 clase de campos de búsqueda-(opcional) proporciona una lista de los campos buscables
9 ejemplo de campos buscables-(condicionalmente obligatorio) si se proporciona la clase de campos de búsqueda, también se deben proporcionar ejemplos.

Objeto de Dominio

Este será el contenido de un objeto de configuración y debe contener todos los atributos relevantes para la configuración que desea definir.

@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
    }
}

Campos buscables

Cada definición de configuración puede ser buscada por campos de búsqueda comunes y específicos de la configuración. Para ver más sobre los campos de búsqueda comunes, vaya a Campos de búsqueda comunes

Los campos de búsqueda específicos de la configuración se definen a través de la implementación de SearchField y SearchableFields.

La implementación de SearchField contiene un mapping entre la constante del campo buscable y la ruta del campo en el objeto de dominio. La ruta debe representar la posición exacta del campo en el objeto de dominio.

e.g.
DpsSampleSetting contiene el campo defaultLimit de tipo Limit.
El límite contiene un campo de tipo Monto.
La cantidad contiene el campo amountValue de tipo BigDecimal.

Esta es la razón por la cual la constante para el campo buscable DEFAULT_LIMIT_AMOUNT_VALUE tiene el valor: 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;
    }
}

La implementación de SearchableFields debe extender CommonSearchableFields. Esto permite que la configuración sea buscada por campos de búsqueda comunes también.

SearchableFields define qué operador de consulta se utiliza para cada campo buscable a través de la construcción de Criterion. Criterion se convierte entonces en un formato de consulta específico de la base de datos.

@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;
    }
}