This commit is contained in:
AKurakin 2023-06-19 16:46:21 +03:00
parent 699a40f157
commit c98087ccd6
7 changed files with 402 additions and 350 deletions

View file

@ -60,7 +60,7 @@ public class CouponPeriodService extends QueueConsumer implements InitializingBe
init();
}
private RequestInfoUpdate newCouponPeriod(BaseRequest<CouponPeriodNewRequest> userRequest) {
public synchronized RequestInfoUpdate newCouponPeriod(BaseRequest<CouponPeriodNewRequest> userRequest) {
CouponPeriodNewRequest req = userRequest.getRequestPayload();
RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.couponPeriodNewValidator());
@ -79,7 +79,7 @@ public class CouponPeriodService extends QueueConsumer implements InitializingBe
return null; // default success
}
private RequestInfoUpdate updateCouponPeriod(BaseRequest<CouponPeriodUpdateRequest> userRequest) {
public synchronized RequestInfoUpdate updateCouponPeriod(BaseRequest<CouponPeriodUpdateRequest> userRequest) {
CouponPeriodUpdateRequest req = userRequest.getRequestPayload();
log.debug("updateCurrency received id = {}", req.getId());

View file

@ -65,7 +65,7 @@ public class FixedIncomeCashFlowService extends QueueConsumer implements Initial
init();
}
public RequestInfoUpdate fixedIncomeCashFlowNew(BaseRequest<FixedIncomeCashFlowNewRequest> userRequest) {
public synchronized RequestInfoUpdate fixedIncomeCashFlowNew(BaseRequest<FixedIncomeCashFlowNewRequest> userRequest) {
log.debug("FixedIncomeCashFlowNewRequest received {}", userRequest.getId());
RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, fixedIncomeCashFlowNewRequestValidator);
@ -85,7 +85,7 @@ public class FixedIncomeCashFlowService extends QueueConsumer implements Initial
return null;
}
public RequestInfoUpdate fixedIncomeCashFlowUpdate(BaseRequest<FixedIncomeCashFlowUpdateRequest> userRequest) {
public synchronized RequestInfoUpdate fixedIncomeCashFlowUpdate(BaseRequest<FixedIncomeCashFlowUpdateRequest> userRequest) {
log.debug("FixedIncomeCashFlowUpdateRequest received {}", userRequest.getId());
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest);

View file

@ -0,0 +1,395 @@
package ru.spcex.clearing.securities.service.cud;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.instrument.issue.CouponPeriod;
import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity;
import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeCashFlow;
import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity;
import ru.clearing.classes.statics.data.misc.Listing;
import ru.clearing.classes.statics.data.security.Security;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.company.SecurityFondGatewayRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.*;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.securities.validation.ValidationProvider;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.CompanySymbol;
import ru.spcex.platform.enumeration.InstrumentType;
import ru.spcex.platform.enumeration.UserRole;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Service
public class GatewaySecurityService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<FixedIncomeSecurity> fixedIncomeSecurityImdg;
private final Imdg<EquitySecurity> equitySecurityImdg;
private final Imdg<Listing> listingImdg;
private final Imdg<CouponPeriod> couponPeriodImdg;
private final Imdg<FixedIncomeCashFlow> fixedIncomeCashFlowImdg;
private final Imdg<CompanySymbols> companySymbolsImdg;
private final ImdgProvider imdgProvider;
private final ImdgId idGenerator;
final FixedIncomeSecurityService fixedIncomeSecurityService;
final EquitySecurityService equitySecurityService;
final ListingService listingService;
final CouponPeriodService couponPeriodService;
final FixedIncomeCashFlowService fixedIncomeCashFlowService;
private final ValidationProvider validation;
private final UserRoleVerification userRoleVerification;
private final ValidationHelper validationHelper;
@Autowired
public GatewaySecurityService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
ValidationProvider validation,
UserRoleVerification userRoleVerification,
ValidationHelper validationHelper,
FixedIncomeSecurityService fixedIncomeSecurityService,
EquitySecurityService equitySecurityService,
ListingService listingService,
CouponPeriodService couponPeriodService,
FixedIncomeCashFlowService fixedIncomeCashFlowService) {
super(kafkaQueue, kafkaProducer);
this.validation = validation;
this.fixedIncomeSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class);
this.equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class);
this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
this.couponPeriodImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CouponPeriod, CouponPeriod.class);
this.fixedIncomeCashFlowImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeCashFlow, FixedIncomeCashFlow.class);
this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
this.imdgProvider = imdgProvider;
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin);
this.validationHelper = validationHelper;
this.fixedIncomeSecurityService = fixedIncomeSecurityService;
this.equitySecurityService = equitySecurityService;
this.listingService = listingService;
this.couponPeriodService = couponPeriodService;
this.fixedIncomeCashFlowService = fixedIncomeCashFlowService;
}
@Override
public void afterPropertiesSet() {
callback(SecurityFondGatewayRequest.class)
.setFunction(this::newSecurities)
.forDestination(Consts.DESTINATION_SECURITY_GATEWAY, callbacks::put);
imdgProvider.waitAvailable();
init();
}
Long findCompany(SecurityFondGatewayRequest byReq) {
String byUuid = byReq.getUuid();
if (byUuid == null) {
log.warn("Request without company UUID");
return null;
}
Collection<CompanySymbols> companySymbols = companySymbolsImdg.getCollectionObjectsByFieldValues(
Map.of(
"companySymbol", CompanySymbol.UUID.getKey(),
"companySymbolValue", byUuid
)
);
if (companySymbols.isEmpty()) {
log.warn("Company not found with uuid={}", byUuid);
return null;
} else if (companySymbols.size() > 1) {
log.warn("For {} = {} found {} company_symbol, use first", CompanySymbol.UUID.getKey(), byUuid, companySymbols.size());
}
// Проверяем, что в базе помимо реквизита есть компания
Long companyId = companySymbols.iterator().next().getCompanyId();
// Company company = companyImdg.getSingleObjectByID(companyId);
return companyId;
}
<T extends Security> T findSecurityBySecuritySymbol(Imdg<T> imdg, String securitySymbol) {
Collection<T> securities = imdg.getCollectionObjectsByFieldValues(
Map.of("securitySymbol", securitySymbol)
);
if (securities.isEmpty()) {
log.trace("{} not found by securitySymbol={}", imdg.getMapName(), securitySymbol);
return null;
} else {
if (securities.size() > 1)
log.warn("Found {} {} by securitySymbol={}", securities.size(), imdg.getMapName(), securitySymbol);
T security = securities.iterator().next();
log.trace("Found {}[{}] with securitySymbol={}", imdg.getMapName(), security.getId(), securitySymbol);
return security;
}
}
private RequestInfoUpdate newSecurities(BaseRequest<SecurityFondGatewayRequest> baseRequest) {
log.debug("SecurityFondGatewayRequest id={} received", baseRequest.getId());
SecurityFondGatewayRequest req = baseRequest.getRequestPayload();
Long companyId = findCompany(req);//issuerId findCompany
if (companyId == null) {
log.debug("CompanyId (issuer) not found.");
} else {
log.debug("CompanyId (issuer) found: {}", companyId);
}
// ImdgTransaction transaction = imdgProvider.newTransaction(); todo transaction
Security security = null;
if (req.getSecurity() != null && InstrumentType.BOND.equalsByKey(req.getSecurityType())) {
FixedIncomeSecurityNewRequest fixedIncomeRequest = (FixedIncomeSecurityNewRequest) req.getSecurity();
fixedIncomeRequest.setIssuerId(companyId);
log.trace("FixedIncomeSecurityNewRequest - BOND");
String securitySymbol = fixedIncomeRequest.getSecuritySymbol();
security = findSecurityBySecuritySymbol(fixedIncomeSecurityImdg, securitySymbol);
if (security == null) {
RequestInfoUpdate resp = fixedIncomeSecurityService.newFixedIncome(wrapRequest(baseRequest, fixedIncomeRequest, null));
validateReply(companyId, "newFixedIncome", resp);
security = findSecurityBySecuritySymbol(fixedIncomeSecurityImdg, securitySymbol);
} else {
FixedIncomeSecurityUpdateRequest updateRequest = toUpdateRequest(security, fixedIncomeRequest);
RequestInfoUpdate resp = fixedIncomeSecurityService.updateFixedIncome(wrapRequest(baseRequest, updateRequest, ActionType.UPDATE));
validateReply(companyId, "newFixedIncome", resp);
}
}
if (req.getSecurity() != null && InstrumentType.EQTY.equalsByKey(req.getSecurityType())) {
EquitySecurityNewRequest equityRequest = (EquitySecurityNewRequest) req.getSecurity();
equityRequest.setIssuerId(companyId);
log.trace("EquitySecurityNewRequest - FOND");
String securitySymbol = equityRequest.getSecuritySymbol();
security = findSecurityBySecuritySymbol(equitySecurityImdg, securitySymbol);
if (security == null) {
RequestInfoUpdate resp = equitySecurityService.newEquity(wrapRequest(baseRequest, equityRequest, null));
validateReply(companyId, "newFixedIncome", resp);
security = findSecurityBySecuritySymbol(equitySecurityImdg, securitySymbol);
} else {
EquitySecurityUpdateRequest updateRequest = toUpdateRequest(security, equityRequest);
RequestInfoUpdate resp = equitySecurityService.updateEquity(wrapRequest(baseRequest, updateRequest, ActionType.UPDATE));
validateReply(companyId, "newFixedIncome", resp);
}
}
Long securityId;
if (security == null) {
log.error("No new or update security.");
securityId = null;
} else {
securityId = security.getId();
log.debug("Use security {}.id={} ({} {})", security.getClass().getSimpleName(), securityId, security.getInstrumentType(), security.getShortName());
}
if (req.getListing() == null)
req.setListing(new ArrayList<>());
if (req.getCouponPeriods() == null)
req.setCouponPeriods(new ArrayList<>());
if (req.getFixedIncomesCashFlow() == null)
req.setFixedIncomesCashFlow(new ArrayList<>());
for (Object partRequestO : req.getListing()) {
ListingNewRequest partRequest = (ListingNewRequest) partRequestO;
partRequest.setSecurityId(securityId);
Listing existListing = findListing(partRequest);
if (existListing == null) {
log.trace("For company[{}] do new Listing", companyId);
RequestInfoUpdate replyI = listingService.newListing(wrapRequest(baseRequest, partRequest, ActionType.NEW));
validateReply(companyId, "ListingNew", replyI);
} else {
log.trace("For company[{}] do update Listing[{}]", companyId, existListing.getId());
ListingUpdateRequest partUpdateRequest = toUpdateRequest(existListing, partRequest);
RequestInfoUpdate replyI = listingService.updateListing(wrapRequest(baseRequest, partUpdateRequest, ActionType.UPDATE));
validateReply(companyId, "ListingUpdate", replyI);
}
}
for (Object partRequestO : req.getCouponPeriods()) {
CouponPeriodNewRequest partRequest = (CouponPeriodNewRequest) partRequestO;
partRequest.setSecurityId(securityId);
CouponPeriod existCouponPeriod = findCouponPeriod(partRequest);
if (existCouponPeriod == null) {
log.trace("For company[{}] do new CouponPeriod", companyId);
RequestInfoUpdate replyI = couponPeriodService.newCouponPeriod(wrapRequest(baseRequest, partRequest, ActionType.NEW));
validateReply(companyId, "CouponPeriodNew", replyI);
} else {
log.trace("For company[{}] do update CouponPeriod[{}]", companyId, existCouponPeriod.getId());
CouponPeriodUpdateRequest partUpdateRequest = toUpdateRequest(existCouponPeriod, partRequest);
RequestInfoUpdate replyI = couponPeriodService.updateCouponPeriod(wrapRequest(baseRequest, partUpdateRequest, ActionType.UPDATE));
validateReply(companyId, "CouponPeriodUpdate", replyI);
}
}
for (Object partRequestO : req.getFixedIncomesCashFlow()) {
FixedIncomeCashFlowNewRequest partRequest = (FixedIncomeCashFlowNewRequest) partRequestO;
partRequest.setSecuritySymbol(String.valueOf(securityId)); // не getSecuritySymbol
FixedIncomeCashFlow existFixedIncomeCashFlow = findFixedIncomeCashFlow(partRequest);
if (existFixedIncomeCashFlow == null) {
log.trace("For company[{}] do new FixedIncomeCashFlow", companyId);
RequestInfoUpdate replyI = fixedIncomeCashFlowService.fixedIncomeCashFlowNew(wrapRequest(baseRequest, partRequest, ActionType.NEW));
validateReply(companyId, "FixedIncomeCashFlowNew", replyI);
} else {
log.trace("For company[{}] do update FixedIncomeCashFlow[{}]", companyId, existFixedIncomeCashFlow.getId());
FixedIncomeCashFlowUpdateRequest partUpdateRequest = toUpdateRequest(existFixedIncomeCashFlow, partRequest);
RequestInfoUpdate replyI = fixedIncomeCashFlowService.fixedIncomeCashFlowUpdate(wrapRequest(baseRequest, partUpdateRequest, ActionType.UPDATE));
validateReply(companyId, "FixedIncomeCashFlowUpdate", replyI);
}
}
log.debug("successfully processed, request id {}", baseRequest.getId());
return null; // default success
}
Listing findListing(ListingNewRequest byRequest) {
Map<String, Comparable<?>> query = new HashMap<>();
query.put("securityId", byRequest.getSecurityId());
query.put("market", byRequest.getMarket());
Listing existListing = listingImdg.getSingleObjectByFieldValues(query);
if (existListing == null)
log.trace("Listing not found by query {}", query);
else
log.trace("Found listing.id={} by query {}", existListing.getId(), query);
return existListing;
}
CouponPeriod findCouponPeriod(CouponPeriodNewRequest byRequest) {
if (byRequest.getSecurityId() == null)
return null;
CouponPeriod existCouponPeriod = couponPeriodImdg.getSingleObjectByFieldValues(Map.of("securityId", byRequest.getSecurityId()));
if (existCouponPeriod == null)
log.trace("CouponPeriod not found by securityId={}", byRequest.getSecurityId());
else
log.trace("CouponPeriod.id={} found by securityId={}", existCouponPeriod.getId(), byRequest.getSecurityId());
return existCouponPeriod;
}
FixedIncomeCashFlow findFixedIncomeCashFlow(FixedIncomeCashFlowNewRequest byRequest) {
Long securityId;
try {
securityId = Long.valueOf(byRequest.getSecuritySymbol());
} catch (NumberFormatException | NullPointerException nan) {
log.error("Not a number \"{}\": {}", byRequest.getSecuritySymbol(), nan.toString());
return null;
}
FixedIncomeCashFlow existFixedIncomeCashFlow = fixedIncomeCashFlowImdg.getSingleObjectByFieldValues(Map.of("securityId", securityId));
if (existFixedIncomeCashFlow == null)
log.trace("FixedIncomeCashFlow not found by securityId={}", securityId);
else
log.trace("FixedIncomeCashFlow.id={} found by securityId={}", existFixedIncomeCashFlow.getId(), securityId);
return existFixedIncomeCashFlow;
}
FixedIncomeSecurityUpdateRequest toUpdateRequest(Security security, FixedIncomeSecurityNewRequest newRequest) {
FixedIncomeSecurityUpdateRequest updateRequest = new FixedIncomeSecurityUpdateRequest();
updateRequest.setId(security.getId());
if (newRequest.getIssuerId() == null && security.getIssuerId() != null) {
newRequest.setIssuerId(security.getIssuerId());
log.debug("Issuer exist in security[{}].issuerId={}, do leave them.", security.getId(), security.getIssuerId());
}
updateRequest.setSecuritySymbol(newRequest.getSecuritySymbol());
updateRequest.setShortName(newRequest.getShortName());
updateRequest.setFullName(newRequest.getFullName());
updateRequest.setIsin(newRequest.getIsin());
updateRequest.setBondType(newRequest.getBondType());
updateRequest.setLotSize(newRequest.getLotSize());
updateRequest.setNominalValue(newRequest.getNominalValue());
updateRequest.setNominalCurrency(newRequest.getNominalCurrency());
updateRequest.setMaturityDate(newRequest.getMaturityDate());
updateRequest.setCoupon(newRequest.getCoupon());
updateRequest.setCouponFrequency(newRequest.getCouponFrequency());
updateRequest.setIssuerId(newRequest.getIssuerId());
updateRequest.setShortNameEng(newRequest.getShortNameEng());
updateRequest.setFullNameEng(newRequest.getFullNameEng());
updateRequest.setWorkflowStatus(newRequest.getWorkflowStatus());
updateRequest.setInstrumentType(newRequest.getInstrumentType());
return updateRequest;
}
EquitySecurityUpdateRequest toUpdateRequest(Security security, EquitySecurityNewRequest newRequest) {
EquitySecurityUpdateRequest updateRequest = new EquitySecurityUpdateRequest();
updateRequest.setId(security.getId());
updateRequest.setSecuritySymbol(newRequest.getSecuritySymbol());
updateRequest.setShortName(newRequest.getShortName());
updateRequest.setFullName(newRequest.getFullName());
updateRequest.setIsin(newRequest.getIsin());
updateRequest.setShareType(newRequest.getShareType());
updateRequest.setLotSize(newRequest.getLotSize());
updateRequest.setIssuerId(newRequest.getIssuerId());
updateRequest.setShortNameEng(newRequest.getShortNameEng());
updateRequest.setFullNameEng(newRequest.getFullNameEng());
updateRequest.setWorkflowStatus(newRequest.getWorkflowStatus());
updateRequest.setInstrumentType(newRequest.getInstrumentType());
return updateRequest;
}
ListingUpdateRequest toUpdateRequest(Listing listing, ListingNewRequest newRequest) {
ListingUpdateRequest updateRequest = new ListingUpdateRequest();
updateRequest.setId(listing.getId());
updateRequest.setSecurityId(newRequest.getSecurityId());
updateRequest.setMarket(newRequest.getMarket());
updateRequest.setLotSize(newRequest.getLotSize());
updateRequest.setTradingCurrency(newRequest.getTradingCurrency());
updateRequest.setWorkflowStatus(newRequest.getWorkflowStatus());
return updateRequest;
}
CouponPeriodUpdateRequest toUpdateRequest(CouponPeriod couponPeriod, CouponPeriodNewRequest newRequest) {
CouponPeriodUpdateRequest updateRequest = new CouponPeriodUpdateRequest();
updateRequest.setId(couponPeriod.getId());
updateRequest.setSecurityId(newRequest.getSecurityId());
updateRequest.setCouponRate(newRequest.getCouponRate());
updateRequest.setNumber(newRequest.getNumber());
updateRequest.setPeriodEndDate(newRequest.getPeriodEndDate());
updateRequest.setPeriodStartDate(newRequest.getPeriodStartDate());
return updateRequest;
}
FixedIncomeCashFlowUpdateRequest toUpdateRequest(FixedIncomeCashFlow fxedIncomeCashFlow, FixedIncomeCashFlowNewRequest newRequest) {
FixedIncomeCashFlowUpdateRequest updateRequest = new FixedIncomeCashFlowUpdateRequest();
updateRequest.setId(fxedIncomeCashFlow.getId());
updateRequest.setSecuritySymbol(newRequest.getSecuritySymbol());
updateRequest.setAccruedCoupon(newRequest.getAccruedCoupon());
updateRequest.setNominalValue(newRequest.getNominalValue());
updateRequest.setNumber(newRequest.getNumber());
updateRequest.setValueDate(newRequest.getValueDate());
return updateRequest;
}
private <T> BaseRequest<T> wrapRequest(BaseRequest<?> template, T payload, ActionType action) {
BaseRequest<T> r = new BaseRequest<>();
r.setId(template.getId());
if (action == null) {
r.setActionType(template.getActionType());
} else {
r.setActionType(action);
}
r.setUserId(template.getUserId());
r.setCorrelationId(template.getCorrelationId());
r.setRequestPayload(payload);
return r;
}
private void validateReply(Long companyId, String process, RequestInfoUpdate replyI) {
if (replyI != null && replyI.getMessage() != null) {
log.warn("Error process {} for companyId={}: {}", process, companyId, replyI.getMessage());
}
}
}

View file

@ -75,7 +75,7 @@ public class ListingService extends QueueConsumer implements InitializingBean {
init();
}
private synchronized RequestInfoUpdate newListing(BaseRequest<ListingNewRequest> userRequest) {
public synchronized RequestInfoUpdate newListing(BaseRequest<ListingNewRequest> userRequest) {
ListingNewRequest req = userRequest.getRequestPayload();
log.debug("newListing received, id={}", userRequest.getId());
@ -110,7 +110,7 @@ public class ListingService extends QueueConsumer implements InitializingBean {
return null; // default success
}
private synchronized RequestInfoUpdate updateListing(BaseRequest<ListingUpdateRequest> userRequest) {
public synchronized RequestInfoUpdate updateListing(BaseRequest<ListingUpdateRequest> userRequest) {
ListingUpdateRequest req = userRequest.getRequestPayload();
log.debug("updateListing received id = {}", req.getId());

View file

@ -1,277 +0,0 @@
package ru.spcex.clearing.securities.service.cud;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity;
import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity;
import ru.clearing.classes.statics.data.misc.Listing;
import ru.clearing.classes.statics.data.security.Security;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.ActionType;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.*;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.securities.validation.ValidationProvider;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.validation.common.ValidationHelper;
import ru.spcex.platform.enumeration.UserRole;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgId;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.api.ImdgTransaction;
import java.time.Instant;
import java.util.Collection;
import java.util.Map;
@Service
public class MultiSecurityService extends QueueConsumer implements InitializingBean {
private final Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<FixedIncomeSecurity> fixedIncomeSecurityImdg;
private final Imdg<EquitySecurity> equitySecurityImdg;
private final Imdg<Listing> listingImdg;
private final ImdgProvider imdgProvider;
private final ImdgId idGenerator;
FixedIncomeSecurityService fixedIncomeSecurityService;
EquitySecurityService equitySecurityService;
ListingService listingService;
FixedIncomeCashFlowService fixedIncomeCashFlowService;
private final ValidationProvider validation;
private final UserRoleVerification userRoleVerification;
private final ValidationHelper validationHelper;
@Autowired
public MultiSecurityService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
ValidationProvider validation,
UserRoleVerification userRoleVerification,
ValidationHelper validationHelper) {
super(kafkaQueue, kafkaProducer);
this.validation = validation;
this.fixedIncomeSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class);
this.equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class);
this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
this.imdgProvider = imdgProvider;
this.idGenerator = imdgProvider.getImdgIdGenerator();
this.userRoleVerification = userRoleVerification.setRoleForVerification(UserRole.Admin);
this.validationHelper = validationHelper;
}
@Override
public void afterPropertiesSet() {
callback(MultiSecurityRequest.class)
.setFunction(this::newSecurities)
.forDestination(Consts.DESTINATION_SECUIRTY_MULTIREQUEST, callbacks::put);
imdgProvider.waitAvailable();
init();
}
<T extends Security> T findSecurityBySecuritySymbol(Imdg<T> imdg, String securitySymbol) {
Collection<T> securities = imdg.getCollectionObjectsByFieldValues(
Map.of("securitySymbol", securitySymbol)
);
if (securities.isEmpty()) {
log.trace("{} not found by securitySymbol={}", imdg.getMapName(), securitySymbol);
return null;
} else {
if (securities.size() > 1)
log.warn("Found {} {} by securitySymbol={}", securities.size(), imdg.getMapName(), securitySymbol);
T security = securities.iterator().next();
log.trace("Found {}[{}] with securitySymbol={}", imdg.getMapName(), security.getId(), securitySymbol);
return security;
}
}
private RequestInfoUpdate newSecurities(BaseRequest<MultiSecurityRequest> userRequest) {
log.debug("MultiSecurityRequest id={} received", userRequest.getId());
MultiSecurityRequest req = userRequest.getRequestPayload();
if (req.getFixedIncomeSecurityNewRequest() == null && req.getEquitySecurityNewRequest() == null) {
log.error("Required one of sub-request: FixedIncomeSecurityNewRequest or FixedIncomeSecurityNewRequest");
} else if (req.getFixedIncomeSecurityNewRequest() != null && req.getEquitySecurityNewRequest() != null) {
log.error("Filling both one of sub-request: FixedIncomeSecurityNewRequest or getEquitySecurityNewRequest");
}
;
final Long companyId = req.getCompanyId();
// ImdgTransaction transaction = imdgProvider.newTransaction(); todo transaction
Security security = null;
if (req.getFixedIncomeSecurityNewRequest() != null) {
log.trace("FixedIncomeSecurityNewRequest - BOND");
String securitySymbol = req.getFixedIncomeSecurityNewRequest().getSecuritySymbol();
security = findSecurityBySecuritySymbol(fixedIncomeSecurityImdg, securitySymbol);
if (security == null) {
RequestInfoUpdate resp = fixedIncomeSecurityService.newFixedIncome(wrapRequest(userRequest, req.getFixedIncomeSecurityNewRequest(), null));
validateReply(companyId, "newFixedIncome", resp);
security = findSecurityBySecuritySymbol(fixedIncomeSecurityImdg, securitySymbol);
} else {
FixedIncomeSecurityUpdateRequest updateRequest = toUpdateRequest(security, req.getFixedIncomeSecurityNewRequest());
RequestInfoUpdate resp = fixedIncomeSecurityService.updateFixedIncome(wrapRequest(userRequest, updateRequest, ActionType.UPDATE));
validateReply(companyId, "newFixedIncome", resp);
}
}
if (req.getEquitySecurityNewRequest() != null) {
log.trace("EquitySecurityNewRequest - FOND");
String securitySymbol = req.getFixedIncomeSecurityNewRequest().getSecuritySymbol();
security = findSecurityBySecuritySymbol(equitySecurityImdg, securitySymbol);
if (security == null) {
RequestInfoUpdate resp = equitySecurityService.newEquity(wrapRequest(userRequest, req.getEquitySecurityNewRequest(), null));
validateReply(companyId, "newFixedIncome", resp);
security = findSecurityBySecuritySymbol(equitySecurityImdg, securitySymbol);
} else {
EquitySecurityUpdateRequest updateRequest = toUpdateRequest(security, req.getEquitySecurityNewRequest());
RequestInfoUpdate resp = equitySecurityService.updateEquity(wrapRequest(userRequest, updateRequest, ActionType.UPDATE));
validateReply(companyId, "newFixedIncome", resp);
}
}
log.error("TODO listing,couponSchedule,nominal");
/*
todo оставшиеся части:
for (IncomeListing listing : security.getListingList()) {
if (listing.isInvalidData()) continue;
if (!security.isAlreadyExist() || !listing.isAlreadyExist()) {
ListingNewRequest listingNewRequest = new ListingNewRequest();
listingNewRequest.setSecurityId(securityId);
listingNewRequest.setMarket(listing.getCode());
listingNewRequest.setLotSize(listing.getLotSize());
listingNewRequest.setTradingCurrency(listing.getTradingCurrency());
listingNewRequest.setWorkflowStatus(listing.getWorkflowStatus());
kafkaSender.sendRequestToQueue(Consts.LISTING_NEW, listingNewRequest);
} else {
ListingUpdateRequest listingUpdateRequest = new ListingUpdateRequest();
listingUpdateRequest.setId(listing.getMapId());
listingUpdateRequest.setSecurityId(securityId);
listingUpdateRequest.setMarket(listing.getCode());
listingUpdateRequest.setLotSize(listing.getLotSize());
listingUpdateRequest.setTradingCurrency(listing.getTradingCurrency());
listingUpdateRequest.setWorkflowStatus(listing.getWorkflowStatus());
kafkaSender.sendRequestToQueue(Consts.LISTING_UPDATE, listingUpdateRequest);
}
}
for (CouponSchedule couponSchedule : security.getCouponScheduleList()) {
if (couponSchedule.isInvalidData()) continue;
if (!security.isAlreadyExist() || !couponSchedule.isAlreadyExist()) {
CouponPeriodNewRequest couponPeriodNewRequest = new CouponPeriodNewRequest();
couponPeriodNewRequest.setSecurityId(securityId);
couponPeriodNewRequest.setCouponRate(couponSchedule.getCouponRate());
couponPeriodNewRequest.setNumber(couponSchedule.getCouponNumber());
couponPeriodNewRequest.setPeriodEndDate(couponSchedule.getPeriodEndDate());
couponPeriodNewRequest.setPeriodStartDate(couponSchedule.getPeriodStartDate());
kafkaSender.sendRequestToQueue(Consts.DESTINATION_COUPON_PERIOD_NEW, couponPeriodNewRequest);
} else {
CouponPeriodUpdateRequest couponPeriodUpdateRequest = new CouponPeriodUpdateRequest();
couponPeriodUpdateRequest.setId(couponSchedule.getMapId());
couponPeriodUpdateRequest.setSecurityId(securityId);
couponPeriodUpdateRequest.setCouponRate(couponSchedule.getCouponRate());
couponPeriodUpdateRequest.setNumber(couponSchedule.getCouponNumber());
couponPeriodUpdateRequest.setPeriodEndDate(couponSchedule.getPeriodEndDate());
couponPeriodUpdateRequest.setPeriodStartDate(couponSchedule.getPeriodStartDate());
kafkaSender.sendRequestToQueue(Consts.DESTINATION_COUPON_PERIOD_UPDATE, couponPeriodUpdateRequest);
}
}
for (Nominal nominal : security.getNominalList()) {
if (nominal.isInvalidData()) continue;
if (!security.isAlreadyExist() || !nominal.isAlreadyExist()) {
FixedIncomeCashFlowNewRequest fixedIncomeCashFlowNewRequest = new FixedIncomeCashFlowNewRequest();
fixedIncomeCashFlowNewRequest.setSecuritySymbol(security.getSecuritySymbol());
fixedIncomeCashFlowNewRequest.setAccruedCoupon(nominal.getAccruedCoupon());
fixedIncomeCashFlowNewRequest.setNominalValue(nominal.getNominal());
fixedIncomeCashFlowNewRequest.setNumber(nominal.getCouponNumber());
kafkaSender.sendRequestToQueue(Consts.DESTINATION_FIXED_INCOME_CASH_FLOW_NEW, fixedIncomeCashFlowNewRequest);
} else {
FixedIncomeCashFlowUpdateRequest fixedIncomeCashFlowUpdateRequest = new FixedIncomeCashFlowUpdateRequest();
fixedIncomeCashFlowUpdateRequest.setId(nominal.getMapId());
fixedIncomeCashFlowUpdateRequest.setSecuritySymbol(security.getSecuritySymbol());
fixedIncomeCashFlowUpdateRequest.setAccruedCoupon(nominal.getAccruedCoupon());
fixedIncomeCashFlowUpdateRequest.setNominalValue(nominal.getNominal());
fixedIncomeCashFlowUpdateRequest.setNumber(nominal.getCouponNumber());
kafkaSender.sendRequestToQueue(Consts.DESTINATION_FIXED_INCOME_CASH_FLOW_UPDATE, fixedIncomeCashFlowUpdateRequest);
}
}
*/
log.debug("successfully processed, request id {}", userRequest.getId());
return null; // default success
}
FixedIncomeSecurityUpdateRequest toUpdateRequest(Security security, FixedIncomeSecurityNewRequest newRequest) {
FixedIncomeSecurityUpdateRequest updateRequest = new FixedIncomeSecurityUpdateRequest();
updateRequest.setId(security.getId());
updateRequest.setSecuritySymbol(newRequest.getSecuritySymbol());
updateRequest.setShortName(newRequest.getShortName());
updateRequest.setFullName(newRequest.getFullName());
updateRequest.setIsin(newRequest.getIsin());
updateRequest.setBondType(newRequest.getBondType());
updateRequest.setLotSize(newRequest.getLotSize());
updateRequest.setNominalValue(newRequest.getNominalValue());
updateRequest.setNominalCurrency(newRequest.getNominalCurrency());
updateRequest.setMaturityDate(newRequest.getMaturityDate());
updateRequest.setCoupon(newRequest.getCoupon());
updateRequest.setCouponFrequency(newRequest.getCouponFrequency());
updateRequest.setIssuerId(newRequest.getIssuerId());
updateRequest.setShortNameEng(newRequest.getShortNameEng());
updateRequest.setFullNameEng(newRequest.getFullNameEng());
updateRequest.setWorkflowStatus(newRequest.getWorkflowStatus());
updateRequest.setInstrumentType(newRequest.getInstrumentType());
return updateRequest;
}
EquitySecurityUpdateRequest toUpdateRequest(Security security, EquitySecurityNewRequest newRequest) {
EquitySecurityUpdateRequest updateRequest = new EquitySecurityUpdateRequest();
updateRequest.setId(security.getId());
updateRequest.setSecuritySymbol(newRequest.getSecuritySymbol());
updateRequest.setShortName(newRequest.getShortName());
updateRequest.setFullName(newRequest.getFullName());
updateRequest.setIsin(newRequest.getIsin());
updateRequest.setShareType(newRequest.getShareType());
updateRequest.setLotSize(newRequest.getLotSize());
updateRequest.setIssuerId(newRequest.getIssuerId());
updateRequest.setShortNameEng(newRequest.getShortNameEng());
updateRequest.setFullNameEng(newRequest.getFullNameEng());
updateRequest.setWorkflowStatus(newRequest.getWorkflowStatus());
updateRequest.setInstrumentType(newRequest.getInstrumentType());
return updateRequest;
}
private <T> BaseRequest<T> wrapRequest(BaseRequest<?> template, T payload, ActionType action) {
BaseRequest<T> r = new BaseRequest<>();
r.setId(template.getId());
if (action == null) {
r.setActionType(template.getActionType());
} else {
r.setActionType(action);
}
r.setUserId(template.getUserId());
r.setCorrelationId(template.getCorrelationId());
r.setRequestPayload(payload);
return r;
}
private void validateReply(Long companyId, String process, RequestInfoUpdate replyI) {
if (replyI != null && replyI.getMessage() != null) {
log.warn("Error process {} for companyId={}: {}", process, companyId, replyI.getMessage());
}
}
}

View file

@ -14,7 +14,7 @@ public interface Consts {
String DESTINATION_FIXED_INCOME_SECURITY_UPDATE = "fixed-income-security-update";
String DESTINATION_FIXED_INCOME_SECURITY_DELETE = "fixed-income-security-delete";
String DESTINATION_SECUIRTY_MULTIREQUEST = "secuirty-multirequest-new";
String DESTINATION_SECURITY_GATEWAY = "security-gateway-request-new";
String DESTINATION_FIXED_INCOME_CASH_FLOW_NEW = "fixed-income-cash-flow-new";
String DESTINATION_FIXED_INCOME_CASH_FLOW_UPDATE = "fixed-income-cash-flow-update";

View file

@ -1,66 +0,0 @@
package ru.spcex.clearing.platform.messaging.domain.cud.securitites;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.List;
public class MultiSecurityRequest {
@JsonProperty
Long companyId;
FixedIncomeSecurityNewRequest fixedIncomeSecurityNewRequest; // BOND
EquitySecurityNewRequest equitySecurityNewRequest; // FOND
List<ListingNewRequest> listingNewRequests = new ArrayList<>();
List<CouponPeriodNewRequest> couponPeriodNewRequests = new ArrayList<>();
List<FixedIncomeCashFlowNewRequest> fixedIncomeCashFlowNewRequests = new ArrayList<>();
public Long getCompanyId() {
return companyId;
}
public void setCompanyId(Long companyId) {
this.companyId = companyId;
}
public FixedIncomeSecurityNewRequest getFixedIncomeSecurityNewRequest() {
return fixedIncomeSecurityNewRequest;
}
public void setFixedIncomeSecurityNewRequest(FixedIncomeSecurityNewRequest fixedIncomeSecurityNewRequest) {
this.fixedIncomeSecurityNewRequest = fixedIncomeSecurityNewRequest;
}
public EquitySecurityNewRequest getEquitySecurityNewRequest() {
return equitySecurityNewRequest;
}
public void setEquitySecurityNewRequest(EquitySecurityNewRequest equitySecurityNewRequest) {
this.equitySecurityNewRequest = equitySecurityNewRequest;
}
public List<ListingNewRequest> getListingNewRequests() {
return listingNewRequests;
}
public void setListingNewRequests(List<ListingNewRequest> listingNewRequests) {
this.listingNewRequests = listingNewRequests;
}
public List<CouponPeriodNewRequest> getCouponPeriodNewRequests() {
return couponPeriodNewRequests;
}
public void setCouponPeriodNewRequests(List<CouponPeriodNewRequest> couponPeriodNewRequests) {
this.couponPeriodNewRequests = couponPeriodNewRequests;
}
public List<FixedIncomeCashFlowNewRequest> getFixedIncomeCashFlowNewRequests() {
return fixedIncomeCashFlowNewRequests;
}
public void setFixedIncomeCashFlowNewRequests(List<FixedIncomeCashFlowNewRequest> fixedIncomeCashFlowNewRequests) {
this.fixedIncomeCashFlowNewRequests = fixedIncomeCashFlowNewRequests;
}
}