This commit is contained in:
parent
c70874b179
commit
2a365606fa
8 changed files with 203 additions and 15 deletions
|
|
@ -28,7 +28,7 @@ public class RatesNewAction implements IAction<RatesNewRequest> {
|
||||||
RatesNewRequest request = new RatesNewRequest();
|
RatesNewRequest request = new RatesNewRequest();
|
||||||
request.setValue(this.value);
|
request.setValue(this.value);
|
||||||
request.setValueDate(this.valueDate);
|
request.setValueDate(this.valueDate);
|
||||||
request.setCurrencyPairId(this.currencyPairId);
|
request.setCurrencyId(this.currencyPairId);
|
||||||
request.setStatus(this.status);
|
request.setStatus(this.status);
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ import io.swagger.annotations.ApiModelProperty;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import ru.spcex.clearing.backendapi.domain.actions.IAction;
|
import ru.spcex.clearing.backendapi.domain.actions.IAction;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.ActionType;
|
import ru.spcex.clearing.platform.messaging.domain.ActionType;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesUpdateRequest;
|
||||||
|
|
||||||
public class RatesUpdateAction implements IAction<RatesNewRequest> {
|
public class RatesUpdateAction implements IAction<RatesUpdateRequest> {
|
||||||
|
|
||||||
@ApiModelProperty(hidden = true)
|
@ApiModelProperty(hidden = true)
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
|
|
@ -20,8 +20,9 @@ public class RatesUpdateAction implements IAction<RatesNewRequest> {
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RatesNewRequest toRequest() {
|
public RatesUpdateRequest toRequest() {
|
||||||
RatesNewRequest request = new RatesNewRequest();
|
RatesUpdateRequest request = new RatesUpdateRequest();
|
||||||
|
request.setId(this.id);
|
||||||
request.setValue(this.value);
|
request.setValue(this.value);
|
||||||
request.setStatus(this.status);
|
request.setStatus(this.status);
|
||||||
return request;
|
return request;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ public class RiskParameterUpdateAction implements IAction<RiskParameterUpdateReq
|
||||||
@Override
|
@Override
|
||||||
public RiskParameterUpdateRequest toRequest() {
|
public RiskParameterUpdateRequest toRequest() {
|
||||||
RiskParameterUpdateRequest request = new RiskParameterUpdateRequest();
|
RiskParameterUpdateRequest request = new RiskParameterUpdateRequest();
|
||||||
|
request.setId(this.id);
|
||||||
request.setValue(this.value);
|
request.setValue(this.value);
|
||||||
request.setStatus(this.status);
|
request.setStatus(this.status);
|
||||||
return request;
|
return request;
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,14 @@ import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import ru.clearing.classes.statics.data.security.RiskParameter;
|
||||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesUpdateRequest;
|
||||||
import ru.spcex.clearing.securities.errors.SecuritiesError;
|
import ru.spcex.clearing.securities.errors.SecuritiesError;
|
||||||
import ru.spcex.clearing.securities.validation.rule.RatesValidationRule;
|
import ru.spcex.clearing.securities.validation.rule.RatesValidationRule;
|
||||||
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
|
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
|
||||||
|
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
|
||||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
import ru.spcex.platform.imdg.api.Imdg;
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||||
|
|
@ -19,19 +22,37 @@ import ru.spcex.platform.utils.validation.ValidatorImpl;
|
||||||
@Configuration
|
@Configuration
|
||||||
public class RatesValidationConfig {
|
public class RatesValidationConfig {
|
||||||
|
|
||||||
@Bean("ratesValidator")
|
@Bean("ratesNewValidator")
|
||||||
public Function<RatesNewRequest, IValidator> ratesValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
public Function<RatesNewRequest, IValidator> ratesNewValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
||||||
return ratesRequest -> {
|
return ratesRequest -> {
|
||||||
ImdgValidationContext<RatesNewRequest> context = new ImdgValidationContext<>();
|
ImdgValidationContext<RatesNewRequest> context = new ImdgValidationContext<>();
|
||||||
context.setValidatedObject(ratesRequest);
|
context.setValidatedObject(ratesRequest);
|
||||||
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
|
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
|
||||||
addImdg.accept(IMDGDistributedNames.Map_Rates);
|
addImdg.accept(IMDGDistributedNames.Map_Rates);
|
||||||
return new ValidatorImpl<>(context,
|
return new ValidatorImpl<>(context,
|
||||||
FieldRequiredRule.instance("currencyPairUd", RatesNewRequest::getCurrencyPairId, SecuritiesError.RequiredFieldIsEmpty),
|
FieldRequiredRule.instance("currencyPairUd", RatesNewRequest::getCurrencyId, SecuritiesError.RequiredFieldIsEmpty),
|
||||||
FieldRequiredRule.instance("value", RatesNewRequest::getValue, SecuritiesError.RequiredFieldIsEmpty),
|
FieldRequiredRule.instance("value", RatesNewRequest::getValue, SecuritiesError.RequiredFieldIsEmpty),
|
||||||
FieldRequiredRule.instance("settlementType", RatesNewRequest::getValueDate, SecuritiesError.RequiredFieldIsEmpty),
|
FieldRequiredRule.instance("settlementType", RatesNewRequest::getValueDate, SecuritiesError.RequiredFieldIsEmpty),
|
||||||
RatesValidationRule.CHECK_ON_EXIST
|
RatesValidationRule.CHECK_ON_EXIST
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean("ratesUpdateValidator")
|
||||||
|
public Function<RatesUpdateRequest, IValidator> ratesUpdateValidator(Map<String, Imdg<? extends SpcexObjectBase>> imdgForValidation) {
|
||||||
|
return ratesUpdateRequest -> {
|
||||||
|
ImdgValidationContext<RatesUpdateRequest> context = new ImdgValidationContext<>();
|
||||||
|
context.setValidatedObject(ratesUpdateRequest);
|
||||||
|
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
|
||||||
|
addImdg.accept(IMDGDistributedNames.Map_Rates);
|
||||||
|
return new ValidatorImpl<>(context,
|
||||||
|
IdPresentRule.instance("id",
|
||||||
|
RatesUpdateRequest::getId,
|
||||||
|
IMDGDistributedNames.Map_Rates,
|
||||||
|
RiskParameter.class,
|
||||||
|
SecuritiesError.RequiredFieldIsEmpty,
|
||||||
|
SecuritiesError.RequiredFieldIsEmpty)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
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.Rates;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesNewRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesUpdateRequest;
|
||||||
|
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 RatesFacade implements IClearingFacade {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
private final ImdgId idGenerator;
|
||||||
|
private final ImdgProvider imdgProvider;
|
||||||
|
private final Imdg<Rates> ratesImdg;
|
||||||
|
|
||||||
|
public RatesFacade(ImdgProvider imdgProvider) {
|
||||||
|
this.idGenerator = imdgProvider.getImdgIdGenerator();
|
||||||
|
this.imdgProvider = imdgProvider;
|
||||||
|
this.ratesImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Rates, Rates.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Создает clientCode, TCR и опционально TCRList, если указаны валюты.
|
||||||
|
*/
|
||||||
|
public void createRates(RatesNewRequest request) {
|
||||||
|
log.trace("Start process creating new rates");
|
||||||
|
Rates rates = new Rates();
|
||||||
|
|
||||||
|
rates.setCurrencyId(request.getCurrencyId());
|
||||||
|
rates.setValue(request.getValue());
|
||||||
|
rates.setValueDate(request.getValueDate());
|
||||||
|
rates.setWorkflowStatus(request.getStatus());
|
||||||
|
rates.setCreated(Instant.now());
|
||||||
|
|
||||||
|
ratesImdg.insert(rates);
|
||||||
|
log.debug("successfully processed, new rates id {}", rates.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateRates(RatesUpdateRequest request) {
|
||||||
|
log.trace("Start process update rates");
|
||||||
|
Rates ratesForUpdate = ratesImdg.getSingleObjectByID(request.getId());
|
||||||
|
|
||||||
|
ratesForUpdate.setValue(request.getValue());
|
||||||
|
ratesForUpdate.setWorkflowStatus(request.getStatus());
|
||||||
|
|
||||||
|
ratesImdg.update(ratesForUpdate);
|
||||||
|
log.debug("successfully processed, updated rates id {}", ratesForUpdate.getId());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void lock() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unlock() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
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.RatesNewRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.domain.cud.security.RatesUpdateRequest;
|
||||||
|
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||||
|
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||||
|
import ru.spcex.clearing.securities.service.facade.RatesFacade;
|
||||||
|
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 RatesMessageListener extends QueueConsumer implements InitializingBean {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
private final ImdgProvider imdgProvider;
|
||||||
|
private final RatesFacade ratesFacade;
|
||||||
|
private final Function<RatesNewRequest, IValidator> ratesNewValidator;
|
||||||
|
private final Function<RatesUpdateRequest, IValidator> ratesUpdateValidator;
|
||||||
|
private final UserRoleVerification userRoleVerification;
|
||||||
|
private final IMessageResolver messageResolver;
|
||||||
|
|
||||||
|
public RatesMessageListener(Consumer<String, Object> kafkaQueue,
|
||||||
|
Producer<String, Object> kafkaProducer,
|
||||||
|
ImdgProvider imdgProvider,
|
||||||
|
RatesFacade ratesFacade,
|
||||||
|
Function<RatesNewRequest, IValidator> ratesNewValidator,
|
||||||
|
Function<RatesUpdateRequest, IValidator> ratesUpdateValidator,
|
||||||
|
UserRoleVerification userRoleVerification,
|
||||||
|
IMessageResolver messageResolver) {
|
||||||
|
super(kafkaQueue, kafkaProducer);
|
||||||
|
this.imdgProvider = imdgProvider;
|
||||||
|
this.ratesFacade = ratesFacade;
|
||||||
|
this.ratesNewValidator = ratesNewValidator;
|
||||||
|
this.ratesUpdateValidator = ratesUpdateValidator;
|
||||||
|
this.userRoleVerification = userRoleVerification;
|
||||||
|
this.messageResolver = messageResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() {
|
||||||
|
imdgProvider.waitAvailable();
|
||||||
|
|
||||||
|
//from backend-api requests
|
||||||
|
callback(RatesNewRequest.class)
|
||||||
|
.setFunction(this::ratesNew)
|
||||||
|
.forDestination(Consts.DESTINATION_RATES_NEW, callbacks::put);
|
||||||
|
callback(RatesUpdateRequest.class)
|
||||||
|
.setFunction(this::ratesUpdate)
|
||||||
|
.forDestination(Consts.DESTINATION_RATES_UPDATE, callbacks::put);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestInfoUpdate ratesNew(BaseRequest<RatesNewRequest> ratesNewRequest) {
|
||||||
|
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(ratesNewRequest);
|
||||||
|
if (requestInfoUpdate != null) return requestInfoUpdate;
|
||||||
|
RatesNewRequest request = ratesNewRequest.getRequestPayload();
|
||||||
|
IValidator validator = ratesNewValidator.apply(request);
|
||||||
|
Optional<EnumMessage> error = validator.tillFirstError();
|
||||||
|
if (error.isPresent()) {
|
||||||
|
String errMsg = messageResolver.resolve(error.get());
|
||||||
|
return new RequestInfoUpdate()
|
||||||
|
.setId(ratesNewRequest.getId())
|
||||||
|
.setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error)
|
||||||
|
.setMessage(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ratesFacade.createRates(request);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestInfoUpdate ratesUpdate(BaseRequest<RatesUpdateRequest> ratesUpdateRequest) {
|
||||||
|
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(ratesUpdateRequest);
|
||||||
|
if (requestInfoUpdate != null) return requestInfoUpdate;
|
||||||
|
RatesUpdateRequest request = ratesUpdateRequest.getRequestPayload();
|
||||||
|
IValidator validator = ratesUpdateValidator.apply(request);
|
||||||
|
Optional<EnumMessage> error = validator.tillFirstError();
|
||||||
|
if (error.isPresent()) {
|
||||||
|
String errMsg = messageResolver.resolve(error.get());
|
||||||
|
return new RequestInfoUpdate()
|
||||||
|
.setId(ratesUpdateRequest.getId())
|
||||||
|
.setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error)
|
||||||
|
.setMessage(errMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ratesFacade.updateRates(request);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,13 +22,13 @@ public enum RatesValidationRule implements IValidationRule<ImdgValidationContext
|
||||||
ImdgPredicateBuilder predicateBuilder = imdgDictionary.predicateBuilder();
|
ImdgPredicateBuilder predicateBuilder = imdgDictionary.predicateBuilder();
|
||||||
Rates rates = imdgDictionary.getFirstObjectByPredicate(
|
Rates rates = imdgDictionary.getFirstObjectByPredicate(
|
||||||
predicateBuilder.and(
|
predicateBuilder.and(
|
||||||
predicateBuilder.equals("currencyPairId", action.getCurrencyPairId()),
|
predicateBuilder.equals("currencyPairId", action.getCurrencyId()),
|
||||||
predicateBuilder.equals("valueDate", action.getValueDate()),
|
predicateBuilder.equals("valueDate", action.getValueDate()),
|
||||||
predicateBuilder.equals("workflowStatus", Status.Active.getKey())
|
predicateBuilder.equals("workflowStatus", Status.Active.getKey())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
if (rates != null) {
|
if (rates != null) {
|
||||||
return of(SecuritiesError.RatesAlreadyExist, action.getCurrencyPairId());
|
return of(SecuritiesError.RatesAlreadyExist, action.getCurrencyId());
|
||||||
}
|
}
|
||||||
return empty();
|
return empty();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ public class RatesNewRequest {
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private LocalDate valueDate;
|
private LocalDate valueDate;
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private Long currencyPairId;
|
private Long currencyId;
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
|
|
@ -31,12 +31,12 @@ public class RatesNewRequest {
|
||||||
this.valueDate = valueDate;
|
this.valueDate = valueDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getCurrencyPairId() {
|
public Long getCurrencyId() {
|
||||||
return currencyPairId;
|
return currencyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrencyPairId(Long currencyPairId) {
|
public void setCurrencyId(Long currencyId) {
|
||||||
this.currencyPairId = currencyPairId;
|
this.currencyId = currencyId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStatus() {
|
public String getStatus() {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue