some stages

This commit is contained in:
akulikov 2023-05-25 16:53:50 +03:00
parent afd3d948fc
commit 6832899c2a
11 changed files with 335 additions and 36 deletions

View file

@ -0,0 +1,44 @@
package ru.spcex.clearing.gatewayapi.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService;
@Configuration
public class GatewayApiImdgConfig {
private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
if (maxPoolSz > 2) {
pool.setKeepAliveSeconds(60);
pool.setAllowCoreThreadTimeOut(true);
}
pool.setCorePoolSize(maxPoolSz);
pool.setWaitForTasksToCompleteOnShutdown(waitForCompletion);
return pool;
}
@Bean(name = "taskExecutorHazelcastClientInitializer")
public ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer() {
return createThreadPoolTaskExecutor(1, true);
}
@Bean(name = "taskExecutorIdGeneratorAwaiter")
public ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter() {
return createThreadPoolTaskExecutor(1, false);
}
@Bean
public ImdgProvider imdgProvider(
@Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer,
@Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter,
GatewayApiSettings settings
) {
return new HazelcastService(taskExecutorHazelcastClientInitializer,
taskExecutorIdGeneratorAwaiter,
settings.getHazelcast());
}
}

View file

@ -0,0 +1,24 @@
package ru.spcex.clearing.gatewayapi.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.gatewayapi.logic.*;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class PipelineConfiguration {
@Bean
public List<Stage<ListingsRequestParam>> listingsRequestPipeline(ImdgProvider imdgProvider) {
List<Stage<ListingsRequestParam>> pipeline = new ArrayList<>();
pipeline.add(new GroupingSecurityParts());
pipeline.add(new GroupingCompanyParts());
pipeline.add(new ValidateIncomeSecurities());
pipeline.add(new CheckSecurityExist(imdgProvider));
return pipeline;
}
}

View file

@ -0,0 +1,59 @@
package ru.spcex.clearing.gatewayapi.logic;
import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity;
import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity;
import ru.spcex.clearing.gatewayapi.request.objects.IncomeSecurity;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.InstrumentType;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class CheckSecurityExist extends Stage<ListingsRequestParam> {
private final Imdg<EquitySecurity> equitySecurityImdg;
private final Imdg<FixedIncomeSecurity> fixedIncomeSecurityImdg;
public CheckSecurityExist(ImdgProvider imdgProvider) {
equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class);
fixedIncomeSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class);
}
@Override
public ProcessResult process(ListingsRequestParam param) {
List<IncomeSecurity> securities = param.getSecurities();
for (IncomeSecurity incomeSecurity : securities) {
String instrumentType = incomeSecurity.getInstrumentType();
String securitySymbol = incomeSecurity.getSecuritySymbol();
if (InstrumentType.BOND.equalsByKey(instrumentType)) {
Collection<FixedIncomeSecurity> fixedIncomeSecurity = fixedIncomeSecurityImdg.getCollectionObjectsByFieldValues(
Map.of("securitySymbol", securitySymbol)
);
if (!fixedIncomeSecurity.isEmpty()) {
incomeSecurity.setAlreadyExist(true);
incomeSecurity.setMapId(fixedIncomeSecurity.iterator().next().getId());
} else {
incomeSecurity.setAlreadyExist(false);
}
} else if (InstrumentType.EQTY.equalsByKey(instrumentType)) {
Collection<EquitySecurity> equitySecurity = equitySecurityImdg.getCollectionObjectsByFieldValues(
Map.of("securitySymbol", securitySymbol)
);
if (!equitySecurity.isEmpty()) {
incomeSecurity.setAlreadyExist(true);
incomeSecurity.setMapId(equitySecurity.iterator().next().getId());
} else {
incomeSecurity.setAlreadyExist(false);
}
}
if (incomeSecurity.isAlreadyExist()) {
// todo after answer
}
}
return null;
}
}

View file

@ -1,28 +1,39 @@
package ru.spcex.clearing.gatewayapi.logic;
import ru.spcex.clearing.gatewayapi.request.ListingsRequest;
import ru.spcex.clearing.gatewayapi.request.objects.IssuerCompany;
import ru.spcex.clearing.gatewayapi.request.objects.IssuerCompanyInfo;
import ru.spcex.clearing.gatewayapi.request.objects.IssuerCompanySymbols;
import ru.spcex.clearing.gatewayapi.request.objects.IssuerContact;
import ru.spcex.clearing.gatewayapi.request.objects.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class GroupingCompanyParts extends Stage<ListingsRequest> {
public class GroupingCompanyParts extends Stage<ListingsRequestParam> {
@Override
public ProcessResult process(ListingsRequest param) {
List<IssuerCompany> companyList = param.getIssuerCompanyList();
public ProcessResult process(ListingsRequestParam param) {
List<IssuerCompany> issuerCompanyList = param.getListingsRequest().getIssuerCompanyList();
Map<UUID, IssuerCompany> issuerCompanyMap = new HashMap<>();
for (IssuerCompany issuerCompany : companyList) {
for (IssuerCompany issuerCompany : issuerCompanyList) {
if (issuerCompanyMap.put(issuerCompany.getId(), issuerCompany) != null) {
throw new IllegalStateException("Duplicate key");
}
}
List<IssuerCompanyInfo> issuerCompanyInfoList = param.getIssuerCompanyInfoList();
for (IssuerCompany issuerCompany : issuerCompanyList) {
UUID issuerCompanyId = issuerCompany.getId();
boolean securityFoundForCompany = false;
for (IncomeSecurity incomeSecurity : param.getSecurities()) {
if (incomeSecurity.getIssuerId().equals(issuerCompanyId)) {
incomeSecurity.getIssuerCompanyList().add(issuerCompany);
securityFoundForCompany = true;
break;
}
}
if (!securityFoundForCompany) {
// todo error: company without security
}
}
List<IssuerCompanyInfo> issuerCompanyInfoList = param.getListingsRequest().getIssuerCompanyInfoList();
for (IssuerCompanyInfo issuerCompanyInfo : issuerCompanyInfoList) {
UUID issuerCompanyInfoUUID = issuerCompanyInfo.getCompanyId();
IssuerCompany issuerCompany = issuerCompanyMap.get(issuerCompanyInfoUUID);
@ -33,7 +44,7 @@ public class GroupingCompanyParts extends Stage<ListingsRequest> {
issuerCompany.getIssuerCompanyInfoList().add(issuerCompanyInfo);
}
List<IssuerCompanySymbols> issuerCompanySymbolsList = param.getIssuerCompanySymbolsList();
List<IssuerCompanySymbols> issuerCompanySymbolsList = param.getListingsRequest().getIssuerCompanySymbolsList();
for (IssuerCompanySymbols issuerCompanySymbols : issuerCompanySymbolsList) {
UUID issuerCompanySymbolsUUID = issuerCompanySymbols.getCompanyId();
IssuerCompany issuerCompany = issuerCompanyMap.get(issuerCompanySymbolsUUID);
@ -44,7 +55,7 @@ public class GroupingCompanyParts extends Stage<ListingsRequest> {
issuerCompany.getIssuerCompanySymbolsList().add(issuerCompanySymbols);
}
List<IssuerContact> issuerContactList = param.getIssuerContactList();
List<IssuerContact> issuerContactList = param.getListingsRequest().getIssuerContactList();
for (IssuerContact issuerContact : issuerContactList) {
UUID issuerContactUUID = issuerContact.getCompanyId();
IssuerCompany issuerCompany = issuerCompanyMap.get(issuerContactUUID);
@ -55,6 +66,7 @@ public class GroupingCompanyParts extends Stage<ListingsRequest> {
issuerCompany.getIssuerContactList().add(issuerContact);
}
param.getIssuerCompanyList().addAll(issuerCompanyList);
return null;
}
}

View file

@ -1,6 +1,5 @@
package ru.spcex.clearing.gatewayapi.logic;
import ru.spcex.clearing.gatewayapi.request.ListingsRequest;
import ru.spcex.clearing.gatewayapi.request.objects.*;
import java.util.HashMap;
@ -8,57 +7,58 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
public class GroupingSecurityParts extends Stage<ListingsRequest> {
public class GroupingSecurityParts extends Stage<ListingsRequestParam> {
@Override
public ProcessResult process(ListingsRequest param) {
List<Security> securities = param.getSecurities();
Map<UUID, Security> securityMap = new HashMap<>();
for (Security security : securities) {
if (securityMap.put(security.getId(), security) != null) {
public ProcessResult process(ListingsRequestParam param) {
List<IncomeSecurity> securities = param.getListingsRequest().getSecurities();
Map<UUID, IncomeSecurity> securityMap = new HashMap<>();
for (IncomeSecurity incomeSecurity : securities) {
if (securityMap.put(incomeSecurity.getId(), incomeSecurity) != null) {
// todo error
throw new IllegalStateException("Duplicate key");
}
}
List<CouponSchedule> couponSchedules = param.getCouponSchedules();
List<CouponSchedule> couponSchedules = param.getListingsRequest().getCouponSchedules();
for (CouponSchedule couponSchedule : couponSchedules) {
UUID couponScheduleUUID = couponSchedule.getSecurityId();
Security security = securityMap.get(couponScheduleUUID);
if (security == null) {
IncomeSecurity incomeSecurity = securityMap.get(couponScheduleUUID);
if (incomeSecurity == null) {
// todo error
continue;
}
security.getCouponScheduleList().add(couponSchedule);
incomeSecurity.getCouponScheduleList().add(couponSchedule);
}
List<Currency> currencyList = param.getCurrencies();
List<Currency> currencyList = param.getListingsRequest().getCurrencies();
for (Currency currency : currencyList) {
UUID currencyUUID = currency.getId();
// todo сделать после выяснения
}
List<Listing> listingList = param.getListingList();
List<Listing> listingList = param.getListingsRequest().getListingList();
for (Listing listing : listingList) {
UUID listingUUID = listing.getSecurityId();
Security security = securityMap.get(listingUUID);
if (security == null) {
IncomeSecurity incomeSecurity = securityMap.get(listingUUID);
if (incomeSecurity == null) {
// todo error
continue;
}
security.getListingList().add(listing);
incomeSecurity.getListingList().add(listing);
}
List<Nominal> nominalList = param.getNominalList();
List<Nominal> nominalList = param.getListingsRequest().getNominalList();
for (Nominal nominal : nominalList) {
UUID nominalUUID = nominal.getSecurityId();
Security security = securityMap.get(nominalUUID);
if (security == null) {
IncomeSecurity incomeSecurity = securityMap.get(nominalUUID);
if (incomeSecurity == null) {
// todo error
continue;
}
security.getNominalList().add(nominal);
incomeSecurity.getNominalList().add(nominal);
}
param.getSecurities().addAll(securities);
return null;
}
}

View file

@ -0,0 +1,31 @@
package ru.spcex.clearing.gatewayapi.logic;
import ru.spcex.clearing.gatewayapi.request.ListingsRequest;
import ru.spcex.clearing.gatewayapi.request.objects.IncomeSecurity;
import ru.spcex.clearing.gatewayapi.request.objects.IssuerCompany;
import java.util.ArrayList;
import java.util.List;
public class ListingsRequestParam {
private final ListingsRequest listingsRequest;
private final List<IncomeSecurity> securities = new ArrayList<>();
private final List<IssuerCompany> issuerCompanyList = new ArrayList<>();
public ListingsRequestParam(ListingsRequest listingsRequest) {
this.listingsRequest = listingsRequest;
}
public ListingsRequest getListingsRequest() {
return listingsRequest;
}
public List<IncomeSecurity> getSecurities() {
return securities;
}
public List<IssuerCompany> getIssuerCompanyList() {
return issuerCompanyList;
}
}

View file

@ -0,0 +1,59 @@
package ru.spcex.clearing.gatewayapi.logic;
import ru.spcex.clearing.gatewayapi.request.objects.IncomeSecurity;
import ru.spcex.clearing.gatewayapi.request.objects.Listing;
import ru.spcex.platform.enumeration.BondType;
import ru.spcex.platform.enumeration.InstrumentType;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import java.util.List;
public class ValidateIncomeSecurities extends Stage<ListingsRequestParam> {
// todo collect errors for response
@Override
public ProcessResult process(ListingsRequestParam param) {
List<IncomeSecurity> securities = param.getSecurities();
for (IncomeSecurity incomeSecurity : securities) {
String instrumentTypeStr = incomeSecurity.getInstrumentType();
InstrumentType instrumentType = IEnumKey.getEnumByKey(InstrumentType.class, instrumentTypeStr);
if (instrumentType != InstrumentType.BOND && instrumentType != InstrumentType.EQTY) {
// todo collect error
continue;
}
String workflowStatusStr = incomeSecurity.getWorkflowStatus();
WorkflowStatus workflowStatus = IEnumKey.getEnumByKey(WorkflowStatus.class, workflowStatusStr);
if (workflowStatus == null) {
// todo collect error
continue;
}
// todo check share_type
String bondTypeStr = incomeSecurity.getBondType();
BondType bondType = IEnumKey.getEnumByKey(BondType.class, bondTypeStr);
if (bondType == null) {
// todo collect error
continue;
}
List<Listing> listingList = incomeSecurity.getListingList();
for (Listing listing : listingList) {
workflowStatusStr = listing.getWorkflowStatus();
workflowStatus = IEnumKey.getEnumByKey(WorkflowStatus.class, workflowStatusStr);
if (workflowStatus == null) {
// todo collect error
continue;
}
}
}
return null;
}
}

View file

@ -46,7 +46,7 @@ public class ListingsRequest {
@JsonProperty("security")
@ApiModelProperty(value = "Список security")
private List<Security> securities;
private List<IncomeSecurity> securities;
@JsonProperty("coupon_schedule")
@ApiModelProperty(value = "Список coupon_schedule")
@ -113,11 +113,11 @@ public class ListingsRequest {
this.section = section;
}
public List<Security> getSecurities() {
public List<IncomeSecurity> getSecurities() {
return securities;
}
public void setSecurities(List<Security> securities) {
public void setSecurities(List<IncomeSecurity> securities) {
this.securities = securities;
}

View file

@ -12,7 +12,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class Security {
public class IncomeSecurity {
@JsonProperty("id")
@ApiModelProperty(
value = "id (uuid)",
@ -171,6 +171,8 @@ public class Security {
)
private BigDecimal couponFrequency;
@JsonIgnore
private List<Listing> listingList = new ArrayList<>();
@ -183,6 +185,12 @@ public class Security {
@JsonIgnore
private List<IssuerCompany> issuerCompanyList = new ArrayList<>();
@JsonIgnore
private boolean alreadyExist = false;
@JsonIgnore
private Long mapId;
public UUID getId() {
return id;
}
@ -358,4 +366,20 @@ public class Security {
public void setIssuerCompanyList(List<IssuerCompany> issuerCompanyList) {
this.issuerCompanyList = issuerCompanyList;
}
public boolean isAlreadyExist() {
return alreadyExist;
}
public void setAlreadyExist(boolean alreadyExist) {
this.alreadyExist = alreadyExist;
}
public Long getMapId() {
return mapId;
}
public void setMapId(Long mapId) {
this.mapId = mapId;
}
}

View file

@ -0,0 +1,25 @@
package ru.spcex.platform.enumeration;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum BondType implements IEnumKey {
Z("Z"), // Дисконтная облигация
F("F"), // Купонная облигация с постоянным купоном
V("V"), // Купонная облигация с переменным купоном
C("C"), // Купонная облигация банка России
E("E"), // Биржевая облигация
I("I"), // Облигация с индексированным номиналом
M("M"), // Облигация с амортизацией долга
;
private final String key;
BondType(String key) {
this.key = key;
}
@Override
public String getKey() {
return key;
}
}

View file

@ -0,0 +1,21 @@
package ru.spcex.platform.enumeration;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum InstrumentType implements IEnumKey {
BOND("BOND"), // Долевые ценные бумаги (акции)
EQTY("EQTY"), // Долговые ценные бумаги (облигации)
;
private final String key;
InstrumentType(String key) {
this.key = key;
}
@Override
public String getKey() {
return key;
}
}