etreschenkov 2024-10-02 13:48:33 +03:00
parent cc48b21066
commit b87f5dbb80
12 changed files with 483 additions and 0 deletions

View file

@ -0,0 +1,37 @@
package ru.spcex.clearing.securities.config.validation;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
import ru.spcex.clearing.securities.errors.SecuritiesError;
import ru.spcex.clearing.securities.validation.rule.RatesValidationRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
@Configuration
public class RatesValidationConfig {
@Bean("ratesValidator")
public Function<RatesNewRequest, IValidator> ratesValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return ratesRequest -> {
ImdgValidationContext<RatesNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(ratesRequest);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Rates);
return new ValidatorImpl<>(context,
FieldRequiredRule.instance("currencyPairUd", RatesNewRequest::getCurrencyPairId, SecuritiesError.RequiredFieldIsEmpty),
FieldRequiredRule.instance("value", RatesNewRequest::getValue, SecuritiesError.RequiredFieldIsEmpty),
FieldRequiredRule.instance("settlementType", RatesNewRequest::getValueDate, SecuritiesError.RequiredFieldIsEmpty),
RatesValidationRule.CHECK_ON_EXIST
);
};
}
}

View file

@ -0,0 +1,37 @@
package ru.spcex.clearing.securities.config.validation;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterNewRequest;
import ru.spcex.clearing.securities.errors.SecuritiesError;
import ru.spcex.clearing.securities.validation.rule.RiskParameterValidationRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl;
@Configuration
public class RiskParameterValidationConfig {
@Bean("riskParameterValidator")
public Function<RiskParameterNewRequest, IValidator> riskParameterValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
return riskParameter -> {
ImdgValidationContext<RiskParameterNewRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(riskParameter);
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_RiskParameter);
return new ValidatorImpl<>(context,
FieldRequiredRule.instance("currencyPairUd", RiskParameterNewRequest::getCurrencyPairId, SecuritiesError.RequiredFieldIsEmpty),
FieldRequiredRule.instance("value", RiskParameterNewRequest::getValue, SecuritiesError.RequiredFieldIsEmpty),
FieldRequiredRule.instance("settlementType", RiskParameterNewRequest::getSettlementType, SecuritiesError.RequiredFieldIsEmpty),
RiskParameterValidationRule.CHECK_ON_EXIST
);
};
}
}

View file

@ -21,6 +21,8 @@ public enum SecuritiesError implements IErrorEnumId {
ListingOnMMSCreatedBySystem(1021L), // Информиция об инструментах Денежного рынка на режимах добавляется автоматически.
ListingOnMMSUpdatedBySystem(1022L), // Информиция об инструментах Денежного рынка на режимах изменяется автоматически.
ListingOnMMSDeletedBySystem(1023L), // Информиция об инструментах Денежного рынка на режимах блокируется автоматически.
RiskParameterAlreadyExist(1024L),
RatesAlreadyExist(1025L)
;
private final Long id;

View file

@ -0,0 +1,54 @@
package ru.spcex.clearing.securities.service.facade;
import java.time.Instant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.security.RiskParameter;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterNewRequest;
import ru.spcex.platform.classes.base.interfaces.IClearingFacade;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
@Service
public class RiskParameterFacade implements IClearingFacade {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgId idGenerator;
private final ImdgProvider imdgProvider;
private final Imdg<RiskParameter> riskParameterImdg;
public RiskParameterFacade(ImdgProvider imdgProvider) {
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.imdgProvider = imdgProvider;
this.riskParameterImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RiskParameter, RiskParameter.class);
}
/**
* Создает clientCode, TCR и опционально TCRList, если указаны валюты.
*/
public void createRiskParameter(RiskParameterNewRequest request) {
log.trace("Start process creating new client code");
RiskParameter riskParameter = new RiskParameter();
riskParameter.setCurrencyPairId(request.getCurrencyPairId());
riskParameter.setSettlementType(request.getSettlementType());
riskParameter.setValue(request.getValue());
riskParameter.setWorkflowStatus(request.getStatus());
riskParameter.setCreated(Instant.now());
riskParameterImdg.insert(riskParameter);
log.debug("successfully processed, new risk_parameter id {}", riskParameter.getId());
}
@Override
public void lock() {
}
@Override
public void unlock() {
}
}

View file

@ -0,0 +1,92 @@
package ru.spcex.clearing.securities.service.listeners;
import java.util.Optional;
import java.util.function.Function;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterUpdateRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.securities.service.facade.RiskParameterFacade;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.validation.IValidator;
@Service
public class RiskParameterMessageListener extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final ImdgProvider imdgProvider;
private final RiskParameterFacade riskParameterFacade;
private final Function<RiskParameterNewRequest, IValidator> riskParameterValidator;
private final UserRoleVerification userRoleVerification;
private final IMessageResolver messageResolver;
public RiskParameterMessageListener(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
RiskParameterFacade riskParameterFacade,
Function<RiskParameterNewRequest, IValidator> riskParameterValidator,
UserRoleVerification userRoleVerification,
IMessageResolver messageResolver) {
super(kafkaQueue, kafkaProducer);
this.imdgProvider = imdgProvider;
this.riskParameterFacade = riskParameterFacade;
this.riskParameterValidator = riskParameterValidator;
this.userRoleVerification = userRoleVerification;
this.messageResolver = messageResolver;
}
@Override
public void afterPropertiesSet() {
imdgProvider.waitAvailable();
//from backend-api requests
callback(RiskParameterNewRequest.class)
.setFunction(this::riskParameterNew)
.forDestination(Consts.DESTINATION_RISK_PARAMETER_NEW, callbacks::put);
callback(RiskParameterUpdateRequest.class)
.setFunction(this::riskParameterUpdate)
.forDestination(Consts.DESTINATION_RISK_PARAMETER_UPDATE, callbacks::put);
init();
}
private RequestInfoUpdate riskParameterNew(BaseRequest<RiskParameterNewRequest> riskParameterRequest) {
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(riskParameterRequest);
if (requestInfoUpdate != null) return requestInfoUpdate;
RiskParameterNewRequest request = riskParameterRequest.getRequestPayload();
IValidator validator = riskParameterValidator.apply(request);
Optional<EnumMessage> error = validator.tillFirstError();
if (error.isPresent()) {
String errMsg = messageResolver.resolve(error.get());
return new RequestInfoUpdate()
.setId(riskParameterRequest.getId())
.setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error)
.setMessage(errMsg);
}
riskParameterFacade.createRiskParameter(request);
return null;
}
private RequestInfoUpdate riskParameterUpdate(BaseRequest<RiskParameterUpdateRequest> clientCodeNewRequest) {
// RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(clientCodeNewRequest);
// if (requestInfoUpdate != null) return requestInfoUpdate;
// RiskParameterUpdateRequest request = clientCodeNewRequest.getRequestPayload();
// ValidationResult validationResult = clientCodeValidator.checkBackendNewRequest(request);
// if (!validationResult.isValid()) {
// return makeErrorResponse(clientCodeNewRequest, validationResult);
// }
//
// clientCodeFacade.createClientCode(request, validationResult.validator());
return null;
}
}

View file

@ -0,0 +1,41 @@
package ru.spcex.clearing.securities.validation.rule;
import java.util.Optional;
import ru.clearing.classes.statics.data.security.Rates;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
import ru.spcex.clearing.securities.errors.SecuritiesError;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
public enum RatesValidationRule implements IValidationRule<ImdgValidationContext<RatesNewRequest>> {
CHECK_ON_EXIST() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RatesNewRequest> context) {
RatesNewRequest action = context.getValidatedObject();
Imdg<Rates> imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_Rates, Rates.class);
ImdgPredicateBuilder predicateBuilder = imdgDictionary.predicateBuilder();
Rates rates = imdgDictionary.getFirstObjectByPredicate(
predicateBuilder.and(
predicateBuilder.equals("currencyPairId", action.getCurrencyPairId()),
predicateBuilder.equals("valueDate", action.getValueDate()),
predicateBuilder.equals("workflowStatus", Status.Active.getKey())
)
);
if (rates != null) {
return of(SecuritiesError.RatesAlreadyExist, action.getCurrencyPairId());
}
return empty();
}
};
@Override
public String ruleName() {
return "MmsNewValidationRule." + name();
}
}

View file

@ -0,0 +1,42 @@
package ru.spcex.clearing.securities.validation.rule;
import java.util.Optional;
import ru.clearing.classes.statics.data.security.RiskParameter;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.security.RiskParameterNewRequest;
import ru.spcex.clearing.securities.errors.SecuritiesError;
import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidationRule;
public enum RiskParameterValidationRule implements IValidationRule<ImdgValidationContext<RiskParameterNewRequest>> {
CHECK_ON_EXIST() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RiskParameterNewRequest> context) {
RiskParameterNewRequest action = context.getValidatedObject();
Imdg<RiskParameter> imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_RiskParameter, RiskParameter.class);
ImdgPredicateBuilder predicateBuilder = imdgDictionary.predicateBuilder();
RiskParameter riskParameter = imdgDictionary.getFirstObjectByPredicate(
predicateBuilder.and(
predicateBuilder.equals("currencyPairId", action.getCurrencyPairId()),
predicateBuilder.equals("settlementType", action.getSettlementType()),
predicateBuilder.equals("workflowStatus", Status.Active.getKey())
)
);
if (riskParameter != null) {
return of(SecuritiesError.RiskParameterAlreadyExist, action.getCurrencyPairId());
}
return empty();
}
};
@Override
public String ruleName() {
return "RiskParameterValidationRule." + name();
}
}

View file

@ -120,6 +120,11 @@ public interface Consts {
String NOTIFICATION_UPDATE = "notification-update";
String PAIR_SDF = "pair-sdf";
String DESTINATION_RISK_PARAMETER_NEW = "risk-parameter-new";
String DESTINATION_RISK_PARAMETER_UPDATE = "risk-parameter-update";
String DESTINATION_RATES_NEW = "rates-new";
String DESTINATION_RATES_UPDATE = "rates-update";
String DESTINATION_SDF08_NEW = "s-df-08-new";
String DESTINATION_SDF02_NEW = "s-df-02-new";

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.platform.messaging.domain.cud.security;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
import java.time.LocalDate;
public class RatesNewRequest {
@JsonProperty
private BigDecimal value;
@JsonProperty
private LocalDate valueDate;
@JsonProperty
private Long currencyPairId;
@JsonProperty
private String status;
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public LocalDate getValueDate() {
return valueDate;
}
public void setValueDate(LocalDate valueDate) {
this.valueDate = valueDate;
}
public Long getCurrencyPairId() {
return currencyPairId;
}
public void setCurrencyPairId(Long currencyPairId) {
this.currencyPairId = currencyPairId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View file

@ -0,0 +1,38 @@
package ru.spcex.clearing.platform.messaging.domain.cud.security;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
public class RatesUpdateRequest {
@JsonProperty
private Long id;
@JsonProperty
private BigDecimal value;
@JsonProperty
private String status;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View file

@ -0,0 +1,48 @@
package ru.spcex.clearing.platform.messaging.domain.cud.security;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
public class RiskParameterNewRequest {
@JsonProperty
private BigDecimal value;
@JsonProperty
private String settlementType;
@JsonProperty
private Long currencyPairId;
@JsonProperty
private String status;
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public String getSettlementType() {
return settlementType;
}
public void setSettlementType(String settlementType) {
this.settlementType = settlementType;
}
public Long getCurrencyPairId() {
return currencyPairId;
}
public void setCurrencyPairId(Long currencyPairId) {
this.currencyPairId = currencyPairId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}

View file

@ -0,0 +1,38 @@
package ru.spcex.clearing.platform.messaging.domain.cud.security;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
public class RiskParameterUpdateRequest {
@JsonProperty
private Long id;
@JsonProperty
private BigDecimal value;
@JsonProperty
private String status;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}