From 56441c39cb3bfcc0ea69e7575d914d8a90fcbcfa Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Sat, 27 May 2023 13:11:06 +0300 Subject: [PATCH 01/36] fix SDF57Executor and registryBuilder --- .../builder/PaymentInstructionBuilder.java | 3 +- .../service/executors/Sdf57Executor.java | 10 ++-- .../session/stage/impl/RegistryBuilder.java | 53 +++++++++++++++---- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java index ff1f9ecde..80479f8c9 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java @@ -7,6 +7,7 @@ import ru.clearing.classes.statics.data.payment.PaymentInstruction; import ru.clearing.classes.statics.data.registry.Registry; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.platform.enumeration.CompanySymbol; +import ru.spcex.platform.enumeration.InOutDirection; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -66,7 +67,7 @@ public class PaymentInstructionBuilder { } paymentInstruction.setDebitLeg_accountId(registry.getAccountId()); - + paymentInstruction.setDebitLeg_direction(InOutDirection.in.getKey()); // Account account = accountImdg.getSingleObjectByID(registry.get()); // paymentInstruction.setDebitLeg_account(); return paymentInstruction; diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java index 3efdc6c1e..9749bc9b6 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java @@ -171,11 +171,12 @@ public class Sdf57Executor extends AbstractExecutor { Registry registry = createRegistryByStatement(stmt, company, account, dsgn); Registry registryB = registry.clone(); + registryB.setId(imdgProvider.getImdgIdGenerator().nextId()); registryB.setRegistryUnit(RegistryUnit.B.getKey()); registryB.setRegistryCode(RegistryUtil.clearingCode(registryB)); - registryB.setId(imdgProvider.getImdgIdGenerator().nextId()); registryB.setBalance(BigDecimal.ZERO); registryB.setDebit(BigDecimal.ZERO); + registryB.setCredit(BigDecimal.ZERO); Registry registryF = registry.clone(); registryF.setRegistryUnit(RegistryUnit.F.getKey()); @@ -291,10 +292,13 @@ public class Sdf57Executor extends AbstractExecutor { //Если значение statement.inOutDirection=OUT, то: //= текущее значение registry.balance - statement.amount switch (inOutDirection) { - case in -> rgs.setBalance(statement.getAmount()); + case in -> { + rgs.setBalance(statement.getAmount()); + rgs.setCredit(statement.getAmount()); + } case out -> { rgs.setBalance(statement.getAmount().negate()); - rgs.setDebit(statement.getAmount()); + rgs.setDebit(statement.getAmount().negate()); } } rgs.setBalanceDimension(BalanceDimension.MONY.getKey()); //fixme ! смотри описание и ссылка на начало html'ки diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java index 18f16b394..b19291e9f 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java @@ -2,10 +2,13 @@ package ru.spcex.clearing.session.stage.impl; import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.account.ClearingAccount; +import ru.clearing.classes.statics.data.account.DepoAccount; +import ru.clearing.classes.statics.data.account.InformationAccount; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.execution.ExecutionCommon; import ru.clearing.classes.statics.data.execution.ExecutionDeposit; import ru.clearing.classes.statics.data.execution.ExecutionFond; +import ru.clearing.classes.statics.data.misc.Currency; import ru.clearing.classes.statics.data.misc.Market; import ru.clearing.classes.statics.data.misc.Session; import ru.clearing.classes.statics.data.registry.Registry; @@ -20,6 +23,7 @@ import ru.spcex.platform.imdg.api.ImdgProvider; import java.time.Instant; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.Map; public class RegistryBuilder { private Imdg companyImdg; @@ -28,6 +32,9 @@ public class RegistryBuilder { private Imdg marketImdg; private Imdg sessionImdg; private Imdg clearingAccountImdg; + private Imdg informationAccountImdg; + private Imdg depoAccountImdg; + private Imdg currencyImdg; private ExecutionCommon exec; private RegistryDesignation regDsgn; @@ -45,6 +52,9 @@ public class RegistryBuilder { this.marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, Market.class); this.sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class); this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class); + this.depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class); + this.informationAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_InformationAccount, InformationAccount.class); + this.currencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Currency, Currency.class); return this; } @@ -69,32 +79,51 @@ public class RegistryBuilder { reg.setShortName(company.getShortName()); reg.setFullName(company.getFullName()); TradingClearingRegistry tcr = searchTradingClearingRegistry(); - ClearingAccount accountForStatement = null; + String capacityByAccount = null; + boolean isMoney = false; + Account account = accountImdg.getSingleObjectByID(reg.getAccountId()); if ((regDsgn.equals(RegistryDesignation.O) && side.isBuy()) || (regDsgn.equals(RegistryDesignation.T) && side.isSell())) { + isMoney = true; reg.setAccountId(tcr.getMoneyAccountId()); reg.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); reg.setBalanceDimension(BalanceDimension.MONY.getKey()); //fixme add second leg code branch - accountForStatement = clearingAccountImdg.getSingleObjectByID(tcr.getMoneyAccountId()); + Currency currency = currencyImdg.getSingleObjectByFieldValues(Map.of("currencyCode", exec.getSettlementCurrency())); + reg.setSecurityId(currency.getId()); + reg.setSecuritySymbol(currency.getCurrencyCode()); + if (AccountType.Clrn.equalsByKey(account.getAccountType())) { + ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(tcr.getMoneyAccountId()); + if (clearingAccount != null) { + capacityByAccount = clearingAccount.getClearingAccountType(); + } + } else if (AccountType.Info.equalsByKey(account.getAccountType())){ + InformationAccount informationAccount = informationAccountImdg.getSingleObjectByID(tcr.getMoneyAccountId()); + if (informationAccount != null) { + capacityByAccount = "A"; //todo сделать enum + } + } } else if ((regDsgn.equals(RegistryDesignation.T) && side.isBuy()) || (regDsgn.equals(RegistryDesignation.O) && side.isSell())) { + isMoney = false; reg.setAccountId(tcr.getDepoAccountId()); reg.setRegistryInstrumentType(RegistryInstrumentType.S.getKey()); reg.setBalanceDimension(BalanceDimension.PICS.getKey()); //fixme add second leg code branch - accountForStatement = clearingAccountImdg.getSingleObjectByID(tcr.getDepoAccountId()); + reg.setSecurityId(exec.getSecurityId()); + reg.setSecuritySymbol(exec.getSecuritySymbol()); + DepoAccount depoAccount = depoAccountImdg.getSingleObjectByID(tcr.getDepoAccountId()); + if (depoAccount != null) { + capacityByAccount = depoAccount.getDepoAccountType(); + } } - Account account = accountImdg.getSingleObjectByID(reg.getAccountId()); reg.setAccountType(account.getAccountType()); reg.setAccount(account.getAccount()); reg.setRegistryDesignation(regDsgn.getKey()); - if (accountForStatement != null) { - reg.setRegistryCapacity(accountForStatement.getClearingAccountType()); + if (capacityByAccount != null) { + reg.setRegistryCapacity(capacityByAccount); } reg.setRegistryUnit(RegistryUnit.T.getKey()); reg.setRegistryCode(RegistryUtil.clearingCode(reg)); reg.setTradingClearingRegistryId(exec.getTradingClearingRegistryId()); reg.setTradingClearingRegistry(tcr.getCode()); reg.setRegistryStatus(RegistryStatus.PROC.getKey()); - reg.setSecurityId(exec.getSecurityId()); - reg.setSecuritySymbol(exec.getSecuritySymbol()); switch (exec.type()) { case ExecutionDeposit -> { ExecutionDeposit execDep = (ExecutionDeposit) this.exec; @@ -112,7 +141,13 @@ public class RegistryBuilder { } case ExecutionFond -> { ExecutionFond execFond = (ExecutionFond) this.exec; - reg.setBalance(execFond.getSettlementAmount()); + if (isMoney) { + //todo ОКРУГЛЕНИЕ(fixedIncomeSecurity.nominalValue * quantity * price/100) + ОКРУГЛЕНИЕ (executionFond.interestAmount) + reg.setBalance(execFond.getSettlementAmount()); + } else { + reg.setBalance(execFond.getQuantity()); + } + reg.setSettlementDate(execFond.getSettlementDate()); reg.setSettlementCode(execFond.getSettlementCode()); } From 9fa165de2ec5317e1b72010fe042d8f463e700bb Mon Sep 17 00:00:00 2001 From: aalehin Date: Sat, 27 May 2023 13:37:29 +0300 Subject: [PATCH 02/36] http://jira.mfd.msk:8088/browse/CLS-316 --- mid swt importer --- clearing-parent/pom.xml | 1 + clearing-parent/swt-importer/pom.xml | 103 +++++++++++++++ .../swt/importer/SWTImporterApplication.java | 18 +++ .../importer/config/ImporterImdgConfig.java | 46 +++++++ .../swt/importer/config/KafkaConfig.java | 60 +++++++++ .../importer/config/SWTImporterConfig.java | 67 ++++++++++ .../swt/importer/config/settings/Common.java | 32 +++++ .../swt/importer/config/settings/Cron.java | 14 +++ .../settings/ImportSWTServiceSettings.java | 68 ++++++++++ .../swt/importer/config/settings/Store.java | 41 ++++++ .../controller/ImporterController.java | 37 ++++++ .../controller/LauncherCommandReceiver.java | 43 +++++++ .../importer/exceptions/ConfigException.java | 6 + .../swt/importer/logic/Processor.java | 44 +++++++ .../logic/data/ColumnStructureSWT.java | 51 ++++++++ .../importer/logic/data/DBStructureSWT.java | 18 +++ .../importer/logic/data/ResultContainer.java | 70 +++++++++++ .../logic/data/TableStructureSWT.java | 25 ++++ .../importer/logic/data/enums/ColumnType.java | 46 +++++++ .../swt/importer/logic/data/enums/ETable.java | 33 +++++ .../logic/data/enums/StageResult.java | 7 ++ .../logic/data/tables/AbstractTable.java | 46 +++++++ .../logic/data/tables/SDf08Table.java | 33 +++++ .../logic/data/tables/SDf10Table.java | 33 +++++ .../logic/data/tables/SDf13Table.java | 29 +++++ .../logic/stages/ChangeDirOfFileStage.java | 79 ++++++++++++ .../swt/importer/logic/stages/ImportToDB.java | 73 +++++++++++ .../logic/stages/LoadFileFromDisk.java | 44 +++++++ .../logic/stages/SWTImportKafkaMessenger.java | 51 ++++++++ .../swt/importer/logic/stages/Stage.java | 16 +++ .../importer/logic/stages/ValidateFields.java | 44 +++++++ .../swt/importer/services/FileChecker.java | 56 +++++++++ .../importer/services/SWTImporterService.java | 119 ++++++++++++++++++ .../src/main/resources/application.properties | 34 +++++ .../src/main/resources/logback.xml | 37 ++++++ .../spcex/platform/enumeration/SdfTable.java | 10 +- 36 files changed, 1529 insertions(+), 5 deletions(-) create mode 100644 clearing-parent/swt-importer/pom.xml create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/SWTImporterApplication.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/ImporterImdgConfig.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/KafkaConfig.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/SWTImporterConfig.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Common.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Cron.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/ImportSWTServiceSettings.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Store.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/controller/ImporterController.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/controller/LauncherCommandReceiver.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/exceptions/ConfigException.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/Processor.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ColumnStructureSWT.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/DBStructureSWT.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ResultContainer.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/TableStructureSWT.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ColumnType.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ETable.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/StageResult.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/AbstractTable.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf13Table.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ChangeDirOfFileStage.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ImportToDB.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/LoadFileFromDisk.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/SWTImportKafkaMessenger.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/Stage.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ValidateFields.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/FileChecker.java create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/SWTImporterService.java create mode 100644 clearing-parent/swt-importer/src/main/resources/application.properties create mode 100644 clearing-parent/swt-importer/src/main/resources/logback.xml diff --git a/clearing-parent/pom.xml b/clearing-parent/pom.xml index b00850e36..4e17f0658 100644 --- a/clearing-parent/pom.xml +++ b/clearing-parent/pom.xml @@ -39,6 +39,7 @@ trade-importer lim-exporter swt-exporter + swt-importer diff --git a/clearing-parent/swt-importer/pom.xml b/clearing-parent/swt-importer/pom.xml new file mode 100644 index 000000000..35515baf1 --- /dev/null +++ b/clearing-parent/swt-importer/pom.xml @@ -0,0 +1,103 @@ + + + + clearing-parent + ru.spcex.clearing + SPCEX-1.0.0.0 + + 4.0.0 + + swt-importer + + + 17 + 17 + + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-autoconfigure + + + + + org.springframework + spring-jdbc + + + com.mchange + c3p0 + + + org.postgresql + postgresql + + + + + com.github.albfernandez + javadbf + + + ru.spcex.platform + platform-imdg-api + + + ru.spcex.platform + platform-imdg-api-hazelcast-impl + + + ru.spcex.clearing + classes + + + ru.spcex.platform + platform-messaging + + + ru.spcex.platform + platform-enum + + + + + + + src/main/resources + + application.properties + + false + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + ${project.artifactId} + + + + + + \ No newline at end of file diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/SWTImporterApplication.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/SWTImporterApplication.java new file mode 100644 index 000000000..534e987ee --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/SWTImporterApplication.java @@ -0,0 +1,18 @@ +package ru.spcex.clearing.swt.importer; + +import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +public class SWTImporterApplication { + public static void main(String[] args) { + try { + SpringApplicationBuilder builder = new SpringApplicationBuilder(SWTImporterApplication.class); + builder.run(args); + } catch (Exception e) { + LoggerFactory.getLogger(SWTImporterApplication.class).error("SWT-Loader start failed: {} -> {}", e.getClass().getSimpleName(), e.getMessage()); + System.exit(-1); + } + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/ImporterImdgConfig.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/ImporterImdgConfig.java new file mode 100644 index 000000000..26dd3bc45 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/ImporterImdgConfig.java @@ -0,0 +1,46 @@ +package ru.spcex.clearing.swt.importer.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.swt.importer.config.settings.ImportSWTServiceSettings; +import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; + +@Configuration +public class ImporterImdgConfig { + 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 HazelcastService imdgProvider( + @Qualifier("taskExecutorHazelcastClientInitializer") ThreadPoolTaskExecutor taskExecutorHazelcastClientInitializer, + @Qualifier("taskExecutorIdGeneratorAwaiter") ThreadPoolTaskExecutor taskExecutorIdGeneratorAwaiter, + ImportSWTServiceSettings settings + ) { + return new HazelcastService(taskExecutorHazelcastClientInitializer, + taskExecutorIdGeneratorAwaiter, + settings.getHazelcast()); + } + +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/KafkaConfig.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/KafkaConfig.java new file mode 100644 index 000000000..f3a9a6117 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/KafkaConfig.java @@ -0,0 +1,60 @@ +package ru.spcex.clearing.swt.importer.config; + +import org.apache.kafka.clients.consumer.Consumer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.config.KafkaConsumerFactory; +import ru.spcex.clearing.platform.messaging.config.KafkaProducerFactory; +import ru.spcex.clearing.platform.messaging.config.element.KafkaProducerSettings; +import ru.spcex.clearing.platform.messaging.service.RequestInfo; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.clearing.swt.importer.config.settings.ImportSWTServiceSettings; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.util.function.Supplier; + +@Configuration +public class KafkaConfig { + + @Bean + public ProducerFactory pf(ImportSWTServiceSettings settings) { + KafkaProducerSettings kafkaSettings = settings.getKafkaProducer(); + return KafkaProducerFactory.producerFactory(kafkaSettings); + } + + @Bean("kafkaTemplate") + public KafkaTemplate kafkaTemplate(ProducerFactory pf) { + return new KafkaTemplate<>(pf); + } + + @Autowired + @Bean + public Supplier kafkaSender(KafkaTemplate kafkaTemplate, + ImdgProvider imdgProvider) { + ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator(); + return () -> KafkaSender + .setup() + .setKafkaTemplate(kafkaTemplate) + .idGenerator(imdgIdGenerator::nextId) + .imdgProvider(s -> { + Imdg imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class); + return imdg::insert; + }) + .build(); + } + + @Autowired + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + @Bean + public Consumer createConsumer(ImportSWTServiceSettings settings) { + return KafkaConsumerFactory.consumer(settings.getKafkaConsumer()); + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/SWTImporterConfig.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/SWTImporterConfig.java new file mode 100644 index 000000000..efffb5d6c --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/SWTImporterConfig.java @@ -0,0 +1,67 @@ +package ru.spcex.clearing.swt.importer.config; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import ru.spcex.clearing.swt.importer.config.settings.ImportSWTServiceSettings; +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; +import ru.spcex.clearing.swt.importer.logic.data.tables.AbstractTable; +import ru.spcex.clearing.swt.importer.logic.data.tables.SDf08Table; +import ru.spcex.clearing.swt.importer.logic.data.tables.SDf10Table; +import ru.spcex.clearing.swt.importer.logic.data.tables.SDf13Table; +import ru.spcex.clearing.swt.importer.logic.stages.*; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +@Configuration +@EnableConfigurationProperties +@ComponentScan(basePackages = {"ru.spcex.clearing.swt.importer"}) +public class SWTImporterConfig { + private final ImportSWTServiceSettings settings; + private final ApplicationContext context; + + + public SWTImporterConfig(ImportSWTServiceSettings settings, ApplicationContext context) { + this.settings = settings; + this.context = context; + } + + @Bean("pipeline") + public List pipeline() { + List pipeline = new LinkedList<>(); + pipeline.add(context.getBean(LoadFileFromDisk.class)); + pipeline.add(context.getBean(ValidateFields.class)); + pipeline.add(context.getBean(ImportToDB.class)); + pipeline.add(context.getBean(ChangeDirOfFileStage.class)); + return pipeline; + } + + @Bean("executor") + public ThreadPoolTaskExecutor executor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setMaxPoolSize(settings.getCommon().getThreadsCount()); + executor.setCorePoolSize(settings.getCommon().getThreadsCount()); + executor.setThreadNamePrefix("swt-importer-thread-"); + executor.setWaitForTasksToCompleteOnShutdown(true); + executor.setAwaitTerminationSeconds(300); + executor.initialize(); + return executor; + } + + @Bean("mapOfTable") + public Map getMapOfTables() { + Map map = new HashMap<>(); + map.put(ETable.S_DF_08, new SDf08Table()); + map.put(ETable.S_DF_10, new SDf10Table()); + map.put(ETable.S_DF_13, new SDf13Table()); + return map; + } + + +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Common.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Common.java new file mode 100644 index 000000000..5069cd71c --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Common.java @@ -0,0 +1,32 @@ +package ru.spcex.clearing.swt.importer.config.settings; + +public class Common { + + private String encodingSource; + private int insertBatchSize; + private int threadsCount; + + public String getEncodingSource() { + return encodingSource; + } + + public void setEncodingSource(String encodingSource) { + this.encodingSource = encodingSource; + } + + public int getInsertBatchSize() { + return insertBatchSize; + } + + public void setInsertBatchSize(int insertBatchSize) { + this.insertBatchSize = insertBatchSize; + } + + public int getThreadsCount() { + return threadsCount; + } + + public void setThreadsCount(int threadsCount) { + this.threadsCount = threadsCount; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Cron.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Cron.java new file mode 100644 index 000000000..d747eab18 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Cron.java @@ -0,0 +1,14 @@ +package ru.spcex.clearing.swt.importer.config.settings; + +public class Cron { + + private String checkSrcDirCron; + + public String getCheckSrcDirCron() { + return checkSrcDirCron; + } + + public void setCheckSrcDirCron(String checkSrcDirCron) { + this.checkSrcDirCron = checkSrcDirCron; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/ImportSWTServiceSettings.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/ImportSWTServiceSettings.java new file mode 100644 index 000000000..5b00ee62d --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/ImportSWTServiceSettings.java @@ -0,0 +1,68 @@ +package ru.spcex.clearing.swt.importer.config.settings; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; +import ru.spcex.clearing.platform.messaging.config.element.KafkaConsumerSettings; +import ru.spcex.clearing.platform.messaging.config.element.KafkaProducerSettings; +import ru.spcex.platform.imdg.iml.hazelcast.config.HazelcastClientParams; + +@Component +@PropertySource("file:${spring.config.location}/application.properties") +@ConfigurationProperties("import-swt-service") +public class ImportSWTServiceSettings { + private HazelcastClientParams hazelcast; + private KafkaProducerSettings kafkaProducer; + private KafkaConsumerSettings kafkaConsumer; + private Common common; + private Store store; + private Cron cron; + + public HazelcastClientParams getHazelcast() { + return hazelcast; + } + + public void setHazelcast(HazelcastClientParams hazelcast) { + this.hazelcast = hazelcast; + } + + public KafkaProducerSettings getKafkaProducer() { + return kafkaProducer; + } + + public void setKafkaProducer(KafkaProducerSettings kafkaProducer) { + this.kafkaProducer = kafkaProducer; + } + + public KafkaConsumerSettings getKafkaConsumer() { + return kafkaConsumer; + } + + public void setKafkaConsumer(KafkaConsumerSettings kafkaConsumer) { + this.kafkaConsumer = kafkaConsumer; + } + + public Common getCommon() { + return common; + } + + public void setCommon(Common common) { + this.common = common; + } + + public Store getStore() { + return store; + } + + public void setStore(Store store) { + this.store = store; + } + + public Cron getCron() { + return cron; + } + + public void setCron(Cron cron) { + this.cron = cron; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Store.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Store.java new file mode 100644 index 000000000..f74a91998 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/config/settings/Store.java @@ -0,0 +1,41 @@ +package ru.spcex.clearing.swt.importer.config.settings; + +public class Store { + + private String srcDir; + private String outDir; + private String outDirError; + private boolean deleteSrcFiles = true; + + public String getSrcDir() { + return srcDir; + } + + public void setSrcDir(String srcDir) { + this.srcDir = srcDir; + } + + public String getOutDir() { + return outDir; + } + + public void setOutDir(String outDir) { + this.outDir = outDir; + } + + public boolean isDeleteSrcFiles() { + return deleteSrcFiles; + } + + public void setDeleteSrcFiles(boolean deleteSrcFiles) { + this.deleteSrcFiles = deleteSrcFiles; + } + + public String getOutDirError() { + return outDirError; + } + + public void setOutDirError(String outDirError) { + this.outDirError = outDirError; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/controller/ImporterController.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/controller/ImporterController.java new file mode 100644 index 000000000..ee2470f5f --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/controller/ImporterController.java @@ -0,0 +1,37 @@ +package ru.spcex.clearing.swt.importer.controller; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import ru.spcex.clearing.swt.importer.services.SWTImporterService; + +@Controller("/") +public class ImporterController implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final SWTImporterService importerService; + + public ImporterController(@Qualifier("swtImporterService") SWTImporterService importerService) { + this.importerService = importerService; + } + + @RequestMapping(method = RequestMethod.GET, path = "/import", produces = MediaType.TEXT_PLAIN_VALUE) + @ResponseBody + public String checkFolder() { + log.info("Call check method for importer controller"); + importerService.run(); + return "dbf import complete, see log"; + } + + + @Override + public void afterPropertiesSet() throws Exception { + log.info("controller started"); + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/controller/LauncherCommandReceiver.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/controller/LauncherCommandReceiver.java new file mode 100644 index 000000000..1ca177ca6 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/controller/LauncherCommandReceiver.java @@ -0,0 +1,43 @@ +package ru.spcex.clearing.swt.importer.controller; + +import org.apache.kafka.clients.consumer.Consumer; +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.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; +import ru.spcex.clearing.swt.importer.services.SWTImporterService; +import ru.spcex.platform.enumeration.Task; + +@Service +public class LauncherCommandReceiver extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final SWTImporterService importer; + + @Autowired + public LauncherCommandReceiver(Consumer kafkaQueue, + SWTImporterService importer) { + super(kafkaQueue); + this.importer = importer; + } + + /** + * В реальности не используется + */ + @Override + public void afterPropertiesSet() { + callback(LauncherCommandRequest.class) + .setConsumer(action -> importer.run(ETable.S_DF_08)) + .forDestination(Task.createOrderConfirm.topic(), callbacks::put); // CORC + callback(LauncherCommandRequest.class) + .setConsumer(action -> importer.run(ETable.S_DF_10)) + .forDestination(Task.accrualOfBalance.topic(), callbacks::put); // GBAL + callback(LauncherCommandRequest.class) + .setConsumer(action -> importer.run(ETable.S_DF_13)) + .forDestination(Task.getBalance.topic(), callbacks::put); // GBLD + init(); + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/exceptions/ConfigException.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/exceptions/ConfigException.java new file mode 100644 index 000000000..e91682613 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/exceptions/ConfigException.java @@ -0,0 +1,6 @@ +package ru.spcex.clearing.swt.importer.exceptions; + +public class ConfigException extends RuntimeException { + public ConfigException(String msg) { super(msg); } + public ConfigException(String msg, Throwable cause) { super(msg, cause); } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/Processor.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/Processor.java new file mode 100644 index 000000000..a34e67c5c --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/Processor.java @@ -0,0 +1,44 @@ +package ru.spcex.clearing.swt.importer.logic; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; +import ru.spcex.clearing.swt.importer.logic.data.ResultContainer; +import ru.spcex.clearing.swt.importer.logic.data.enums.StageResult; +import ru.spcex.clearing.swt.importer.logic.stages.Stage; + +import java.util.Arrays; +import java.util.List; + +@Component("processor") +public class Processor { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final List pipeline; + + public Processor(@Qualifier("pipeline") List pipeline) { + this.pipeline = pipeline; + } + + public void process(ResultContainer task) { + log.info("uuid {}. Task started", task.getUuid()); + long startMills = System.currentTimeMillis(); + for (Stage currStage : pipeline) { + if (statusIsFinal(task.getLastStageStatus()) && currStage.skipCompleted()) { + continue; + } + log.info("uuid {}. Stage: {}", task.getUuid(), currStage.getClass().getSimpleName()); + task.setLastStageStatus(currStage.process(task)); + log.info("uuid {}. Stage {} finished with status {}", task.getUuid(), currStage.getClass().getSimpleName(), task.getLastStageStatus()); + } + long endMills = System.currentTimeMillis(); + log.info("uuid {}. Task completed, result: {}, time working: {} ms", + task.getUuid(), + task, + endMills - startMills); + } + + private boolean statusIsFinal(StageResult previousStageStatus) { + return Arrays.asList(StageResult.ERROR, StageResult.COMPLETE).contains(previousStageStatus); + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ColumnStructureSWT.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ColumnStructureSWT.java new file mode 100644 index 000000000..390873c0f --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ColumnStructureSWT.java @@ -0,0 +1,51 @@ +package ru.spcex.clearing.swt.importer.logic.data; + +import ru.spcex.clearing.swt.importer.logic.data.enums.ColumnType; + +public class ColumnStructureSWT { + private String name; + private ColumnType type; + private int length; + private int decimalDigits; + private String comment; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ColumnType getType() { + return type; + } + + public void setType(ColumnType type) { + this.type = type; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getDecimalDigits() { + return decimalDigits; + } + + public void setDecimalDigits(int decimalDigits) { + this.decimalDigits = decimalDigits; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/DBStructureSWT.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/DBStructureSWT.java new file mode 100644 index 000000000..a8570935f --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/DBStructureSWT.java @@ -0,0 +1,18 @@ +package ru.spcex.clearing.swt.importer.logic.data; + +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; + +import java.util.EnumMap; +import java.util.Map; + +public class DBStructureSWT { + private Map tables = new EnumMap<>(ETable.class); + + public Map getTables() { + return tables; + } + + public void setTables(Map tables) { + this.tables = tables; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ResultContainer.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ResultContainer.java new file mode 100644 index 000000000..f145b8215 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ResultContainer.java @@ -0,0 +1,70 @@ +package ru.spcex.clearing.swt.importer.logic.data; + +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; +import ru.spcex.clearing.swt.importer.logic.data.enums.StageResult; + +import java.io.File; +import java.util.UUID; + +/** + * Контейнер для передачи результата между стадиями + */ +public class ResultContainer { + private UUID uuid; + private ETable swtTable; + private File swtFile; + private StageResult lastStageStatus; + + private byte[] swtSource; + + protected ResultContainer() { + } + + public static ResultContainer createNewTask(ETable dbfTable, File dbfFile) { + ResultContainer container = new ResultContainer(); + container.swtTable = dbfTable; + container.swtFile = dbfFile; + container.uuid = UUID.randomUUID(); + return container; + } + + public ETable getSwtTable() { + return swtTable; + } + + public void setSwtTable(ETable swtTable) { + this.swtTable = swtTable; + } + + public byte[] getSwtSource() { + return swtSource; + } + + public void setSwtSource(byte[] swtSource) { + this.swtSource = swtSource; + } + + public File getSwtFile() { + return swtFile; + } + + public void setSwtFile(File swtFile) { + this.swtFile = swtFile; + } + + public UUID getUuid() { + return uuid; + } + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + + public StageResult getLastStageStatus() { + return lastStageStatus; + } + + public void setLastStageStatus(StageResult lastStageRes) { + this.lastStageStatus = lastStageRes; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/TableStructureSWT.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/TableStructureSWT.java new file mode 100644 index 000000000..c19be9fdd --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/TableStructureSWT.java @@ -0,0 +1,25 @@ +package ru.spcex.clearing.swt.importer.logic.data; + +import java.util.HashMap; +import java.util.Map; + +public class TableStructureSWT { + private Map columns = new HashMap<>(); + + public Map getColumns() { + return columns; + } + + public void setColumns(Map columns) { + this.columns = columns; + } + + public ColumnStructureSWT getIgnoreCase(String columnName) { + for (Map.Entry entry : columns.entrySet()) { + String currColumnName = entry.getKey(); + if (currColumnName.equalsIgnoreCase(columnName)) return entry.getValue(); + } + return null; + } + +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ColumnType.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ColumnType.java new file mode 100644 index 000000000..2a1f5a751 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ColumnType.java @@ -0,0 +1,46 @@ +package ru.spcex.clearing.swt.importer.logic.data.enums; + +import com.linuxense.javadbf.DBFDataType; + +import java.sql.Types; + +/** + * Типы данных в таблицах. + * Ставит в соответствие типы PostGRE и DBF + */ +public enum ColumnType { + VARCHAR(DBFDataType.CHARACTER, Types.VARCHAR), + CHARACTER(DBFDataType.CHARACTER, Types.CHAR), + NUMERIC(DBFDataType.NUMERIC, Types.NUMERIC), + DATE(DBFDataType.DATE, Types.DATE); + + private final DBFDataType dbfType; + private final int sqlType; + + ColumnType(DBFDataType dbfType, int postgreSqlType) { + this.dbfType = dbfType; + this.sqlType = postgreSqlType; + } + + public DBFDataType getDbfType() { + return dbfType; + } + + public int getSqlType() { + return sqlType; + } + + public static ColumnType getForSQLType(int sqlType) { + for (ColumnType columnType : values()) { + if (columnType.sqlType == sqlType) return columnType; + } + return null; + } + + public static ColumnType getForDBFType(DBFDataType dbfType) { + for (ColumnType columnType : values()) { + if (columnType.dbfType == dbfType) return columnType; + } + return null; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ETable.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ETable.java new file mode 100644 index 000000000..25a632513 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ETable.java @@ -0,0 +1,33 @@ +package ru.spcex.clearing.swt.importer.logic.data.enums; + +public enum ETable { + S_DF_08("S_DF08"), + S_DF_10("S_DF10"), + S_DF_13("S_DF13"); + //S_DF20("S_DF20"); + + private final String prefix; + + ETable(String prefix) { + this.prefix = prefix; + } + + public static ETable getTableForFilename(String filename) { + for (ETable table : ETable.values()) { + if (table.fileForThisTable(filename)) return table; + } + return null; + } + + public static ETable tableForName(String name) { + for (ETable table : values()) { + if (name.equalsIgnoreCase(table.name())) + return table; + } + return null; + } + + public boolean fileForThisTable(String filename) { + return filename != null && filename.startsWith(prefix); + } + } diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/StageResult.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/StageResult.java new file mode 100644 index 000000000..570ae98f0 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/StageResult.java @@ -0,0 +1,7 @@ +package ru.spcex.clearing.swt.importer.logic.data.enums; + +public enum StageResult { + OK, + ERROR, + COMPLETE +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/AbstractTable.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/AbstractTable.java new file mode 100644 index 000000000..93b60acd2 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/AbstractTable.java @@ -0,0 +1,46 @@ +package ru.spcex.clearing.swt.importer.logic.data.tables; + +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast; +import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; + +public abstract class AbstractTable { + private final String prefix; + private final Class clazz; + private final String nameOfMap; + protected HazelcastService hazelcastService; + protected ImdgHazelcast map; + protected String filename; + protected Long fileId; + + protected AbstractTable(String prefix, Class clazz, String nameOfMap) { + this.prefix = prefix; + this.clazz = clazz; + this.nameOfMap = nameOfMap; + } + + public void setFileId(Long fileId) { + this.fileId = fileId; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public void setHazelcastService(HazelcastService hazelcastService) { + this.hazelcastService = hazelcastService; + } + + public abstract T getEntity(Object[] entity); + + public void injectEntity(T obj) { + if (map == null) { + bootMap(); + } + map.insert(obj); + } + + private void bootMap() { + map = (ImdgHazelcast) hazelcastService.getImdg(nameOfMap, clazz); + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java new file mode 100644 index 000000000..193b3ed80 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java @@ -0,0 +1,33 @@ +package ru.spcex.clearing.swt.importer.logic.data.tables; + +import ru.clearing.classes.statics.data.sdf.SDf08; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; + +import java.time.Instant; + +public class SDf08Table extends AbstractTable { + + private static final String PREFIX = ETable.S_DF_08.name(); + private static final Class CLAZZ = SDf08.class; + private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf08; + + public SDf08Table() { + super(PREFIX, CLAZZ, NAME_OF_HZ_MAP); + } + + @Override + public SDf08 getEntity(Object[] entity) { + SDf08 result = new SDf08(); + result.setOutDocument((String) entity[0]); + result.setDepoCode((String) entity[1]); + result.setQuantity((String) entity[2]); + result.setSecurityCode((String) entity[3]); + result.setClientName((String) entity[4]); + result.setFileName(filename); + result.setGenerationTime(Instant.now()); + result.setGenerationId(fileId); + return result; + } + +} \ No newline at end of file diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java new file mode 100644 index 000000000..c1a885b20 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java @@ -0,0 +1,33 @@ +package ru.spcex.clearing.swt.importer.logic.data.tables; + +import ru.clearing.classes.statics.data.sdf.SDf10; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; + +import java.time.Instant; + +public class SDf10Table extends AbstractTable { + + private static final String PREFIX = ETable.S_DF_10.name(); + private static final Class CLAZZ = SDf10.class; + private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf10; + + public SDf10Table() { + super(PREFIX, CLAZZ, NAME_OF_HZ_MAP); + } + + @Override + public SDf10 getEntity(Object[] entity) { + SDf10 result = new SDf10(); + result.setOutDocument((String) entity[0]); + result.setDepoCode((String) entity[1]); + result.setQuantity((String) entity[2]); + result.setSecurityCode((String) entity[3]); + result.setClientName((String) entity[4]); + result.setFileName(filename); + result.setGenerationTime(Instant.now()); + result.setGenerationId(fileId); + return result; + } + +} \ No newline at end of file diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf13Table.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf13Table.java new file mode 100644 index 000000000..63385b7e5 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf13Table.java @@ -0,0 +1,29 @@ +package ru.spcex.clearing.swt.importer.logic.data.tables; + +import ru.clearing.classes.statics.data.sdf.SDf13; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; + +import java.time.Instant; + +public class SDf13Table extends AbstractTable { + + private static final String PREFIX = ETable.S_DF_13.name(); + private static final Class CLAZZ = SDf13.class; + private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf13; + + public SDf13Table() { + super(PREFIX, CLAZZ, NAME_OF_HZ_MAP); + } + + @Override + public SDf13 getEntity(Object[] entity) { + SDf13 result = new SDf13(); + + result.setFileName(filename); + result.setGenerationTime(Instant.now()); + result.setGenerationId(fileId); + return result; + } + +} \ No newline at end of file diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ChangeDirOfFileStage.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ChangeDirOfFileStage.java new file mode 100644 index 000000000..60dfa77fb --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ChangeDirOfFileStage.java @@ -0,0 +1,79 @@ +package ru.spcex.clearing.swt.importer.logic.stages; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import ru.spcex.clearing.swt.importer.config.settings.ImportSWTServiceSettings; +import ru.spcex.clearing.swt.importer.logic.data.ResultContainer; +import ru.spcex.clearing.swt.importer.logic.data.enums.StageResult; +import ru.spcex.platform.utils.time.TimeUtil; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.time.Instant; +import java.time.format.DateTimeFormatter; + +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; + + +@Component +public class ChangeDirOfFileStage extends Stage { + + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy.MM.dd HH.mm.ss"); + private final ImportSWTServiceSettings settings; + + @Autowired + public ChangeDirOfFileStage(ImportSWTServiceSettings settings) { + this.settings = settings; + } + + @Override + public boolean skipCompleted() { + return false; + } + + @Override + public StageResult process(ResultContainer resultContainer) { + File srcDir = new File(settings.getStore().getSrcDir()); + File outDir; + if (resultContainer.getLastStageStatus().equals(StageResult.ERROR)) { + outDir = new File(settings.getStore().getOutDirError()); + + } else { + outDir = new File(settings.getStore().getOutDir()); + } + File dbfFile = resultContainer.getSwtFile(); + + if (!srcDir.exists()) { + log.error("SettlementHouse_DocIn does not exists!"); + return StageResult.ERROR; + } + if (!outDir.exists()) { + log.warn("ouput directory {} does not exists! Trying to made new!", outDir.getAbsolutePath()); + if (outDir.mkdir()) { + log.error("Made dir {} successfully!", outDir.getName()); + } else { + log.error("SettlementHouse_DocIn does not exists!"); + return StageResult.ERROR; + } + } + if (!dbfFile.exists()) { + log.error("SWT file to save does not exists!"); + return StageResult.ERROR; + } + String newNameOfFile = TimeUtil.formatInstant(Instant.now(), FORMATTER) + '_' + dbfFile.getName(); + + try { + Files.move(dbfFile.toPath(), outDir.toPath().resolve(newNameOfFile), REPLACE_EXISTING); + } catch (IOException e) { + log.error("Could not move file {}", e.getMessage()); + return StageResult.ERROR; + } + + if (resultContainer.getLastStageStatus().equals(StageResult.ERROR)) { + return StageResult.ERROR; + } else { + return StageResult.COMPLETE; + } + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ImportToDB.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ImportToDB.java new file mode 100644 index 000000000..3bd3fed06 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ImportToDB.java @@ -0,0 +1,73 @@ +package ru.spcex.clearing.swt.importer.logic.stages; + +import com.linuxense.javadbf.DBFReader; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; +import ru.spcex.clearing.swt.importer.config.settings.ImportSWTServiceSettings; +import ru.spcex.clearing.swt.importer.logic.data.ResultContainer; +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; +import ru.spcex.clearing.swt.importer.logic.data.enums.StageResult; +import ru.spcex.clearing.swt.importer.logic.data.tables.AbstractTable; +import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; +import ru.spcex.platform.utils.log.ExceptionUtils; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.Map; + +/** + * Заливка проверенных данных в базу + */ +@Component +public class ImportToDB extends Stage { + private final ImportSWTServiceSettings settings; + private final HazelcastService hazelcastService; + private final Map mappingEnumTableObjectTable; + private final SWTImportKafkaMessenger kafkaMessenger; + + public ImportToDB(ImportSWTServiceSettings settings, + HazelcastService hazelcastService, + @Qualifier("mapOfTable") Map mappingEnumTableObjectTable, + SWTImportKafkaMessenger kafkaMessenger) { + this.settings = settings; + this.hazelcastService = hazelcastService; + this.mappingEnumTableObjectTable = mappingEnumTableObjectTable; + this.kafkaMessenger = kafkaMessenger; + } + + @Override + public StageResult process(ResultContainer resultContainer) { + ETable currTable = resultContainer.getSwtTable(); + byte[] source = resultContainer.getSwtSource(); + Charset sourceCharset = Charset.forName(settings.getCommon().getEncodingSource()); + + try (InputStream is = new ByteArrayInputStream(source); + DBFReader dbfReader = new DBFReader(is, sourceCharset)) { + AbstractTable table = mappingEnumTableObjectTable.get(currTable); + table.setHazelcastService(hazelcastService); + table.setFilename(resultContainer.getSwtFile().getName()); + Long fileId = hazelcastService.getImdgIdGenerator().nextId(); + table.setFileId(fileId); + for (int i = 0; i < dbfReader.getRecordCount(); i++) { + Object[] entity = dbfReader.nextRecord(); + if (entity == null) { + log.warn("record index {} null", i); + continue; + } + table.injectEntity(table.getEntity(entity)); + } + kafkaMessenger.notifySystemIfNeeded(currTable, fileId); + } catch (IOException exception) { + log.warn(exception.getMessage()); + return StageResult.ERROR; + } catch (Throwable e) { + log.error(ExceptionUtils.getStackTrace(e)); + return StageResult.ERROR; + } + + + return StageResult.OK; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/LoadFileFromDisk.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/LoadFileFromDisk.java new file mode 100644 index 000000000..1ed315a33 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/LoadFileFromDisk.java @@ -0,0 +1,44 @@ +package ru.spcex.clearing.swt.importer.logic.stages; + +import org.springframework.stereotype.Component; +import ru.spcex.clearing.swt.importer.config.settings.ImportSWTServiceSettings; +import ru.spcex.clearing.swt.importer.logic.data.ResultContainer; +import ru.spcex.clearing.swt.importer.logic.data.enums.StageResult; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Objects; +import java.util.UUID; + +@Component +public class LoadFileFromDisk extends Stage { + private final ImportSWTServiceSettings settings; + + public LoadFileFromDisk(ImportSWTServiceSettings settings) { + this.settings = settings; + } + + @Override + public StageResult process(ResultContainer resultContainer) { + Objects.requireNonNull(resultContainer.getSwtFile()); + UUID taskUuid = resultContainer.getUuid(); + + File dbfFile = resultContainer.getSwtFile(); + byte[] fileBytes; + try { + log.debug("uuid {}. Read all bytes from source file {}", taskUuid, resultContainer.getSwtFile().getName()); + fileBytes = Files.readAllBytes(Paths.get(dbfFile.getAbsolutePath())); + if (fileBytes.length == 0) throw new IOException("Empty file"); + if (settings.getStore().isDeleteSrcFiles()) Files.delete(dbfFile.toPath()); + } catch (IOException e) { + log.error(String.format("uuid %s. Can't read file %s", taskUuid, resultContainer.getSwtFile().getName()), e); + return StageResult.ERROR; + } + log.debug("uuid {}. Read all bytes from source file complete", taskUuid); + resultContainer.setSwtSource(fileBytes); + return StageResult.OK; + } + +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/SWTImportKafkaMessenger.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/SWTImportKafkaMessenger.java new file mode 100644 index 000000000..f37ec2930 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/SWTImportKafkaMessenger.java @@ -0,0 +1,51 @@ +package ru.spcex.clearing.swt.importer.logic.stages; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Component; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; +import ru.spcex.platform.enumeration.SdfTable; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; + +@Component +public class SWTImportKafkaMessenger implements InitializingBean { + private final Supplier kafka; + private final Map> messengers; + + public SWTImportKafkaMessenger(Supplier kafka) { + this.kafka = kafka; + this.messengers = new HashMap<>(); + } + + @Override + public void afterPropertiesSet() { + messengers.put(ETable.S_DF_08, groupId -> messageBalance(groupId, SdfTable.SDF_08)); + messengers.put(ETable.S_DF_10, groupId -> messageBalance(groupId, SdfTable.SDF_10)); + messengers.put(ETable.S_DF_13, groupId -> messageBalance(groupId, SdfTable.SDF_13)); + } + + /** + * отправляет в кафку сообщение, при необходимости + * (обрабатывается, например, в balance-service, clearing-service) + */ + public void notifySystemIfNeeded(ETable table, Long groupId) { + Consumer messenger = messengers.get(table); + if (messenger != null) { + messenger.accept(groupId); + } + } + + private void messageBalance(Long groupId, SdfTable table) { + StatementRequest statementRequest = new StatementRequest(); + statementRequest.setGroupId(groupId); + statementRequest.setTable(table); + kafka.get().sendRequestToQueue(Consts.STATEMENT_PROCESS, statementRequest); + } + +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/Stage.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/Stage.java new file mode 100644 index 000000000..b8b8fbc73 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/Stage.java @@ -0,0 +1,16 @@ +package ru.spcex.clearing.swt.importer.logic.stages; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.spcex.clearing.swt.importer.logic.data.ResultContainer; +import ru.spcex.clearing.swt.importer.logic.data.enums.StageResult; + +public abstract class Stage { + protected Logger log = LoggerFactory.getLogger(getClass()); + + public abstract StageResult process(ResultContainer resultContainer); + + public boolean skipCompleted() { + return true; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ValidateFields.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ValidateFields.java new file mode 100644 index 000000000..0451716da --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ValidateFields.java @@ -0,0 +1,44 @@ +package ru.spcex.clearing.swt.importer.logic.stages; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Component; +import ru.spcex.clearing.swt.importer.config.settings.ImportSWTServiceSettings; +import ru.spcex.clearing.swt.importer.exceptions.ConfigException; +import ru.spcex.clearing.swt.importer.logic.data.ResultContainer; +import ru.spcex.clearing.swt.importer.logic.data.enums.StageResult; + +import java.nio.charset.Charset; + +/** + * Фильтрация источника на предмет соответствия полей + */ +@Component +public class ValidateFields extends Stage implements InitializingBean { + private final ImportSWTServiceSettings settings; + private Charset swtCharset; + + public ValidateFields(ImportSWTServiceSettings settings) { + this.settings = settings; + } + + @Override + public StageResult process(ResultContainer resultContainer) { + return StageResult.OK; + } + + /** + * 1. Проверяет кодировку из настройки dbf.encoding-source + */ + @Override + public void afterPropertiesSet() throws Exception { + initSWTCharset(); + } + + private void initSWTCharset() { + try { + swtCharset = Charset.forName(settings.getCommon().getEncodingSource()); + } catch (Exception e) { + throw new ConfigException("Unknown encoding from properties: " + settings.getCommon().getEncodingSource(), e); + } + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/FileChecker.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/FileChecker.java new file mode 100644 index 000000000..e4d2d9a26 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/FileChecker.java @@ -0,0 +1,56 @@ +package ru.spcex.clearing.swt.importer.services; + +import org.springframework.stereotype.Service; +import ru.spcex.clearing.swt.importer.config.settings.ImportSWTServiceSettings; +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; + +import java.io.File; +import java.util.*; + +@Service("fileChecker") +public class FileChecker { + private final ImportSWTServiceSettings settings; + + public FileChecker(ImportSWTServiceSettings settings) { + this.settings = settings; + } + + public Map> checkNewFiles() { + return checkNewFiles(null); + } + + public Map> checkNewFiles(ETable specificTable) { + Map> newFiles = new EnumMap<>(ETable.class); + + String srcDir = settings.getStore().getSrcDir(); + List dbfFiles = lsDBF(srcDir); + if (dbfFiles.isEmpty()) return newFiles; + + for (File dbfFile : dbfFiles) { + if (dbfFile.isDirectory()) continue; + + ETable currTable = ETable.getTableForFilename(dbfFile.getName()); + if (currTable == null) continue; + if (specificTable != null && !specificTable.equals(currTable)) continue; + List currList = newFiles.computeIfAbsent(currTable, list -> new LinkedList<>()); + currList.add(dbfFile); + } + return newFiles; + } + + private List lsDBF(String dbfDirPath) { + File dbfDir = new File(dbfDirPath); + File[] dbfFiles = dbfDir.listFiles((dir, name) -> { + int formatPosition = name.lastIndexOf("."); + if (formatPosition == -1 || formatPosition == name.length() - 1) return false; + return "dbf".equalsIgnoreCase(name.substring(formatPosition + 1)); + }); + + List resultFiles = new LinkedList<>(); + if (dbfFiles != null && dbfFiles.length >= 1) { + resultFiles.addAll(Arrays.asList(dbfFiles)); + } + + return resultFiles; + } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/SWTImporterService.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/SWTImporterService.java new file mode 100644 index 000000000..b7b65395f --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/SWTImporterService.java @@ -0,0 +1,119 @@ +package ru.spcex.clearing.swt.importer.services; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Service; +import ru.spcex.clearing.swt.importer.logic.Processor; +import ru.spcex.clearing.swt.importer.logic.data.ResultContainer; +import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; + +import java.io.File; +import java.nio.file.Path; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Service("swtImporterService") +@EnableScheduling +public class SWTImporterService { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final FileChecker fileChecker; + private final ThreadPoolTaskExecutor executorService; + private final Processor processor; + private final Set filesCurrentlyInProcess; + + public SWTImporterService(@Qualifier("fileChecker") FileChecker messageListener, + @Qualifier("executor") ThreadPoolTaskExecutor executorService, + @Qualifier("processor") Processor processor) { + this.fileChecker = messageListener; + this.executorService = executorService; + this.processor = processor; + this.filesCurrentlyInProcess = new HashSet<>(); + } + + private static String forLogging(Map> files) { + return files + .entrySet() + .stream() + .flatMap((Function>, Stream>) entry -> { + List r = new LinkedList<>(); + for (File file : entry.getValue()) { + r.add(entry.getKey().name() + " " + file.toPath()); + } + return r.stream(); + }) + .collect(Collectors.joining(";", "[", "]")); + } + + private static String forLoggingSizeOnly(Map> files) { + return files + .entrySet() + .stream() + .map(entry -> entry.getKey().name() + " " + entry.getValue().size()) + .collect(Collectors.joining(";", "[", "]")); + } + + @Scheduled(cron = "${import-swt-service.scheduler.check-src-dir-cron}") + public void run() { + run(null); + } + + public void run(ETable specificTable) { + if (specificTable == null) { + log.trace("adding import task"); + } else { + log.info("adding import task {}", specificTable); + } + executorService.execute(() -> { + Map> newFiles = null; + try { + log.trace("checking new files... {}", specificTable != null ? specificTable.name() : ""); + newFiles = getFiles(specificTable); + if (newFiles.size() > 0 && log.isDebugEnabled()) { + log.debug("following files will be processed {}", forLogging(newFiles)); + } else if (newFiles.size() > 0) { + log.info("following files will be processed {}", forLoggingSizeOnly(newFiles)); + } else { + log.trace("no files were found"); + } + for (Map.Entry> newFilesEntry : newFiles.entrySet()) { + ETable currTable = newFilesEntry.getKey(); + List fileList = newFilesEntry.getValue(); + for (File swtFile : fileList) { + processor.process(ResultContainer.createNewTask(currTable, swtFile)); + } + } + } finally { + if (newFiles != null && newFiles.size() > 0) { + cleanFiles(newFiles); + } + } + }); + } + + private synchronized Map> getFiles(ETable specificTable) { + Map> newFiles = fileChecker.checkNewFiles(specificTable); + Map> newFilesFiltered = newFiles.entrySet() + .stream() + .map(entry -> + new AbstractMap.SimpleEntry<>(entry.getKey(), entry.getValue() + .stream() + .filter(file -> !filesCurrentlyInProcess.contains(file.toPath())) + .collect(Collectors.toList()))) + .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)); + newFilesFiltered.forEach((table, files) + -> files.forEach(file -> filesCurrentlyInProcess.add(file.toPath()))); + return newFilesFiltered; + } + + private synchronized void cleanFiles(Map> filesFromTask) { + filesFromTask.forEach((table, files) + -> files.forEach(file -> filesCurrentlyInProcess.remove(file.toPath()))); + } + +} diff --git a/clearing-parent/swt-importer/src/main/resources/application.properties b/clearing-parent/swt-importer/src/main/resources/application.properties new file mode 100644 index 000000000..93ff59338 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/resources/application.properties @@ -0,0 +1,34 @@ +server.port=8080 +server.servlet.context-path=/importer-swt +spring.main.web-application-type=servlet + +import-swt-service.scheduler.check-src-dir-cron=* * * * 1 ? + +import-swt-service.store.delete-src-files=false +import-swt-service.store.src-dir=/opt/clearing/file/importer/ +import-swt-service.store.out-dir=/opt/clearing/file/importer/loaded/ +import-swt-service.store.out-dir-error=/opt/clearing/file/importer/error/ + +import-swt-service.common.encoding-source=cp866 +import-swt-service.common.insert-batch-size=100 +import-swt-service.common.threads-count=10 + +import-swt-service.hazelcast.cluster-members=10.200.200.181:5701 +import-swt-service.hazelcast.login=dev +import-swt-service.hazelcast.password=dev-pass + + +import-swt-service.kafka-producer.bootstrap-servers=localhost:9092 +import-swt-service.kafka-producer.acks=all +import-swt-service.kafka-producer.retries=0 +import-swt-service.kafka-producer.batch-size=16384 +import-swt-service.kafka-producer.linger-ms=1 +import-swt-service.kafka-producer.buffer-memory=33554432 + +import-swt-service.kafka-consumer.bootstrap-servers=localhost:9092 +import-swt-service.kafka-consumer.group-id=dev-group-clearing-service +import-swt-service.kafka-consumer.enable-auto-commit=false +import-swt-service.kafka-consumer.session-timeout-ms=30000 +import-swt-service.kafka-consumer.auto-offset-reset=latest +import-swt-service.kafka-consumer.linger-ms=1 +import-swt-service.kafka-consumer.buffer-memory=33554432 \ No newline at end of file diff --git a/clearing-parent/swt-importer/src/main/resources/logback.xml b/clearing-parent/swt-importer/src/main/resources/logback.xml new file mode 100644 index 000000000..242290041 --- /dev/null +++ b/clearing-parent/swt-importer/src/main/resources/logback.xml @@ -0,0 +1,37 @@ + + + + + UTF-8 + %date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + ./logs/swt-importer.log + + UTF-8 + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + ../logs/swt-importer.%i.log + + 1 + 10 + + + 500MB + + + + + + + + + + + + + \ No newline at end of file diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java index 6a920d430..9cadeda18 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java @@ -3,16 +3,16 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum SdfTable implements IEnumKey { - SDF_01("SDF_01"), SDF_04("SDF_04"), SDF_08("SDF_08"), - SDF_13("SDF_13"), SDF_57("SDF_57"), SDF_09("SDF_09"), - SDF_16("SDF_16"); + SDF_08("SDF_08"), + SDF_10("SDF_10"), + SDF_13("SDF_13"); + + private final String key; SdfTable(String key) { this.key = key; } - private final String key; - @Override public String getKey() { return this.key; From a4b70c663582f804ca4ddca23f80d8941cf83372 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 13:42:30 +0300 Subject: [PATCH 03/36] =?UTF-8?q?company-service=20reports-service=20secur?= =?UTF-8?q?ities-service=20http://jira.mfd.msk:8088/browse/CLS-258=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20EndDtAfterSt?= =?UTF-8?q?artDtRule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/rules/EndDtAfterStartDtRule.java | 39 ++++++++++--------- .../company/service/CompanyService.java | 2 + .../config/validation/ValidationConfig.java | 4 +- .../resources/distr/bin/securities-service.sh | 2 +- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java index 1403e9338..92302ad9d 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/validation/common/rules/EndDtAfterStartDtRule.java @@ -14,60 +14,61 @@ import java.util.function.Function; * @param Класс проверяемого объекта */ public record EndDtAfterStartDtRule( - String endDtFieldName, String startDtFieldName, - Function getterEndDt, + String endDtFieldName, Function getterStartDt, + Function getterEndDt, IErrorEnumId errorEmptyRequiredValue, IErrorEnumId errorEndDtAfterStartDt, boolean required ) implements IValidationRule> { /** - * @param endDtFieldName Название поля класса, содержащий EndDt * @param startDtFieldName Название поля класса, содержащий StartDt - * @param getterEndDt Метод получения проверяемой EndDt + * @param endDtFieldName Название поля класса, содержащий EndDt * @param getterStartDt Метод получения проверяемой StartDt + * @param getterEndDt Метод получения проверяемой EndDt * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если одна из дат пустая * @param errorEndDtAfterStartDt Ошибка, которая будет возвращена, если EndDt > StartDt * @param required Флаг обязательности поля * @param Класс проверяемого объекта */ - public static EndDtAfterStartDtRule instance(String endDtFieldName, - String startDtFieldName, - Function getterEndDt, + public static EndDtAfterStartDtRule instance(String startDtFieldName, + String endDtFieldName, Function getterStartDt, + Function getterEndDt, IErrorEnumId errorEmptyRequiredValue, IErrorEnumId errorEndDtAfterStartDt, boolean required) { - return new EndDtAfterStartDtRule<>(endDtFieldName, - startDtFieldName, - getterEndDt, + return new EndDtAfterStartDtRule<>(startDtFieldName, + endDtFieldName, getterStartDt, + getterEndDt, errorEmptyRequiredValue, errorEndDtAfterStartDt, required); } /** - * @param endDtFieldName Название поля класса, содержащий EndDt * @param startDtFieldName Название поля класса, содержащий StartDt - * @param getterEndDt Метод получения проверяемой EndDt + * @param endDtFieldName Название поля класса, содержащий EndDt * @param getterStartDt Метод получения проверяемой StartDt + * @param getterEndDt Метод получения проверяемой EndDt * @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если одна из дат пустая - * @param errorEndDtAfterStartDt Ошибка, которая будет возвращена, если EndDt > StartDt + * @param errorEndDtAfterStartDt Ошибка, которая будет возвращена, если StartDt > EndDt * @param Класс проверяемого объекта */ - public static EndDtAfterStartDtRule instance(String endDtFieldName, + public static EndDtAfterStartDtRule instance( String startDtFieldName, - Function getterEndDt, + String endDtFieldName, Function getterStartDt, + Function getterEndDt, IErrorEnumId errorEmptyRequiredValue, IErrorEnumId errorEndDtAfterStartDt) { - return new EndDtAfterStartDtRule<>(endDtFieldName, - startDtFieldName, - getterEndDt, + return new EndDtAfterStartDtRule<>(startDtFieldName, + endDtFieldName, getterStartDt, + getterEndDt, errorEmptyRequiredValue, errorEndDtAfterStartDt, true); @@ -76,8 +77,8 @@ public record EndDtAfterStartDtRule( @Override public Optional validate(ImdgValidationContext context) { R validatedObject = context.getValidatedObject(); - LocalDate endDt = getterEndDt.apply(validatedObject); LocalDate startDt = getterStartDt.apply(validatedObject); + LocalDate endDt = getterEndDt.apply(validatedObject); if (endDt == null) return required ? of(errorEmptyRequiredValue, endDtFieldName) : Optional.empty(); if (startDt == null) return required ? of(errorEmptyRequiredValue, startDtFieldName) : Optional.empty(); if (startDt.isAfter(endDt)) return of(errorEndDtAfterStartDt, startDtFieldName, endDtFieldName); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java index 855745cf9..148c94093 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java @@ -141,6 +141,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { companyMap.insert(company); log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", companyNewRequestBaseRequest.getId(), company.getId()); + //todo see this CLS-333.2 relationService.createNewRelation(transaction, company.getId()); if (!(WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()))) { // Block relationService.onChangeWorkflowStatus(transaction, company, null, company.getWorkflowStatus()); @@ -196,6 +197,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { if (updateRequest.getWorkflowStatus() != null) { company.setWorkflowStatus(updateRequest.getWorkflowStatus()); if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { + //todo see this CLS-333.2 relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); } else { log.trace("Status was not changed"); diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/validation/ValidationConfig.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/validation/ValidationConfig.java index f01155eaf..5295a3da6 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/validation/ValidationConfig.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/validation/ValidationConfig.java @@ -135,9 +135,9 @@ public class ValidationConfig { }, ReportError.WrongFieldValue, ReportError.RequiredFieldEmpty), - EndDtAfterStartDtRule.instance("endDate", "startDate", - ReportRequestWithPeriod::getEndDate, + EndDtAfterStartDtRule.instance("startDate", "endDate", ReportRequestWithPeriod::getStartDate, + ReportRequestWithPeriod::getEndDate, ReportError.RequiredFieldEmpty, ReportError.WrongFieldValue) ); diff --git a/z-distr/src/main/resources/distr/bin/securities-service.sh b/z-distr/src/main/resources/distr/bin/securities-service.sh index 7ad5dd7e9..5bee3a9d1 100644 --- a/z-distr/src/main/resources/distr/bin/securities-service.sh +++ b/z-distr/src/main/resources/distr/bin/securities-service.sh @@ -3,7 +3,7 @@ CLEARING_HOME=/opt/mfd/clearing/ cd $CLEARING_HOME/bin -CMD="java -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7060 -jar securities-service.jar --spring.config.location=$CLEARING_HOME/settings/securities-service/" +CMD="java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:7060 -jar securities-service.jar --spring.config.location=$CLEARING_HOME/settings/securities-service/" $CMD >/dev/null 2>&1 & From f3067be20d3cbf7c006ad0b7aa2e3308bc5c287b Mon Sep 17 00:00:00 2001 From: aalehin Date: Sat, 27 May 2023 13:50:15 +0300 Subject: [PATCH 04/36] http://jira.mfd.msk:8088/browse/CLS-316 --- FIX UP --- .../java/ru/spcex/platform/enumeration/SdfTable.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java index 9cadeda18..3221f97dd 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SdfTable.java @@ -3,16 +3,21 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum SdfTable implements IEnumKey { + SDF_01("SDF_01"), + SDF_04("SDF_04"), SDF_08("SDF_08"), + SDF_09("SDF_09"), SDF_10("SDF_10"), - SDF_13("SDF_13"); - - private final String key; + SDF_13("SDF_13"), + SDF_16("SDF_16"), + SDF_57("SDF_57"); SdfTable(String key) { this.key = key; } + private final String key; + @Override public String getKey() { return this.key; From acd14d0390f783b10ec176208e18ae432fd9acfc Mon Sep 17 00:00:00 2001 From: ialbert Date: Sat, 27 May 2023 13:58:51 +0300 Subject: [PATCH 05/36] marketCodesForT0 list --- .../config/MarketCodesBySessionConfig.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MarketCodesBySessionConfig.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MarketCodesBySessionConfig.java index bffcb2729..4d7dc85d6 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MarketCodesBySessionConfig.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MarketCodesBySessionConfig.java @@ -2,9 +2,18 @@ package ru.spcex.clearing.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import ru.clearing.classes.statics.data.misc.Market; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.enumeration.MarketType; +import ru.spcex.platform.enumeration.Section; +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; +import java.util.function.Supplier; +import java.util.stream.Collectors; @Configuration public class MarketCodesBySessionConfig { @@ -20,4 +29,28 @@ public class MarketCodesBySessionConfig { "AESC", "ABFC", "KBIC", "WBMC", "BMMC", "ABEC", "SMIC", "ABMC", "SMVC", "KBFC", "SKVC", "ABVC", "WEPC", "KBMC", "SMFC", "BKVC", "WBVC", "BMIC", "WESC"); } + + @Bean(name = "marketCodesForT0") + public Supplier> marketCodesForT0(ImdgProvider imdgProvider) { + final Object lock = new Object(); + return new Supplier<>() { + private volatile List codes; + @Override + public List get() { + if (codes == null) { + synchronized (lock) { + if (codes == null) { + imdgProvider.waitAvailable(); + Imdg marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, Market.class); + Collection markets = marketImdg.getCollectionObjectsByFieldValues(Map.of( + "section", Section.FOND.getKey(), + "marketType", MarketType.SCND.getKey())); + codes = markets.stream().map(Market::getCode).distinct().collect(Collectors.toList()); + } + } + } + return codes; + } + }; + } } From 232d034126a31a6ae814180eee668567dfdfc818 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 14:01:08 +0300 Subject: [PATCH 06/36] =?UTF-8?q?backend-api=20http://jira.mfd.msk:8088/br?= =?UTF-8?q?owse/CLS-257=20MoneyMarketSecurity*Action=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BF=D0=BE=D0=BB=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cud/securities/MoneyMarketSecurityNewAction.java | 12 ++++++++++++ .../securities/MoneyMarketSecurityUpdateAction.java | 12 ++++++++++++ .../securitites/MoneyMarketSecurityNewRequest.java | 10 ++++++++++ .../MoneyMarketSecurityUpdateRequest.java | 10 ++++++++++ 4 files changed, 44 insertions(+) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java index b24ad5e04..e282edc5f 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/securities/MoneyMarketSecurityNewAction.java @@ -30,6 +30,9 @@ public class MoneyMarketSecurityNewAction implements IAction Date: Sat, 27 May 2023 14:02:26 +0300 Subject: [PATCH 07/36] SecondaryAuctionT0Session --- .../stage/SecondaryAuctionT0Session.java | 195 ++++++++++++++++++ .../platform/enumeration/SessionType.java | 2 +- 2 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java new file mode 100644 index 000000000..6df4b79b2 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java @@ -0,0 +1,195 @@ +package ru.spcex.clearing.session.stage; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.execution.ExecutionCommon; +import ru.clearing.classes.statics.data.execution.ExecutionFond; +import ru.clearing.classes.statics.data.misc.Session; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.session.stage.impl.*; +import ru.spcex.clearing.session.stage.task.*; +import ru.spcex.platform.classes.base.interfaces.ExecutionType; +import ru.spcex.platform.enumeration.Section; +import ru.spcex.platform.enumeration.SessionStatus; +import ru.spcex.platform.enumeration.SessionType; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.utils.enumeration.IMessageResolver; + +import java.time.LocalDate; +import java.util.List; +import java.util.function.Supplier; + +@Service +public class SecondaryAuctionT0Session extends AbstractSession implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final BalanceRevise balanceRevise; + private final DealsPrepare dealsPrepare; + private final RequirementsAndObligationCreation requirementsAndObligationCreation; + private final ObligationAdmission obligationsAdmission; + + private final InclusionObligations inclusionObligations; + private final InspectionObligations inspectionObligations; + private final FormingRegistersOnOS formingRegistersOnOS; + private final FormingPaymentInstruction formingPaymentInstruction; + private final UnlockResources unlockResources; + private final FinishingSession finishingSession; + private final EndStageNotification endStageNotification; + + private final Imdg executionFondImdg; + private final Supplier> marketCodes; + + + public SecondaryAuctionT0Session( + ImdgProvider imdgProvider, + BalanceRevise balanceRevise, + DealsPrepare dealsPrepare, + RequirementsAndObligationCreation requirementsAndObligationCreation, + ObligationAdmission obligationsAdmission, + InclusionObligations inclusionObligations, + FormingRegistersOnOS formingRegistersOnOS, + FormingPaymentInstruction formingPaymentInstruction, + UnlockResources unlockResources, + FinishingSession finishingSession, + EndStageNotification endStageNotification, + IMessageResolver messageResolver, + InspectionObligations inspectionObligations, + @Qualifier("marketCodesForT0") Supplier> marketCodes) { + super(imdgProvider, messageResolver); + this.balanceRevise = balanceRevise; + this.dealsPrepare = dealsPrepare; + this.requirementsAndObligationCreation = requirementsAndObligationCreation; + this.obligationsAdmission = obligationsAdmission; + this.inclusionObligations = inclusionObligations; + this.formingRegistersOnOS = formingRegistersOnOS; + this.formingPaymentInstruction = formingPaymentInstruction; + this.unlockResources = unlockResources; + this.finishingSession = finishingSession; + this.endStageNotification = endStageNotification; + this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class); + this.inspectionObligations = inspectionObligations; + this.marketCodes = marketCodes; + } + + @Override + public void afterPropertiesSet() throws Exception { + dealsPrepare.searchForExecutions(ExecutionType.ExecutionFond); + ImdgPredicateBuilder execFondPb = executionFondImdg.predicateBuilder(); + dealsPrepare.addExecutionFondCondition(execFondPb.regex("settlementCode", "^T0.*$")); + dealsPrepare.addExecutionFondCondition(execFondPb.in("market", marketCodes.get().toArray(new String[0]))); + } + + public void runSession(BaseRequest req) { + if (!startSession()) { + return; + } + StageResult submit = balanceRevise.submit(new Task<>(TaskType.StartRevise, null)); + if (!submit.success) { + log.error("stage {} error={}", balanceRevise.getClass().getSimpleName(), messageResolver.resolve(submit.error)); + endSession(); + } else { + log.info("stage BalanceRevise success, waiting for a response from kafka"); + } + } + + public void continueSession(BaseRequest req) { + try { + if (!checkStage(TaskType.StartRevise)) { + log.error("cannot continue session, current stage is {}", currStage.get()); + throw new StageException(); + } + if (checkStage(TaskType.StartRevise)) { + firstPart(req); + } else if (checkStage(TaskType.FormingPaymentInstruction)) { + finishPart(req); + } + } catch (StageException e) { + //already logged + } + } + + private void firstPart(BaseRequest req) { + try { + //stage 1 + StageResult> dealsPreparationResult; + { + DealsPreparePayload payload = new DealsPreparePayload(); + payload.setSessionId(currSession.getId()); + dealsPreparationResult = runStage(TaskType.DealsPrepare, payload, dealsPrepare); + } + //stage 2 + runStage(TaskType.RequirementsAndObligationsCreate, dealsPreparationResult.getStageResult(), requirementsAndObligationCreation); + //stage 3 + runStage(TaskType.ObligationsAdmission, currSession.getId(), obligationsAdmission); + //stage 4 + { + InclusionToPoolPayload inclusionToPoolPayload = new InclusionToPoolPayload(); + inclusionToPoolPayload.setSessionType(currSession.getSessionType()); + runStage(TaskType.InclusionToPool, inclusionToPoolPayload, inclusionObligations); + } + //stage 5 + { + InspectionPoolPayload companyIdPayload = new InspectionPoolPayload(); + companyIdPayload.setProcessedCompanyId(currSession.getCompanyId()); + runStage(TaskType.InspectionObligations, companyIdPayload, inspectionObligations); + } + //stage 6 + runStage(TaskType.FormingRegistersOnOS, formingRegistersOnOS); //returns Collection + //stage 7 + runStage(TaskType.FormingPaymentInstruction, formingPaymentInstruction); + } catch (StageException e) { + //already logged + } + } + + + public void finishPart(BaseRequest req) { + try { + if (!checkStage(TaskType.FormingPaymentInstruction)) { + log.error("cannot continue session, current stage is {}", currStage.get()); + throw new StageException(); + } + //stage 10 + { + FinishingSessionPayload payload = new FinishingSessionPayload(); + payload.setSessionId(currSession.getId()); + runStage(TaskType.FinishingSession, payload, finishingSession); + } + //stage 11 + { + EndStageNotificationPayload payload = new EndStageNotificationPayload(); + payload.setSection(currSession.getSection()); + runStage(TaskType.EndStageNotification, payload, endStageNotification); + } + } catch (StageException e) { + //already logged + } + } + + private boolean startSession() { + synchronized (this.currStage) { + if (this.currStage.get() != null) { + log.info("already running session.id={}", this.currSession.getId()); + return false; + } else { + Session newSession = new Session(); + newSession.setSection(Section.FOND.getKey()); + newSession.setSessionType(SessionType.TRDT.getKey()); + newSession.setSessionStatus(SessionStatus.CLRN.getKey()); + newSession.setClearingDate(LocalDate.now()); + + //todo companyId/securityId/userId передается из сообщения очереди + sessionImdg.insert(newSession); + currSession = newSession; + log.info("started new session.id={}", this.currSession.getId()); + currStage.set(TaskType.StartRevise); + return true; + } + } + } +} diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SessionType.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SessionType.java index b299f910f..11fb75871 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SessionType.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/SessionType.java @@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration; import ru.spcex.platform.utils.enumeration.IEnumKey; public enum SessionType implements IEnumKey { - IPOB("IPOB"), IPO0("IPO0"), IPOT("IPOT"), + IPOB("IPOB"), IPO0("IPO0"), IPOT("IPOT"), TRDT("TRDT"), ; SessionType(String key) { From d51cbf809a104300c4f2e79a877e407cc8358ee1 Mon Sep 17 00:00:00 2001 From: ialbert Date: Sat, 27 May 2023 14:16:32 +0300 Subject: [PATCH 08/36] marketCodesForBn --- .../config/MarketCodesBySessionConfig.java | 57 ++++++++++--------- .../stage/PrimaryAuctionBnSession.java | 7 ++- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MarketCodesBySessionConfig.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MarketCodesBySessionConfig.java index 4d7dc85d6..af0c000db 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MarketCodesBySessionConfig.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/MarketCodesBySessionConfig.java @@ -19,38 +19,43 @@ import java.util.stream.Collectors; public class MarketCodesBySessionConfig { @Bean(name = "marketCodesForBn") - public List marketCodesForBn(ImdgProvider imdgProvider) { -// Imdg marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, Market.class); -// Collection markets = marketImdg.getCollectionObjectsByFieldValues(Map.of( -// "section", Section.FOND.getKey(), -// "marketType", MarketType.PRMR.getKey())); -// return markets.stream().map(Market::getCode).distinct().collect(Collectors.toList()); - return List.of("BMFC", "SMMC", "AEPC", "WBIC", "KBVC", "WBFC", "BMVC", "ABIC", - "AESC", "ABFC", "KBIC", "WBMC", "BMMC", "ABEC", "SMIC", "ABMC", "SMVC", "KBFC", "SKVC", "ABVC", "WEPC", - "KBMC", "SMFC", "BKVC", "WBVC", "BMIC", "WESC"); + public Supplier> marketCodesForBn(ImdgProvider imdgProvider) { + return new MarketCodesProvider(imdgProvider, Section.FOND, MarketType.PRMR); } @Bean(name = "marketCodesForT0") public Supplier> marketCodesForT0(ImdgProvider imdgProvider) { - final Object lock = new Object(); - return new Supplier<>() { - private volatile List codes; - @Override - public List get() { - if (codes == null) { - synchronized (lock) { - if (codes == null) { - imdgProvider.waitAvailable(); - Imdg marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, Market.class); - Collection markets = marketImdg.getCollectionObjectsByFieldValues(Map.of( - "section", Section.FOND.getKey(), - "marketType", MarketType.SCND.getKey())); - codes = markets.stream().map(Market::getCode).distinct().collect(Collectors.toList()); - } + return new MarketCodesProvider(imdgProvider, Section.FOND, MarketType.SCND); + } + + private static class MarketCodesProvider implements Supplier> { + private volatile List codes; + private final Object lock = new Object(); + private final ImdgProvider imdgProvider; + private final Section section; + private final MarketType marketType; + + public MarketCodesProvider(ImdgProvider imdgProvider, Section section, MarketType marketType) { + this.imdgProvider = imdgProvider; + this.section = section; + this.marketType = marketType; + } + + @Override + public List get() { + if (codes == null) { + synchronized (lock) { + if (codes == null) { + imdgProvider.waitAvailable(); + Imdg marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, Market.class); + Collection markets = marketImdg.getCollectionObjectsByFieldValues(Map.of( + "section", section.getKey(), + "marketType", marketType.getKey())); + codes = markets.stream().map(Market::getCode).distinct().collect(Collectors.toList()); } } - return codes; } - }; + return codes; + } } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java index 7b69881cd..79b87da88 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java @@ -23,6 +23,7 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver; import java.time.LocalDate; import java.util.List; +import java.util.function.Supplier; @Service public class PrimaryAuctionBnSession extends AbstractSession implements InitializingBean { @@ -41,7 +42,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali private final EndStageNotification endStageNotification; private final Imdg executionFondImdg; - private final List marketCodes; + private final Supplier> marketCodes; public PrimaryAuctionBnSession( @@ -58,7 +59,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali EndStageNotification endStageNotification, IMessageResolver messageResolver, InspectionObligations inspectionObligations, - @Qualifier("marketCodesForBn") List marketCodes) { + @Qualifier("marketCodesForBn") Supplier> marketCodes) { super(imdgProvider, messageResolver); this.balanceRevise = balanceRevise; this.dealsPrepare = dealsPrepare; @@ -80,7 +81,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali dealsPrepare.searchForExecutions(ExecutionType.ExecutionFond); ImdgPredicateBuilder execFondPb = executionFondImdg.predicateBuilder(); dealsPrepare.addExecutionFondCondition(execFondPb.regex("settlementCode", "^B\\d{2}$")); - dealsPrepare.addExecutionFondCondition(execFondPb.in("market", marketCodes.toArray(new String[0]))); + dealsPrepare.addExecutionFondCondition(execFondPb.in("market", marketCodes.get().toArray(new String[0]))); } public void runSession(BaseRequest req) { From 84bda2fa12b7f92bfaa31f41f83179d8bdccb199 Mon Sep 17 00:00:00 2001 From: ialbert Date: Sat, 27 May 2023 14:30:34 +0300 Subject: [PATCH 09/36] start sessions based on request --- .../clearing/service/EventsReceiver.java | 26 +++++++++++++++++-- .../service/executors/Sdf57Executor.java | 2 +- .../ru/spcex/platform/enumeration/Task.java | 1 + 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java index e080ec3f7..24784bad9 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java @@ -1,8 +1,11 @@ package ru.spcex.clearing.service; import org.apache.kafka.clients.consumer.Consumer; +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.clearing.CreateRegistryRequest; import ru.spcex.clearing.platform.messaging.domain.cud.clearing.Sdf04Request; @@ -12,26 +15,32 @@ import ru.spcex.clearing.platform.messaging.domain.cud.utilities.STradesImported import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.session.stage.PrimaryAuctionB0Session; import ru.spcex.clearing.session.stage.PrimaryAuctionBnSession; +import ru.spcex.clearing.session.stage.SecondaryAuctionT0Session; import ru.spcex.platform.enumeration.Task; +import ru.spcex.platform.utils.enumeration.IEnumKey; import static ru.spcex.clearing.platform.messaging.domain.Consts.S_TRADES_IMPORTED; @Service public class EventsReceiver extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); private final ClearingService clearingService; private final RegistryService registryService; private final PrimaryAuctionBnSession primaryAuctionBnSession; + private final SecondaryAuctionT0Session secondaryAuctionT0Session; private final PrimaryAuctionB0Session primaryAuctionB0Session; public EventsReceiver(Consumer kafkaQueue, ClearingService clearingService, RegistryService registryService, PrimaryAuctionBnSession primaryAuctionBnSession, + SecondaryAuctionT0Session secondaryAuctionT0Session, PrimaryAuctionB0Session primaryAuctionB0Session) { super(kafkaQueue); this.clearingService = clearingService; this.registryService = registryService; this.primaryAuctionBnSession = primaryAuctionBnSession; + this.secondaryAuctionT0Session = secondaryAuctionT0Session; this.primaryAuctionB0Session = primaryAuctionB0Session; } @@ -61,8 +70,8 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean { // .forDestination(Task.startOfB0.topic(), callbacks::put); - callback(Object.class) - .setConsumer(primaryAuctionBnSession::runSession) + callback(LauncherCommandRequest.class) + .setConsumer(this::startSession) .forDestination(Task.startOfClearing.topic(), callbacks::put); callback(Object.class) .setConsumer(primaryAuctionBnSession::continueSession) @@ -76,4 +85,17 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean { .forDestination(Consts.REGISTRY_NEW, callbacks::put); init(); } + + private void startSession(BaseRequest request) { + LauncherCommandRequest payload = request.getRequestPayload(); + Task specificSession = IEnumKey.getEnumByKey(Task.class, payload.getTaskName()); + if (specificSession == null) { + log.error("unknown session: {}", payload.getTaskName()); + return; + } + switch (specificSession) { + case startOfClearing -> primaryAuctionBnSession.runSession(request); + case startOfT0 -> secondaryAuctionT0Session.runSession(request); + } + } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java index 9749bc9b6..9575bfd9a 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java @@ -96,7 +96,7 @@ public class Sdf57Executor extends AbstractExecutor { @Override public boolean isNeedToSendCommand() { - return true; + return false; } @Override diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Task.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Task.java index bde7c6d30..495661e89 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Task.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Task.java @@ -11,6 +11,7 @@ public enum Task implements IEnumKey { @Deprecated /* todo GBLD удаляется по CLS-267, CLS-275 */ getBalance("GBLD"),// Поступление средств startOfClearing("SCLR"),// Запуск клиринговой сессии startOfB0("IPO0"),// Запуск клиринговой сессии + startOfT0("TRDT"),// Запуск клиринговой сессии startOfPreClearing("SPRC"),// Запуск преклиринга startPostClearing("SPOC"),// Запуск постклиринга createOrder("CORD"), From 8d21e5a23edaab5e13ffaa32168d88b713bdad22 Mon Sep 17 00:00:00 2001 From: ialbert Date: Sat, 27 May 2023 14:40:07 +0300 Subject: [PATCH 10/36] EventsReceiver start sessions fix --- .../clearing/service/EventsReceiver.java | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java index 24784bad9..678b06f36 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java @@ -5,7 +5,6 @@ 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.clearing.CreateRegistryRequest; import ru.spcex.clearing.platform.messaging.domain.cud.clearing.Sdf04Request; @@ -17,7 +16,6 @@ import ru.spcex.clearing.session.stage.PrimaryAuctionB0Session; import ru.spcex.clearing.session.stage.PrimaryAuctionBnSession; import ru.spcex.clearing.session.stage.SecondaryAuctionT0Session; import ru.spcex.platform.enumeration.Task; -import ru.spcex.platform.utils.enumeration.IEnumKey; import static ru.spcex.clearing.platform.messaging.domain.Consts.S_TRADES_IMPORTED; @@ -71,8 +69,13 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean { callback(LauncherCommandRequest.class) - .setConsumer(this::startSession) + .setConsumer(primaryAuctionBnSession::runSession) .forDestination(Task.startOfClearing.topic(), callbacks::put); + + callback(LauncherCommandRequest.class) + .setConsumer(secondaryAuctionT0Session::runSession) + .forDestination(Task.startOfT0.topic(), callbacks::put); + callback(Object.class) .setConsumer(primaryAuctionBnSession::continueSession) .forDestination(Consts.CONTINUE_SESSION_BN_FIRST_PART, callbacks::put); @@ -85,17 +88,4 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean { .forDestination(Consts.REGISTRY_NEW, callbacks::put); init(); } - - private void startSession(BaseRequest request) { - LauncherCommandRequest payload = request.getRequestPayload(); - Task specificSession = IEnumKey.getEnumByKey(Task.class, payload.getTaskName()); - if (specificSession == null) { - log.error("unknown session: {}", payload.getTaskName()); - return; - } - switch (specificSession) { - case startOfClearing -> primaryAuctionBnSession.runSession(request); - case startOfT0 -> secondaryAuctionT0Session.runSession(request); - } - } } From 786e4af3ebb9c0cd912115070d3325aa9f06fcfb Mon Sep 17 00:00:00 2001 From: ialbert Date: Sat, 27 May 2023 14:45:25 +0300 Subject: [PATCH 11/36] sessions continue phase --- .../main/java/ru/spcex/clearing/service/EventsReceiver.java | 5 ++++- .../ru/spcex/clearing/session/stage/AbstractSession.java | 6 ++++++ .../clearing/session/stage/PrimaryAuctionBnSession.java | 3 +++ .../clearing/session/stage/SecondaryAuctionT0Session.java | 3 +++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java index 678b06f36..25025c63b 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java @@ -77,7 +77,10 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean { .forDestination(Task.startOfT0.topic(), callbacks::put); callback(Object.class) - .setConsumer(primaryAuctionBnSession::continueSession) + .setConsumer(req -> { + primaryAuctionBnSession.continueSession(req); + secondaryAuctionT0Session.continueSession(req); + }) .forDestination(Consts.CONTINUE_SESSION_BN_FIRST_PART, callbacks::put); callback(STradesImportedRequest.class) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/AbstractSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/AbstractSession.java index a6c172cf7..0ab74d8e1 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/AbstractSession.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/AbstractSession.java @@ -65,4 +65,10 @@ public class AbstractSession { } } + protected boolean isRunning() { + synchronized (this.currStage) { + return this.currStage.get() != null; + } + } + } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java index 79b87da88..aa9f9ca02 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java @@ -99,6 +99,9 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali public void continueSession(BaseRequest req) { try { + if (!isRunning()) { + return; + } if (!checkStage(TaskType.StartRevise)) { log.error("cannot continue session, current stage is {}", currStage.get()); throw new StageException(); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java index 6df4b79b2..7ae83e1c7 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java @@ -99,6 +99,9 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia public void continueSession(BaseRequest req) { try { + if (!isRunning()) { + return; + } if (!checkStage(TaskType.StartRevise)) { log.error("cannot continue session, current stage is {}", currStage.get()); throw new StageException(); From 25b64c3c098fd0aae7ae1afa4a74da56e187e58a Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Sat, 27 May 2023 14:47:25 +0300 Subject: [PATCH 12/36] fix up stage 7; session BN --- .../stage/PrimaryAuctionBnSession.java | 8 +- .../stage/impl/FormingPaymentInstruction.java | 133 +++++++++++++++++- .../platform/enumeration/InstrumentType.java | 19 +++ 3 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/InstrumentType.java diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java index aa9f9ca02..6fb5b8342 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.execution.ExecutionCommon; import ru.clearing.classes.statics.data.execution.ExecutionFond; import ru.clearing.classes.statics.data.misc.Session; +import ru.clearing.classes.statics.data.payment.PaymentInstruction; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.session.stage.impl.*; @@ -22,6 +23,7 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.utils.enumeration.IMessageResolver; import java.time.LocalDate; +import java.util.Collection; import java.util.List; import java.util.function.Supplier; @@ -144,7 +146,11 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali //stage 6 runStage(TaskType.FormingRegistersOnOS, formingRegistersOnOS); //returns Collection //stage 7 - runStage(TaskType.FormingPaymentInstruction, formingPaymentInstruction); + StageResult> paymentResult = runStage(TaskType.FormingPaymentInstruction, formingPaymentInstruction); + if (paymentResult.getStageResult().isEmpty()) { + //todo где сверка + firstPart(req); + } } catch (StageException e) { //already logged } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstruction.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstruction.java index a9d203374..e03df0611 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstruction.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstruction.java @@ -6,10 +6,18 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.payment.PaymentInstruction; import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.sdf.SDf03; +import ru.clearing.classes.statics.data.sdf.SDf12; +import ru.clearing.classes.statics.data.security.Security; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.clearing.service.builder.PaymentInstructionBuilder; import ru.spcex.clearing.session.stage.ISessionStage; import ru.spcex.clearing.session.stage.StageResult; import ru.spcex.clearing.session.stage.Task; @@ -23,6 +31,8 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.enumeration.SimpleMessageResolver; import java.math.BigDecimal; +import java.time.Instant; +import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -35,6 +45,11 @@ public class FormingPaymentInstruction implements ISessionStage { private ImdgId idGenerator; private Imdg registryImdg; private Imdg paymentInstructionImdg; + private Imdg securityImdg; + private Imdg accountImdg; + private Imdg companyImdg; + private Imdg sDf03Imdg; + private Imdg sDf12Imdg; private KafkaSender kafkaSender; private final IMessageResolver msgResolver = new SimpleMessageResolver(); @@ -43,6 +58,11 @@ public class FormingPaymentInstruction implements ISessionStage { this.imdgProvider = imdgProvider; this.idGenerator = imdgProvider.getImdgIdGenerator(); this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class); + this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); + this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.sDf03Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf03, SDf03.class); + this.sDf12Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf12, SDf12.class); this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class); } @@ -204,6 +224,7 @@ public class FormingPaymentInstruction implements ISessionStage { } } + List formedPaymentInstructions = new ArrayList<>(); for (Registry obligation : obligations) { RegistryTradingParams registryTradingParamsLT = new RegistryTradingParams(RegistryDesignation.L, null, null, RegistryUnit.T); @@ -214,22 +235,120 @@ public class FormingPaymentInstruction implements ISessionStage { BigDecimal sumBalance = registries.stream().map(Registry::getBalance).reduce(BigDecimal.ZERO, BigDecimal::add); PaymentInstruction paymentInstruction = createPaymentInstruction(obligation, sumBalance); + formedPaymentInstructions.add(paymentInstruction); paymentInstructionImdg.insert(paymentInstruction); obligation.setPaymentId(paymentInstruction.getId()); registryImdg.update(obligation); } + sendSdfs(formedPaymentInstructions); - //todo send message to queue for forming sDf03 and sDf12? + StageResult> stageResult = new StageResult(null, true); + stageResult.setStageResult(formedPaymentInstructions); + return stageResult; + } - return new StageResult(null, true); + private void sendSdfs(List formedPaymentInstructions) { + Long sdf03GroupId = null; + Long sdf12GroupId = null; + for (PaymentInstruction paymentInstruction : formedPaymentInstructions) { + Security security = securityImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_securityId()); + Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId()); + if (InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) && + List.of(AccountType.Corr, AccountType.Clrn).contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) { + sdf03GroupId = sdf03GroupId != null ? sdf12GroupId : imdgProvider.getImdgIdGenerator().nextId(); + newSDf03(paymentInstruction, sdf03GroupId); + } else if (!InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) && + AccountType.Depo.equalsByKey(account.getAccountType())) { + sdf12GroupId = sdf12GroupId != null ? sdf12GroupId : imdgProvider.getImdgIdGenerator().nextId(); + newSDf12(paymentInstruction, sdf12GroupId); + } + } + + if (sdf03GroupId != null) { + ExportToFileRequest exportToFileRequest = new ExportToFileRequest(); + exportToFileRequest.setNameOfTable("DF-03"); + exportToFileRequest.setSdfGroupId(sdf03GroupId); + kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportToFileRequest); + } + + if (sdf12GroupId != null) { + ExportToFileRequest exportToFileRequest = new ExportToFileRequest(); + exportToFileRequest.setNameOfTable("DF-12"); + exportToFileRequest.setSdfGroupId(sdf12GroupId); + kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportToFileRequest); + } } private PaymentInstruction createPaymentInstruction(Registry registry, BigDecimal balance) { - PaymentInstruction paymentInstruction = new PaymentInstruction(); - paymentInstruction.setSenderId(registry.getCompanyId()); - paymentInstruction.setAddresseeId(registry.getCounterPartyId()); - //todo add builder for paymentInstruction - return paymentInstruction; + PaymentInstructionBuilder paymentInstructionBuilder = PaymentInstructionBuilder.builder(imdgProvider, registry); + return paymentInstructionBuilder.build(); } + + private void newSDf03(PaymentInstruction paymentInstruction, Long sdf03GroupId) { + log.debug("creating sdf03"); + SDf03 sDf03 = new SDf03(); + sDf03.setId(idGenerator.nextId()); + sDf03.setSeg_type("S"); + sDf03.setDoc_type("002"); + String strId = paymentInstruction.getId().toString(); + String strIdCut = strId.length() > 16 ? strId.substring(strId.length() - 16) : strId; + sDf03.setDocnm_ref(strIdCut); + sDf03.setC_acc_deb(paymentInstruction.getDebitLeg_account()); + + String senderSbankName = ""; + if (paymentInstruction.getSenderId().equals(1L)) { + senderSbankName = paymentInstruction.getPayeeBankName(); + } else { + Company company = companyImdg.getSingleObjectByID(paymentInstruction.getSenderId()); + if (company != null) { + senderSbankName = company.getShortName(); + } + } + sDf03.setSbanknam1(senderSbankName); + sDf03.setSbanknam2(senderSbankName); + sDf03.setSbanknam3(senderSbankName); + sDf03.setSbanknam4(senderSbankName); + sDf03.setSbanknam5(senderSbankName); + + sDf03.setC_acc_cred(paymentInstruction.getCreditLeg_account()); + + String addresseeSbankName = ""; + if (paymentInstruction.getAddresseeId().equals(1L)) { + addresseeSbankName = paymentInstruction.getAddresseeBankName(); + } else { + Company company = companyImdg.getSingleObjectByID(paymentInstruction.getAddresseeId()); + if (company != null) { + addresseeSbankName = company.getShortName(); + } + } + sDf03.setRbanknam1(addresseeSbankName); + sDf03.setRbanknam2(addresseeSbankName); + sDf03.setRbanknam3(addresseeSbankName); + sDf03.setRbanknam4(addresseeSbankName); + sDf03.setRbanknam5(addresseeSbankName); + +// sDf03.setPay_date();// + sDf03.setPay_val("RUR"); + sDf03.setSum_deb(paymentInstruction.getDebitLeg_amount() != null ? paymentInstruction.getDebitLeg_amount().toString() : ""); + sDf03.setSpecif_1(paymentInstruction.getPaymentPurpose()); + sDf03.setGenerationTime(Instant.now()); + sDf03.setGenerationId(sdf03GroupId); + sDf03.setPaymentInstructionId(paymentInstruction.getId()); + sDf03Imdg.insert(sDf03); + log.debug("successfully processed, new id {}", sDf03.getId()); + } + + private void newSDf12(PaymentInstruction paymentInstruction, Long sdf12GroupId) { + log.debug("creating sdf12"); + SDf12 sDf12 = new SDf12(); + sDf12.setId(idGenerator.nextId()); + sDf12.setOutDocument(sDf12.getId().toString()); +// sDf12.setQuantity(); + sDf12.setGenerationTime(Instant.now()); + sDf12.setGenerationId(sdf12GroupId); + sDf12Imdg.insert(sDf12); + } + +// private String defineCompanyName(Function function, ) } diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/InstrumentType.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/InstrumentType.java new file mode 100644 index 000000000..f5c07ccfd --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/InstrumentType.java @@ -0,0 +1,19 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public enum InstrumentType implements IEnumKey { + CRNC ("CRNC") + ; + + private final String key; + + InstrumentType(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } +} From 515e68de67bfb978109f520d19b3fd603679d50f Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Sat, 27 May 2023 14:58:19 +0300 Subject: [PATCH 13/36] PaymentInstructionBuilder fix --- .../builder/PaymentInstructionBuilder.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java index 80479f8c9..e259cef2a 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilder.java @@ -11,12 +11,15 @@ import ru.spcex.platform.enumeration.InOutDirection; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import java.time.Instant; +import java.time.LocalDate; import java.util.Map; public class PaymentInstructionBuilder { private Registry registry; private ImdgProvider imdgProvider; + private Long sessionId; public static PaymentInstructionBuilder builder(ImdgProvider imdgProvider, Registry registry) { return new PaymentInstructionBuilder(imdgProvider, registry); @@ -27,6 +30,11 @@ public class PaymentInstructionBuilder { this.registry = registry; } + public PaymentInstructionBuilder sessionId(Long sessionId) { + this.sessionId = sessionId; + return this; + } + public PaymentInstruction build() { PaymentInstruction paymentInstruction = new PaymentInstruction(); paymentInstruction.setSenderId(registry.getCompanyId()); @@ -67,9 +75,21 @@ public class PaymentInstructionBuilder { } paymentInstruction.setDebitLeg_accountId(registry.getAccountId()); + +// Imdg depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class); + account = accountImdg.getSingleObjectByID(paymentInstruction.getDebitLeg_accountId()); + if (account != null) { + paymentInstruction.setDebitLeg_account(account.getAccount()); + } + + paymentInstruction.setCreditLeg_direction(InOutDirection.out.getKey()); paymentInstruction.setDebitLeg_direction(InOutDirection.in.getKey()); -// Account account = accountImdg.getSingleObjectByID(registry.get()); -// paymentInstruction.setDebitLeg_account(); + + + paymentInstruction.setTransactionStatus("STLD"); + paymentInstruction.setCreated(Instant.now()); + paymentInstruction.setClearingDate(LocalDate.now()); + return paymentInstruction; } } From b539db766448d251c41b66a45db6fb009eb3784c Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Sat, 27 May 2023 15:02:28 +0300 Subject: [PATCH 14/36] finish session if stage7 result is empty --- .../spcex/clearing/session/stage/PrimaryAuctionBnSession.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java index 6fb5b8342..74548c8bd 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java @@ -148,8 +148,8 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali //stage 7 StageResult> paymentResult = runStage(TaskType.FormingPaymentInstruction, formingPaymentInstruction); if (paymentResult.getStageResult().isEmpty()) { - //todo где сверка - firstPart(req); + runStage(TaskType.ContinueRevise, balanceRevise); + finishPart(req); } } catch (StageException e) { //already logged From 3c252ca3f6c09234f2a42cde7d3c176662d4cef6 Mon Sep 17 00:00:00 2001 From: ialbert Date: Sat, 27 May 2023 15:08:43 +0300 Subject: [PATCH 15/36] SecondaryT0 stage 7 --- .../clearing/session/stage/SecondaryAuctionT0Session.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java index 7ae83e1c7..78bfbf5f3 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/SecondaryAuctionT0Session.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.execution.ExecutionCommon; import ru.clearing.classes.statics.data.execution.ExecutionFond; import ru.clearing.classes.statics.data.misc.Session; +import ru.clearing.classes.statics.data.payment.PaymentInstruction; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.session.stage.impl.*; @@ -22,6 +23,7 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.utils.enumeration.IMessageResolver; import java.time.LocalDate; +import java.util.Collection; import java.util.List; import java.util.function.Supplier; @@ -144,7 +146,11 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia //stage 6 runStage(TaskType.FormingRegistersOnOS, formingRegistersOnOS); //returns Collection //stage 7 - runStage(TaskType.FormingPaymentInstruction, formingPaymentInstruction); + StageResult> paymentResult = runStage(TaskType.FormingPaymentInstruction, formingPaymentInstruction); + if (paymentResult.getStageResult().isEmpty()) { + runStage(TaskType.ContinueRevise, balanceRevise); + finishPart(req); + } } catch (StageException e) { //already logged } From adc4d101f0f5214f410bce778ba811ea3b984851 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 15:33:49 +0300 Subject: [PATCH 16/36] =?UTF-8?q?reports-service=20http://jira.mfd.msk:808?= =?UTF-8?q?8/browse/CLS-283=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D1=8B=D1=85=20=D0=BE=D1=82=D1=87=D1=91=D1=82?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=BF=D0=BE=20GREP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../services/AbstractReportCollector.java | 1 + .../services/ReportWithPeriodCollector.java | 1 + .../services/ReportsServiceCommand.java | 116 ++++++++++++++++-- .../services/SimpleReportCollector.java | 1 + 4 files changed, 112 insertions(+), 7 deletions(-) diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/AbstractReportCollector.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/AbstractReportCollector.java index f6276c2cc..8c79bf7df 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/AbstractReportCollector.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/AbstractReportCollector.java @@ -17,6 +17,7 @@ import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Locale; +@Deprecated public abstract class AbstractReportCollector { public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy"); public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportWithPeriodCollector.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportWithPeriodCollector.java index b11179d01..607d35ede 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportWithPeriodCollector.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportWithPeriodCollector.java @@ -10,6 +10,7 @@ import java.time.Instant; import java.time.LocalDate; import java.util.Collection; +@Deprecated public abstract class ReportWithPeriodCollector extends AbstractReportCollector { /** * Подготовка отчета на период startDate..endDate diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportsServiceCommand.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportsServiceCommand.java index 499228968..a9244df38 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportsServiceCommand.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportsServiceCommand.java @@ -4,12 +4,22 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.misc.Session; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.reports.ReportRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.reports.ReportRequestWithPeriod; +import ru.spcex.clearing.platform.messaging.domain.cud.reports.ReportRequestWithSessionId; +import ru.spcex.clearing.platform.messaging.domain.cud.reports.ReportRequestWithSessionIdList; +import ru.spcex.clearing.reports.config.ReportBuildersConfig; import ru.spcex.clearing.reports.config.element.ReportsServiceSettings; -import ru.spcex.clearing.reports.reports.AbstractReport; -import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.*; import ru.spcex.clearing.reports.services.builders.XMLReportBuilder; +import ru.spcex.platform.enumeration.ReportType; +import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.IEnumKey; import ru.spcex.platform.utils.log.ExceptionUtils; @@ -17,9 +27,7 @@ import ru.spcex.platform.utils.log.ExceptionUtils; import java.io.File; import java.io.IOException; import java.time.LocalDate; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Исполняет создание отчётов. @@ -35,17 +43,42 @@ public class ReportsServiceCommand implements InitializingBean { protected ReportsServiceSettings settings; protected ImdgProvider imdg; + + @Deprecated protected List allPeriodReports; // Spring services + @Deprecated protected List allSimpleReports; + @Deprecated private final Map collectorForReportById; + // new format report: + ReportService newReportService; // by ReportBuildersConfig + Map>> reportBuildersWithoutParams; + Map>> reportBuildersWithSessionIdParam; + Map>> reportBuildersWithSessionIdListParam; + Map>> reportBuildersWithPeriodParams; + + @Autowired - public ReportsServiceCommand(ImdgProvider imdg, List allPeriodReports, + public ReportsServiceCommand(ImdgProvider imdg, + List allPeriodReports, List allSimpleReports, + @Qualifier("reportBuildersWithoutParams") Map>> reportBuildersWithoutParams, + @Qualifier("reportBuildersWithSessionIdParam") Map>> reportBuildersWithSessionIdParam, + @Qualifier("reportBuildersWithSessionIdListParam") Map>> reportBuildersWithSessionIdListParam, + @Qualifier("reportBuildersWithPeriodParams") Map>> reportBuildersWithPeriodParams, + + ReportService reportService, ReportsServiceSettings settings) { this.imdg = imdg; this.settings = settings; + this.newReportService = reportService; + this.reportBuildersWithoutParams = reportBuildersWithoutParams; + this.reportBuildersWithSessionIdParam = reportBuildersWithSessionIdParam; + this.reportBuildersWithSessionIdListParam = reportBuildersWithSessionIdListParam; + this.reportBuildersWithPeriodParams = reportBuildersWithPeriodParams; + this.allSimpleReports = allSimpleReports; this.allPeriodReports = allPeriodReports; // allReports = context.getBeansOfType(ReportDataCollector.class); this.collectorForReportById = new HashMap<>(); @@ -73,6 +106,75 @@ public class ReportsServiceCommand implements InitializingBean { } public void generateReportAll(@Nullable String reportGroup, LocalDate startDate, LocalDate endDate) throws IOException { + // new reports: + { + HashSet reported=new HashSet<>(); + for (ReportType rType : reportBuildersWithoutParams.keySet()) { + if (reported.contains(rType)) continue; + reported.add(rType); + log.info("Make report {}", rType); + try { + BaseRequest request = new BaseRequest<>(); + request.setRequestPayload(new ReportRequest()); + request.getRequestPayload().setReportId(rType.getKey()); + newReportService.createReport(request); + } catch (Exception e) { + log.error("Error make report {}: {}", rType, ExceptionUtils.getStackTrace(e)); + } + } + Imdg sessionImdg = imdg.getImdg(IMDGDistributedNames.Map_Session, Session.class); + Long sessionId = sessionImdg.aggregateLongMax("id", sessionImdg.predicateBuilder().greatEqual("id", 0L)); // max, always true + log.info("For all report sessionId={}", sessionId); + for (ReportType rType : reportBuildersWithSessionIdParam.keySet()) { + if (reported.contains(rType)) continue; + reported.add(rType); + log.info("Make report {}, session {}", rType, sessionId); + try { + BaseRequest request = new BaseRequest<>(); + request.setRequestPayload(new ReportRequestWithSessionId()); + request.getRequestPayload().setReportId(rType.getKey()); + request.getRequestPayload().setSessionId(sessionId); + newReportService.createReportForSessionId(request); + } catch (Exception e) { + log.error("Error make report {}: {}", rType, ExceptionUtils.getStackTrace(e)); + } + } + for (ReportType rType : reportBuildersWithSessionIdListParam.keySet()) { + if (reported.contains(rType)) continue; + reported.add(rType); + log.info("Make report {}, sessions {}", rType, sessionId); + try { + BaseRequest request = new BaseRequest<>(); + request.setRequestPayload(new ReportRequestWithSessionIdList()); + request.getRequestPayload().setReportId(rType.getKey()); + request.getRequestPayload().setSessionIdList(Arrays.asList(sessionId)); + newReportService.createReportForSessionIdList(request); + } catch (Exception e) { + log.error("Error make report {}: {}", rType, ExceptionUtils.getStackTrace(e)); + } + } + for (ReportType rType : reportBuildersWithPeriodParams.keySet()) { + if (reported.contains(rType)) continue; + reported.add(rType); + LocalDate d1=LocalDate.now().minusDays(1); + LocalDate d2=LocalDate.now().minusDays(1); + log.info("Make report {} period {} - {}", rType, d1, d2); + try { + BaseRequest request = new BaseRequest<>(); + request.setRequestPayload(new ReportRequestWithPeriod()); + request.getRequestPayload().setReportId(rType.getKey()); + request.getRequestPayload().setStartDate(d1); + request.getRequestPayload().setStartDate(d2); + newReportService.createReportForPeriod(request); + } catch (Exception e) { + log.error("Error make report {}: {}", rType, ExceptionUtils.getStackTrace(e)); + } + } + + } + + log.info(" Old format report..."); + // deprecated code: for (ReportWithPeriodCollector reportDataCollector : allPeriodReports) { if (reportGroup == null || QUEUE_RUN_REPORT_COMMAND.equals(reportGroup)) { try { @@ -124,7 +226,7 @@ public class ReportsServiceCommand implements InitializingBean { XMLReportBuilder reportBuilder = new XMLReportBuilder(reportDataCollector.getReportClass(), outPath); AbstractReport report = reportDataCollector.collectReportWithPeriod(startDate, endDate); if (report == null) { - throw new NullPointerException("reportDataCollector "+ reportDataCollector +" return null"); + throw new NullPointerException("reportDataCollector " + reportDataCollector + " return null"); } File reportFile = reportBuilder.createReport(report); if (reportFile != null) { diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/SimpleReportCollector.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/SimpleReportCollector.java index 7f637d611..c25db9cd2 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/SimpleReportCollector.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/SimpleReportCollector.java @@ -2,6 +2,7 @@ package ru.spcex.clearing.reports.services; import ru.spcex.clearing.reports.reports.AbstractReport; +@Deprecated public abstract class SimpleReportCollector extends AbstractReportCollector { /** * Подготовка отчета (без входных параметров) From 9b8c2d3e3743de20f6054123a48e086a5185ea3d Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Sat, 27 May 2023 15:41:24 +0300 Subject: [PATCH 17/36] fix continue --- .../stage/PrimaryAuctionBnSession.java | 5 +- .../session/stage/impl/BalanceRevise.java | 95 ++++++++++--------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java index 74548c8bd..137b1df75 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java @@ -148,15 +148,14 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali //stage 7 StageResult> paymentResult = runStage(TaskType.FormingPaymentInstruction, formingPaymentInstruction); if (paymentResult.getStageResult().isEmpty()) { - runStage(TaskType.ContinueRevise, balanceRevise); - finishPart(req); + runStage(TaskType.FormingPaymentInstruction, balanceRevise); +// finishPart(req); } } catch (StageException e) { //already logged } } - public void finishPart(BaseRequest req) { try { if (!checkStage(TaskType.FormingPaymentInstruction)) { diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/BalanceRevise.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/BalanceRevise.java index bb6dae9ad..bc79ed1d1 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/BalanceRevise.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/BalanceRevise.java @@ -57,12 +57,10 @@ public class BalanceRevise implements ISessionStage { @Override public StageResult submit(Task task) { switch (task.getTaskType()) { - case StartRevise -> { + case StartRevise, FormingPaymentInstruction -> { return sendSdfs(); } case ContinueRevise -> { - //больше не используются, удалить после проверки - cashFlow(); //((SdfClearingRequest) task.getData()).getGroupId() if needed //todo убрать это отсюда return revise(); } default -> throw new IllegalStateException("unknown task " + task.getTaskType()); @@ -91,6 +89,53 @@ public class BalanceRevise implements ISessionStage { return new StageResult<>(null, true); } + private StageResult revise() { + String statementSQL = String.format("inOutSDfType = %s and operationStatus = %s and statementType = %s", + InOutSDfType.type1.getKey(), OperationStatus.Pending.getKey(), StatementType.full.getKey()); + Collection stmts = statementImdg.getCollectionObjectsBySQL(statementSQL); + for (Statement stmt : stmts) { + + RegistryTradingParams registryAMT = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.M, + null, RegistryUnit.T); + String registrySqlAMT = String.format("%s and account = '%s' and securityId = %d", + RegistryCodeSqlBuilder.getInstance(registryAMT).build(), + stmt.getAccount(), + stmt.getSecurityId() + ); + Registry rgsAMT = registryImdg.getSingleObjectBySQL(registrySqlAMT); + rgsAMT.setCheckBalance(stmt.getAmount()); + rgsAMT.setDiffBalance(safeBD(rgsAMT.getBalance()).subtract(safeBD(rgsAMT.getCheckBalance()))); + } + return new StageResult<>(null, true); + } + + private BigDecimal safeBD(BigDecimal value) { + return value != null ? value : BigDecimal.ZERO; + } + + private void newSDf56(Statement statement) { + log.debug("creating sdf56"); + SDf56 sDf56 = new SDf56(); + sDf56.setNumber(idGenerator.nextId().toString()); + Instant now = Instant.now(); + String startTime = String.valueOf(statement != null ? + statement.getCreated().toEpochMilli() : now.minus(1, ChronoUnit.DAYS).toEpochMilli()); + sDf56.setStart_datetime(startTime); + sDf56.setEnd_datetime(String.valueOf(now.toEpochMilli())); + sDf56.setAccount("ТБС"); + sDf56.setDeal("КОДУ"); + sDf56.setGenerationTime(now); + sDf56.setGenerationId(idGenerator.nextId()); + sDf56Imdg.insert(sDf56); + SdfClearingRequest requestForExporter = new SdfClearingRequest(); + requestForExporter.setGroupId(sDf56.getGenerationId()); + kafkaSender.sendRequestToQueue(Consts.SDF56_PROCESS, requestForExporter); + log.debug("successfully processed, new id {}", sDf56.getId()); + } + + + + private StageResult cashFlow() { String statementSQL = String.format("inOutSDfType = %s and operationStatus = %s and statementType = %s", InOutSDfType.type57.getKey(), OperationStatus.Pending.getKey(), StatementType.incr.getKey()); @@ -149,48 +194,4 @@ public class BalanceRevise implements ISessionStage { //todoSdf1 return new StageResult<>(null, true); } - - private StageResult revise() { - String statementSQL = String.format("inOutSDfType = %s and operationStatus = %s and statementType = %s", - InOutSDfType.type1.getKey(), OperationStatus.Pending.getKey(), StatementType.full.getKey()); - Collection stmts = statementImdg.getCollectionObjectsBySQL(statementSQL); - for (Statement stmt : stmts) { - - RegistryTradingParams registryAMT = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.M, - null, RegistryUnit.T); - String registrySqlAMT = String.format("%s and account = '%s' and securityId = %d", - RegistryCodeSqlBuilder.getInstance(registryAMT).build(), - stmt.getAccount(), - stmt.getSecurityId() - ); - Registry rgsAMT = registryImdg.getSingleObjectBySQL(registrySqlAMT); - rgsAMT.setCheckBalance(stmt.getAmount()); - rgsAMT.setDiffBalance(safeBD(rgsAMT.getBalance()).subtract(safeBD(rgsAMT.getCheckBalance()))); - } - return new StageResult<>(null, true); - } - - private BigDecimal safeBD(BigDecimal value) { - return value != null ? value : BigDecimal.ZERO; - } - - private void newSDf56(Statement statement) { - log.debug("creating sdf56"); - SDf56 sDf56 = new SDf56(); - sDf56.setNumber(idGenerator.nextId().toString()); - Instant now = Instant.now(); - String startTime = String.valueOf(statement != null ? - statement.getCreated().toEpochMilli() : now.minus(1, ChronoUnit.DAYS).toEpochMilli()); - sDf56.setStart_datetime(startTime); - sDf56.setEnd_datetime(String.valueOf(now.toEpochMilli())); - sDf56.setAccount("ТБС"); - sDf56.setDeal("КОДУ"); - sDf56.setGenerationTime(now); - sDf56.setGenerationId(idGenerator.nextId()); - sDf56Imdg.insert(sDf56); - SdfClearingRequest requestForExporter = new SdfClearingRequest(); - requestForExporter.setGroupId(sDf56.getGenerationId()); - kafkaSender.sendRequestToQueue(Consts.SDF56_PROCESS, requestForExporter); - log.debug("successfully processed, new id {}", sDf56.getId()); - } } From eafd571518df01bc0ae7849f0531f768cf6cb4f5 Mon Sep 17 00:00:00 2001 From: aalehin Date: Sat, 27 May 2023 16:09:03 +0300 Subject: [PATCH 18/36] http://jira.mfd.msk:8088/browse/CLS-316 --- improvement --- .../importer/logic/data/ResultContainer.java | 6 ++-- .../swt/importer/logic/data/enums/ETable.java | 12 +++---- .../logic/data/tables/AbstractTable.java | 2 +- .../logic/data/tables/SDf08Table.java | 12 +++---- .../logic/data/tables/SDf10Table.java | 12 +++---- .../logic/data/tables/SDf13Table.java | 3 +- .../swt/importer/logic/stages/ImportToDB.java | 14 +++++--- .../logic/stages/LoadFileFromDisk.java | 6 ++-- .../importer/logic/stages/ValidateFields.java | 2 +- .../swt/importer/services/FileChecker.java | 27 +++++++------- .../clearing/swt/importer/util/SWTReader.java | 36 +++++++++++++++++++ 11 files changed, 85 insertions(+), 47 deletions(-) create mode 100644 clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/util/SWTReader.java diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ResultContainer.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ResultContainer.java index f145b8215..de88522e4 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ResultContainer.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/ResultContainer.java @@ -20,10 +20,10 @@ public class ResultContainer { protected ResultContainer() { } - public static ResultContainer createNewTask(ETable dbfTable, File dbfFile) { + public static ResultContainer createNewTask(ETable swtTable, File swtFile) { ResultContainer container = new ResultContainer(); - container.swtTable = dbfTable; - container.swtFile = dbfFile; + container.swtTable = swtTable; + container.swtFile = swtFile; container.uuid = UUID.randomUUID(); return container; } diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ETable.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ETable.java index 25a632513..076a6beb3 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ETable.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/enums/ETable.java @@ -1,10 +1,10 @@ package ru.spcex.clearing.swt.importer.logic.data.enums; public enum ETable { - S_DF_08("S_DF08"), - S_DF_10("S_DF10"), - S_DF_13("S_DF13"); - //S_DF20("S_DF20"); + S_DF_08("DF-08"), + S_DF_10("DF-10"), + S_DF_13("DF-13"); + //S_DF20("DF-20"); private final String prefix; @@ -28,6 +28,6 @@ public enum ETable { } public boolean fileForThisTable(String filename) { - return filename != null && filename.startsWith(prefix); - } + return filename != null && filename.contains(prefix); } +} diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/AbstractTable.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/AbstractTable.java index 93b60acd2..ac5eecee8 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/AbstractTable.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/AbstractTable.java @@ -31,7 +31,7 @@ public abstract class AbstractTable { this.hazelcastService = hazelcastService; } - public abstract T getEntity(Object[] entity); + public abstract T getEntity(String[] entity); public void injectEntity(T obj) { if (map == null) { diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java index 193b3ed80..199a7f3ac 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java @@ -17,13 +17,13 @@ public class SDf08Table extends AbstractTable { } @Override - public SDf08 getEntity(Object[] entity) { + public SDf08 getEntity(String[] entity) { SDf08 result = new SDf08(); - result.setOutDocument((String) entity[0]); - result.setDepoCode((String) entity[1]); - result.setQuantity((String) entity[2]); - result.setSecurityCode((String) entity[3]); - result.setClientName((String) entity[4]); + result.setOutDocument(entity[3]); + result.setDepoCode(entity[0]); + result.setQuantity(entity[1]); + result.setSecurityCode(entity[2]); + result.setClientName(entity[5]); result.setFileName(filename); result.setGenerationTime(Instant.now()); result.setGenerationId(fileId); diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java index c1a885b20..7380c1aab 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java @@ -17,13 +17,13 @@ public class SDf10Table extends AbstractTable { } @Override - public SDf10 getEntity(Object[] entity) { + public SDf10 getEntity(String[] entity) { SDf10 result = new SDf10(); - result.setOutDocument((String) entity[0]); - result.setDepoCode((String) entity[1]); - result.setQuantity((String) entity[2]); - result.setSecurityCode((String) entity[3]); - result.setClientName((String) entity[4]); + result.setOutDocument(entity[3]); + result.setDepoCode(entity[0]); + result.setQuantity(entity[1]); + result.setSecurityCode(entity[2]); + result.setClientName(entity[5]); result.setFileName(filename); result.setGenerationTime(Instant.now()); result.setGenerationId(fileId); diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf13Table.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf13Table.java index 63385b7e5..d708e442c 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf13Table.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf13Table.java @@ -17,9 +17,8 @@ public class SDf13Table extends AbstractTable { } @Override - public SDf13 getEntity(Object[] entity) { + public SDf13 getEntity(String[] entity) { SDf13 result = new SDf13(); - result.setFileName(filename); result.setGenerationTime(Instant.now()); result.setGenerationId(fileId); diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ImportToDB.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ImportToDB.java index 3bd3fed06..7b0e6eb3f 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ImportToDB.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ImportToDB.java @@ -1,6 +1,5 @@ package ru.spcex.clearing.swt.importer.logic.stages; -import com.linuxense.javadbf.DBFReader; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import ru.spcex.clearing.swt.importer.config.settings.ImportSWTServiceSettings; @@ -8,6 +7,7 @@ import ru.spcex.clearing.swt.importer.logic.data.ResultContainer; import ru.spcex.clearing.swt.importer.logic.data.enums.ETable; import ru.spcex.clearing.swt.importer.logic.data.enums.StageResult; import ru.spcex.clearing.swt.importer.logic.data.tables.AbstractTable; +import ru.spcex.clearing.swt.importer.util.SWTReader; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; import ru.spcex.platform.utils.log.ExceptionUtils; @@ -43,17 +43,21 @@ public class ImportToDB extends Stage { byte[] source = resultContainer.getSwtSource(); Charset sourceCharset = Charset.forName(settings.getCommon().getEncodingSource()); + + try (InputStream is = new ByteArrayInputStream(source); - DBFReader dbfReader = new DBFReader(is, sourceCharset)) { + SWTReader swtReader = new SWTReader(is, sourceCharset)) { AbstractTable table = mappingEnumTableObjectTable.get(currTable); table.setHazelcastService(hazelcastService); table.setFilename(resultContainer.getSwtFile().getName()); Long fileId = hazelcastService.getImdgIdGenerator().nextId(); table.setFileId(fileId); - for (int i = 0; i < dbfReader.getRecordCount(); i++) { - Object[] entity = dbfReader.nextRecord(); + int counter = 0; + while (swtReader.hasNextRecord()) { + counter++; + String[] entity = swtReader.nextRecord(); if (entity == null) { - log.warn("record index {} null", i); + log.warn("record index {} null", counter); continue; } table.injectEntity(table.getEntity(entity)); diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/LoadFileFromDisk.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/LoadFileFromDisk.java index 1ed315a33..4ebcb8ad1 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/LoadFileFromDisk.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/LoadFileFromDisk.java @@ -25,13 +25,13 @@ public class LoadFileFromDisk extends Stage { Objects.requireNonNull(resultContainer.getSwtFile()); UUID taskUuid = resultContainer.getUuid(); - File dbfFile = resultContainer.getSwtFile(); + File swtFile = resultContainer.getSwtFile(); byte[] fileBytes; try { log.debug("uuid {}. Read all bytes from source file {}", taskUuid, resultContainer.getSwtFile().getName()); - fileBytes = Files.readAllBytes(Paths.get(dbfFile.getAbsolutePath())); + fileBytes = Files.readAllBytes(Paths.get(swtFile.getAbsolutePath())); if (fileBytes.length == 0) throw new IOException("Empty file"); - if (settings.getStore().isDeleteSrcFiles()) Files.delete(dbfFile.toPath()); + if (settings.getStore().isDeleteSrcFiles()) Files.delete(swtFile.toPath()); } catch (IOException e) { log.error(String.format("uuid %s. Can't read file %s", taskUuid, resultContainer.getSwtFile().getName()), e); return StageResult.ERROR; diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ValidateFields.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ValidateFields.java index 0451716da..d29b5261c 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ValidateFields.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/stages/ValidateFields.java @@ -27,7 +27,7 @@ public class ValidateFields extends Stage implements InitializingBean { } /** - * 1. Проверяет кодировку из настройки dbf.encoding-source + * 1. Проверяет кодировку из настройки swt.encoding-source */ @Override public void afterPropertiesSet() throws Exception { diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/FileChecker.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/FileChecker.java index e4d2d9a26..35778d474 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/FileChecker.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/services/FileChecker.java @@ -23,32 +23,31 @@ public class FileChecker { Map> newFiles = new EnumMap<>(ETable.class); String srcDir = settings.getStore().getSrcDir(); - List dbfFiles = lsDBF(srcDir); - if (dbfFiles.isEmpty()) return newFiles; + List swtFiles = lsSWT(srcDir); + if (swtFiles.isEmpty()) return newFiles; - for (File dbfFile : dbfFiles) { - if (dbfFile.isDirectory()) continue; + for (File swtFile : swtFiles) { + if (swtFile.isDirectory()) continue; - ETable currTable = ETable.getTableForFilename(dbfFile.getName()); + ETable currTable = ETable.getTableForFilename(swtFile.getName()); if (currTable == null) continue; if (specificTable != null && !specificTable.equals(currTable)) continue; List currList = newFiles.computeIfAbsent(currTable, list -> new LinkedList<>()); - currList.add(dbfFile); + currList.add(swtFile); } return newFiles; } - private List lsDBF(String dbfDirPath) { - File dbfDir = new File(dbfDirPath); - File[] dbfFiles = dbfDir.listFiles((dir, name) -> { - int formatPosition = name.lastIndexOf("."); - if (formatPosition == -1 || formatPosition == name.length() - 1) return false; - return "dbf".equalsIgnoreCase(name.substring(formatPosition + 1)); + private List lsSWT(String swtDirPath) { + File swtDir = new File(swtDirPath); + File[] swtFiles = swtDir.listFiles((dir, name) -> { + String offsetName = name.substring(0, 9); + return offsetName.equalsIgnoreCase("RDC_KS_DF"); }); List resultFiles = new LinkedList<>(); - if (dbfFiles != null && dbfFiles.length >= 1) { - resultFiles.addAll(Arrays.asList(dbfFiles)); + if (swtFiles != null && swtFiles.length >= 1) { + resultFiles.addAll(Arrays.asList(swtFiles)); } return resultFiles; diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/util/SWTReader.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/util/SWTReader.java new file mode 100644 index 000000000..9415ddc9e --- /dev/null +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/util/SWTReader.java @@ -0,0 +1,36 @@ +package ru.spcex.clearing.swt.importer.util; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; +import java.util.Scanner; + +public class SWTReader implements Closeable { + protected InputStream inputStream; + protected Scanner scanner; + + public SWTReader(InputStream inputStream, Charset charset) { + this.inputStream = inputStream; + this.scanner = new Scanner(inputStream, charset); + } + + public String[] nextRecord() { + String line = scanner.nextLine(); + String[] separetedLine = line.split(":"); + if (separetedLine.length < 5) { + return null; + } + return separetedLine; + } + + public boolean hasNextRecord() { + return scanner.hasNextLine(); + } + + @Override + public void close() throws IOException { + inputStream.close(); + scanner.close(); + } +} From a60f5506454affc3d9642ebbdd3ad8b4d52b7e81 Mon Sep 17 00:00:00 2001 From: aalehin Date: Sat, 27 May 2023 16:09:53 +0300 Subject: [PATCH 19/36] http://jira.mfd.msk:8088/browse/CLS-316 --- small fix --- .../clearing/swt/importer/logic/data/tables/SDf08Table.java | 1 - .../clearing/swt/importer/logic/data/tables/SDf10Table.java | 1 - 2 files changed, 2 deletions(-) diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java index 199a7f3ac..ee1bd40e9 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf08Table.java @@ -19,7 +19,6 @@ public class SDf08Table extends AbstractTable { @Override public SDf08 getEntity(String[] entity) { SDf08 result = new SDf08(); - result.setOutDocument(entity[3]); result.setDepoCode(entity[0]); result.setQuantity(entity[1]); result.setSecurityCode(entity[2]); diff --git a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java index 7380c1aab..ff53c97e3 100644 --- a/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java +++ b/clearing-parent/swt-importer/src/main/java/ru/spcex/clearing/swt/importer/logic/data/tables/SDf10Table.java @@ -19,7 +19,6 @@ public class SDf10Table extends AbstractTable { @Override public SDf10 getEntity(String[] entity) { SDf10 result = new SDf10(); - result.setOutDocument(entity[3]); result.setDepoCode(entity[0]); result.setQuantity(entity[1]); result.setSecurityCode(entity[2]); From d2da0e24c4521c4494dc0b2bd40e7508f50b2a06 Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Sat, 27 May 2023 16:17:03 +0300 Subject: [PATCH 20/36] http://jira.mfd.msk:8088/browse/CLS-290 --- .../session/stage/PrimaryAuctionBnSession.java | 7 +++---- .../clearing/session/stage/impl/RegistryBuilder.java | 11 ++++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java index 137b1df75..03ae1b4ea 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/PrimaryAuctionBnSession.java @@ -104,14 +104,13 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali if (!isRunning()) { return; } - if (!checkStage(TaskType.StartRevise)) { - log.error("cannot continue session, current stage is {}", currStage.get()); - throw new StageException(); - } if (checkStage(TaskType.StartRevise)) { firstPart(req); } else if (checkStage(TaskType.FormingPaymentInstruction)) { finishPart(req); + } else { + log.error("cannot continue session, current stage is {}", currStage.get()); + throw new StageException(); } } catch (StageException e) { //already logged diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java index b19291e9f..d8a98d3c3 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/RegistryBuilder.java @@ -81,10 +81,11 @@ public class RegistryBuilder { TradingClearingRegistry tcr = searchTradingClearingRegistry(); String capacityByAccount = null; boolean isMoney = false; - Account account = accountImdg.getSingleObjectByID(reg.getAccountId()); + Account account = null; if ((regDsgn.equals(RegistryDesignation.O) && side.isBuy()) || (regDsgn.equals(RegistryDesignation.T) && side.isSell())) { isMoney = true; reg.setAccountId(tcr.getMoneyAccountId()); + account = accountImdg.getSingleObjectByID(tcr.getMoneyAccountId()); reg.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); reg.setBalanceDimension(BalanceDimension.MONY.getKey()); //fixme add second leg code branch Currency currency = currencyImdg.getSingleObjectByFieldValues(Map.of("currencyCode", exec.getSettlementCurrency())); @@ -104,6 +105,7 @@ public class RegistryBuilder { } else if ((regDsgn.equals(RegistryDesignation.T) && side.isBuy()) || (regDsgn.equals(RegistryDesignation.O) && side.isSell())) { isMoney = false; reg.setAccountId(tcr.getDepoAccountId()); + account = accountImdg.getSingleObjectByID(tcr.getDepoAccountId()); reg.setRegistryInstrumentType(RegistryInstrumentType.S.getKey()); reg.setBalanceDimension(BalanceDimension.PICS.getKey()); //fixme add second leg code branch reg.setSecurityId(exec.getSecurityId()); @@ -113,8 +115,11 @@ public class RegistryBuilder { capacityByAccount = depoAccount.getDepoAccountType(); } } - reg.setAccountType(account.getAccountType()); - reg.setAccount(account.getAccount()); + + if (account != null) { + reg.setAccountType(account.getAccountType()); + reg.setAccount(account.getAccount()); + } reg.setRegistryDesignation(regDsgn.getKey()); if (capacityByAccount != null) { reg.setRegistryCapacity(capacityByAccount); From 18f17923f9e265f17e637a4650c8aa63fe48e778 Mon Sep 17 00:00:00 2001 From: aalehin Date: Sat, 27 May 2023 16:37:29 +0300 Subject: [PATCH 21/36] http://jira.mfd.msk:8088/browse/CLS-316 --- sh update --- z-distr/src/main/resources/distr/bin/kill_all.sh | 1 + z-distr/src/main/resources/distr/bin/launch_all.sh | 1 + z-distr/src/main/resources/distr/bin/swt-importer.sh | 9 +++++++++ 3 files changed, 11 insertions(+) create mode 100644 z-distr/src/main/resources/distr/bin/swt-importer.sh diff --git a/z-distr/src/main/resources/distr/bin/kill_all.sh b/z-distr/src/main/resources/distr/bin/kill_all.sh index cf91cdbe9..1552e30b7 100644 --- a/z-distr/src/main/resources/distr/bin/kill_all.sh +++ b/z-distr/src/main/resources/distr/bin/kill_all.sh @@ -16,5 +16,6 @@ kill -9 $(ps -ef | grep java | grep utility-service.jar | awk '{print $2}') kill -9 $(ps -ef | grep java | grep scheduler-service.jar | awk '{print $2}') kill -9 $(ps -ef | grep java | grep reports-service.jar | awk '{print $2}') kill -9 $(ps -ef | grep java | grep registry-service.jar | awk '{print $2}') +kill -9 $(ps -ef | grep java | grep swt-importer.jar | awk '{print $2}') diff --git a/z-distr/src/main/resources/distr/bin/launch_all.sh b/z-distr/src/main/resources/distr/bin/launch_all.sh index 1cad17024..b8d62aeba 100644 --- a/z-distr/src/main/resources/distr/bin/launch_all.sh +++ b/z-distr/src/main/resources/distr/bin/launch_all.sh @@ -16,3 +16,4 @@ cd /opt/mfd/clearing/bin /opt/mfd/clearing/bin/scheduler-service.sh /opt/mfd/clearing/bin/reports-service.sh /opt/mfd/clearing/bin/registry-service.sh +/opt/mfd/clearing/bin/swt-importer.sh diff --git a/z-distr/src/main/resources/distr/bin/swt-importer.sh b/z-distr/src/main/resources/distr/bin/swt-importer.sh new file mode 100644 index 000000000..15cf5a6fe --- /dev/null +++ b/z-distr/src/main/resources/distr/bin/swt-importer.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +CLEARING_HOME=/opt/mfd/clearing/ +cd $CLEARING_HOME/bin + +CMD="java -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7111 -jar swt-importer.jar --spring.config.location=$CLEARING_HOME/settings/swt-importer/" + +$CMD >/dev/null 2>&1 & + From 5e5133b580ce344151ae66904d18335d6d0a18a6 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 15:51:58 +0300 Subject: [PATCH 22/36] . --- .../spcex/clearing/util/services/IMDGMessageResolver.java | 2 +- .../reports/reports/bp/LiabilitiesClaimsReportBuilder.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/IMDGMessageResolver.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/IMDGMessageResolver.java index 0149ece9f..ce5a7e0f4 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/IMDGMessageResolver.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/IMDGMessageResolver.java @@ -30,7 +30,7 @@ public class IMDGMessageResolver implements IMessageResolver { try { ErrorCodeDictionary errorDictionary = errorCodeDictionaryIMDG.getSingleObjectByID(errMsg.getSubject().getId()); if (errorDictionary == null) { - log.warn("ERROR_CODE_DICTIONARY not found fo id={}", errMsg.getSubject().getId()); + log.warn("ERROR_CODE_DICTIONARY not found for id={}", errMsg.getSubject().getId()); return simplFormatter.get(); } String textTemplate = errorDictionary.getName(); diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/LiabilitiesClaimsReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/LiabilitiesClaimsReportBuilder.java index 8c505c261..5e82a2020 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/LiabilitiesClaimsReportBuilder.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/LiabilitiesClaimsReportBuilder.java @@ -104,6 +104,10 @@ public abstract class LiabilitiesClaimsReportBuilder

extends CSVReportBuilder execution.getTradingClearingRegistryId() ); + if (registry == null) { + log.warn("registry not found for companyId={}", execution.getCompanyId()); + } + String id = String.valueOf(execution.getId()); String docDate = dateFormatter.format(nowDate); String docTime = timeFormatter.format(nowTime); @@ -114,7 +118,7 @@ public abstract class LiabilitiesClaimsReportBuilder

extends CSVReportBuilder String sessionId = String.valueOf(execution.getSessionId()); String clearingDate = dateFormatter.format(execution.getClearingDate()); String clearingTime = dateFormatter.format(execution.getClearingDate()); - String trdAccId = registry.getTradingClearingRegistry(); + String trdAccId = registry == null? null : registry.getTradingClearingRegistry(); String account = String.valueOf(tradingClearingRegistry.getMoneyAccountId()); String depoAccount = String.valueOf(tradingClearingRegistry.getDepoAccountId()); String currency = execution.getSettlementCurrency(); From 602604aa8109581f1c4b08aaffc4c00b6ef2f4a1 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 16:10:56 +0300 Subject: [PATCH 23/36] =?UTF-8?q?securities-service=20=D0=BF=D0=BE=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80=D1=8B=20(=D0=B2=20=D1=81=D0=BE=D0=BE?= =?UTF-8?q?=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D0=B8=20=D1=81?= =?UTF-8?q?=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validation/ValidationProvider.java | 42 ++++++++++--------- .../rule/HaveValidCodeByDictionary.java | 14 ++++++- .../validation/rule/HaveValidCompanyId.java | 13 +++++- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java index 2dfae6757..d3ac6f228 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java @@ -64,14 +64,15 @@ public class ValidationProvider { MoneyMarketSecurityNewRequest::getStartDate, MoneyMarketSecurityNewRequest::getEndDate, SecuritiesError.RequiredFieldIsEmpty, - SecuritiesError.WrongFieldValue), + SecuritiesError.WrongFieldValue, + false), new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentAlreadyExists, MoneyMarketSecurityNewRequest.class), new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "RATE"), MmsNewValidationRule.RequiredFieldIsNotEmpty, new HaveValidCompanyId<>(MoneyMarketSecurityNewRequest::getIssuerId, "issuerId"), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, MoneyMarketSecurityNewRequest::getInstrumentType, "instrumentType"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, MoneyMarketSecurityNewRequest::getWorkflowStatus, "workflowStatus"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_TermTypeDictionary, MoneyMarketSecurityNewRequest::getTermType, "termType"), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, MoneyMarketSecurityNewRequest::getWorkflowStatus, "workflowStatus", false), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_TermTypeDictionary, MoneyMarketSecurityNewRequest::getTermType, "termType", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, MoneyMarketSecurityNewRequest::getNominalCurrency, "nominalCurrency") ); }; @@ -92,15 +93,16 @@ public class ValidationProvider { MoneyMarketSecurityUpdateRequest::getStartDate, MoneyMarketSecurityUpdateRequest::getEndDate, SecuritiesError.RequiredFieldIsEmpty, - SecuritiesError.WrongFieldValue), + SecuritiesError.WrongFieldValue, + false), new PresentById(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "RATE"), new WorkflowStatusActv(), - new HaveValidCompanyId<>(MoneyMarketSecurityUpdateRequest::getIssuerId, "issuerId"), + new HaveValidCompanyId<>(MoneyMarketSecurityUpdateRequest::getIssuerId, "issuerId", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, MoneyMarketSecurityUpdateRequest::getInstrumentType, "instrumentType"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, MoneyMarketSecurityUpdateRequest::getWorkflowStatus, "workflowStatus"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_TermTypeDictionary, MoneyMarketSecurityUpdateRequest::getTermType, "termType"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, MoneyMarketSecurityUpdateRequest::getNominalCurrency, "nominalCurrency") + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, MoneyMarketSecurityUpdateRequest::getWorkflowStatus, "workflowStatus", false), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_TermTypeDictionary, MoneyMarketSecurityUpdateRequest::getTermType, "termType", false), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, MoneyMarketSecurityUpdateRequest::getNominalCurrency, "nominalCurrency", false) ); }; } @@ -133,8 +135,8 @@ public class ValidationProvider { EquityNewValidationRule.RequiredFieldIsNotEmpty, new HaveValidCompanyId<>(EquitySecurityNewRequest::getIssuerId, "issuerId"), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, EquitySecurityNewRequest::getInstrumentType, "instrumentType"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, EquitySecurityNewRequest::getWorkflowStatus, "workflowStatus"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_ShareTypeDictionary, EquitySecurityNewRequest::getShareType, "shareType")); + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, EquitySecurityNewRequest::getWorkflowStatus, "workflowStatus", false), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_ShareTypeDictionary, EquitySecurityNewRequest::getShareType, "shareType", false)); }; } @@ -151,10 +153,10 @@ public class ValidationProvider { new PresentById(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "EQTY"), new WorkflowStatusActv(), - new HaveValidCompanyId<>(EquitySecurityUpdateRequest::getIssuerId, "issuerId"), + new HaveValidCompanyId<>(EquitySecurityUpdateRequest::getIssuerId, "issuerId", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, EquitySecurityUpdateRequest::getInstrumentType, "instrumentType"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, EquitySecurityUpdateRequest::getWorkflowStatus, "workflowStatus"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_ShareTypeDictionary, EquitySecurityUpdateRequest::getShareType, "shareType")); + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, EquitySecurityUpdateRequest::getWorkflowStatus, "workflowStatus", false), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_ShareTypeDictionary, EquitySecurityUpdateRequest::getShareType, "shareType", false)); }; } @@ -185,11 +187,11 @@ public class ValidationProvider { new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_FixedIncomeSecurity, SecuritiesError.InstrumentAlreadyExists, FixedIncomeSecurityNewRequest.class), new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "BOND"), FixedIncomeNewValidationRule.RequiredFieldIsNotEmpty, - new HaveValidCompanyId<>(FixedIncomeSecurityNewRequest::getIssuerId, "issuerId"), + new HaveValidCompanyId<>(FixedIncomeSecurityNewRequest::getIssuerId, "issuerId", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, FixedIncomeSecurityNewRequest::getInstrumentType, "instrumentType"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, FixedIncomeSecurityNewRequest::getWorkflowStatus, "workflowStatus"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_BondTypeDictionary, FixedIncomeSecurityNewRequest::getBondType, "bondType"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, FixedIncomeSecurityNewRequest::getNominalCurrency, "nominalCurrency") + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, FixedIncomeSecurityNewRequest::getWorkflowStatus, "workflowStatus", false), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_BondTypeDictionary, FixedIncomeSecurityNewRequest::getBondType, "bondType", false), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, FixedIncomeSecurityNewRequest::getNominalCurrency, "nominalCurrency", false) ); }; } @@ -211,9 +213,9 @@ public class ValidationProvider { new WorkflowStatusActv(), new HaveValidCompanyId<>(FixedIncomeSecurityUpdateRequest::getIssuerId, "issuerId"), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, FixedIncomeSecurityUpdateRequest::getInstrumentType, "instrumentType"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, FixedIncomeSecurityUpdateRequest::getWorkflowStatus, "workflowStatus"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_BondTypeDictionary, FixedIncomeSecurityUpdateRequest::getBondType, "bondType"), - new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, FixedIncomeSecurityUpdateRequest::getNominalCurrency, "nominalCurrency") + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, FixedIncomeSecurityUpdateRequest::getWorkflowStatus, "workflowStatus", false), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_BondTypeDictionary, FixedIncomeSecurityUpdateRequest::getBondType, "bondType", false), + new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_CurrencyCodeDictionary, FixedIncomeSecurityUpdateRequest::getNominalCurrency, "nominalCurrency", false) ); }; } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java index 5ec7f2ec6..995367116 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java @@ -12,21 +12,33 @@ import java.util.Map; import java.util.Optional; import java.util.function.Function; +@Deprecated // use common validator public class HaveValidCodeByDictionary implements IValidationRule> { String mapName; String errArg; Function codeGetter; + boolean required; + public HaveValidCodeByDictionary(String mapName, Function codeGetter, String errArg, boolean required) { + this.mapName = mapName; + this.codeGetter = codeGetter; + this.errArg = errArg; + this.required = required; + } public HaveValidCodeByDictionary(String mapName, Function codeGetter, String errArg) { this.mapName = mapName; this.codeGetter = codeGetter; this.errArg = errArg; + this.required = true; } @Override public Optional validate(ImdgValidationContext context) { R validatedObject = context.getValidatedObject(); String code = codeGetter.apply(validatedObject); if(!StringUtils.hasText(code)) { - return of(SecuritiesError.RequiredFieldIsEmpty, errArg); + if (required) + return of(SecuritiesError.RequiredFieldIsEmpty, errArg); + else + return null; } Imdg imdgDictionary = context.obtainMap(mapName, SpcexObjectBase.class); SpcexObjectBase dictionary = imdgDictionary.getSingleObjectByFieldValues(Map.of( diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCompanyId.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCompanyId.java index 914fa2903..b4f45a65b 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCompanyId.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCompanyId.java @@ -11,19 +11,30 @@ import ru.spcex.platform.utils.validation.IValidationRule; import java.util.Optional; import java.util.function.Function; +@Deprecated // use common validator public class HaveValidCompanyId implements IValidationRule> { Function idGetter; String errArg; + boolean required; + public HaveValidCompanyId(Function idGetter, String errArg, boolean required) { + this.idGetter = idGetter; + this.errArg = errArg; + this.required=required; + } public HaveValidCompanyId(Function idGetter, String errArg) { this.idGetter = idGetter; this.errArg = errArg; + this.required=true; } @Override public Optional validate(ImdgValidationContext context) { R validatedObject = context.getValidatedObject(); Long id = idGetter.apply(validatedObject); if(id == null) { - return of(SecuritiesError.RequiredFieldIsEmpty, errArg); + if (required) + return of(SecuritiesError.RequiredFieldIsEmpty, errArg); + else + return empty(); } Imdg imdgDictionary = context.obtainMap(IMDGDistributedNames.Map_Company, SpcexObjectBase.class); SpcexObjectBase dictionary = imdgDictionary.getSingleObjectByID(id); From 5fee2ac276a39dbf4f466f90a2320638c725a7f2 Mon Sep 17 00:00:00 2001 From: aalehin Date: Sat, 27 May 2023 16:56:15 +0300 Subject: [PATCH 24/36] http://jira.mfd.msk:8088/browse/CLS-316 --- sh update --- z-distr/src/main/resources/distr/bin/swt-importer.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/z-distr/src/main/resources/distr/bin/swt-importer.sh b/z-distr/src/main/resources/distr/bin/swt-importer.sh index 15cf5a6fe..f06403c1f 100644 --- a/z-distr/src/main/resources/distr/bin/swt-importer.sh +++ b/z-distr/src/main/resources/distr/bin/swt-importer.sh @@ -3,7 +3,6 @@ CLEARING_HOME=/opt/mfd/clearing/ cd $CLEARING_HOME/bin -CMD="java -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7111 -jar swt-importer.jar --spring.config.location=$CLEARING_HOME/settings/swt-importer/" +CMD="java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:7111 -jar swt-importer.jar --spring.config.location=$CLEARING_HOME/settings/swt-importer/" $CMD >/dev/null 2>&1 & - From 58dcfe6061251c855ec595be86a6339745cf1ea5 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 17:18:29 +0300 Subject: [PATCH 25/36] =?UTF-8?q?company-service=20http://jira.mfd.msk:808?= =?UTF-8?q?8/browse/CLS-333=20=D1=87=D0=B0=D1=81=D1=82=D1=8C=202.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/validation/ProfileDocumentValidationConfig.java | 3 --- .../company/service/ClearingMemberCategoryService.java | 7 +++++-- .../ru/spcex/clearing/company/service/CompanyService.java | 6 ------ .../ru/spcex/clearing/company/service/RelationService.java | 5 ++--- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ProfileDocumentValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ProfileDocumentValidationConfig.java index ffc0ca3f2..d08613612 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ProfileDocumentValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ProfileDocumentValidationConfig.java @@ -57,9 +57,6 @@ public class ProfileDocumentValidationConfig { FieldRequiredRule.instance("issuer", ProfileDocumentNewRequest::getIssuer, CompanyErrors.RequiredFieldEmpty), - FieldRequiredRule.instance("issuerCode", - ProfileDocumentNewRequest::getIssuerCode, - CompanyErrors.RequiredFieldEmpty), FieldRequiredRule.instance("name", ProfileDocumentNewRequest::getName, CompanyErrors.RequiredFieldEmpty), diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClearingMemberCategoryService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClearingMemberCategoryService.java index 33bdb7ed2..dd4b8f2b4 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClearingMemberCategoryService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClearingMemberCategoryService.java @@ -21,11 +21,11 @@ import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; 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 ru.spcex.platform.utils.validation.IValidator; -import java.util.Map; import java.util.function.Function; @Service @@ -34,6 +34,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private final Imdg clearingMemberCategoryMap; private final Imdg companyMap; private final ImdgProvider imdgProvider; + private final ImdgId idSequence; private final Function clearingMemberCategoryNewRequestValidator; private final Function clearingMemberCategoryUpdateRequestValidator; @@ -56,6 +57,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init this.clearingMemberCategoryMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.imdgProvider = imdgProvider; + this.idSequence = imdgProvider.getImdgIdGenerator(); this.clearingMemberCategoryNewRequestValidator = clearingMemberCategoryNewRequestValidator; this.clearingMemberCategoryUpdateRequestValidator = clearingMemberCategoryUpdateRequestValidator; this.clearingMemberCategoryDeleteRequestValidator = clearingMemberCategoryDeleteRequestValidator; @@ -88,6 +90,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init if (requestInfoUpdate != null) return requestInfoUpdate; ClearingMemberCategoryNewRequest req = userRequest.getRequestPayload(); ClearingMemberCategory newCategory = new ClearingMemberCategory(); + newCategory.setId(idSequence.nextId()); newCategory.setCompanyId(req.getCompanyId()); newCategory.setClearingMemberCategory(req.getClearingMemberCategory()); @@ -96,7 +99,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init transaction.beginTransaction(); boolean txOk = false; try { - companyService.relationService.createNewRelation(transaction, req.getCompanyId()); + companyService.relationService.createNewRelation(transaction, req.getCompanyId(), newCategory); Imdg txClearingMemberCategoryMap = transaction.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); txClearingMemberCategoryMap.insert(newCategory); txOk = true; diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java index 148c94093..0460cb621 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyService.java @@ -141,11 +141,6 @@ public class CompanyService extends QueueConsumer implements InitializingBean { companyMap.insert(company); log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", companyNewRequestBaseRequest.getId(), company.getId()); - //todo see this CLS-333.2 - relationService.createNewRelation(transaction, company.getId()); - if (!(WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()))) { // Block - relationService.onChangeWorkflowStatus(transaction, company, null, company.getWorkflowStatus()); - } txOk = true; } finally { if (txOk) @@ -197,7 +192,6 @@ public class CompanyService extends QueueConsumer implements InitializingBean { if (updateRequest.getWorkflowStatus() != null) { company.setWorkflowStatus(updateRequest.getWorkflowStatus()); if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { - //todo see this CLS-333.2 relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); } else { log.trace("Status was not changed"); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java index 491107d32..7632612c6 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java @@ -280,16 +280,15 @@ public class RelationService extends QueueConsumer implements InitializingBean { // --- internal API --- - protected void createNewRelation(ImdgTransaction transaction, Long companyId) { + protected void createNewRelation(ImdgTransaction transaction, Long companyId, ClearingMemberCategory clearingMemberCategory) { Imdg relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); Relation relation = new Relation(); Company company = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class).getSingleObjectByFieldValues(Map.of("id", companyId)); - ClearingMemberCategory clearingMemberCategory = transaction.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class).getSingleObjectByFieldValues(Map.of("companyId", companyId)); WorkflowStatus workflowStatus = getEnumByKey(WorkflowStatus.class, company.getWorkflowStatus()); String serviceStatus = null; if (clearingMemberCategory == null) { - log.debug("clearingMemberCategory not found for companyId={}", companyId); + log.warn("clearingMemberCategory not set for companyId={}", companyId); } else { ClearingCategory clearingCategory = getEnumByKey(ClearingCategory.class, clearingMemberCategory.getClearingMemberCategory()); switch (Objects.requireNonNull(clearingCategory)) { From 1c54744fdf10f338d30db2d4289980d9c85773ff Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 17:33:40 +0300 Subject: [PATCH 26/36] =?UTF-8?q?securities-service=20=D0=BF=D0=BE=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80=D1=8B=20(=D0=B2=20=D1=81=D0=BE=D0=BE?= =?UTF-8?q?=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D0=B8=20=D1=81?= =?UTF-8?q?=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B9).=20=D0=94=D0=BE=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=BA=D0=B0=202.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validation/rule/EquityNewValidationRule.java | 3 --- .../rule/FixedIncomeNewValidationRule.java | 3 --- .../validation/rule/MmsNewValidationRule.java | 12 ------------ 3 files changed, 18 deletions(-) diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java index 6e61fb0c8..bc12b751a 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/EquityNewValidationRule.java @@ -17,9 +17,6 @@ public enum EquityNewValidationRule implements IValidationRule Date: Sat, 27 May 2023 17:44:42 +0300 Subject: [PATCH 27/36] =?UTF-8?q?securities-service=20=D0=BF=D0=BE=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80=D1=8B=20(=D0=B2=20=D1=81=D0=BE=D0=BE?= =?UTF-8?q?=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D0=B8=20=D1=81?= =?UTF-8?q?=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B9).=20=D0=94=D0=BE=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=BA=D0=B0=203.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../clearing/securities/validation/ValidationProvider.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java index d3ac6f228..fd7a08d4f 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java @@ -97,7 +97,6 @@ public class ValidationProvider { false), new PresentById(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "RATE"), - new WorkflowStatusActv(), new HaveValidCompanyId<>(MoneyMarketSecurityUpdateRequest::getIssuerId, "issuerId", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, MoneyMarketSecurityUpdateRequest::getInstrumentType, "instrumentType"), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, MoneyMarketSecurityUpdateRequest::getWorkflowStatus, "workflowStatus", false), @@ -152,7 +151,6 @@ public class ValidationProvider { return new ValidatorImpl<>(context, new PresentById(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "EQTY"), - new WorkflowStatusActv(), new HaveValidCompanyId<>(EquitySecurityUpdateRequest::getIssuerId, "issuerId", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, EquitySecurityUpdateRequest::getInstrumentType, "instrumentType"), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, EquitySecurityUpdateRequest::getWorkflowStatus, "workflowStatus", false), @@ -210,7 +208,6 @@ public class ValidationProvider { return new ValidatorImpl<>(context, new PresentById(IMDGDistributedNames.Map_FixedIncomeSecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "BOND"), - new WorkflowStatusActv(), new HaveValidCompanyId<>(FixedIncomeSecurityUpdateRequest::getIssuerId, "issuerId"), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, FixedIncomeSecurityUpdateRequest::getInstrumentType, "instrumentType"), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, FixedIncomeSecurityUpdateRequest::getWorkflowStatus, "workflowStatus", false), From 8e3b49220a362e964fe419fb79c821633a2c18bf Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 17:49:14 +0300 Subject: [PATCH 28/36] =?UTF-8?q?backend-api=20BankAccountNewAction=20?= =?UTF-8?q?=D1=83=D0=B1=D1=80=D0=B0=D0=BB=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=BA=D1=83=20=D0=BD=D0=B0=20RUB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cud/account/BankAccountNewAction.java | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountNewAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountNewAction.java index 694729b3e..04f55964b 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountNewAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/account/BankAccountNewAction.java @@ -48,24 +48,6 @@ public class BankAccountNewAction implements IAction { @JsonProperty private Long companyId; - @Override - public Collection validate() { - List errors = new ArrayList<>(); - if ("RUB".equalsIgnoreCase(this.currency) && !StringUtils.hasLength(correspondentAccount)) { - errors.add(new EnumMessage(BackEndError.ValidationError, "correspondentAccount")); - } - if ("RUB".equalsIgnoreCase(this.currency) && !StringUtils.hasLength(correspondentAccountName)) { - errors.add(new EnumMessage(BackEndError.ValidationError, "correspondentAccountName")); - } - if ("RUB".equalsIgnoreCase(this.currency) && !StringUtils.hasLength(taxpayerIdentificationNumber)) { - errors.add(new EnumMessage(BackEndError.ValidationError, "taxpayerIdentificationNumber")); - } - if ("RUB".equalsIgnoreCase(this.currency) && !StringUtils.hasLength(taxRegistrationReasonCode)) { - errors.add(new EnumMessage(BackEndError.ValidationError, "taxRegistrationReasonCode")); - } - return errors.isEmpty() ? Collections.emptyList() : errors; - } - @Override public BankAccountNewRequest toRequest() { var req = new BankAccountNewRequest(); From e68be9e8d3818e8ff65ee121087ef7554019a92e Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 18:10:27 +0300 Subject: [PATCH 29/36] =?UTF-8?q?securities-service=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B4=D0=BE=D0=BB=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=B5?= =?UTF-8?q?=D0=BE=D0=B1=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D0=B8...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../clearing/securities/validation/ValidationProvider.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java index fd7a08d4f..d5fa822c3 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/ValidationProvider.java @@ -69,7 +69,7 @@ public class ValidationProvider { new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_MoneyMarketSecurity, SecuritiesError.InstrumentAlreadyExists, MoneyMarketSecurityNewRequest.class), new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "RATE"), MmsNewValidationRule.RequiredFieldIsNotEmpty, - new HaveValidCompanyId<>(MoneyMarketSecurityNewRequest::getIssuerId, "issuerId"), + new HaveValidCompanyId<>(MoneyMarketSecurityNewRequest::getIssuerId, "issuerId", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, MoneyMarketSecurityNewRequest::getInstrumentType, "instrumentType"), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, MoneyMarketSecurityNewRequest::getWorkflowStatus, "workflowStatus", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_TermTypeDictionary, MoneyMarketSecurityNewRequest::getTermType, "termType", false), @@ -132,7 +132,7 @@ public class ValidationProvider { new NotPresentBySecuritySymbolAndWorkflowStatusActv(IMDGDistributedNames.Map_EquitySecurity, SecuritiesError.InstrumentAlreadyExists, EquitySecurityNewRequest.class), new IsValidInstrumentTypeFromRequest(SecuritiesError.RequiredFieldIsEmpty, "EQTY"), EquityNewValidationRule.RequiredFieldIsNotEmpty, - new HaveValidCompanyId<>(EquitySecurityNewRequest::getIssuerId, "issuerId"), + new HaveValidCompanyId<>(EquitySecurityNewRequest::getIssuerId, "issuerId", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, EquitySecurityNewRequest::getInstrumentType, "instrumentType"), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, EquitySecurityNewRequest::getWorkflowStatus, "workflowStatus", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_ShareTypeDictionary, EquitySecurityNewRequest::getShareType, "shareType", false)); @@ -208,7 +208,7 @@ public class ValidationProvider { return new ValidatorImpl<>(context, new PresentById(IMDGDistributedNames.Map_FixedIncomeSecurity, SecuritiesError.InstrumentNotFound, true), new IsValidInstrumentTypeById(SecuritiesError.InstrumentNotFound, "BOND"), - new HaveValidCompanyId<>(FixedIncomeSecurityUpdateRequest::getIssuerId, "issuerId"), + new HaveValidCompanyId<>(FixedIncomeSecurityUpdateRequest::getIssuerId, "issuerId", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_InstrumentTypeDictionary, FixedIncomeSecurityUpdateRequest::getInstrumentType, "instrumentType"), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_WorkflowStatusDictionary, FixedIncomeSecurityUpdateRequest::getWorkflowStatus, "workflowStatus", false), new HaveValidCodeByDictionary<>(IMDGDistributedNames.Map_BondTypeDictionary, FixedIncomeSecurityUpdateRequest::getBondType, "bondType", false), From 616df8d5e5812da9623f754b03642b46eb6e4070 Mon Sep 17 00:00:00 2001 From: ialbert Date: Sat, 27 May 2023 18:35:27 +0300 Subject: [PATCH 30/36] ValidationConfig clearing-service fix --- .../clearing/config/ValidationConfig.java | 86 +++++++++---------- 1 file changed, 39 insertions(+), 47 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java index 4ad5956a6..3f46dca2e 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java @@ -8,14 +8,15 @@ import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.relation.Relation; import ru.clearing.classes.statics.data.execution.ExecutionDeposit; import ru.clearing.classes.statics.data.misc.STrades; +import ru.clearing.classes.statics.data.misc.Session; import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.classes.statics.data.sdf.SDf01; import ru.clearing.classes.statics.data.sdf.SDf57; import ru.clearing.classes.statics.data.security.Security; +import ru.clearing.platform.dictionary.SectionDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.service.validation.*; -import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.enumeration.ClearingCategory; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -23,48 +24,42 @@ import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.ValidatorImpl; -import java.util.HashMap; -import java.util.Map; -import java.util.function.BiConsumer; import java.util.function.BiFunction; -import java.util.function.Consumer; import java.util.function.Function; @Configuration public class ValidationConfig { - private final Map> imdgs; - private final BiConsumer, String> addImdg = (context, s) - -> context.addImdg(s, getImdg(s)); + + Imdg imdgRelation; + Imdg imdgCompany; + Imdg imdgAccount; + Imdg imdgAccountBalance; + Imdg imdgSecurity; + Imdg imdgTradingClearingRegistry; + Imdg imdgSession; + Imdg imdgSectionDictionary; public ValidationConfig(ImdgProvider imdgProvider) { - this.imdgs = new HashMap<>(); - BiConsumer> addImdg = (s, aClass) -> imdgs.put(s, imdgProvider.getImdg(s, aClass)); - addImdg.accept(IMDGDistributedNames.Map_Relation, Relation.class); - addImdg.accept(IMDGDistributedNames.Map_Company, Company.class); - addImdg.accept(IMDGDistributedNames.Map_Account, Account.class); - addImdg.accept(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class); - addImdg.accept(IMDGDistributedNames.Map_Security, Security.class); - addImdg.accept(IMDGDistributedNames.Map_Company, Company.class); - addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); - } - - /** - * чтобы во всех валидаторах был один экземпляр Imdg - */ - private Imdg getImdg(String key) { - return imdgs.get(key); + this.imdgRelation = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + this.imdgCompany = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.imdgAccount = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); + this.imdgAccountBalance = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class); + this.imdgSecurity = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class); + this.imdgTradingClearingRegistry = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + this.imdgSession = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class); + this.imdgSectionDictionary = imdgProvider.getImdg(IMDGDistributedNames.Map_SectionDictionary, SectionDictionary.class); } @Bean("executionDepositValidator") - public BiFunction executionDepositValidator() { + public BiFunction executionDepositValidator(ImdgProvider imdgProvider) { return (category, execDeposit) -> { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(execDeposit); context.storeObject(ClrngValidationStored.categoryPredefined, category); - addImdg.accept(context, IMDGDistributedNames.Map_Relation); - addImdg.accept(context, IMDGDistributedNames.Map_Company); - addImdg.accept(context, IMDGDistributedNames.Map_Account); - addImdg.accept(context, IMDGDistributedNames.Map_AccountBalance); + context.addImdg(IMDGDistributedNames.Map_Relation, imdgRelation); + context.addImdg(IMDGDistributedNames.Map_Company, imdgCompany); + context.addImdg(IMDGDistributedNames.Map_Account, imdgAccount); + context.addImdg(IMDGDistributedNames.Map_AccountBalance, imdgAccountBalance); return new ValidatorImpl<>(context, ExecutionDepositValidationRule.ClearingIsAllowed, ExecutionDepositValidationRule.AccountIsNotBlocked, @@ -78,9 +73,9 @@ public class ValidationConfig { return sTrades -> { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(sTrades); - addImdg.accept(context, IMDGDistributedNames.Map_Security); - addImdg.accept(context, IMDGDistributedNames.Map_Company); - addImdg.accept(context, IMDGDistributedNames.Map_TradingClearingRegistry); + context.addImdg(IMDGDistributedNames.Map_Security, imdgSecurity); + context.addImdg(IMDGDistributedNames.Map_Company, imdgCompany); + context.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry); return new ValidatorImpl<>(context, STradesValidationRule.SecurityPresent, STradesValidationRule.CompanyPresent, @@ -94,12 +89,12 @@ public class ValidationConfig { return rgs -> { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(rgs); - addImdg.accept(context, IMDGDistributedNames.Map_Relation); - addImdg.accept(context, IMDGDistributedNames.Map_Session); - addImdg.accept(context, IMDGDistributedNames.Map_SectionDictionary); - addImdg.accept(context, IMDGDistributedNames.Map_Account); - addImdg.accept(context, IMDGDistributedNames.Map_Company); - addImdg.accept(context, IMDGDistributedNames.Map_TradingClearingRegistry); + context.addImdg(IMDGDistributedNames.Map_Relation, imdgRelation); + context.addImdg(IMDGDistributedNames.Map_Session, imdgSession); + context.addImdg(IMDGDistributedNames.Map_SectionDictionary, imdgSectionDictionary); + context.addImdg(IMDGDistributedNames.Map_Account, imdgAccount); + context.addImdg(IMDGDistributedNames.Map_Company, imdgCompany); + context.addImdg(IMDGDistributedNames.Map_TradingClearingRegistry, imdgTradingClearingRegistry); return new ValidatorImpl<>(context, RegistryStep3ValidationRule.ClearingAvailable, RegistryStep3ValidationRule.AccountActive, @@ -112,9 +107,8 @@ public class ValidationConfig { return sDf01 -> { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(sDf01); - Consumer addImdg = (s) -> context.addImdg(s, getImdg(s)); - addImdg.accept(IMDGDistributedNames.Map_Account); - addImdg.accept(IMDGDistributedNames.Map_Company); + context.addImdg(IMDGDistributedNames.Map_Account, imdgAccount); + context.addImdg(IMDGDistributedNames.Map_Company, imdgCompany); return new ValidatorImpl<>(context, Sdf01ValidationRule.CompanyPresent, Sdf01ValidationRule.AccountPresent, @@ -130,9 +124,8 @@ public class ValidationConfig { return sDf57 -> { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(sDf57); - Consumer addImdg = (s) -> context.addImdg(s, getImdg(s)); - addImdg.accept(IMDGDistributedNames.Map_Account); - addImdg.accept(IMDGDistributedNames.Map_Company); + context.addImdg(IMDGDistributedNames.Map_Account, imdgAccount); + context.addImdg(IMDGDistributedNames.Map_Company, imdgCompany); return new ValidatorImpl<>(context, Sdf57ValidationRule.CompanyDebOrCredPresent, Sdf57ValidationRule.AccountDebOrCredPresent, @@ -146,9 +139,8 @@ public class ValidationConfig { return sDf01 -> { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(sDf01); - Consumer addImdg = (s) -> context.addImdg(s, getImdg(s)); - addImdg.accept(IMDGDistributedNames.Map_Account); - addImdg.accept(IMDGDistributedNames.Map_Company); + context.addImdg(IMDGDistributedNames.Map_Account, imdgAccount); + context.addImdg(IMDGDistributedNames.Map_Company, imdgCompany); return new ValidatorImpl<>(context, Sdf01NewValidationRule.CompanyPresent, Sdf01NewValidationRule.AccountType, From 4b25a6d1e961d01ad47e4c2c92b43dd7a087be06 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 18:41:08 +0300 Subject: [PATCH 31/36] =?UTF-8?q?account-service=20securities-service=20?= =?UTF-8?q?=D0=92=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=82=D0=BE=D1=80=D1=8B...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/validation/BankAccountValidationConfig.java | 4 +--- .../securities/validation/rule/HaveValidCodeByDictionary.java | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java index 3c6b00d6e..4b5693806 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java @@ -53,6 +53,7 @@ public class BankAccountValidationConfig { Company.class, AccountError.RequiredFieldEmpty, AccountError.CompanyNotFound, + false, company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : AccountError.CompanyNotActive), FieldRequiredRule.instance("account", BankAccountNewRequest::getAccount, @@ -83,9 +84,6 @@ public class BankAccountValidationConfig { AccountError.RequiredFieldEmpty), FieldRequiredRule.instance("bankName", BankAccountNewRequest::getBankName, - AccountError.RequiredFieldEmpty), - FieldRequiredRule.instance("destination", - BankAccountNewRequest::getDestination, AccountError.RequiredFieldEmpty) ); }; diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java index 995367116..62643e3de 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/validation/rule/HaveValidCodeByDictionary.java @@ -38,7 +38,7 @@ public class HaveValidCodeByDictionary implements IValidationRule imdgDictionary = context.obtainMap(mapName, SpcexObjectBase.class); SpcexObjectBase dictionary = imdgDictionary.getSingleObjectByFieldValues(Map.of( From ebe8bbb13f377de47a8dcba023235fb8aae12841 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 19:04:05 +0300 Subject: [PATCH 32/36] =?UTF-8?q?account-service=20=D0=92=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D0=B4=D0=B0=D1=82=D0=BE=D1=80r=D1=8B...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../account/config/validation/BankAccountValidationConfig.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java index 4b5693806..9f153e56d 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/BankAccountValidationConfig.java @@ -53,8 +53,7 @@ public class BankAccountValidationConfig { Company.class, AccountError.RequiredFieldEmpty, AccountError.CompanyNotFound, - false, - company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : AccountError.CompanyNotActive), + false), FieldRequiredRule.instance("account", BankAccountNewRequest::getAccount, AccountError.RequiredFieldEmpty, From f4b1f08eeca1d36f0685744aefdb02e73e43ea4e Mon Sep 17 00:00:00 2001 From: ialbert Date: Sat, 27 May 2023 19:26:35 +0300 Subject: [PATCH 33/36] execution uploading logging fix --- .../java/ru/spcex/clearing/service/ClearingService.java | 2 ++ .../service/{ => execution}/ExecutionDepositComponent.java | 7 +++++-- .../service/{ => execution}/ExecutionFondComponent.java | 2 +- .../clearing-service/src/main/resources/logback.xml | 5 +++++ .../ru/spcex/clearing/service/AbstractClearingTest.java | 1 + .../{ => execution}/ExecutionDepositComponentTest.java | 4 +++- 6 files changed, 17 insertions(+), 4 deletions(-) rename clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/{ => execution}/ExecutionDepositComponent.java (97%) rename clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/{ => execution}/ExecutionFondComponent.java (99%) rename clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/{ => execution}/ExecutionDepositComponentTest.java (96%) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ClearingService.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ClearingService.java index 50cf5d56f..2d20b69c9 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ClearingService.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ClearingService.java @@ -8,6 +8,8 @@ import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.stereotype.Service; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; +import ru.spcex.clearing.service.execution.ExecutionDepositComponent; +import ru.spcex.clearing.service.execution.ExecutionFondComponent; import ru.spcex.platform.utils.log.ExceptionUtils; import java.util.concurrent.ExecutorService; diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ExecutionDepositComponent.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/execution/ExecutionDepositComponent.java similarity index 97% rename from clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ExecutionDepositComponent.java rename to clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/execution/ExecutionDepositComponent.java index d7756f23a..e42996875 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ExecutionDepositComponent.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/execution/ExecutionDepositComponent.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.service; +package ru.spcex.clearing.service.execution; import org.apache.kafka.clients.producer.Producer; import org.slf4j.Logger; @@ -25,7 +25,10 @@ import ru.spcex.clearing.service.validation.ValidationStored; import ru.spcex.platform.enumeration.*; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; -import ru.spcex.platform.utils.enumeration.*; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumId; +import ru.spcex.platform.utils.enumeration.IEnumKey; +import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.log.ExceptionUtils; import ru.spcex.platform.utils.time.TimeUtil; import ru.spcex.platform.utils.validation.IValidator; diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ExecutionFondComponent.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/execution/ExecutionFondComponent.java similarity index 99% rename from clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ExecutionFondComponent.java rename to clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/execution/ExecutionFondComponent.java index c5170df92..4f533e9fc 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ExecutionFondComponent.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/execution/ExecutionFondComponent.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.service; +package ru.spcex.clearing.service.execution; import org.apache.kafka.clients.producer.Producer; import org.slf4j.Logger; diff --git a/clearing-parent/clearing-service/src/main/resources/logback.xml b/clearing-parent/clearing-service/src/main/resources/logback.xml index 39d4ebcaa..25bfcafba 100644 --- a/clearing-parent/clearing-service/src/main/resources/logback.xml +++ b/clearing-parent/clearing-service/src/main/resources/logback.xml @@ -39,4 +39,9 @@ + + + + + \ No newline at end of file diff --git a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/AbstractClearingTest.java b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/AbstractClearingTest.java index 3dc3ab16e..fd58ce008 100644 --- a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/AbstractClearingTest.java +++ b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/AbstractClearingTest.java @@ -13,6 +13,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import ru.spcex.clearing.config.*; import ru.spcex.clearing.service.builder.LiabilitiesClaimsAssetsCreator; import ru.spcex.clearing.service.builder.LiabilitiesClaimsMoneyCreator; +import ru.spcex.clearing.service.execution.ExecutionDepositComponent; import ru.spcex.clearing.service.order.ExecutionDepositSorter; import ru.spcex.clearing.service.order.PaymentInstructionSorter; import ru.spcex.clearing.utils.TestUtils; diff --git a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/ExecutionDepositComponentTest.java b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/execution/ExecutionDepositComponentTest.java similarity index 96% rename from clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/ExecutionDepositComponentTest.java rename to clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/execution/ExecutionDepositComponentTest.java index 3cc096ed0..55007f097 100644 --- a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/ExecutionDepositComponentTest.java +++ b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/execution/ExecutionDepositComponentTest.java @@ -1,4 +1,4 @@ -package ru.spcex.clearing.service; +package ru.spcex.clearing.service.execution; import org.apache.kafka.clients.consumer.MockConsumer; import org.junit.jupiter.api.Test; @@ -11,6 +11,8 @@ import ru.clearing.classes.statics.data.misc.STrades; import ru.clearing.classes.statics.data.security.Security; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest; +import ru.spcex.clearing.service.AbstractClearingTest; +import ru.spcex.clearing.service.EventsReceiver; import ru.spcex.platform.enumeration.Task; import ru.spcex.platform.imdg.api.Imdg; From a289ed3672907ef45a8233d77b217f40e6afc84b Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Sat, 27 May 2023 19:16:50 +0300 Subject: [PATCH 34/36] http://jira.mfd.msk:8088/browse/CLS-290 --- .../service/validation/RegistryStep3ValidationRule.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java index 495574f9e..7d1eb69d9 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/RegistryStep3ValidationRule.java @@ -45,7 +45,11 @@ public enum RegistryStep3ValidationRule implements IValidationRule relationImdg = context.obtainMap(IMDGDistributedNames.Map_Relation, Relation.class); - Relation relation = relationImdg.getSingleObjectByFieldValues(Map.of("consumerId", validatedObject.getCompanyId())); + Imdg sessionImdg = context.obtainMap(IMDGDistributedNames.Map_Session, Session.class); + Session activeSession = sessionImdg.getSingleObjectByID(validatedObject.getSessionId()); + Relation relation = relationImdg.getSingleObjectByFieldValues(Map.of( + "consumerId", validatedObject.getCompanyId(), + "service", activeSession.getSection())); if (relation == null || (!ServiceStatus.Active.equalsByKey(relation.getServiceStatus()) && !ServiceStatus.Reopened.equalsByKey(relation.getServiceStatus()))) { return of(ClearingError.ClearingUnavailableForCompany, sectionFind.get(), validatedObject.getCompanyId()); } @@ -90,7 +94,7 @@ public enum RegistryStep3ValidationRule implements IValidationRule tradingClearingRegistryImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); TradingClearingRegistry tcr = tradingClearingRegistryImdg.getSingleObjectBySQL("id = " + validatedObject.getTradingClearingRegistryId()); - if (tcr == null || (ServiceStatus.Active.equalsByKey(tcr.getStatus()) || ServiceStatus.Reopened.equalsByKey(tcr.getStatus()))) + if (tcr == null || !(ServiceStatus.Active.equalsByKey(tcr.getStatus()) || ServiceStatus.Reopened.equalsByKey(tcr.getStatus()))) return of(ClearingError.TradingClearingRegistryNotActive, validatedObject.getTradingClearingRegistryId()); return empty(); } From fbda04082a33f0e276525dc06ff343af22c64caf Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 19:55:59 +0300 Subject: [PATCH 35/36] =?UTF-8?q?securities-service=20http://jira.mfd.msk:?= =?UTF-8?q?8088/browse/CLS-325=20http://jira.mfd.msk:8088/browse/CLS-326?= =?UTF-8?q?=20=D0=9B=D0=B8=D1=81=D1=82=D0=B8=D0=BD=D0=B3.=20todo=20=D0=B2?= =?UTF-8?q?=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D1=8E.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/cud/EquitySecurityService.java | 38 ++-- .../cud/FixedIncomeSecurityService.java | 38 ++-- .../service/cud/ListingService.java | 199 ++++++++++++++++++ .../cud/MoneyMarketSecurityService.java | 38 ++-- 4 files changed, 255 insertions(+), 58 deletions(-) create mode 100644 clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/ListingService.java diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java index e5ead4784..70a7e49af 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/EquitySecurityService.java @@ -100,12 +100,12 @@ public class EquitySecurityService extends QueueConsumer implements Initializing try { transaction.beginTransaction(); Imdg equityImdg = transaction.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class); - Imdg

listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); +// Imdg listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); //одним скопом выполняем реквест equityImdg.insert(equity); - Listing listing = ListingBuilder.builder() - .append(equity).append(req).build(); - listingMap.insert(listing); +// Listing listing = ListingBuilder.builder() +// .append(equity).append(req).build(); +// listingMap.insert(listing); //и сохраняем обновленный // reqInfoMap.insert(reqInfo); transaction.commitTransaction(); @@ -144,13 +144,13 @@ public class EquitySecurityService extends QueueConsumer implements Initializing equity.setInstrumentType(req.getInstrumentType()); equitySecurityImdg.update(equity); - Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); - if (listing == null) { - log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); - return null; - } - listing = updateListingByEquity(equity, listing); - listingImdg.update(listing); +// Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); +// if (listing == null) { +// log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); +// return null; +// } +// listing = updateListingByEquity(equity, listing); +// listingImdg.update(listing); return null; } @@ -170,14 +170,14 @@ public class EquitySecurityService extends QueueConsumer implements Initializing equity.setUpdated(updateTime); equitySecurityImdg.update(equity); - Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); - if (listing == null) { - log.error("CommonDeleteRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); - return null; - } - listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); - listing.setUpdated(updateTime); - listingImdg.update(listing); +// Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); +// if (listing == null) { +// log.error("CommonDeleteRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); +// return null; +// } +// listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); +// listing.setUpdated(updateTime); +// listingImdg.update(listing); return null; } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java index 5b58b4d97..6cc5448fd 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/FixedIncomeSecurityService.java @@ -104,12 +104,12 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial try { transaction.beginTransaction(); Imdg fixedIncomeImdg = transaction.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class); - Imdg listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); +// Imdg listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); //одним скопом выполняем реквест fixedIncomeImdg.insert(fixedIncome); - Listing listing = ListingBuilder.builder() - .append(fixedIncome).append(req).build(); - listingMap.insert(listing); +// Listing listing = ListingBuilder.builder() +// .append(fixedIncome).append(req).build(); +// listingMap.insert(listing); //и сохраняем обновленный // reqInfoMap.insert(reqInfo); transaction.commitTransaction(); @@ -154,13 +154,13 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial fixedIncome.setSecurityId(fixedIncome.getId()); fixedIncomeSecurityImdg.update(fixedIncome); - Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", fixedIncome.getId())); - if (listing == null) { - log.error("updateFixedIncome id {} couldn't find listing with securityId {}", req.getId(), fixedIncome.getId()); - return null; - } - listing = updateListingByFixedIncome(fixedIncome, listing); - listingImdg.update(listing); +// Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", fixedIncome.getId())); +// if (listing == null) { +// log.error("updateFixedIncome id {} couldn't find listing with securityId {}", req.getId(), fixedIncome.getId()); +// return null; +// } +// listing = updateListingByFixedIncome(fixedIncome, listing); +// listingImdg.update(listing); return null; } @@ -180,14 +180,14 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial equity.setUpdated(updateTime); fixedIncomeSecurityImdg.update(equity); - Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); - if (listing == null) { - log.error("CommonDeleteRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); - return null; - } - listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); - listing.setUpdated(updateTime); - listingImdg.update(listing); +// Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", equity.getId())); +// if (listing == null) { +// log.error("CommonDeleteRequest id {} couldn't find listing with securityId {}", req.getId(), equity.getId()); +// return null; +// } +// listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); +// listing.setUpdated(updateTime); +// listingImdg.update(listing); return null; } diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/ListingService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/ListingService.java new file mode 100644 index 000000000..237da46f3 --- /dev/null +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/ListingService.java @@ -0,0 +1,199 @@ +package ru.spcex.clearing.securities.service.cud; + +import org.apache.commons.lang3.StringUtils; +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.MoneyMarketSecurity; +import ru.clearing.classes.statics.data.security.Security; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +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.ListingNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.securitites.ListingUpdateRequest; +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; + +@Service +public class ListingService extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final Imdg fixedIncomeSecurityImdg; + private final Imdg moneyMarketSecurityImdg; + private final Imdg equitySecurity; + + private final Imdg listingImdg; + private final ImdgProvider imdgProvider; + private final ImdgId idGenerator; + private final ValidationProvider validation; + private final UserRoleVerification userRoleVerification; + private final ValidationHelper validationHelper; + + @Autowired + public ListingService(Consumer kafkaQueue, + Producer 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.moneyMarketSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_MoneyMarketSecurity, MoneyMarketSecurity.class); + this.equitySecurity = 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(ListingNewRequest.class) + .setFunction(this::newListing) + .forDestination(Consts.LISTING_NEW, callbacks::put); + callback(ListingUpdateRequest.class) + .setFunction(this::updateListing) + .forDestination(Consts.LISTING_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(this::deleteListing) + .forDestination(Consts.LISTING_DELETE, callbacks::put); + imdgProvider.waitAvailable(); + init(); + } + + protected Security selectSecurityById(Long securityId) { + Security security = fixedIncomeSecurityImdg.getSingleObjectByID(securityId); + if (security != null) return security; + security = moneyMarketSecurityImdg.getSingleObjectByID(securityId); + if (security != null) return security; + security = equitySecurity.getSingleObjectByID(securityId); + if (security != null) return security; + + return security; + } + + private RequestInfoUpdate newListing(BaseRequest userRequest) { + ImdgTransaction transaction = imdgProvider.newTransaction(); + ListingNewRequest req = userRequest.getRequestPayload(); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; +// RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.listingNewValidator()); +// if (requestInfoUpdate != null) return requestInfoUpdate; + /* + todo +3. Проверяем значения полученных параметров: + 3.1. Необходимо выполнить ряд проверок, стандартных для всех методов (проверка на обязательность параметров исключена). + 3.2. Проверить, что в таблице security есть инструмент, для которого нужно добавить листинг по security.id = securityId из очереди. Если такой записи нет, вернуть ошибку (1011) «Инструмент %s не найден». + 3.3. Проверить, что в таблице security тип инструмента instrumentType ≠ RATE (см. справочник instrumentType). Если тип инструмента другой, вернуть ошибку (1021) «Информиция об инструментах Денежного рынка на режимах добавляется автоматически». + 3.4. Проверить, что в таблице market есть режим, с которым нужно добавить листинг по market.code = market из очереди. Если такой записи нет, вернуть ошибку (1020) «Режим %s не найден». + 3.5. Проверить, что еще нет такой же записи в таблице listing по ключу securityId И market И со статусом listing.workflowStatus=ACTV (см. справочник workflowStatus). Если запись существует, вернуть ошибку (1017) «Инструмент на режиме %s уже существует». + */ + + log.debug("newListing received"); + + Security security = selectSecurityById(req.getSecurityId()); + if (security == null) { + log.error("Security not found {}", req.getSecurityId()); + //return validationHelper.getMessageResolver() + //todo error! + } + + Listing listing = new Listing(); + listing.setId(idGenerator.nextId()); + listing.setCreated(Instant.now()); + listing.setUpdated(listing.getCreated()); + listing.setSecurityId(req.getSecurityId()); + listing.setMarket(req.getMarket()); + listing.setLotSize(req.getLotSize()); + listing.setSymbolCode(security.getSecuritySymbol()); // listing.setSymbolCode(req.getSymbolCode()); + listing.setSymbolName(security.getFullName()); // req.getSymbolName + listing.setTradingCurrency(req.getTradingCurrency()); + if (StringUtils.isEmpty(req.getWorkflowStatus())) { + listing.setWorkflowStatus(WorkflowStatus.Active.getKey()); + } else { + listing.setWorkflowStatus(req.getWorkflowStatus()); + } + + listingImdg.insert(listing); + log.debug("successfully processed, request id {}, new object id {}", userRequest.getId(), listing.getId()); + return null; // default success + } + + private RequestInfoUpdate updateListing(BaseRequest userRequest) { + ListingUpdateRequest req = userRequest.getRequestPayload(); + log.debug("updateListing received id = {}", req.getId()); + + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; +// RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); +// if (requestInfoUpdate != null) return requestInfoUpdate; + + Listing listing = listingImdg.getSingleObjectByID(req.getId()); + + Security security = selectSecurityById(req.getSecurityId()); + if (security == null) { + log.error("Security not found {}", req.getSecurityId()); + //return validationHelper.getMessageResolver() + //todo error! + } + if (listing == null) { + log.error("listing not found {}", req.getId()); + //return validationHelper.getMessageResolver() + //todo error! + } + + listing.setUpdated(Instant.now()); + listing.setLotSize(req.getLotSize()); + //if (req.getSymbolCode()!=null) listing.setSymbolCode(req.getSymbolCode()); + //if (req.getSymbolName!=null) listing.setSymbolName(req.getSymbolName); + listing.setTradingCurrency(req.getTradingCurrency()); + if (StringUtils.isNotEmpty(req.getWorkflowStatus())) { + listing.setWorkflowStatus(req.getWorkflowStatus()); + } + + listingImdg.update(listing); + return null; + } + + private RequestInfoUpdate deleteListing(BaseRequest userRequest) { + CommonDeleteRequest req = userRequest.getRequestPayload(); + log.debug("CommonDeleteRequest received id = {}", req.getId()); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; +// requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, validation.listingDeleteValidator()); +// if (requestInfoUpdate != null) return requestInfoUpdate; + + Instant updateTime = Instant.now(); + Listing listing = listingImdg.getSingleObjectByID(req.getId()); + listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); + listing.setUpdated(updateTime); + + listingImdg.update(listing); + return null; + } + +} diff --git a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java index d9f5bd9e2..f6273c1c4 100644 --- a/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java +++ b/clearing-parent/securities-service/src/main/java/ru/spcex/clearing/securities/service/cud/MoneyMarketSecurityService.java @@ -138,11 +138,9 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial Imdg listingMap = transaction.getImdg(IMDGDistributedNames.Map_Listing, Listing.class); //одним скопом выполняем реквест moneyMarketSecurityMap.insert(mms); - Listing listing = ListingBuilder.builder() - .append(mms).append(req).build(); - listingMap.insert(listing); - //и сохраняем обновленный -// reqInfoMap.insert(reqInfo); +// Listing listing = ListingBuilder.builder() +// .append(mms).append(req).build(); +// listingMap.insert(listing); transaction.commitTransaction(); } catch (Throwable e) { transaction.rollbackTransaction(); @@ -193,13 +191,13 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial mms.setWorkflowStatus(req.getWorkflowStatus()); moneyMarketSecurityMap.update(mms); - Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", mms.getId())); - if (listing == null) { - log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), mms.getId()); - return null; - } - listing = updateListingByMms(mms, listing); - listingImdg.update(listing); +// Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", mms.getId())); +// if (listing == null) { +// log.error("MoneyMarketSecurityUpdateRequest id {} couldn't find listing with securityId {}", req.getId(), mms.getId()); +// return null; +// } +// listing = updateListingByMms(mms, listing); +// listingImdg.update(listing); return null; } @@ -227,14 +225,14 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial mms.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); mms.setUpdated(updateTime); moneyMarketSecurityMap.update(mms); - Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", mms.getId())); - if (listing == null) { - log.error("CommonDeleteRequest id {} couldn't find listing with securityId {}", req.getId(), mms.getId()); - return null; - } - listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); - listing.setUpdated(updateTime); - listingImdg.update(listing); +// Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", mms.getId())); +// if (listing == null) { +// log.error("CommonDeleteRequest id {} couldn't find listing with securityId {}", req.getId(), mms.getId()); +// return null; +// } +// listing.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Blocked.getKey()); +// listing.setUpdated(updateTime); +// listingImdg.update(listing); return null; } From 6f4daca734f7d88e75b72f3cc1621d1b1a8009ee Mon Sep 17 00:00:00 2001 From: AKurakin Date: Sat, 27 May 2023 20:08:09 +0300 Subject: [PATCH 36/36] meta 3.5.0.28 data --- .../src/main/resources/meta/data.xml | 38 ++- .../src/main/resources/meta/meta.json | 274 +++++++++--------- .../src/main/resources/meta/meta.xml | 66 ++--- .../db-scripts/src/main/resources/db/DATA.sql | 54 +++- 4 files changed, 237 insertions(+), 195 deletions(-) diff --git a/clearing-parent/backend-api/src/main/resources/meta/data.xml b/clearing-parent/backend-api/src/main/resources/meta/data.xml index 6390799cf..f072ec37c 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/data.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/data.xml @@ -1,5 +1,5 @@ - + @@ -152,17 +152,30 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + @@ -538,6 +551,7 @@ + diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.json b/clearing-parent/backend-api/src/main/resources/meta/meta.json index d48786815..5cef8c7a1 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.json +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.json @@ -1,6 +1,6 @@ { - "version": "3.5.0.27", + "version": "3.5.0.28", "enums": { @@ -1640,11 +1640,11 @@ } , {"code": "companySymbol", - "field": "id","type": 12,"name": "Тип реквизита","shortname": "Тип реквизита","searchable": true,"sortable": true,"visible": true,"linkKeyCode": "companyId","linkCode": "companySymbol","link": "companySymbols","extends": "companySymbols","ignore": true + "field": "id","type": 12,"name": "Тип реквизита","shortname": "Тип реквизита","searchable": true,"sortable": true,"visible": true,"linkKeyCode": "companyId","linkCode": "companySymbol","link": "companySymbols","extends": "companySymbols" } , {"code": "companySymbolValue", - "field": "id","type": 2,"length": 255,"name": "Значение реквизита","shortname": "Значение реквизита","searchable": true,"sortable": true,"visible": true,"linkKeyCode": "companyId","linkCode": "companySymbolValue","link": "companySymbols","extends": "companySymbols","ignore": true + "field": "id","type": 2,"length": 255,"name": "Значение реквизита","shortname": "Значение реквизита","searchable": true,"sortable": true,"visible": true,"linkKeyCode": "companyId","linkCode": "companySymbolValue","link": "companySymbols","extends": "companySymbols" } , {"code": "workflowStatus", @@ -4741,7 +4741,7 @@ , "planner": { - "name": "Расписание", + "name": "Расписание на все даты", "destination": "schedule/planners", @@ -4996,6 +4996,50 @@ } ] ,"actions":[ + {"method":"post", + + "destination": "GVER", + + "group": "Общее", + + "name": "Запуск сверки", + + "fields": [] + } + , + {"method":"post", + + "destination": "GRYT", + + "group": "Общее", + + "name": "Подготовка КС к клиринговому дню", + + "fields": [] + } + , + {"method":"post", + + "destination": "LOCM", + + "group": "Обмен с интеграционными модулями", + + "name": "Загрузка участников", + + "fields": [] + } + , + {"method":"post", + + "destination": "LOSC", + + "group": "Обмен с интеграционными модулями", + + "name": "Загрузка инструментов", + + "fields": [] + } + , {"method":"post", "destination": "GALB", @@ -5020,35 +5064,6 @@ , {"method":"post", - "destination": "SCLR", - - "group": "Клиринг", - - "name": "Запуск клиринговой сессии", - - "confirmation": "section,sessionType", - - "fields": [ - {"code": "section", - "type": 12,"name": "Секция","shortname": "Секция","link": "section","linkCode": "name","linkKeyCode": "code" - } - , - {"code": "sessionType", - "type": 12,"name": "Тип клиринговой сессии","shortname": "Тип клиринговой сессии","link": "sessionType","linkCode": "name","linkKeyCode": "code" - } - , - {"code": "companyId", - "type": 1,"name": "Наименование инициатора","shortname": "Инициатор","link": "company","linkCode": "shortName","visible": false - } - , - {"code": "securityId", - "type": 1,"name": "Наименование инструмента","shortname": "Инструмент","link": "security","linkCode": "shortName","visible": false - } - ] - } - , - {"method":"post", - "destination": "GTRD", "group": "Обмен с Торговой системой", @@ -5082,108 +5097,38 @@ , {"method":"post", - "destination": "GRRT", + "destination": "SCLR", - "group": "Формирование реестров и отчетности", + "group": "Клиринг", - "name": "Формирование реестра остатков ценных бумаг", + "name": "Запуск клиринговой сессии", - "fields": [] - } - , - {"method":"post", + "confirmation": "section,sessionType", - "destination": "GBRR", - - "group": "Формирование реестров и отчетности", - - "name": "Формирование реестра остатков денежных средств", - - "fields": [] - } - , - {"method":"post", - - "destination": "ADLR", - - "group": "Формирование реестров и отчетности", - - "name": "Формирование реестра обязательств, допущенных к клирингу", - - "fields": [] - } - , - {"method":"post", - - "destination": "CDLR", - - "group": "Формирование реестров и отчетности", - - "name": "Формирование реестра обязательств, прошедших процедуру контроля обеспечения", - - "fields": [] - } - , - {"method":"post", - - "destination": "GORR", - - "group": "Формирование реестров и отчетности", - - "name": "Формирование реестра распоряжений, направленных расчетной организации", - - "fields": [] - } - , - {"method":"post", - - "destination": "GORD", - - "group": "Формирование реестров и отчетности", - - "name": "Формирование реестра распоряжений, направленных расчетному депозитарию", - - "fields": [] - } - , - {"method":"post", - - "destination": "EXLR", - - "group": "Формирование реестров и отчетности", - - "name": "Формирование реестра обязательств, исключенных из клирингового пула", - - "fields": [] - } - , - {"method":"post", - - "destination": "LBSR", - - "group": "Формирование реестров и отчетности", - - "name": "Формирование реестра учета обязательств", - - "fields": [] - } - , - {"method":"post", - - "destination": "ECNR", - - "group": "Формирование реестров и отчетности", - - "name": "Формирование реестра сделок", - - "fields": [] + "fields": [ + {"code": "section", + "type": 12,"name": "Секция","shortname": "Секция","link": "section","linkCode": "name","linkKeyCode": "code" + } + , + {"code": "sessionType", + "type": 12,"name": "Тип клиринговой сессии","shortname": "Тип клиринговой сессии","link": "sessionType","linkCode": "name","linkKeyCode": "code" + } + , + {"code": "companyId", + "type": 1,"name": "Наименование инициатора","shortname": "Инициатор","link": "company","linkCode": "shortName","visible": false + } + , + {"code": "securityId", + "type": 1,"name": "Наименование инструмента","shortname": "Инструмент","link": "security","linkCode": "shortName","visible": false + } + ] } , {"method":"post", "destination": "GREP", - "group": "Формирование реестров и отчетности", + "group": "Формирование отчетности", "name": "Формирование отчетности", @@ -5196,44 +5141,99 @@ , {"method":"post", - "destination": "LOCM", + "destination": "GRRT", - "group": "Обмен с интеграционными модулями", + "group": "Формирование реестров", - "name": "Загрузка участников", + "name": "Формирование реестра остатков ценных бумаг", "fields": [] } , {"method":"post", - "destination": "LOSC", + "destination": "GBRR", - "group": "Обмен с интеграционными модулями", + "group": "Формирование реестров", - "name": "Загрузка инструментов", + "name": "Формирование реестра остатков денежных средств", "fields": [] } , {"method":"post", - "destination": "GVER", + "destination": "ADLR", - "group": "Общее", + "group": "Формирование реестров", - "name": "Запуск сверки", + "name": "Формирование реестра обязательств, допущенных к клирингу", "fields": [] } , {"method":"post", - "destination": "GRYT", + "destination": "CDLR", - "group": "Общее", + "group": "Формирование реестров", - "name": "Подготовка КС к клиринговому дню", + "name": "Формирование реестра обязательств, прошедших процедуру контроля обеспечения", + + "fields": [] + } + , + {"method":"post", + + "destination": "GORR", + + "group": "Формирование реестров", + + "name": "Формирование реестра распоряжений, направленных расчетной организации", + + "fields": [] + } + , + {"method":"post", + + "destination": "GORD", + + "group": "Формирование реестров", + + "name": "Формирование реестра распоряжений, направленных расчетному депозитарию", + + "fields": [] + } + , + {"method":"post", + + "destination": "EXLR", + + "group": "Формирование реестров", + + "name": "Формирование реестра обязательств, исключенных из клирингового пула", + + "fields": [] + } + , + {"method":"post", + + "destination": "LBSR", + + "group": "Формирование реестров", + + "name": "Формирование реестра учета обязательств", + + "fields": [] + } + , + {"method":"post", + + "destination": "ECNR", + + "group": "Формирование реестров", + + "name": "Формирование реестра сделок", "fields": [] } diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.xml b/clearing-parent/backend-api/src/main/resources/meta/meta.xml index b08418cf1..72b097b1f 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.xml @@ -1,6 +1,6 @@ - + @@ -367,8 +367,8 @@ - - + + @@ -1104,7 +1104,7 @@ - + @@ -1165,50 +1165,50 @@ + + + + + + + + - -
- - - - - + +
+ + + - - - - - - - - - - - - - - - - - + - - - + - + - + + + + + + + + + + + + + diff --git a/clearing-parent/db-scripts/src/main/resources/db/DATA.sql b/clearing-parent/db-scripts/src/main/resources/db/DATA.sql index ea34850e6..67b22776b 100644 --- a/clearing-parent/db-scripts/src/main/resources/db/DATA.sql +++ b/clearing-parent/db-scripts/src/main/resources/db/DATA.sql @@ -1,5 +1,5 @@ --- DB version: 3.5.0.26 --- DATA version: 3.5.0.6 +-- DB version: 3.5.0.28 +-- DATA version: 3.5.0.7 /* Dictionaries */ INSERT INTO ALLOWED_DICTIONARY(ID, CODE, NAME) values (1, 'ALWD', 'Разрешено') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; @@ -302,27 +302,53 @@ INSERT INTO REGISTRY_UNIT_DICTIONARY(ID, CODE, NAME) values (3, 'B', 'Забло INSERT INTO REGISTRY_UNIT_DICTIONARY(ID, CODE, NAME) values (4, 'C', 'Комиссия') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (1, 'AMPT', 'Денежные средства - на торги') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (1, 'AMAT', 'Денежные средства - на торги') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (2, 'AMPF', 'Денежные средства - свободные') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (2, 'AMAF', 'Денежные средства - свободные') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (3, 'AMPB', 'Денежные средства - блокированные') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (3, 'AMAB', 'Денежные средства - блокированные') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (4, 'TMPT', 'Требования по деньгам - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (4, 'TMAT', 'Требования по деньгам - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (5, 'OSPT', 'Обязательства по инструментам - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (5, 'OSAT', 'Обязательства по инструментам - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (6, 'OMPT', 'Обязательства по деньгам - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (6, 'OMAT', 'Обязательства по деньгам - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (7, 'TSPT', 'Требования по инструментам - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (7, 'TSAT', 'Требования по инструментам - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (8, 'CMPT', 'Требования по деньгам - свои') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (8, 'CMAT', 'Требования по деньгам - свои') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (9, 'LSPT', 'Обязательства по инструментам - свои') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (9, 'LSAT', 'Обязательства по инструментам - свои') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (10, 'LMPT', 'Обязательства по деньгам - свои') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (10, 'LMAT', 'Обязательства по деньгам - свои') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (11, 'CSPT', 'Требования по инструментам - свои') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (11, 'CSAT', 'Требования по инструментам - свои') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (12, 'AMBT', 'Денежные средства клиента - на торги') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (13, 'AMBF', 'Денежные средства клиента - свободные') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (14, 'AMBB', 'Денежные средства клиента - блокированные') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (15, 'TMBT', 'Требования по деньгам клиента - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (16, 'OSBT', 'Обязательства по инструментам клиента - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (17, 'OMBT', 'Обязательства по деньгам клиента - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (18, 'TSBT', 'Требования по инструментам клиента - клиринговый пул') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (19, 'CMBT', 'Требования по деньгам - клиента') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (20, 'LSBT', 'Обязательства по инструментам - клиента') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (21, 'LMBT', 'Обязательства по деньгам - клиента') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (22, 'CSBT', 'Требования по инструментам - клиента') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (23, 'DMAT', 'Возврат депозита по деньгам - свои') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; + +INSERT INTO REGISTRY_CODE_DICTIONARY(ID, CODE, NAME) values (24, 'DMBT', 'Возврат депозита по деньгам - клиента') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; INSERT INTO REGISTRY_STATUS_DICTIONARY(ID, CODE, NAME) values (1, 'OK', 'Успешно') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; @@ -1011,3 +1037,5 @@ INSERT INTO MARKET(ID, MARKET_TYPE, SECTION, SETTLEMENT_CURRENCY, CODE, NAME, EX INSERT INTO MARKET(ID, MARKET_TYPE, SECTION, SETTLEMENT_CURRENCY, CODE, NAME, EXCHANGE_ID, DESCRIPTION) values (79, 'SCND', 'FOND', 'RUB', 'DMIC', 'ОФЗИН-Дискретный аукцион', 1, 'ОФЗИН-Дискретный аукцион: Облигации Минфина') ON CONFLICT (ID) DO UPDATE SET MARKET_TYPE = EXCLUDED.MARKET_TYPE, SECTION = EXCLUDED.SECTION, SETTLEMENT_CURRENCY = EXCLUDED.SETTLEMENT_CURRENCY, CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME, EXCHANGE_ID = EXCLUDED.EXCHANGE_ID, DESCRIPTION = EXCLUDED.DESCRIPTION; INSERT INTO MARKET(ID, MARKET_TYPE, SECTION, SETTLEMENT_CURRENCY, CODE, NAME, EXCHANGE_ID, DESCRIPTION) values (80, 'SCND', 'FOND', 'RUB', 'MMIC', 'ОФЗИН-Торги в режиме выкупа', 1, 'ОФЗИН-Торги в режиме выкупа: Облигации Минфина') ON CONFLICT (ID) DO UPDATE SET MARKET_TYPE = EXCLUDED.MARKET_TYPE, SECTION = EXCLUDED.SECTION, SETTLEMENT_CURRENCY = EXCLUDED.SETTLEMENT_CURRENCY, CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME, EXCHANGE_ID = EXCLUDED.EXCHANGE_ID, DESCRIPTION = EXCLUDED.DESCRIPTION; + +INSERT INTO MARKET(ID, MARKET_TYPE, SECTION, SETTLEMENT_CURRENCY, CODE, NAME, EXCHANGE_ID, DESCRIPTION) values (81, 'PRMR', 'MKR', 'RUB', 'MKRS', 'Размещение', 1, 'Размещение: МКР') ON CONFLICT (ID) DO UPDATE SET MARKET_TYPE = EXCLUDED.MARKET_TYPE, SECTION = EXCLUDED.SECTION, SETTLEMENT_CURRENCY = EXCLUDED.SETTLEMENT_CURRENCY, CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME, EXCHANGE_ID = EXCLUDED.EXCHANGE_ID, DESCRIPTION = EXCLUDED.DESCRIPTION;