Documentation for a newer release is available. View Latest

Client Library

Independientemente del método de despliegue, el módulo cliente que invoca CSM Reachability debe importar csm-reachability-client-port y usar las interfaces proporcionadas por ClientPort para invocar la lógica de CSM Reachability.

Se debe añadir la siguiente dependencia de Maven:

<dependency>
    <groupId>com.iconsolutions.ipf.payments.csm.reachability</groupId>
    <artifactId>csm-reachability-client-port</artifactId>
    <version>${csm-reachability-api.version}</version>
</dependency>

CSM Reachability actualmente soporta la implementación de conector de las interfaces del client port.

Se debe añadir la siguiente dependencia de Maven:

<dependency>
    <groupId>com.iconsolutions.ipf.payments.csm.reachability</groupId>
    <artifactId>csm-reachability-client-connector</artifactId>
    <version>${csm-reachability-api.version}</version>
</dependency>

How to use client library

Un ejemplo de cómo puede usarse el client port:

import com.iconsolutions.ipf.csmreachability.client.port.v2.BicValidationClientPort;
import com.iconsolutions.ipf.csmreachability.client.port.v2.IbanDeconstructClientPort;
import com.iconsolutions.ipf.csmreachability.client.port.v2.PartyEntitiesClientPort;
import com.iconsolutions.ipf.csmreachability.client.port.v2.ProcessingEntityClientPort;
import com.iconsolutions.ipf.csmreachability.client.port.v2.SelectCsmAgentClientPort;
import com.iconsolutions.ipf.csmreachability.client.port.v2.SettlementAgentClientPort;
import com.iconsolutions.ipf.csmreachability.client.port.v2.ValidateCsmReachabilityClientPort;
import com.iconsolutions.ipf.csmreachability.client.port.v2.ValidateIntraEntityReachabilityClientPort;
import com.iconsolutions.ipf.csmreachability.dto.v2.IbanServiceResponseDto;
import com.iconsolutions.ipf.core.connector.api.Response;
import com.iconsolutions.ipf.core.shared.domain.context.ProcessingContext;
import com.iconsolutions.ipf.core.shared.domain.context.SupportingContext;
...

@AllArgsConstructor
public class DecisionLibraryAdapter implements DecisionLibraryPort {

    private final BicValidationClientPort bicValidationClientPort;
    private final IbanDeconstructClientPort ibanDeconstructClientPort;
    private final PartyEntitiesClientPort partyEntitiesClientPort;
    private final ProcessingEntityClientPort processingEntityClientPort;
    private final SelectCsmAgentClientPort selectCsmAgentClientPort;
    private final SettlementAgentClientPort settlementAgentClientPort;
    private final ValidateCsmReachabilityClientPort validateCsmReachabilityClientPort;
    private final ValidateIntraEntityReachabilityClientPort validateIntraEntityReachabilityClientPort;
    private final DetermineProcessingEntityClientPort determineProcessingEntityClientPort;
    ...

    @Override
    public Outcomes performBicValidation(Parameters decision) {
        String bic = decision.getBic();

        return bicValidationClientPort.deconstruct(
                processingContext,
                supportingContext,
                bic
        ).thenApply(DecisionLibraryAdapter::handleBicValidationResponse);
    }

    private static Outcomes handleBicValidationResponse(Response<Boolean> response) {
        if (response.getValue()) {
            return continueProcessing();
        } else {
            return Outcomes.BIC_NOT_VALID;
        }
    }

    private static Outcomes continueProcessing() {
        ...
    }
}

How to configure client library

Como se mencionó, la implementación del cliente soporta el transporte mediante conector HTTP. Cada API connector puede configurarse de forma independiente, pero también proporcionamos una configuración por defecto del conector.

Configuración del cliente HTTP:

Esta configuración está obsoleta y se eliminará en versiones futuras.
csm-reachability-api.http.client {
    host = "localhost"
    port = "8080"
}

Esta configuración se ha cambiado para seguir el estándar de IPF, pero sigue siendo compatible con el antiguo nombre:

ipf.csm-reachability-api {
  http.client {
    host = "localhost"
    port = "8080"
  }
  http.client = ${?csm-reachability-api.http.client}
}

Configuración de resiliencia:

Esta configuración está obsoleta y se eliminará en versiones futuras.
csm-reachability-api.resiliency-settings {
    # Determines the maximum number of retries to be made. Note that this includes the first failed attempt.
    max-attempts = 2
    # Retry if HTTP error code is in the list
    retryable-status-codes = [500, 503]
    # Determines the minimum number of calls (within a sliding window period) that need to be made before the circuit breaker can calculate the error rate to determine the transport health.
    minimum-number-of-calls = 10
}

Cambiado para seguir el estándar de IPF, pero sigue siendo compatible con el nombre antiguo. Tenemos la configuración por defecto del conector que cada conector hereda y puede sobrescribir:

ipf.csm-reachability-api {
  connector {
    get-party-entities = ${ipf.csm-reachability-api.default-connector}
    get-processing-entities = ${ipf.csm-reachability-api.default-connector}
    bic-validation = ${ipf.csm-reachability-api.default-connector}
    iban-deconstruct = ${ipf.csm-reachability-api.default-connector}
    validate-csm-reachability = ${ipf.csm-reachability-api.default-connector}
    validate-intra-entity-reachability = ${ipf.csm-reachability-api.default-connector}
    select-csm-agent = ${ipf.csm-reachability-api.default-connector}
    get-settlement-agent = ${ipf.csm-reachability-api.default-connector}
    determine-processing-entity = ${ipf.csm-reachability-api.default-connector}
  }

  default-connector {
    resiliency-settings {
      # Determines the maximum number of retries to be made. Note that this includes the first failed attempt.
      max-attempts = 2
      # Retry if HTTP error code is in the list
      retryable-status-codes = [500, 503]
      # Determines the minimum number of calls (within a sliding window period) that need to be made before the circuit breaker can calculate the error rate to determine the transport health.
      minimum-number-of-calls = 10
    }
    resiliency-settings = ${?csm-reachability-api.resiliency-settings}
  }
}

SelectCsmAgentConnector

Ejemplo de uso:

SelectCsmAgentCriteria req = SelectCsmAgentCriteria.builder()
                .processingEntity("001")
                .paymentType("RTGS")
                .serviceLevel("SVC")
                .transferCurrency("EUR")
                .transferAmount(BigDecimal.valueOf(900))
                .asOfDate(LocalDate.of(2024, 5, 1))
                .counterPartyIdentifiers(List.of(CounterPartyIdentifier.builder()
                    .identifier("identifier")
                    .identifierType("identifierType")
                    .identifierSubType("subType")
                    .identifierCountry("GB")
                    .build()))
                .returnEnhancedCSMData(false)
                .returnAllMatchingCSMAgents(false)
                .build();
 CompletionStage<Response<SelectCsmAgentDto>> res = selectCsmAgentClientPort.getCsmAgent(processingContext, supportingContext, req);

PartyEntitiesConnector

Ejemplo de uso:

GetPartyEntitiesCriteria req = GetPartyEntitiesCriteria.builder()
                .entityIdentifierType(EntityIdentifierType.BIC)
                .entityIdentifier("MDBALT22XXX")
                .entityIdentifierSubType("ACCOUNT_ISSUING_BIC")
                .entityCountry("LT")
                .entityDataSource("Bank_Directory_Plus")
                .build();
CompletionStage<Response<PartyEntitiesDto>> res = partyEntitiesClientPort.getPartyEntities(processingContext, supportingContext, req);

ProcessingEntityConnector

Ejemplo de uso:

GetProcessingEntityCriteria req = GetProcessingEntityCriteria.builder()
                .processingEntity("001")
                .includeGenericProcessingSettings(true)
                .settingCategories(List.of("PROCESSING_ENTITY_ACCOUNTS", "SUPPORTED_TRANSFER_CURRENCIES"))
                .build();
CompletionStage<Response<ProcessingEntitiesDto>> res = processingEntitiesClientPort.getProcessingEntity(processingContext, supportingContext, req);

DetermineProcessingEntityConnector

Ejemplo de uso cuando el tipo de identificador es NCC y tiene país en la petición, deriveDirectParticipant por defecto es false:

DetermineProcessingEntityCriteria req = DetermineProcessingEntityCriteria.builder()
                .entityIdentifier("309790")
                .identifierType("NCC")
                .identifierSubType("GBDSC")
                .entityCountry("GB")
                .build();
CompletionStage<Response<DeterminedProcessingEntity>> res = determineProcessingEntityClientPort.determineProcessingEntity(processingContext, supportingContext, req);

Ejemplo de uso cuando el tipo de identificador es NCC y no tiene país en la petición, deriveDirectParticipant por defecto es false:

DetermineProcessingEntityCriteria req = DetermineProcessingEntityCriteria.builder()
                .entityIdentifier("309790")
                .identifierType("NCC")
                .identifierSubType("GBDSC")
                .build();
CompletionStage<Response<DeterminedProcessingEntity>> res = determineProcessingEntityClientPort.determineProcessingEntity(processingContext, supportingContext, req);

Ejemplo de uso cuando el tipo de identificador es BIC, deriveDirectParticipant por defecto es false:

DetermineProcessingEntityCriteria req = DetermineProcessingEntityCriteria.builder()
                .entityIdentifier("LOYDGBGB2LXXX")
                .identifierType("BIC")
                .identifierSubType("SCHEME_MEMBERSHIP_BIC")
                .build();
CompletionStage<Response<DeterminedProcessingEntity>> res = determineProcessingEntityClientPort.determineProcessingEntity(processingContext, supportingContext, req);

Ejemplo de uso cuando el tipo de identificador es LEI, deriveDirectParticipant por defecto es false:

DetermineProcessingEntityCriteria req = DetermineProcessingEntityCriteria.builder()
                .entityIdentifier("39846232")
                .identifierType("LEI")
                .entityCountry("GB")
                .build();
CompletionStage<Response<DeterminedProcessingEntity>> res = determineProcessingEntityClientPort.determineProcessingEntity(processingContext, supportingContext, req);

Ejemplo de uso cuando el tipo de identificador es IBAN, deriveDirectParticipant por defecto es false:

DetermineProcessingEntityCriteria req = DetermineProcessingEntityCriteria.builder()
                .entityIdentifier("CH7177823000123456998")
                .identifierType("IBAN")
                .build();
CompletionStage<Response<DeterminedProcessingEntity>> res = determineProcessingEntityClientPort.determineProcessingEntity(processingContext, supportingContext, req);

Ejemplo de uso cuando el tipo de identificador es BIC y deriveDirectParticipant es true, se debe establecer csmAgentId:

DetermineProcessingEntityCriteria req = DetermineProcessingEntityCriteria.builder()
                .entityIdentifier("LOYDGBGB2LXXX")
                .identifierType("BIC")
                .identifierSubType("SCHEME_MEMBERSHIP_BIC")
                .deriveDirectParticipant(true)
                .csmAgentId("TIPS")
                .build();
CompletionStage<Response<DeterminedProcessingEntity>> res = determineProcessingEntityClientPort.determineProcessingEntity(processingContext, supportingContext, req);

IbanDeconstructConnector

Ejemplo de uso:

String req = "IBAN0123456789";

CompletionStage<Response<IbanServiceResponseDto>> res = ibanDeconstructClientPort.deconstruct(processingContext, supportingContext, request);

BicValidationConnector

Ejemplo de uso:

CompletionStage<Response<Boolean>> res = bicValidationClientPort.validateBic(processingContext, supportingContext, "MDBALT22XXX");

SettlementAgentConnector

Ejemplo de uso:

GetSettlementAgentsCriteria req = GetSettlementAgentsCriteria.builder()
        .processingEntity("001")
        .agentIdentifier("MDBALT22XXX")
        .agentIdentifierType(EntityIdentifierType.BIC)
        .agentIdentifierSubType("ACCOUNT_ISSUING_BIC")
        .agentCountry("LT")
        .transferCurrency("EUR")
        .transferDirection(TransferDirection.INBOUND)
        .includeSettlementSettings(true)
        .includeClearingSettings(true)
        .build();
CompletionStage<Response<SettlementAgentsResponseDto>> res = settlementAgentClientPort.getSettlementAgent(processingContext, supportingContext, req);

ValidateCsmReachabilityConnector

Ejemplo de uso:

ValidateCsmReachabilityCriteria req = ValidateCsmReachabilityCriteria.builder()
                .processingEntity("PE_001")
                .agentUniqueId("testCsmAgentId")
                .counterPartyIdentifiers(List.of(
                        CounterPartyIdentifier.builder()
                                .identifier("IBAN0123456789")
                                .identifierType("IBAN")
                                .build(),
                        CounterPartyIdentifier.builder()
                                .identifier("csmParId")
                                .identifierType("BIC")
                                .build()
                ))
                .transferCurrency("GBP")
                .transferAmount(BigDecimal.TEN)
                .asOfDate(LocalDate.of(2024, 5, 1))
                .build();

CompletionStage<Response<ValidateCsmReachabilityDto>> res = validateCsmReachabilityClientPort.validate(processingContext, supportingContext, req);

ValidateIntraEntityReachabilityConnector

Ejemplo de uso:

ValidateIntraEntityReachabilityCriteria req = ValidateIntraEntityReachabilityCriteria.builder()
                .processingEntity("PE_001")
                .counterPartyIdentifier(
                        CounterPartyIdentifier.builder()
                                .identifier("IBAN0123456789")
                                .identifierType("IBAN")
                                .build()
                )
                .transferCurrency("GBP")
                .build();

CompletionStage<Response<ValidateIntraEntityReachabilityDto>> res = validateIntraEntityReachabilityClientPort.validate(processingContext, supportingContext, req);