diff --git a/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/config/ImdgConfig.java b/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/config/ImdgConfig.java new file mode 100644 index 000000000..34ed1dcd9 --- /dev/null +++ b/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/config/ImdgConfig.java @@ -0,0 +1,46 @@ +package ru.spcex.clearing.lim.exporter.config; + +import org.springframework.beans.factory.annotation.Autowired; +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.clearing.lim.exporter.config.settings.ExportLimServiceSettings; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; + +@Configuration +public class ImdgConfig { + 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); + } + + @Autowired + @Bean + public ImdgProvider imdgProvider( + @Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer, + @Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter, + ExportLimServiceSettings settings) { + return new HazelcastService(taskExecutorHazelcastClientInitializer, + taskExecutorIdGeneratorAwaiter, + settings.getHazelcast()); + } + +} diff --git a/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/AbstractExporterService.java b/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/AbstractExporterService.java index 8d1023274..61cb29394 100644 --- a/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/AbstractExporterService.java +++ b/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/AbstractExporterService.java @@ -1,5 +1,7 @@ package ru.spcex.clearing.lim.exporter.services; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import ru.spcex.clearing.lim.exporter.config.SFTPConfig; import java.io.File; @@ -11,7 +13,7 @@ import java.time.format.DateTimeFormatter; import java.util.Collection; public abstract class AbstractExporterService { - + private final Logger log = LoggerFactory.getLogger(getClass()); private static final DateTimeFormatter dtFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); private final SFTPConfig.LimGateway gateway; @@ -21,7 +23,9 @@ public abstract class AbstractExporterService { public abstract Collection getLimFileRows(); public abstract String getTargetFileName(); + public void process() { + log.debug("Start export {} Lim file", getTargetFileName()); String fileName = getTargetFileName(); File limFile = new File(fileName); @@ -29,8 +33,11 @@ public abstract class AbstractExporterService { try { Files.write(limFilePath, getLimFileRows()); gateway.sendToSftp(limFile); + + log.debug("Successfully exported {} file", fileName); Files.deleteIfExists(limFilePath); } catch (IOException e) { + log.error("Failed export {} file", fileName); throw new RuntimeException(e); } } diff --git a/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/MoneyExporterService.java b/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/MoneyExporterService.java index 057263e9b..c66f61648 100644 --- a/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/MoneyExporterService.java +++ b/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/MoneyExporterService.java @@ -1,27 +1,104 @@ package ru.spcex.clearing.lim.exporter.services; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.lim.exporter.config.SFTPConfig; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; -import java.util.Arrays; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Service public class MoneyExporterService extends AbstractExporterService { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg registryImdg; + private final List validStatus = List.of("ACTV", "ROPN"); + private final Imdg tradingClearingRegistryImdg; - public MoneyExporterService(SFTPConfig.LimGateway gateway) { + public MoneyExporterService(SFTPConfig.LimGateway gateway, ImdgProvider imdgProvider) { super(gateway); - } - - @Override - public Collection getLimFileRows(){ - List limFileRows = Arrays.asList("a", "b", "c"); - return limFileRows; + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); } @Override public String getTargetFileName() { return prepareFileName("money"); } + + @Override + public Collection getLimFileRows() { + log.debug("Started loading and formation of money file lines"); + LocalDate currentDate = LocalDate.now(); + List limFileRows = new ArrayList<>(); + Collection registriesA = registryImdg.getCollectionObjectsByFieldValues( + Map.of("registryDesignation", "A", + "registryInstrumentType", "M", + "registryCode", "F", + "clearingDate", currentDate)); + Collection registriesD = registryImdg.getCollectionObjectsByFieldValues( + Map.of("registryDesignation", "D", + "registryInstrumentType", "M", + "registryCode", "T", + "clearingDate", currentDate)); + Map> byTcrA = registriesA.stream() + .collect(Collectors.groupingBy(Registry::getTradingClearingRegistry)); + Map> byTcrD = registriesD.stream() + .collect(Collectors.groupingBy(Registry::getTradingClearingRegistry)); + + for(Map.Entry> entryA : byTcrA.entrySet()){ + List registriesListA = entryA.getValue(); + List registriesListB = byTcrD.get(entryA.getKey()); + for (Registry registry : registriesListA){ + if(checkNotBloked(registry)){ + //из ТЗ пока не понятно как соотнести Registry из registriesListA и registriesListB по валюте(RUB, USD) и вычислить остаток на денежном счете +// limFileRows.add(getRow(...)); + } + } + } + log.debug("Successfully completed the formation of rows: {} for export money", limFileRows.size()); + return limFileRows; + } + + private boolean checkNotBloked(Registry registry){ + TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getSingleObjectByID(registry.getTradingClearingRegistryId()); + return validStatus.contains(tradingClearingRegistry.getStatus()); + } + + //поменяется при обновлении ТЗ + private String getRow(Registry registryA, Registry registryB){ + StringBuilder row = new StringBuilder(); + + row.append("MONEY: FIRM_ID = "); + row.append(registryA.getTradingCode()); + + row.append("; TAG = SPVB"); + + row.append("; CURR_CODE = "); +// MoneyMarketSecurity mms = moneyMarketSecurityMap.getSingleObjectByFieldValues(Map.of("securityId", )); + + row.append("; CLIENT_CODE = "); + row.append(registryA.getTradingClearingRegistry()); + + row.append("; OPEN_BALANCE = "); + BigDecimal balance = registryA.getBalance() != null ? + registryB.getBalance() != null ? registryA.getBalance().subtract(registryB.getBalance()) : registryA.getBalance() : + BigDecimal.ZERO; + row.append(balance); + + row.append("; OPEN_LIMIT = 0.00"); + + row.append("; LIMIT_KIND = 0;"); + return row.toString(); + } } diff --git a/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/SecurityExporterService.java b/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/SecurityExporterService.java index 254f89ab0..206bbfb42 100644 --- a/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/SecurityExporterService.java +++ b/clearing-parent/lim-exporter/src/main/java/ru/spcex/clearing/lim/exporter/services/SecurityExporterService.java @@ -1,26 +1,81 @@ package ru.spcex.clearing.lim.exporter.services; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.lim.exporter.config.SFTPConfig; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; -import java.util.Arrays; +import java.time.LocalDate; +import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; @Service public class SecurityExporterService extends AbstractExporterService { - public SecurityExporterService(SFTPConfig.LimGateway gateway) { + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final Imdg registryImdg; + + public SecurityExporterService(SFTPConfig.LimGateway gateway, ImdgProvider imdgProvider) { super(gateway); + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); } - @Override - public Collection getLimFileRows(){ - List limFileRows = Arrays.asList("a", "b", "c"); - return limFileRows; - } @Override public String getTargetFileName() { return prepareFileName("security"); } + + @Override + public Collection getLimFileRows(){ + log.debug("Started loading and formation of DEPO file lines"); + LocalDate currentDate = LocalDate.now(); + List limFileRows = new ArrayList<>(); + Collection registries = registryImdg.getCollectionObjectsByFieldValues( + Map.of("registryDesignation", "A", + "registryInstrumentType", "S", + "registryCode", "T", + "clearingDate", currentDate)); + for (Registry registry : registries){ + limFileRows.add(getRow(registry)); + } + log.debug("Successfully completed the formation of rows: {} for export DEPO", limFileRows.size()); + return limFileRows; + } + + private String getRow(Registry registry){ + StringBuilder row = new StringBuilder(); + + row.append("DEPO: FIRM_ID = "); + row.append(registry.getTradingCode()); + + row.append("; SECCODE = "); + row.append(getSecurityShortName(registry)); + + row.append("; CLIENT_CODE = "); + row.append(registry.getTradingClearingRegistry()); + + row.append("; OPEN_BALANCE = "); + row.append(registry.getBalance()); + + row.append("; OPEN_LIMIT = 0"); + + row.append("; TRDACCID = "); + row.append(registry.getTradingClearingRegistry()); + + row.append("; LIMIT_KIND = 0;"); + + return row.toString(); + } + + //скорее всего в новой редакции ТЗ не понадобится + private String getSecurityShortName(Registry registry){ + return null; + } }