From ae1c39f8b44624be17e20d36cdb957e1df98d80f Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 27 Apr 2023 18:55:14 +0300 Subject: [PATCH 01/30] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-272?= =?UTF-8?q?=20=20ClientCodeService,=20=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BB=20BiDirectionQueueExchanger.=20=D0=9D=D0=B5=D0=BE=D0=B1?= =?UTF-8?q?=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D0=BE=20=D1=8D=D1=82=D0=BE=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BA=D1=80=D1=8B=D1=82=D1=8C=20=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=BC=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exchangers/BiDirectionQueueExchanger.java | 180 +++++++- .../ClientCodeValidationConfig.java | 184 ++++++++ .../config/validation/ValidationConfig.java | 7 + .../clearing/company/error/CompanyErrors.java | 4 +- .../company/service/ClientCodeService.java | 416 ++++++++++++++++++ .../platform/messaging/domain/Consts.java | 2 + .../TradingClearingRegistryNewRequest.java | 10 + 7 files changed, 784 insertions(+), 19 deletions(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java index f8aef7bf6..1439927b8 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java @@ -1,25 +1,56 @@ package ru.spcex.clearing.util.services.exchangers; +import org.apache.commons.lang3.StringUtils; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; +import ru.spcex.clearing.platform.messaging.domain.ActionType; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountBalanceClearingRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.clearing.Sdf04Request; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.platform.messaging.service.Status; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.platform.enumeration.Task; +import ru.spcex.platform.utils.log.ExceptionUtils; + +import java.io.Closeable; +import java.util.Objects; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; /** * Синхронный обмен сообщениями с ассинхронным сервисом. - * Метод exchange() отправляет сообщение в очередь и дожидается ответа из другой очереди + * Метод exchange() отправляет сообщение в очередь и дожидается ответа из другой очереди. + * Использовать с осторожностью, т.к. нет возобновления ожидания в случае нештатного выключения модуля при ожидании ответа из kafka. + *

+ *

+ * Ожидает из очереди (CommonIdRequest) + * + * @param отправляется в очередь */ -public class BiDirectionQueueExchanger> extends QueueConsumer implements InitializingBean, DisposableBean { +public class BiDirectionQueueExchanger> extends QueueConsumer implements Closeable { protected final Logger log = LoggerFactory.getLogger(getClass()); - protected final Object sync = new Object(); protected String outQueue; protected String inQueue; - protected Class listenClass; protected long timeout; + private Producer producer; + + protected volatile boolean isTerminated; + protected Object syncObject; + protected Long lastSentRequestId; + protected volatile Long lastResponseId; + protected boolean ignoreOtherResponse = true; // Пропускать другие ID, пока не получит lastResponseId==lastSentRequestId /** * Синхронно-ассинхронный обмен сообщениями @@ -27,40 +58,153 @@ public class BiDirectionQueueExchanger> extends * @param kafkaQueue * @param kafkaProducer * @param outQueue отправляет в очередь - * @param inQueue слушает очередь, ожидает ответов - * @param listenClass типы объектов из inQueue - * @param timeout - максимальное ожидание ответа, в миллисекундах, 0 - неограничено + * @param inQueue слушает очередь/топик, ожидает ответов. Пример: Consts.CONTINUE_CLEARING + * @param timeout - максимальное ожидание ответа, в миллисекундах, 0 - неограничено */ public BiDirectionQueueExchanger(Consumer kafkaQueue, Producer kafkaProducer, String outQueue, - String inQueue, Class listenClass, + String inQueue, long timeout) { - super(kafkaQueue, kafkaProducer); + super(kafkaQueue); + this.producer = kafkaProducer; + if (kafkaQueue == null) { + throw new IllegalArgumentException("kafkaQueue is empty"); + } + if (kafkaProducer == null) { + throw new IllegalArgumentException("kafkaProducer is empty"); + } + if (StringUtils.isEmpty(outQueue)) { + throw new IllegalArgumentException("outQueue is empty"); + } this.outQueue = outQueue; + if (StringUtils.isEmpty(inQueue)) { + throw new IllegalArgumentException("inQueue is empty"); + } this.inQueue = inQueue; - this.listenClass = listenClass; + if (timeout < 0) { + timeout = 0; + } this.timeout = timeout; + + init(); } /** * Отправить сообщение message в outQueue и дождаться ответа из очереди inQueue * * @param message - * @return - * @throws InterruptedException + * @return request/reply id + * @throws InterruptedException или когда поток прерывают, или когда BiDirectionQueueExchanger.close() */ - public TOut exchange(TIn message) throws InterruptedException { - //todo impl BiDirectionQueueExchanger - return null; + public Long exchange(TOut message) throws InterruptedException { + if (syncObject == null) + throw new IllegalStateException("Listener queue not initialized"); + if (message.getId() == null) { + throw new IllegalArgumentException("Required message " + message.getClass().getSimpleName() + ".id is null"); + } + + //send request to kafka, wait for a reply + try { + synchronized (syncObject) { + Long sentRequestId = sendMessage(message); + log.trace("sent request to kafka, requestId: {}", sentRequestId); + this.lastSentRequestId = sentRequestId; + + long waitStart = System.currentTimeMillis(); + long waitTime = timeout; + do { + try { + if (timeout > 0) { + syncObject.wait(waitTime); + } else { + syncObject.wait(); + } + //если на этом месте произошла ошибка - непонятно как обрабатывать + //т.к. request на самом деле могла быть проблема с сетью/недоступностью кафки etc. + } catch (InterruptedException e) { + log.error(ExceptionUtils.getStackTrace(e)); + throw e; +// Thread.currentThread().interrupt(); +// throw new RuntimeException(e); + } + waitTime = timeout - (System.currentTimeMillis() - waitStart); + if (isTerminated && lastResponseId == null) { + log.warn("Terminated waiter {} kafka at thread {}", this, Thread.currentThread().getName()); + throw new InterruptedException(getClass().getSimpleName() + " closed"); + } + } while (ignoreOtherResponse && !sentRequestId.equals(lastResponseId) && (timeout > 0 && waitTime > 0)); + if (!sentRequestId.equals(lastResponseId)) { + log.error("FATAL: last response from {} update from Kafka ID was {}, but sent ID was {}", + inQueue, lastResponseId, sentRequestId); + throw new IllegalStateException("Expected wait till requestId=" + sentRequestId + " but catch lastResponseId=" + lastResponseId); + } + return sentRequestId; + + } + } finally { + this.lastSentRequestId = null; + } } @Override - public void destroy() throws Exception { + public void close() { + isTerminated = true; + if (lastSentRequestId != null) { + log.warn("Finished before wait, lastSentRequestId={}", lastSentRequestId); + if (syncObject != null) { + synchronized (syncObject) { + lastResponseId = null; + syncObject.notifyAll(); + } + } + } + syncObject = null; log.debug("Listener {} for async exchange {}-{} close", this, outQueue, inQueue); } - @Override - public void afterPropertiesSet() throws Exception { + public void init() { + if (syncObject != null) { + throw new IllegalStateException("Already initialized"); + } + callback(CommonIdRequest.class) + .setConsumer(this::continueWaiting) + .forDestination(inQueue, callbacks::put); + init(); + + syncObject = new Object(); + isTerminated = false; + log.debug("Listener {} for async exchange {}-{} ready", this, outQueue, inQueue); } + + protected Long sendMessage(TOut message) throws InterruptedException { + Long sentRequestId = message.getId(); + if (sentRequestId == null) { + throw new IllegalArgumentException("Message " + message.getClass().getSimpleName() + " required id."); + } + try { + Future send = producer.send(new ProducerRecord<>(Consts.REQUEST_INFO_UPDATE, message)); + send.get(); + return sentRequestId; + } catch (InterruptedException e) { + log.error("Interrupt when send message, {}", ExceptionUtils.getStackTrace(e)); + Thread.currentThread().interrupt(); + throw e; + } catch (ExecutionException e) { + log.error("Error at send message, {} cause: {}", e.toString(), ExceptionUtils.getStackTrace(e.getCause())); + throw new RuntimeException("Send message error", e.getCause()); + } catch (Exception e) { + log.error("Unexpected exception when send message: {}", ExceptionUtils.getStackTrace(e)); + } + return null; + } + + protected void continueWaiting(BaseRequest event) { + synchronized (syncObject) { + CommonIdRequest requestPayload = event.getRequestPayload(); + log.debug("continueWaiting {} for id={}", inQueue, requestPayload.getId()); + lastResponseId = requestPayload.getId(); + syncObject.notifyAll(); + } + } } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java new file mode 100644 index 000000000..296b3b103 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java @@ -0,0 +1,184 @@ +package ru.spcex.clearing.company.config.validation; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.account.ClientCode; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +import ru.clearing.platform.dictionary.WorkflowStatusDictionary; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolUpdateRequest; +import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; +import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; +import ru.spcex.clearing.validation.common.rules.IdPresentRule; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.validation.IValidator; +import ru.spcex.platform.utils.validation.ValidatorImpl; + +import java.util.Map; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Function; + +@Configuration +public class ClientCodeValidationConfig { + + @Bean("clientCodeNewRequestValidator") + public Function clientCodeNewRequestValidator(Map> imdgForValidation) { + return clientCodeUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(clientCodeUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_Account); + addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + return new ValidatorImpl<>(context, + FieldRequiredRule.instance("companyId", CompanySymbolUpdateRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), + IdPresentRule.instance("companyId", + ClientCodeNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound), + + IdPresentRule.instance("moneyAccountId", + ClientCodeNewRequest::getMoneyAccountId, + IMDGDistributedNames.Map_Account, + Account.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.AccountNotFound, + false, + acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId()) + ? null : CompanyErrors.AccountNotFound + ), + IdPresentRule.instance("depoAccountId", + ClientCodeNewRequest::getDepoAccountId, + IMDGDistributedNames.Map_Account, + Account.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.AccountNotFound, + false, + acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId()) + ? null : CompanyErrors.AccountNotFound + ), + IdPresentRule.instance("tradingClearingRegistryId", + ClientCodeNewRequest::getTradingClearingRegistryId, + IMDGDistributedNames.Map_TradingClearingRegistry, + Account.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.TradingClearingRegistryNotFound, + false, + acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId()) + ? null : CompanyErrors.TradingClearingRegistryNotFound + ), + + + DictionaryPresentRule.instance("stauts", + ClientCodeNewRequest::getStatus, + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.DictionaryNotFound, + false) + ); + }; + } + + @Bean("clientCodeUpdateRequestValidator") + public Function clientCodeUpdateRequestValidator(Map> imdgForValidation) { + return clientCodeUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(clientCodeUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_ClientCode); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_Account); + addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + return new ValidatorImpl>(context, + IdPresentRule.instance("id", + ClientCodeUpdateRequest::getId, + IMDGDistributedNames.Map_ClientCode, + ClientCode.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.RecordNotFound + ), + + FieldRequiredRule.instance("companyId", CompanySymbolUpdateRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), + IdPresentRule.instance("companyId", + ClientCodeUpdateRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound), + + IdPresentRule.instance("moneyAccountId", + ClientCodeUpdateRequest::getMoneyAccountId, + IMDGDistributedNames.Map_Account, + Account.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.AccountNotFound, + false, + acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId()) + ? null : CompanyErrors.AccountNotFound + ), + IdPresentRule.instance("depoAccountId", + ClientCodeUpdateRequest::getDepoAccountId, + IMDGDistributedNames.Map_Account, + Account.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.AccountNotFound, + false, + acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId()) + ? null : CompanyErrors.AccountNotFound + ), + IdPresentRule.instance("tradingClearingRegistryId", + ClientCodeUpdateRequest::getTradingClearingRegistryId, + IMDGDistributedNames.Map_TradingClearingRegistry, + Account.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.TradingClearingRegistryNotFound, + false, + acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId()) + ? null : CompanyErrors.TradingClearingRegistryNotFound + ), + + DictionaryPresentRule.instance("stauts", + ClientCodeUpdateRequest::getStatus, + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.DictionaryNotFound, + false) + ); + }; + } + + @Bean("clientCodeDeleteRequestValidator") + public Function clientCodeDeleteRequestValidator(Map> imdgForValidation) { + return companyDeleteRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(companyDeleteRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + return new ValidatorImpl<>(context, +// FieldRequiredRule.instance("id", CommonDeleteRequest::getId, CompanyErrors.RequiredFieldEmpty), + IdPresentRule.instance("id", + CommonDeleteRequest::getId, + IMDGDistributedNames.Map_ClientCode, + ClientCode.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.RecordNotFound) + ); + }; + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java index 597365270..cd6671cf1 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java @@ -2,11 +2,14 @@ package ru.spcex.clearing.company.config.validation; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.account.ClientCode; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.clearing.classes.statics.data.company.ClearingMemberCategory; import ru.clearing.classes.statics.data.profile.Contact; import ru.clearing.classes.statics.data.profile.ProfileDocument; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.platform.dictionary.*; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.validation.common.ValidationHelper; @@ -44,6 +47,10 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_LegalKindDictionary, LegalKindDictionary.class); addImdg.accept(IMDGDistributedNames.Map_OrganizationTypeDictionary, OrganizationTypeDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_ClientCode, ClientCode.class); + addImdg.accept(IMDGDistributedNames.Map_Account, Account.class); + addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + return imdg; } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java index d36d2104f..3979ab8b9 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java @@ -22,7 +22,9 @@ public enum CompanyErrors implements IErrorEnumId { CompanyAlreadyHasLiabilities(3018L), // У компании %s присутствуют обязательства. CompanyWithCompanySymbolAlreadyExist(3019L), // Компания с %s = %s уже создана" (где первый %s - companySymbol, второй %s - companySymbolValue) EditCompanySymbols(3020L), // Тип реквизита компании %s не может быть изменен. - EditContactType(3021L) // Тип контакта компании %s не может быть изменен. + EditContactType(3021L), // Тип контакта компании %s не может быть изменен. + TradingClearingRegistryNotFound(3022L), // ТКР с %s не найден + AccountNotFound(3023L), // Счет %s не найден ; private final Long id; diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java new file mode 100644 index 000000000..105ef2589 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java @@ -0,0 +1,416 @@ +package ru.spcex.clearing.company.service; + +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.account.ClientCode; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.ActionType; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.clearing.util.security.UserRoleVerification; +import ru.spcex.clearing.util.services.exchangers.BiDirectionQueueExchanger; +import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.TradingClearingRegistryType; +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.iml.hazelcast.adapter.ImdgIdGeneratorHazelcast; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.error.ClearingBaseException; +import ru.spcex.platform.utils.log.ExceptionUtils; +import ru.spcex.platform.utils.validation.IValidator; + +import java.time.Instant; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.function.Function; + +@Service +public class ClientCodeService extends QueueConsumer implements InitializingBean, DisposableBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Producer kafkaProducer; + private final ImdgId idGenerator; + private final Imdg clientCodeMap; + private final Imdg companyMap; + private final Imdg tradingClearingRegistryMap; + + + private final Function clientCodeNewRequestValidator; + private final Function clientCodeUpdateRequestValidator; + private final Function clientCodeDeleteRequestValidator; + private final ValidationHelper validationHelper; + private final UserRoleVerification userRoleVerification; + private final IMessageResolver messageResolver; + + BiDirectionQueueExchanger> accountServiceExchanger; + + @Autowired + public ClientCodeService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationHelper validationHelper, + IMessageResolver messageResolver, + UserRoleVerification userRoleVerification, + @Qualifier("clientCodeNewRequestValidator") Function clientCodeNewRequestValidator, + @Qualifier("clientCodeUpdateRequestValidator") Function clientCodeUpdateRequestValidator, + @Qualifier("clientCodeDeleteRequestValidator") Function clientCodeDeleteRequestValidator) { + super(kafkaQueue, kafkaProducer); + this.kafkaProducer = kafkaProducer; + this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.clientCodeMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.class); + this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.tradingClearingRegistryMap = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + this.clientCodeNewRequestValidator = clientCodeNewRequestValidator; + this.clientCodeUpdateRequestValidator = clientCodeUpdateRequestValidator; + this.clientCodeDeleteRequestValidator = clientCodeDeleteRequestValidator; + this.validationHelper = validationHelper; + this.messageResolver = messageResolver; + this.userRoleVerification = userRoleVerification; + + this.accountServiceExchanger = new BiDirectionQueueExchanger<>(kafkaQueue, kafkaProducer, + Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, + Consts.DESTINATION_TRADING_CLEARING_REGISTRY_REPLY, // todo naming + 60000 + ); + } + + @Override + public void afterPropertiesSet() { + callback(ClientCodeNewRequest.class) + .setConsumer(this::clientCodeNew) + .forDestination(Consts.DESTINATION_CLIENT_CODE_NEW, callbacks::put); + callback(ClientCodeNewRequest.class) + .setConsumer(this::clientCodeNewFromApiUmCompany) + .forDestination(Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, callbacks::put); + + callback(ClientCodeUpdateRequest.class) + .setConsumer(this::clientCodeUpdate) + .forDestination(Consts.DESTINATION_CLIENT_CODE_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setConsumer(this::clientCodeDelete) + .forDestination(Consts.DESTINATION_CLIENT_CODE_DELETE, callbacks::put); + init(); + + } + + @Override + public void destroy() { + accountServiceExchanger.close(); + } + + protected RequestInfoUpdate clientCodeNew(BaseRequest userRequest) { + log.debug("ClientCodeNewRequest received {}", userRequest.getId()); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clientCodeNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + ClientCodeNewRequest req = userRequest.getRequestPayload(); + + boolean doCreateTCR = checkNeedCreateTCR(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + if (doCreateTCR) { + try { + createAndWaitTCR(userRequest.getId(), null, + req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + } catch (ClearingBaseException e) { + log.error("Can not wait creation of TCR. request id={};CompanyId={}, MoneyAccountId={}, DepoAccountId={}; {}", + userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(), + e.toString()); + return makeErrorResponse(userRequest, CompanyErrors.GeneralError, "Can not create TCR at this moment"); + } + } + + if (req.getTradingClearingRegistryId() == null && req.getMoneyAccountId() != null) { + TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + if (tradingClearingRegistry == null) { + return makeErrorResponse(userRequest, CompanyErrors.TradingClearingRegistryNotFound); + } else { + req.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + } + } + ClientCode newClientCode = buildClientCode(req); + clientCodeMap.insert(newClientCode); + log.debug("successfully processed, new clientCode id {}", newClientCode.getId()); + + return null; + } + + + protected RequestInfoUpdate clientCodeNewFromApiUmCompany(BaseRequest userRequest) { + log.debug("ClientCodeNewRequest received {}", userRequest.getId()); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clientCodeNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + + ClientCodeNewRequest req = userRequest.getRequestPayload(); + + boolean doCreateTCR = checkNeedCreateTCR(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + if (doCreateTCR) { + try { + createAndWaitTCR(userRequest.getId(), null, + req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + } catch (ClearingBaseException e) { + log.error("Can not wait creation of TCR. request id={};CompanyId={}, MoneyAccountId={}, DepoAccountId={}; {}", + userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(), + e.toString()); + return makeErrorResponse(userRequest, CompanyErrors.GeneralError, "Can not create TCR at this moment"); + } + } + + if (req.getTradingClearingRegistryId() == null && req.getMoneyAccountId() != null) { + TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + if (tradingClearingRegistry == null) { + return makeErrorResponse(userRequest, CompanyErrors.TradingClearingRegistryNotFound); + } else { + req.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + } + } + ClientCode newClientCode = buildClientCode(req); + clientCodeMap.insert(newClientCode); + log.debug("successfully processed, new clientCode id {}", newClientCode.getId()); + + return null; + } + + + protected RequestInfoUpdate clientCodeUpdate(BaseRequest userRequest) { + ClientCodeUpdateRequest req = userRequest.getRequestPayload(); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clientCodeUpdateRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + + log.debug("ClientCodeUpdateRequest received, id={}", req.getId()); + ClientCode clientCode = clientCodeMap.getSingleObjectByID(req.getId()); + if (clientCode == null) { + return makeErrorResponse(userRequest, CompanyErrors.RecordNotFound, req.getId()); + } + + boolean doCreateTCR = checkNeedCreateTCR(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + if (doCreateTCR) { + try { + createAndWaitTCR(userRequest.getId(), clientCode.getId(), + req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + } catch (ClearingBaseException e) { + log.error("Can not wait creation of TCR. request id={};CompanyId={}, MoneyAccountId={}, DepoAccountId={}; {}", + userRequest.getId(), req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId(), + e.toString()); + return makeErrorResponse(userRequest, CompanyErrors.GeneralError, "Can not create TCR at this moment"); + } + } + + if (req.getTradingClearingRegistryId() == null && req.getMoneyAccountId() != null) { + TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + if (tradingClearingRegistry == null) { + return makeErrorResponse(userRequest, CompanyErrors.TradingClearingRegistryNotFound); + } else { + req.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + } + } + updateClientCode(clientCode, req); + + clientCodeMap.update(clientCode); + log.debug("successfully processed update, id {}", clientCode.getId()); + return null; + } + + private RequestInfoUpdate makeErrorResponse(BaseRequest req, CompanyErrors err, Object... arg) { + String errMsg = messageResolver.resolve(new EnumMessage(err, arg)); + return new RequestInfoUpdate() + .setId(req.getId()) + .setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error) + .setMessage(errMsg); + + } + + protected RequestInfoUpdate clientCodeDelete(BaseRequest userRequest) { + log.debug("CommonDeleteRequest received id = {}", userRequest.getId()); + CommonDeleteRequest req = userRequest.getRequestPayload(); + + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, clientCodeDeleteRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + ClientCode clientCode = clientCodeMap.getSingleObjectByID(req.getId()); + if (clientCode.getMoneyAccountId() != null) { + log.debug("Delete clientCode.id = {}: send message to account-service", clientCode.getId()); + sendBlockTCR(clientCode.getTradingClearingRegistryId(), clientCode.getMoneyAccountId()); + } + log.debug("Delete clientCode.id={}", clientCode.getId()); + clientCodeMap.delete(clientCode); + + return null; + } + + TradingClearingRegistry selectTradingClearingRegistry(Long companyId, Long moneyAccountId, Long depoAccountId) { + Map> query = new HashMap<>(); + query.put("companyId", companyId); + query.put("moneyAccountId", moneyAccountId); + query.put("tradingClearingRegistryType", TradingClearingRegistryType.Client_B.getKey()); + if (depoAccountId != null) { + query.put("depoAccountId", depoAccountId); + } + TradingClearingRegistry result = tradingClearingRegistryMap.getSingleObjectByFieldValues(query); + log.trace("TradingClearingRegistry by: {}; {}found", query, result == null ? "not " : ""); + return result; + } + + private boolean checkNeedCreateTCR(Long companyId, Long moneyAccountId, Long depoAccountId) { + // moneyAccountId обязателен, depoAccountId опционален + if (moneyAccountId == null) { + return false; + } + TradingClearingRegistry result = selectTradingClearingRegistry(companyId, moneyAccountId, depoAccountId); + if (result == null) { + return true; + } else { + return false; + } + } + + protected void createAndWaitTCR(Long reqId, Long clientCode, + Long companyId, Long moneyAccountId, Long depoAccountId) throws ClearingBaseException { + log.debug("For request {}, clientCode={} need create TCR: companyId={}, moneyAccountId={}, depoAccountId={}", + reqId, clientCode == null ? "new" : clientCode, + companyId, moneyAccountId, depoAccountId); + BaseRequest request = new BaseRequest<>(); + request.setId(idGenerator.nextId()); + request.setActionType(ActionType.NEW); + TradingClearingRegistryNewRequest requestPayload = new TradingClearingRegistryNewRequest(); + requestPayload.setCompanyId(companyId); + requestPayload.setMoneyAccountId(moneyAccountId); + requestPayload.setDepoAccountId(depoAccountId); +// requestPayload.setStatus(WorkflowStatus.Active.getKey()); + requestPayload.setTradingClearingRegistryType(TradingClearingRegistryType.Client_B.getKey()); + request.setRequestPayload(requestPayload); + try { + Long reply = accountServiceExchanger.exchange(request); + if (reply == null) { + throw new ClearingBaseException(CompanyErrors.GeneralError, "Waiting account-service timeout"); + } + // примечание: ошибка и сбой (непредвиденное завершение программы) не приведёт к необратимым последствиям, + // т.к. пользователь сможет повторить запрос, а созданный на предыдущем запросе ТКР уже будет создан и найдётся. + } catch (InterruptedException e) { + throw new ClearingBaseException(CompanyErrors.GeneralError, "Waiting account-service timeout"); + } + } + + protected void sendBlockTCR(Long tradingClearingRegistryId, Long moneyAccountId) { + if (tradingClearingRegistryId == null) { + throw new IllegalArgumentException("tradingClearingRegistryId was null"); + } + BaseRequest request = new BaseRequest<>(); + request.setId(idGenerator.nextId()); + request.setActionType(ActionType.UPDATE); + TradingClearingRegistryUpdateRequest requestPayload = new TradingClearingRegistryUpdateRequest(); + requestPayload.setId(tradingClearingRegistryId); + requestPayload.setStatus(WorkflowStatus.Blocked.getKey()); + request.setRequestPayload(requestPayload); + + try { + sendMessage(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE, request); + } catch (Exception e) { + log.error("Can not send block TCR message, {}", e.toString()); + throw e; + } + } + + + /** + * @param queue Consts.* + * @param message BaseRequest + * @return + */ + private Long sendMessage(String queue, BaseRequest message) { + Long sentRequestId = message.getId(); + if (sentRequestId == null) { + throw new IllegalArgumentException("Message " + message.getClass().getSimpleName() + " required id."); + } + log.debug("Send to \"{}\" message {} id={}", queue, message.getActionType(), sentRequestId); + try { + Future send = kafkaProducer.send(new ProducerRecord<>(queue, message)); + send.get(); + return sentRequestId; + } catch (InterruptedException e) { + log.error("Interrupt when send message, {}", ExceptionUtils.getStackTrace(e)); + Thread.currentThread().interrupt(); + throw new RuntimeException("Thread interrupted when send message to " + queue, e); + } catch (ExecutionException e) { + log.error("Error at send message, {} cause: {}", e.toString(), ExceptionUtils.getStackTrace(e.getCause())); + throw new RuntimeException("Send message error", e.getCause()); + } catch (Exception e) { + log.error("Unexpected exception when send message: {}", ExceptionUtils.getStackTrace(e)); + } + return null; + } + + /** + * @param req требуется заполнить tradingClearingRegistryId по tradingClearingRegistry.code + * @return + */ + private ClientCode buildClientCode(ClientCodeNewRequest req) { + ClientCode clientCode = new ClientCode(); +// clientCode.setId(idSequence.newId()); add in insert + clientCode.setCreated(Instant.now()); + clientCode.setUpdated(clientCode.getCreated()); + + clientCode.setCompanyId(req.getCompanyId()); + clientCode.setCode(req.getCode()); + clientCode.setTradingClearingRegistryId(req.getTradingClearingRegistryId()); + clientCode.setMoneyAccountId(req.getMoneyAccountId()); + clientCode.setDepoAccountId(req.getDepoAccountId()); + clientCode.setStatus(req.getStatus()); + + return clientCode; + } + + private void updateClientCode(ClientCode clientCode, ClientCodeUpdateRequest req) { + assert clientCode.getId() != null && clientCode.getId().equals(req.getId()); + + clientCode.setCompanyId(req.getCompanyId()); + clientCode.setCode(req.getCode()); + clientCode.setTradingClearingRegistryId(req.getTradingClearingRegistryId()); + clientCode.setMoneyAccountId(req.getMoneyAccountId()); + clientCode.setDepoAccountId(req.getDepoAccountId()); + clientCode.setStatus(req.getStatus()); + + clientCode.setUpdated(Instant.now()); + } + +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index f07a3033e..95b708d0d 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -66,12 +66,14 @@ public interface Consts { String DESTINATION_PROFILE_DOCUMENT_DELETE = "profile-document-delete"; String DESTINATION_CLIENT_CODE_NEW = "client-code-new"; + String DESTINATION_CLIENT_CODE_NEW_UM_COMPANY = "client-code-new-from-api-um-company"; String DESTINATION_CLIENT_CODE_UPDATE = "client-code-update"; String DESTINATION_CLIENT_CODE_DELETE = "client-code-delete"; String DESTINATION_TRADING_CLEARING_REGISTRY_NEW = "trading-clearing-registry-new"; String DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE = "trading-clearing-registry-update"; String DESTINATION_TRADING_CLEARING_REGISTRY_DELETE = "trading-clearing-registry-delete"; + String DESTINATION_TRADING_CLEARING_REGISTRY_REPLY = "trading-clearing-registry"; String DESTINATION_SDF08_NEW = "s-df-08-new"; String DESTINATION_SDF02_NEW = "s-df-02-new"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/registry/TradingClearingRegistryNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/registry/TradingClearingRegistryNewRequest.java index 75041b81e..c68eed1ba 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/registry/TradingClearingRegistryNewRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/registry/TradingClearingRegistryNewRequest.java @@ -21,6 +21,8 @@ public class TradingClearingRegistryNewRequest { private Long depoAccountId; @JsonProperty private String status; + @JsonProperty + private String tradingClearingRegistryType; public Long getCompanyId() { return companyId; @@ -50,6 +52,14 @@ public class TradingClearingRegistryNewRequest { return status; } + public String getTradingClearingRegistryType() { + return tradingClearingRegistryType; + } + + public void setTradingClearingRegistryType(String tradingClearingRegistryType) { + this.tradingClearingRegistryType = tradingClearingRegistryType; + } + public void setStatus(String status) { this.status = status; } From a87f2ac0dcbe2ef4af6f9fe643e472abaea3b147 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 28 Apr 2023 19:50:30 +0300 Subject: [PATCH 02/30] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-272?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BE?= =?UTF-8?q?=D1=88=D0=B8=D0=B1=D0=BA=D0=B8,=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D1=8E=D0=BD=D0=B8=D1=82=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=20(=D0=BF=D0=BE=D0=BA=D0=B0=20=D0=BD=D0=B5=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=85=D0=BE=D0=B4=D0=B8=D1=82)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exchangers/BiDirectionQueueExchanger.java | 4 +- .../company/service/ClientCodeService.java | 2 +- .../service/ClientCodeServiceTest.java | 309 ++++++++++++++++++ 3 files changed, 312 insertions(+), 3 deletions(-) create mode 100644 clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java index 1439927b8..6a0444a4e 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java @@ -86,7 +86,7 @@ public class BiDirectionQueueExchanger> extends Queu } this.timeout = timeout; - init(); + initReplyListener(); } /** @@ -162,7 +162,7 @@ public class BiDirectionQueueExchanger> extends Queu log.debug("Listener {} for async exchange {}-{} close", this, outQueue, inQueue); } - public void init() { + protected void initReplyListener() { if (syncObject != null) { throw new IllegalStateException("Already initialized"); } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java index 105ef2589..a03d9c7a0 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java @@ -284,7 +284,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean query.put("moneyAccountId", moneyAccountId); query.put("tradingClearingRegistryType", TradingClearingRegistryType.Client_B.getKey()); if (depoAccountId != null) { - query.put("depoAccountId", depoAccountId); + query.put("depoAaccountId", depoAccountId); // todo опечатка в поле класса, см. meta.xml! } TradingClearingRegistry result = tradingClearingRegistryMap.getSingleObjectByFieldValues(query); log.trace("TradingClearingRegistry by: {}; {}found", query, result == null ? "not " : ""); diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java new file mode 100644 index 000000000..1510de3e8 --- /dev/null +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java @@ -0,0 +1,309 @@ +package ru.spcex.clearing.company.service; + +import org.apache.kafka.clients.consumer.MockConsumer; +import org.apache.kafka.clients.producer.MockProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import ru.clearing.classes.statics.data.account.ClientCode; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.profile.CompanyInfo; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.clearing.platform.dictionary.*; +import ru.spcex.clearing.company.config.BeanConfiguration; +import ru.spcex.clearing.company.config.validation.ClientCodeValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; +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.account.ClientCodeNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.test.MatcherFactory; +import ru.spcex.clearing.test.TestUtils; +import ru.spcex.clearing.test.config.ImdgTestConfig; +import ru.spcex.clearing.test.config.KafkaTestConfig; +import ru.spcex.platform.enumeration.TradingClearingRegistryType; +import ru.spcex.platform.enumeration.WorkflowStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import javax.annotation.PostConstruct; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; +import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + ClientCodeService.class, + ClientCodeValidationConfig.class, + + ValidationConfig.class, + BeanConfiguration.class, + + KafkaTestConfig.class, + ImdgTestConfig.class}) +class ClientCodeServiceTest { + + private static final int PARTITION = 0; + private static final Long ID = 4L; + public static final MatcherFactory.Matcher CLIENT_CODE_MATCHER = usingIgnoringFieldsComparator(); + + private static final Long TCR_ID = 41L; + private static final Long COMPANY_ID = 42L; + + @Autowired + ClientCodeService clientCodeService; + @Autowired + @Qualifier("hazelcastServiceTest") + private ImdgProvider hazelcastServiceTest; + @Captor + private ArgumentCaptor producerRecord; + @SpyBean + private MockProducer mockProducer; + + private Imdg clientCodeImdg; + + + // ****************************-******************* + + @PostConstruct + private void init() { + waitAvailableImdgProviderAndAddAdminWithDefaultId(); + clientCodeImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.class); + + // Словари для теста, применяются в ValidationConfig + putToDictionary(IMDGDistributedNames.Map_WorkflowStatusDictionary, new WorkflowStatusDictionary(), "ACTV"); + putToDictionary(IMDGDistributedNames.Map_CompanySymbolDictionary, new CompanySymbolDictionary(), "CLRC"); + putToDictionary(IMDGDistributedNames.Map_CorporationSoleTypeDictionary, new CorporationSoleTypeDictionary(), "GDIR"); + putToDictionary(IMDGDistributedNames.Map_CountryCodeDictionary, new CountryCodeDictionary(), "RUS"); + putToDictionary(IMDGDistributedNames.Map_AllowedDictionary, new AllowedDictionary(), "ALWD"); + putToDictionary(IMDGDistributedNames.Map_LegalKindDictionary, new LegalKindDictionary(), "JURD"); + putToDictionary(IMDGDistributedNames.Map_OrganizationTypeDictionary, new OrganizationTypeDictionary(), "NCRD"); + + + Imdg companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + Company company1 = new Company(); + company1.setId(COMPANY_ID); + company1.setWorkflowStatus(WorkflowStatus.Active.getKey()); + company1.setFullName("Company prime"); + company1.setShortName("Seizwell"); + company1.setProfile(new CompanyInfo()); + company1.getProfile().setCompanyId(COMPANY_ID); + company1.getProfile().setCountryCode("TLDI"); + company1.getProfile().setDescription("Big profit from TLD Company Prime."); + company1.getProfile().setLegalKind("TLDI"); + company1.getProfile().setResidence("TLDI"); + companyImdg.insert(company1); + + Imdg tcrImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + TradingClearingRegistry registry1 = new TradingClearingRegistry(); + registry1.setId(TCR_ID); + registry1.setCompanyId(COMPANY_ID); + registry1.setCode("code-120-101"); + registry1.setMoneyAccountId(131L); + registry1.setDepoAaccountId(132L); + registry1.setTradingClearingRegistryType(TradingClearingRegistryType.Client_B.getKey()); + registry1.setStatus(WorkflowStatus.Active.getKey()); + tcrImdg.insert(registry1); + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); + } + + private void putToDictionary(String mapName, D object, String code) { + Imdg dMap = (Imdg) hazelcastServiceTest.getImdg(mapName, object.getClass()); + object.setId(2L); + object.setCode(code); + object.setName("name of " + code); + dMap.insert(object); + } + + @Test + void selectTradingClearingRegistry() { + TradingClearingRegistry tcr = clientCodeService.selectTradingClearingRegistry(COMPANY_ID, 131L, 132L); + assertNotNull(tcr); + assertEquals(41L, tcr.getId()); + + tcr = clientCodeService.selectTradingClearingRegistry(COMPANY_ID, 131L, null); + assertNotNull(tcr); + assertEquals(41L, tcr.getId()); + + assertNull(clientCodeService.selectTradingClearingRegistry(0L, 131L, 132L)); + assertNull(clientCodeService.selectTradingClearingRegistry(COMPANY_ID, 0L, 132L)); + assertNull(clientCodeService.selectTradingClearingRegistry(COMPANY_ID, 131L, 0L)); + } + + + /** + * {@link ClientCodeService#clientCodeUpdate(BaseRequest)}
+ * Тест проверяет создание {@link ClientCode} в IMDG при передаче из Apache Kafka (очередь 1).
+ * Входной запрос {@link ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest}:
+ **/ + @Test + void clientCodeNew1() { + //ARRANGE + final String ccCode = "Lucky planet"; + ClientCodeNewRequest clientCodeNewRequest = new ClientCodeNewRequest(); + clientCodeNewRequest.setCompanyId(COMPANY_ID); + clientCodeNewRequest.setCode(ccCode); + clientCodeNewRequest.setTradingClearingRegistryId(TCR_ID); + clientCodeNewRequest.setDepoAccountId(null); + clientCodeNewRequest.setMoneyAccountId(null); + clientCodeNewRequest.setStatus("ACTV"); + + ClientCode predictableClientCode = new ClientCode(); + predictableClientCode.setCode(ccCode); + predictableClientCode.setStatus("ACTV"); + predictableClientCode.setCompanyId(COMPANY_ID); + predictableClientCode.setMoneyAccountId(131L); + predictableClientCode.setDepoAccountId(132L); + predictableClientCode.setTradingClearingRegistryId(TCR_ID); + + //ACT + String jsonString = getJsonStringForNew(clientCodeNewRequest, ID); + + addRecordToKafka((MockConsumer) clientCodeService.getConsumer(), Consts.DESTINATION_CLIENT_CODE_NEW, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = %d", ccCode)); + predictableClientCode.setId(resultNew.getId()); + CLIENT_CODE_MATCHER.assertMatch(resultNew, predictableClientCode); + } + + /** + * {@link ClientCodeService#clientCodeUpdate(BaseRequest)}
+ * Тест проверяет создание {@link ClientCode} в IMDG при передаче из Apache Kafka (очередь 2).
+ * Входной запрос {@link ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest}:
+ **/ + @Test + void clientCodeNew2() { + //ARRANGE + final String ccCode = "Lucky planet"; + ClientCodeNewRequest clientCodeNewRequest = new ClientCodeNewRequest(); + clientCodeNewRequest.setCompanyId(COMPANY_ID); + clientCodeNewRequest.setCode(ccCode); + clientCodeNewRequest.setTradingClearingRegistryId(TCR_ID); + clientCodeNewRequest.setDepoAccountId(null); + clientCodeNewRequest.setMoneyAccountId(null); + clientCodeNewRequest.setStatus("ACTV"); + + ClientCode predictableClientCode = new ClientCode(); + predictableClientCode.setCode(ccCode); + predictableClientCode.setStatus("ACTV"); + predictableClientCode.setCompanyId(COMPANY_ID); + predictableClientCode.setMoneyAccountId(131L); + predictableClientCode.setDepoAccountId(132L); + predictableClientCode.setTradingClearingRegistryId(TCR_ID); + + //ACT + String jsonString = getJsonStringForNew(clientCodeNewRequest, ID); + + addRecordToKafka((MockConsumer) clientCodeService.getConsumer(), Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = %d", ccCode)); + predictableClientCode.setId(resultNew.getId()); + CLIENT_CODE_MATCHER.assertMatch(resultNew, predictableClientCode); + } + + /** + * {@link ClientCodeService#clientCodeUpdate(BaseRequest)}
+ * Тест проверяет обновление сущности {@link ClientCode} в IMDG при передаче из Apache Kafka.
+ * Входной запрос {@link ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeUpdateRequest}:
+ **/ + @Test + void clientCodeUpdate() { + //ARRANGE + ClientCode existsClientCode = new ClientCode(); + existsClientCode.setId(ID); + existsClientCode.setCompanyId(COMPANY_ID); + existsClientCode.setCode("0000"); + existsClientCode.setTradingClearingRegistryId(TCR_ID); + existsClientCode.setMoneyAccountId(200L); + existsClientCode.setDepoAccountId(201L); + existsClientCode.setStatus("ACTV"); + + ClientCodeUpdateRequest clientCodeUpdateRequest = new ClientCodeUpdateRequest(); + clientCodeUpdateRequest.setId(ID); + existsClientCode.setCompanyId(COMPANY_ID); + existsClientCode.setCode("1111"); +// existsClientCode.setTradingClearingRegistryId(TCR_ID); + existsClientCode.setMoneyAccountId(200L); + existsClientCode.setDepoAccountId(201L); + existsClientCode.setStatus("ACTV"); + + ClientCode predictableClientCode = new ClientCode(); + predictableClientCode.setId(ID); + predictableClientCode.setCompanyId(COMPANY_ID); + predictableClientCode.setCode("1111"); + predictableClientCode.setTradingClearingRegistryId(TCR_ID); + predictableClientCode.setMoneyAccountId(200L); + predictableClientCode.setDepoAccountId(201L); + predictableClientCode.setStatus("ACTV"); + + //ACT + String jsonString = getJsonStringForUpdate(clientCodeUpdateRequest, ID); + + addRecordToKafka((MockConsumer) clientCodeService.getConsumer(), Consts.DESTINATION_CLIENT_CODE_UPDATE, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + + ClientCode resultUpdating = clientCodeImdg.getSingleObjectByID(ID); + CLIENT_CODE_MATCHER.assertMatch(resultUpdating, predictableClientCode); + //todo !!!! + } + + + /** + * {@link ClientCodeService#clientCodeUpdate(BaseRequest)}
+ * Тест проверяет удаление {@link ClientCode} из IMDG при передаче из Apache Kafka.
+ * Входной запрос {@link ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest}:
+ **/ + @Test + void clientCodeDelete() { + //ARRANGE + ClientCode existsClientCode = new ClientCode(); + existsClientCode.setId(ID); + existsClientCode.setCompanyId(COMPANY_ID); + existsClientCode.setCode("0000"); + existsClientCode.setTradingClearingRegistryId(TCR_ID); + existsClientCode.setMoneyAccountId(200L); + existsClientCode.setDepoAccountId(201L); + existsClientCode.setStatus("ACTV"); + + clientCodeImdg.insert(existsClientCode); + + CommonDeleteRequest clientCodeDeleteRequest = new CommonDeleteRequest(); + clientCodeDeleteRequest.setId(ID); + + Assertions.assertNotNull(clientCodeImdg.getSingleObjectByID(ID)); // verify test data + + //ACT + String jsonString = getJsonStringForUpdate(clientCodeDeleteRequest, ID); + + addRecordToKafka((MockConsumer) clientCodeService.getConsumer(), Consts.DESTINATION_CLIENT_CODE_DELETE, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + ClientCode resultUpdate = clientCodeImdg.getSingleObjectByID(ID); + Assertions.assertNull(resultUpdate); + } + + +} \ No newline at end of file From 795b488629630acbfd6f41f60d1f7b0013078baf Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 3 May 2023 13:58:35 +0300 Subject: [PATCH 03/30] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-272?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BE?= =?UTF-8?q?=D1=88=D0=B8=D0=B1=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exchangers/BiDirectionQueueExchanger.java | 8 ++- .../ClientCodeValidationConfig.java | 14 +++--- .../company/service/ClientCodeService.java | 2 +- .../service/ClientCodeServiceTest.java | 49 ++++++++++++++++--- .../platform/messaging/domain/Consts.java | 2 +- 5 files changed, 58 insertions(+), 17 deletions(-) diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java index 6a0444a4e..35da485b1 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java @@ -59,11 +59,13 @@ public class BiDirectionQueueExchanger> extends Queu * @param kafkaProducer * @param outQueue отправляет в очередь * @param inQueue слушает очередь/топик, ожидает ответов. Пример: Consts.CONTINUE_CLEARING + * @param ignoreOtherResponse true для inQueue=Consts.REQUEST_INFO_UPDATE * @param timeout - максимальное ожидание ответа, в миллисекундах, 0 - неограничено */ public BiDirectionQueueExchanger(Consumer kafkaQueue, Producer kafkaProducer, String outQueue, String inQueue, + boolean ignoreOtherResponse, long timeout) { super(kafkaQueue); this.producer = kafkaProducer; @@ -85,8 +87,9 @@ public class BiDirectionQueueExchanger> extends Queu timeout = 0; } this.timeout = timeout; + this.ignoreOtherResponse = ignoreOtherResponse; - initReplyListener(); + //fixme debug only ! initReplyListener(); } /** @@ -132,6 +135,9 @@ public class BiDirectionQueueExchanger> extends Queu log.warn("Terminated waiter {} kafka at thread {}", this, Thread.currentThread().getName()); throw new InterruptedException(getClass().getSimpleName() + " closed"); } + if (ignoreOtherResponse && !sentRequestId.equals(lastResponseId)) { + log.debug("Ignore response id={}, we waiting {}.", lastResponseId, sentRequestId); + } } while (ignoreOtherResponse && !sentRequestId.equals(lastResponseId) && (timeout > 0 && waitTime > 0)); if (!sentRequestId.equals(lastResponseId)) { log.error("FATAL: last response from {} update from Kafka ID was {}, but sent ID was {}", diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java index 296b3b103..0b88150b4 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java @@ -5,15 +5,13 @@ import org.springframework.context.annotation.Configuration; import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.account.ClientCode; import ru.clearing.classes.statics.data.company.Company; -import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.platform.dictionary.WorkflowStatusDictionary; import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryNewRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolUpdateRequest; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule; @@ -42,7 +40,7 @@ public class ClientCodeValidationConfig { addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry); addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); return new ValidatorImpl<>(context, - FieldRequiredRule.instance("companyId", CompanySymbolUpdateRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("companyId", ClientCodeNewRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), IdPresentRule.instance("companyId", ClientCodeNewRequest::getCompanyId, IMDGDistributedNames.Map_Company, @@ -73,7 +71,7 @@ public class ClientCodeValidationConfig { IdPresentRule.instance("tradingClearingRegistryId", ClientCodeNewRequest::getTradingClearingRegistryId, IMDGDistributedNames.Map_TradingClearingRegistry, - Account.class, + TradingClearingRegistry.class, CompanyErrors.RequiredFieldEmpty, CompanyErrors.TradingClearingRegistryNotFound, false, @@ -113,7 +111,7 @@ public class ClientCodeValidationConfig { CompanyErrors.RecordNotFound ), - FieldRequiredRule.instance("companyId", CompanySymbolUpdateRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("companyId", ClientCodeNewRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), IdPresentRule.instance("companyId", ClientCodeUpdateRequest::getCompanyId, IMDGDistributedNames.Map_Company, @@ -144,7 +142,7 @@ public class ClientCodeValidationConfig { IdPresentRule.instance("tradingClearingRegistryId", ClientCodeUpdateRequest::getTradingClearingRegistryId, IMDGDistributedNames.Map_TradingClearingRegistry, - Account.class, + TradingClearingRegistry.class, CompanyErrors.RequiredFieldEmpty, CompanyErrors.TradingClearingRegistryNotFound, false, @@ -169,7 +167,7 @@ public class ClientCodeValidationConfig { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(companyDeleteRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); - addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_ClientCode); return new ValidatorImpl<>(context, // FieldRequiredRule.instance("id", CommonDeleteRequest::getId, CompanyErrors.RequiredFieldEmpty), IdPresentRule.instance("id", diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java index a03d9c7a0..2e82f5e9b 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java @@ -94,7 +94,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean this.accountServiceExchanger = new BiDirectionQueueExchanger<>(kafkaQueue, kafkaProducer, Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, - Consts.DESTINATION_TRADING_CLEARING_REGISTRY_REPLY, // todo naming + Consts.REQUEST_INFO_UPDATE, true, // REQUEST_INFO_UPDATE - стандартная очередь, для результатов всех реквестов. DESTINATION_TRADING_CLEARING_REGISTRY_REPLY, 60000 ); } diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java index 1510de3e8..46867f68a 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java @@ -39,8 +39,7 @@ import ru.spcex.platform.imdg.api.ImdgProvider; import javax.annotation.PostConstruct; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.*; import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.test.TestUtils.*; import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId; @@ -179,7 +178,7 @@ class ClientCodeServiceTest { //ASSERT waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); - ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = %d", ccCode)); + ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = '%s'", ccCode)); predictableClientCode.setId(resultNew.getId()); CLIENT_CODE_MATCHER.assertMatch(resultNew, predictableClientCode); } @@ -216,7 +215,7 @@ class ClientCodeServiceTest { //ASSERT waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); - ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = %d", ccCode)); + ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = '%s'", ccCode)); predictableClientCode.setId(resultNew.getId()); CLIENT_CODE_MATCHER.assertMatch(resultNew, predictableClientCode); } @@ -276,12 +275,50 @@ class ClientCodeServiceTest { * Входной запрос {@link ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest}:
**/ @Test - void clientCodeDelete() { + void clientCodeDelete1() { //ARRANGE ClientCode existsClientCode = new ClientCode(); existsClientCode.setId(ID); existsClientCode.setCompanyId(COMPANY_ID); existsClientCode.setCode("0000"); + // Если следующие поля заполнить, то дополнительно отправит сообщение в trading-clearing-registry-update: +// existsClientCode.setTradingClearingRegistryId(TCR_ID); +// existsClientCode.setMoneyAccountId(200L); +// existsClientCode.setDepoAccountId(201L); + existsClientCode.setStatus("ACTV"); + + clientCodeImdg.insert(existsClientCode); + + CommonDeleteRequest clientCodeDeleteRequest = new CommonDeleteRequest(); + clientCodeDeleteRequest.setId(ID); + + Assertions.assertNotNull(clientCodeImdg.getSingleObjectByID(ID)); // verify test data + + //ACT + String jsonString = getJsonStringForUpdate(clientCodeDeleteRequest, ID); + + addRecordToKafka((MockConsumer) clientCodeService.getConsumer(), Consts.DESTINATION_CLIENT_CODE_DELETE, PARTITION, 0, jsonString); + + //ASSERT + + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + ClientCode resultUpdate = clientCodeImdg.getSingleObjectByID(ID); + Assertions.assertNull(resultUpdate); + } + + /** + * {@link ClientCodeService#clientCodeUpdate(BaseRequest)}
+ * Тест проверяет удаление {@link ClientCode} из IMDG при передаче из Apache Kafka.
+ * Входной запрос {@link ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest}:
+ **/ + @Test + void clientCodeDelete2() { + //ARRANGE + ClientCode existsClientCode = new ClientCode(); + existsClientCode.setId(ID); + existsClientCode.setCompanyId(COMPANY_ID); + existsClientCode.setCode("0000"); + // Если следующие поля заполнить, то дополнительно отправит сообщение в trading-clearing-registry-update: existsClientCode.setTradingClearingRegistryId(TCR_ID); existsClientCode.setMoneyAccountId(200L); existsClientCode.setDepoAccountId(201L); @@ -300,10 +337,10 @@ class ClientCodeServiceTest { addRecordToKafka((MockConsumer) clientCodeService.getConsumer(), Consts.DESTINATION_CLIENT_CODE_DELETE, PARTITION, 0, jsonString); //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); ClientCode resultUpdate = clientCodeImdg.getSingleObjectByID(ID); Assertions.assertNull(resultUpdate); } - } \ No newline at end of file diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index 95b708d0d..20b041d22 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -73,7 +73,7 @@ public interface Consts { String DESTINATION_TRADING_CLEARING_REGISTRY_NEW = "trading-clearing-registry-new"; String DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE = "trading-clearing-registry-update"; String DESTINATION_TRADING_CLEARING_REGISTRY_DELETE = "trading-clearing-registry-delete"; - String DESTINATION_TRADING_CLEARING_REGISTRY_REPLY = "trading-clearing-registry"; +// String DESTINATION_TRADING_CLEARING_REGISTRY_REPLY = "trading-clearing-registry"; String DESTINATION_SDF08_NEW = "s-df-08-new"; String DESTINATION_SDF02_NEW = "s-df-02-new"; From 93d707961c4152a1f5028c512c287c8e4889c4f7 Mon Sep 17 00:00:00 2001 From: akulikov Date: Wed, 3 May 2023 17:47:19 +0300 Subject: [PATCH 04/30] TradingClearingRegistryService in progress --- ...adingClearingRegistryValidationConfig.java | 130 +++++++++++++ .../config/validation/ValidationConfig.java | 2 + .../clearing/account/errors/AccountError.java | 3 +- .../TradingClearingRegistryService.java | 179 ++++++++++++++++++ .../TradingClearingRegistryController.java | 4 +- ...TradingClearingRegistryControllerTest.java | 4 +- .../registry/TradingClearingRegistry.java | 1 + .../TradingClearingRegistryPurpose.java | 20 ++ .../platform/messaging/domain/Consts.java | 2 +- 9 files changed, 339 insertions(+), 6 deletions(-) create mode 100644 clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java create mode 100644 clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java create mode 100644 platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/TradingClearingRegistryPurpose.java diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java new file mode 100644 index 000000000..4cfd24e05 --- /dev/null +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java @@ -0,0 +1,130 @@ +package ru.spcex.clearing.account.config.validation; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.clearing.platform.dictionary.WorkflowStatusDictionary; +import ru.spcex.clearing.account.errors.AccountError; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest; +import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; +import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; +import ru.spcex.clearing.validation.common.rules.IdPresentRule; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.enumeration.WorkflowStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.validation.IValidator; +import ru.spcex.platform.utils.validation.ValidatorImpl; + +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; + +@Configuration +public class TradingClearingRegistryValidationConfig { + @Bean("tradingClearingRegistryNewRequest") + public Function tradingClearingRegistryNewRequestValidator( + Map> imdgForValidation + ) { + return tradingClearingRegistryNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(tradingClearingRegistryNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_Account); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + return new ValidatorImpl<>(context, + IdPresentRule.instance("companyId", + TradingClearingRegistryNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + AccountError.RequiredFieldEmpty, + AccountError.CompanyNotFound), + FieldRequiredRule.instance("moneyAccountId", + TradingClearingRegistryNewRequest::getMoneyAccountId, + AccountError.RequiredFieldEmpty, + moneyAccountId -> { + Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); + Account account = accountImdg.getSingleObjectByID(moneyAccountId); + if (account == null) return AccountError.AccountNotFound; + return null; + }), + FieldRequiredRule.instance("depoAccountId", + TradingClearingRegistryNewRequest::getDepoAccountId, + AccountError.RequiredFieldEmpty, + false, + depoAccountId -> { + Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); + Account account = accountImdg.getSingleObjectByID(depoAccountId); + if (account == null) return AccountError.AccountNotFound; + return null; + }), + DictionaryPresentRule.instance("status", + TradingClearingRegistryNewRequest::getStatus, + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class, + AccountError.RequiredFieldEmpty, + AccountError.WrongFieldValue, + false, + statusValue -> { + String statusCode = statusValue.getCode(); + if (WorkflowStatus.Active.equalsByKey(statusCode)) return null; + return AccountError.WrongFieldValue; + }) + ); + }; + } + + @Bean("tradingClearingRegistryUpdateRequest") + public Function tradingClearingRegistryUpdateRequestValidator( + Map> imdgForValidation + ) { + return tradingClearingRegistryUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(tradingClearingRegistryUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + TradingClearingRegistryUpdateRequest::getId, + IMDGDistributedNames.Map_TradingClearingRegistry, + TradingClearingRegistry.class, + AccountError.RequiredFieldEmpty, + AccountError.TradingClearingRegistryNotFound), + DictionaryPresentRule.instance("status", + TradingClearingRegistryUpdateRequest::getStatus, + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class, + AccountError.RequiredFieldEmpty, + AccountError.WrongFieldValue, + false) + ); + }; + } + + @Bean("tradingClearingRegistryBlockRequest") + public Function tradingClearingRegistryBlockRequestValidator( + Map> imdgForValidation + ) { + return tradingClearingRegistryBlockRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(tradingClearingRegistryBlockRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + CommonDeleteRequest::getId, + IMDGDistributedNames.Map_TradingClearingRegistry, + TradingClearingRegistry.class, + AccountError.RequiredFieldEmpty, + AccountError.TradingClearingRegistryNotFound) + ); + }; + } +} diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java index 36cebc49d..e9d50af15 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java @@ -11,6 +11,7 @@ import ru.clearing.classes.statics.data.company.ClearingMemberCategory; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.platform.dictionary.ClearingAccountTypeDictionary; import ru.clearing.platform.dictionary.CurrencyCodeDictionary; +import ru.clearing.platform.dictionary.WorkflowStatusDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.classes.base.SpcexObjectBase; @@ -39,6 +40,7 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_BankAccount, BankAccount.class); addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class); return imdg; } diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java index 82789613d..7a4b12852 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java @@ -12,7 +12,8 @@ public enum AccountError implements IErrorEnumId { CompanyNotFound(5013L), CompanyNotActive(5014L), InfoAccountAlreadyExist(5015L), - ClearingCategoryNotFound(5019L) + ClearingCategoryNotFound(5019L), + TradingClearingRegistryNotFound(5022L), ; private final Long id; diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java new file mode 100644 index 000000000..43a903066 --- /dev/null +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java @@ -0,0 +1,179 @@ +package ru.spcex.clearing.account.service; + +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.Qualifier; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.account.ClearingAccount; +import ru.clearing.classes.statics.data.account.DepoAccount; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +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.registry.TradingClearingRegistryNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +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.enumeration.TradingClearingRegistryPurpose; +import ru.spcex.platform.enumeration.WorkflowStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.validation.IValidator; + +import java.time.Instant; +import java.util.function.Function; + +@Service +public class TradingClearingRegistryService extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final ValidationHelper validationHelper; + private final UserRoleVerification userRoleVerification; + + private final Imdg tradingClearingRegistryImdg; + private final Imdg depoAccountImdg; + private final Imdg clearingAccountImdg; + private final Imdg companyImdg; + + private final Function tradingClearingRegistryUpdateRequestValidator; + private final Function tradingClearingRegistryNewRequestValidator; + private final Function tradingClearingRegistryBlockRequestValidator; + + public TradingClearingRegistryService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + ValidationHelper validationHelper, + UserRoleVerification userRoleVerification, + @Qualifier("tradingClearingRegistryNewRequest") + Function tradingClearingRegistryNewRequestValidator, + @Qualifier("tradingClearingRegistryUpdateRequest") + Function tradingClearingRegistryUpdateRequestValidator, + @Qualifier("tradingClearingRegistryBlockRequest") + Function tradingClearingRegistryBlockRequestValidator) { + super(kafkaQueue, kafkaProducer); + this.validationHelper = validationHelper; + this.userRoleVerification = userRoleVerification; + this.tradingClearingRegistryNewRequestValidator = tradingClearingRegistryNewRequestValidator; + this.tradingClearingRegistryImdg = imdgProvider.getImdg( + IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class + ); + this.depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class); + this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class); + this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.tradingClearingRegistryUpdateRequestValidator = tradingClearingRegistryUpdateRequestValidator; + this.tradingClearingRegistryBlockRequestValidator = tradingClearingRegistryBlockRequestValidator; + } + + @Override + public void afterPropertiesSet() throws Exception { + init(); + callback(TradingClearingRegistryNewRequest.class) + .setConsumer(this::tradingClearingRegistryNew) + .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, callbacks::put); + callback(TradingClearingRegistryUpdateRequest.class) + .setConsumer(this::tradingClearingRegistryUpdate) + .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setConsumer(this::tradingClearingRegistryBlock) + .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, callbacks::put); + } + + public RequestInfoUpdate tradingClearingRegistryNew(BaseRequest userRequest) { + log.debug("TradingClearingRegistryNewRequest received"); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + TradingClearingRegistryNewRequest req = userRequest.getRequestPayload(); + + Long id = tradingClearingRegistryImdg.nextIDSequenceFor(); + TradingClearingRegistry tradingClearingRegistry = new TradingClearingRegistry(); + tradingClearingRegistry.setId(id); + tradingClearingRegistry.setCompanyId(req.getCompanyId()); + tradingClearingRegistry.setMoneyAccountId(req.getMoneyAccountId()); + tradingClearingRegistry.setDepoAaccountId(req.getDepoAccountId()); + tradingClearingRegistry.setStatus(WorkflowStatus.Active.getKey()); + + // todo tradingClearingRegistryType из соответствующего параметра очереди но в запросе он не фигурирует + // пока оставил вычисление аналогичное автоматическому добавлению ТКР + String tradingRegistryType; + if (req.getDepoAccountId() != null) { + DepoAccount depoAccount = depoAccountImdg.getSingleObjectByID(req.getDepoAccountId()); + tradingRegistryType = depoAccount.getDepoAccountType(); + } else { + ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(req.getMoneyAccountId()); + tradingRegistryType = clearingAccount.getClearingAccountType(); + } + tradingClearingRegistry.setTradingClearingRegistryType(tradingRegistryType); + + TradingClearingRegistryPurpose registryPurpose; + if (req.getDepoAccountId() != null) registryPurpose = TradingClearingRegistryPurpose.C; + else registryPurpose = TradingClearingRegistryPurpose.M; + tradingClearingRegistry.setTradingClearingRegistryPurpose(registryPurpose.getKey()); + + Company company = companyImdg.getSingleObjectByID(req.getCompanyId()); + String code = company.getClearingCode() + registryPurpose.getKey() + registryPurpose; + if (registryPurpose == TradingClearingRegistryPurpose.C) code += tradingRegistryType + id; + else code += "AT" + id; + tradingClearingRegistry.setCode(code); + + Instant now = Instant.now(); + tradingClearingRegistry.setCreated(now); + tradingClearingRegistry.setUpdated(now); + + tradingClearingRegistryImdg.insert(tradingClearingRegistry); + + log.debug("successfully processed, id {}", id); + return null; + } + + public RequestInfoUpdate tradingClearingRegistryUpdate(BaseRequest userRequest) { + log.debug("TradingClearingRegistryUpdateRequest received"); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryUpdateRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + TradingClearingRegistryUpdateRequest req = userRequest.getRequestPayload(); + TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getSingleObjectByID(req.getId()); + + if (req.getStatus() != null) tradingClearingRegistry.setStatus(req.getStatus()); + + Instant now = Instant.now(); + tradingClearingRegistry.setUpdated(now); + + tradingClearingRegistryImdg.update(tradingClearingRegistry); + + log.debug("successfully processed, id {}", tradingClearingRegistry.getId()); + return null; + } + + public RequestInfoUpdate tradingClearingRegistryBlock(BaseRequest userRequest) { + log.debug("TradingClearingRegistryBlockRequest received"); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryBlockRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + CommonDeleteRequest req = userRequest.getRequestPayload(); + TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getSingleObjectByID(req.getId()); + + tradingClearingRegistry.setStatus(WorkflowStatus.Blocked.getKey()); + + tradingClearingRegistryImdg.update(tradingClearingRegistry); + + log.debug("successfully processed, id {}", tradingClearingRegistry.getId()); + return null; + } +} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/registry/TradingClearingRegistryController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/registry/TradingClearingRegistryController.java index 0d984ff0f..50c5984ab 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/registry/TradingClearingRegistryController.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/registry/TradingClearingRegistryController.java @@ -10,9 +10,9 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.spcex.clearing.backendapi.controller.queue.AbstractQueueController; +import ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction; import ru.spcex.clearing.backendapi.controller.request.cud.registry.TradingClearingRegistryNewAction; import ru.spcex.clearing.backendapi.controller.request.cud.registry.TradingClearingRegistryUpdateAction; -import ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction; import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse; import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse; import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse; @@ -69,7 +69,7 @@ public class TradingClearingRegistryController extends AbstractQueueController { @PathVariable("id") Long id) throws ExecutionException, InterruptedException { CommonDeleteAction deleteAction = new CommonDeleteAction(); deleteAction.setId(id); - return processRequest(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_DELETE, deleteAction); + return processRequest(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, deleteAction); } @ApiOperation(value = "get TradingClearingRegistry by id.") diff --git a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/registry/TradingClearingRegistryControllerTest.java b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/registry/TradingClearingRegistryControllerTest.java index c45ddd2ed..be9151b6b 100644 --- a/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/registry/TradingClearingRegistryControllerTest.java +++ b/clearing-parent/backend-api/src/test/java/ru/spcex/clearing/backendapi/controller/queue/registry/TradingClearingRegistryControllerTest.java @@ -6,9 +6,9 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.spcex.clearing.backendapi.controller.queue.AbstractControllerTest; +import ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction; import ru.spcex.clearing.backendapi.controller.request.cud.registry.TradingClearingRegistryNewAction; import ru.spcex.clearing.backendapi.controller.request.cud.registry.TradingClearingRegistryUpdateAction; -import ru.spcex.clearing.backendapi.controller.request.cud.common.CommonDeleteAction; import ru.spcex.clearing.backendapi.controller.response.entity.registry.TradingClearingRegistryBackendGetById; import ru.spcex.clearing.backendapi.controller.response.entity.registry.TradingClearingRegistryBackendGetFields; import ru.spcex.clearing.backendapi.domain.actions.IAction; @@ -97,7 +97,7 @@ class TradingClearingRegistryControllerTest extends AbstractControllerTest { deleteAction.setId(id); //ACT and ASSERT checkDeletingByRestApi(REST_URL, id); - checkSendedMessegeFromKafka(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_DELETE, deleteAction); + checkSendedMessegeFromKafka(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, deleteAction); } /** diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/TradingClearingRegistry.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/TradingClearingRegistry.java index 9fa9a6050..91bb3ca6f 100644 --- a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/TradingClearingRegistry.java +++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/registry/TradingClearingRegistry.java @@ -15,6 +15,7 @@ public class TradingClearingRegistry extends BusinessObject { private Long companyId; private String code; private Long moneyAccountId; + // todo fix typo private Long depoAaccountId; private String tradingClearingRegistryType; private String tradingClearingRegistryLevel; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/TradingClearingRegistryPurpose.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/TradingClearingRegistryPurpose.java new file mode 100644 index 000000000..724d5519d --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/TradingClearingRegistryPurpose.java @@ -0,0 +1,20 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +public enum TradingClearingRegistryPurpose implements IEnumKey { + M("M"), + C("C"), + ; + + private final String key; + + TradingClearingRegistryPurpose(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index 9842d71ef..4a9861ffd 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -83,7 +83,7 @@ public interface Consts { String DESTINATION_TRADING_CLEARING_REGISTRY_NEW = "trading-clearing-registry-new"; String DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE = "trading-clearing-registry-update"; - String DESTINATION_TRADING_CLEARING_REGISTRY_DELETE = "trading-clearing-registry-delete"; + String DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK = "trading-clearing-registry-block"; String DESTINATION_SDF08_NEW = "s-df-08-new"; String DESTINATION_SDF02_NEW = "s-df-02-new"; From 3ec2177641fb3acf849622f694a635f491950940 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 4 May 2023 16:16:13 +0300 Subject: [PATCH 05/30] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-272?= =?UTF-8?q?=20=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D1=8B=20(=D0=BD=D0=B5=20=D1=81=D1=82=D0=B0=D0=B1?= =?UTF-8?q?=D0=B8=D0=BB=D1=8C=D0=BD=D0=BE=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=D1=8E=D1=82)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exchangers/BiDirectionQueueExchanger.java | 2 +- .../ClientCodeValidationConfig.java | 2 +- .../service/ClientCodeServiceTest.java | 172 ++++++++++-------- 3 files changed, 99 insertions(+), 77 deletions(-) diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java index 35da485b1..c26f63b0c 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java @@ -89,7 +89,7 @@ public class BiDirectionQueueExchanger> extends Queu this.timeout = timeout; this.ignoreOtherResponse = ignoreOtherResponse; - //fixme debug only ! initReplyListener(); + initReplyListener(); } /** diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java index 0b88150b4..653c6320d 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java @@ -111,7 +111,7 @@ public class ClientCodeValidationConfig { CompanyErrors.RecordNotFound ), - FieldRequiredRule.instance("companyId", ClientCodeNewRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), + FieldRequiredRule.instance("companyId", ClientCodeUpdateRequest::getCompanyId, CompanyErrors.RequiredFieldEmpty), IdPresentRule.instance("companyId", ClientCodeUpdateRequest::getCompanyId, IMDGDistributedNames.Map_Company, diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java index 46867f68a..503174d22 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java @@ -13,6 +13,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; +import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.account.ClientCode; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.profile.CompanyInfo; @@ -44,6 +45,7 @@ import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparato import static ru.spcex.clearing.test.TestUtils.*; import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId; +//todo тесты случайно ломаются из-за BiDirectionQueueExchanger. Когда там выключаю initReplyListener() то тесты стабильно работают. @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { ClientCodeService.class, @@ -58,7 +60,7 @@ class ClientCodeServiceTest { private static final int PARTITION = 0; private static final Long ID = 4L; - public static final MatcherFactory.Matcher CLIENT_CODE_MATCHER = usingIgnoringFieldsComparator(); + public static final MatcherFactory.Matcher CLIENT_CODE_MATCHER = usingIgnoringFieldsComparator("created","updated"); private static final Long TCR_ID = 41L; private static final Long COMPANY_ID = 42L; @@ -118,6 +120,20 @@ class ClientCodeServiceTest { registry1.setStatus(WorkflowStatus.Active.getKey()); tcrImdg.insert(registry1); + Imdg accounts = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class); + Account moneyAccount=new Account(); + moneyAccount.setId(131L); + moneyAccount.setAccount("AAAA-4444"); + moneyAccount.setStatus("ACTV"); + moneyAccount.setCompanyId(COMPANY_ID); // для валидации принадлежности счёта + accounts.insert(moneyAccount); + Account depoAccount=new Account(); + depoAccount.setId(132L); + depoAccount.setAccount("AAAB-44654"); + depoAccount.setStatus("ACTV"); + depoAccount.setCompanyId(COMPANY_ID); // для валидации принадлежности счёта + accounts.insert(depoAccount); + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); doReturn(future).when(mockProducer).send(producerRecord.capture()); } @@ -167,8 +183,8 @@ class ClientCodeServiceTest { predictableClientCode.setCode(ccCode); predictableClientCode.setStatus("ACTV"); predictableClientCode.setCompanyId(COMPANY_ID); - predictableClientCode.setMoneyAccountId(131L); - predictableClientCode.setDepoAccountId(132L); +// predictableClientCode.setMoneyAccountId(131L); +// predictableClientCode.setDepoAccountId(132L); predictableClientCode.setTradingClearingRegistryId(TCR_ID); //ACT @@ -181,6 +197,7 @@ class ClientCodeServiceTest { ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = '%s'", ccCode)); predictableClientCode.setId(resultNew.getId()); CLIENT_CODE_MATCHER.assertMatch(resultNew, predictableClientCode); + assertNotNull(resultNew.getCreated()); } /** @@ -204,8 +221,8 @@ class ClientCodeServiceTest { predictableClientCode.setCode(ccCode); predictableClientCode.setStatus("ACTV"); predictableClientCode.setCompanyId(COMPANY_ID); - predictableClientCode.setMoneyAccountId(131L); - predictableClientCode.setDepoAccountId(132L); +// predictableClientCode.setMoneyAccountId(131L); +// predictableClientCode.setDepoAccountId(132L); predictableClientCode.setTradingClearingRegistryId(TCR_ID); //ACT @@ -218,8 +235,11 @@ class ClientCodeServiceTest { ClientCode resultNew = clientCodeImdg.getSingleObjectBySQL(String.format("code = '%s'", ccCode)); predictableClientCode.setId(resultNew.getId()); CLIENT_CODE_MATCHER.assertMatch(resultNew, predictableClientCode); + assertNotNull(resultNew.getCreated()); } + //todo добавить тест NEW заполненными MoneyAccountId(131L), DepoAccountId(132L); - от этого направляется дополнительное сообщение в очередь и используется ожидание ответа. + /** * {@link ClientCodeService#clientCodeUpdate(BaseRequest)}
* Тест проверяет обновление сущности {@link ClientCode} в IMDG при передаче из Apache Kafka.
@@ -233,26 +253,27 @@ class ClientCodeServiceTest { existsClientCode.setCompanyId(COMPANY_ID); existsClientCode.setCode("0000"); existsClientCode.setTradingClearingRegistryId(TCR_ID); - existsClientCode.setMoneyAccountId(200L); - existsClientCode.setDepoAccountId(201L); + existsClientCode.setMoneyAccountId(131L); + existsClientCode.setDepoAccountId(132L); existsClientCode.setStatus("ACTV"); + clientCodeImdg.insert(existsClientCode); ClientCodeUpdateRequest clientCodeUpdateRequest = new ClientCodeUpdateRequest(); clientCodeUpdateRequest.setId(ID); - existsClientCode.setCompanyId(COMPANY_ID); - existsClientCode.setCode("1111"); -// existsClientCode.setTradingClearingRegistryId(TCR_ID); - existsClientCode.setMoneyAccountId(200L); - existsClientCode.setDepoAccountId(201L); - existsClientCode.setStatus("ACTV"); + clientCodeUpdateRequest.setCompanyId(COMPANY_ID); + clientCodeUpdateRequest.setCode("1111"); + clientCodeUpdateRequest.setTradingClearingRegistryId(TCR_ID); + clientCodeUpdateRequest.setMoneyAccountId(131L); + clientCodeUpdateRequest.setDepoAccountId(132L); + clientCodeUpdateRequest.setStatus("ACTV"); ClientCode predictableClientCode = new ClientCode(); predictableClientCode.setId(ID); predictableClientCode.setCompanyId(COMPANY_ID); predictableClientCode.setCode("1111"); predictableClientCode.setTradingClearingRegistryId(TCR_ID); - predictableClientCode.setMoneyAccountId(200L); - predictableClientCode.setDepoAccountId(201L); + predictableClientCode.setMoneyAccountId(131L); + predictableClientCode.setDepoAccountId(132L); predictableClientCode.setStatus("ACTV"); //ACT @@ -265,7 +286,7 @@ class ClientCodeServiceTest { ClientCode resultUpdating = clientCodeImdg.getSingleObjectByID(ID); CLIENT_CODE_MATCHER.assertMatch(resultUpdating, predictableClientCode); - //todo !!!! + assertNotNull(resultUpdating.getUpdated()); } @@ -282,65 +303,66 @@ class ClientCodeServiceTest { existsClientCode.setCompanyId(COMPANY_ID); existsClientCode.setCode("0000"); // Если следующие поля заполнить, то дополнительно отправит сообщение в trading-clearing-registry-update: + existsClientCode.setTradingClearingRegistryId(null); + existsClientCode.setMoneyAccountId(null); + existsClientCode.setDepoAccountId(null); + existsClientCode.setStatus("ACTV"); + + clientCodeImdg.insert(existsClientCode); + + CommonDeleteRequest clientCodeDeleteRequest = new CommonDeleteRequest(); + clientCodeDeleteRequest.setId(ID); + + Assertions.assertNotNull(clientCodeImdg.getSingleObjectByID(ID)); // verify test data + + //ACT + String jsonString = getJsonStringForUpdate(clientCodeDeleteRequest, ID); + + addRecordToKafka((MockConsumer) clientCodeService.getConsumer(), Consts.DESTINATION_CLIENT_CODE_DELETE, PARTITION, 0, jsonString); + + //ASSERT + + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + ClientCode resultUpdate = clientCodeImdg.getSingleObjectByID(ID); + Assertions.assertNull(resultUpdate); + } + +// /** +// * {@link ClientCodeService#clientCodeUpdate(BaseRequest)}
+// * Тест проверяет удаление {@link ClientCode} из IMDG при передаче из Apache Kafka.
+// * У ClientCode заполнены MoneyAccountId, DepoAccountId - по этому при удалении должно направиться дополнительное сообщение в очередь DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE
+// * Входной запрос {@link ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest}:
+// **/ +// @Test +// void clientCodeDelete2() { +// //ARRANGE +// ClientCode existsClientCode = new ClientCode(); +// existsClientCode.setId(ID); +// existsClientCode.setCompanyId(COMPANY_ID); +// existsClientCode.setCode("0000"); +// // Если следующие поля заполнить, то дополнительно отправит сообщение в trading-clearing-registry-update: // existsClientCode.setTradingClearingRegistryId(TCR_ID); -// existsClientCode.setMoneyAccountId(200L); -// existsClientCode.setDepoAccountId(201L); - existsClientCode.setStatus("ACTV"); - - clientCodeImdg.insert(existsClientCode); - - CommonDeleteRequest clientCodeDeleteRequest = new CommonDeleteRequest(); - clientCodeDeleteRequest.setId(ID); - - Assertions.assertNotNull(clientCodeImdg.getSingleObjectByID(ID)); // verify test data - - //ACT - String jsonString = getJsonStringForUpdate(clientCodeDeleteRequest, ID); - - addRecordToKafka((MockConsumer) clientCodeService.getConsumer(), Consts.DESTINATION_CLIENT_CODE_DELETE, PARTITION, 0, jsonString); - - //ASSERT - - waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); - ClientCode resultUpdate = clientCodeImdg.getSingleObjectByID(ID); - Assertions.assertNull(resultUpdate); - } - - /** - * {@link ClientCodeService#clientCodeUpdate(BaseRequest)}
- * Тест проверяет удаление {@link ClientCode} из IMDG при передаче из Apache Kafka.
- * Входной запрос {@link ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest}:
- **/ - @Test - void clientCodeDelete2() { - //ARRANGE - ClientCode existsClientCode = new ClientCode(); - existsClientCode.setId(ID); - existsClientCode.setCompanyId(COMPANY_ID); - existsClientCode.setCode("0000"); - // Если следующие поля заполнить, то дополнительно отправит сообщение в trading-clearing-registry-update: - existsClientCode.setTradingClearingRegistryId(TCR_ID); - existsClientCode.setMoneyAccountId(200L); - existsClientCode.setDepoAccountId(201L); - existsClientCode.setStatus("ACTV"); - - clientCodeImdg.insert(existsClientCode); - - CommonDeleteRequest clientCodeDeleteRequest = new CommonDeleteRequest(); - clientCodeDeleteRequest.setId(ID); - - Assertions.assertNotNull(clientCodeImdg.getSingleObjectByID(ID)); // verify test data - - //ACT - String jsonString = getJsonStringForUpdate(clientCodeDeleteRequest, ID); - - addRecordToKafka((MockConsumer) clientCodeService.getConsumer(), Consts.DESTINATION_CLIENT_CODE_DELETE, PARTITION, 0, jsonString); - - //ASSERT - - waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); - ClientCode resultUpdate = clientCodeImdg.getSingleObjectByID(ID); - Assertions.assertNull(resultUpdate); - } +// existsClientCode.setMoneyAccountId(131L); +// existsClientCode.setDepoAccountId(132L); +// existsClientCode.setStatus("ACTV"); +// +// clientCodeImdg.insert(existsClientCode); +// +// CommonDeleteRequest clientCodeDeleteRequest = new CommonDeleteRequest(); +// clientCodeDeleteRequest.setId(ID); +// +// Assertions.assertNotNull(clientCodeImdg.getSingleObjectByID(ID)); // verify test data +// +// //ACT +// String jsonString = getJsonStringForUpdate(clientCodeDeleteRequest, ID); +// +// addRecordToKafka((MockConsumer) clientCodeService.getConsumer(), Consts.DESTINATION_CLIENT_CODE_DELETE, PARTITION, 0, jsonString); +// +// //ASSERT +// +// waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); +// ClientCode resultUpdate = clientCodeImdg.getSingleObjectByID(ID); +// Assertions.assertNull(resultUpdate); +// } } \ No newline at end of file From 864bbcf125a12fbd40bf9421b4cf1c9c09cca18f Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 4 May 2023 16:29:52 +0300 Subject: [PATCH 06/30] =?UTF-8?q?company-service=20http://jira.mfd.msk:808?= =?UTF-8?q?8/browse/CLS-272=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20BiDirectionQueueExchanger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/services/exchangers/BiDirectionQueueExchanger.java | 2 +- .../spcex/clearing/company/service/ClientCodeService.java | 6 +++--- .../clearing/company/service/ClientCodeServiceTest.java | 1 - .../clearing/platform/messaging/service/QueueConsumer.java | 1 + 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java index c26f63b0c..b90b1993e 100644 --- a/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/exchangers/BiDirectionQueueExchanger.java @@ -55,7 +55,7 @@ public class BiDirectionQueueExchanger> extends Queu /** * Синхронно-ассинхронный обмен сообщениями * - * @param kafkaQueue + * @param kafkaQueue уникальный kafka Consumer (Spring prototype). Нельзя переиспользовать существующие. * @param kafkaProducer * @param outQueue отправляет в очередь * @param inQueue слушает очередь/топик, ожидает ответов. Пример: Consts.CONTINUE_CLEARING diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java index 2e82f5e9b..a795a26db 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java @@ -70,7 +70,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean BiDirectionQueueExchanger> accountServiceExchanger; @Autowired - public ClientCodeService(Consumer kafkaQueue, + public ClientCodeService(Consumer kafkaQueue1, Consumer kafkaQueue2, Producer kafkaProducer, ImdgProvider imdgProvider, ValidationHelper validationHelper, @@ -79,7 +79,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean @Qualifier("clientCodeNewRequestValidator") Function clientCodeNewRequestValidator, @Qualifier("clientCodeUpdateRequestValidator") Function clientCodeUpdateRequestValidator, @Qualifier("clientCodeDeleteRequestValidator") Function clientCodeDeleteRequestValidator) { - super(kafkaQueue, kafkaProducer); + super(kafkaQueue1, kafkaProducer); this.kafkaProducer = kafkaProducer; this.idGenerator = imdgProvider.getImdgIdGenerator(); this.clientCodeMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClientCode, ClientCode.class); @@ -92,7 +92,7 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean this.messageResolver = messageResolver; this.userRoleVerification = userRoleVerification; - this.accountServiceExchanger = new BiDirectionQueueExchanger<>(kafkaQueue, kafkaProducer, + this.accountServiceExchanger = new BiDirectionQueueExchanger<>(kafkaQueue2, kafkaProducer, Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, Consts.REQUEST_INFO_UPDATE, true, // REQUEST_INFO_UPDATE - стандартная очередь, для результатов всех реквестов. DESTINATION_TRADING_CLEARING_REGISTRY_REPLY, 60000 diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java index 503174d22..0f34d0778 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java @@ -45,7 +45,6 @@ import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparato import static ru.spcex.clearing.test.TestUtils.*; import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId; -//todo тесты случайно ломаются из-за BiDirectionQueueExchanger. Когда там выключаю initReplyListener() то тесты стабильно работают. @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { ClientCodeService.class, diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java index 0b26d5c03..3f7afe713 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java @@ -74,6 +74,7 @@ public class QueueConsumer implements AutoCloseable { public void init() { inputExecutor.submit(() -> { try { + log.debug("Using kafka consumer {} for subscribe on \"{}\"", consumer, callbacks.keySet()); if (supportStartOffsetTimeWindow) { consumer.subscribe(callbacks.keySet(), new OffsetChanger(consumer, callbacks.keySet())); } else { From b6eb7a9d71b96b9ae9472e409e7584f671db35b3 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 4 May 2023 17:10:55 +0300 Subject: [PATCH 07/30] =?UTF-8?q?company-service=20http://jira.mfd.msk:808?= =?UTF-8?q?8/browse/CLS-272=20=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=20=D0=BA=20=D1=82?= =?UTF-8?q?=D0=B0=D1=81=D0=BA=D1=83=2027/=D0=B0=D0=BF=D1=80/23=2016:24?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ClientCodeValidationConfig.java | 20 -------- .../company/service/ClientCodeService.java | 47 +++++++++---------- .../service/ClientCodeServiceTest.java | 4 +- 3 files changed, 24 insertions(+), 47 deletions(-) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java index 653c6320d..c3b2776ae 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ClientCodeValidationConfig.java @@ -68,16 +68,6 @@ public class ClientCodeValidationConfig { acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId()) ? null : CompanyErrors.AccountNotFound ), - IdPresentRule.instance("tradingClearingRegistryId", - ClientCodeNewRequest::getTradingClearingRegistryId, - IMDGDistributedNames.Map_TradingClearingRegistry, - TradingClearingRegistry.class, - CompanyErrors.RequiredFieldEmpty, - CompanyErrors.TradingClearingRegistryNotFound, - false, - acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId()) - ? null : CompanyErrors.TradingClearingRegistryNotFound - ), DictionaryPresentRule.instance("stauts", @@ -139,16 +129,6 @@ public class ClientCodeValidationConfig { acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId()) ? null : CompanyErrors.AccountNotFound ), - IdPresentRule.instance("tradingClearingRegistryId", - ClientCodeUpdateRequest::getTradingClearingRegistryId, - IMDGDistributedNames.Map_TradingClearingRegistry, - TradingClearingRegistry.class, - CompanyErrors.RequiredFieldEmpty, - CompanyErrors.TradingClearingRegistryNotFound, - false, - acc -> Objects.equals(context.getValidatedObject().getCompanyId(), acc.getCompanyId()) - ? null : CompanyErrors.TradingClearingRegistryNotFound - ), DictionaryPresentRule.instance("stauts", ClientCodeUpdateRequest::getStatus, diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java index a795a26db..183e6da6d 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClientCodeService.java @@ -147,14 +147,6 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean } } - if (req.getTradingClearingRegistryId() == null && req.getMoneyAccountId() != null) { - TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); - if (tradingClearingRegistry == null) { - return makeErrorResponse(userRequest, CompanyErrors.TradingClearingRegistryNotFound); - } else { - req.setTradingClearingRegistryId(tradingClearingRegistry.getId()); - } - } ClientCode newClientCode = buildClientCode(req); clientCodeMap.insert(newClientCode); log.debug("successfully processed, new clientCode id {}", newClientCode.getId()); @@ -188,14 +180,6 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean } } - if (req.getTradingClearingRegistryId() == null && req.getMoneyAccountId() != null) { - TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); - if (tradingClearingRegistry == null) { - return makeErrorResponse(userRequest, CompanyErrors.TradingClearingRegistryNotFound); - } else { - req.setTradingClearingRegistryId(tradingClearingRegistry.getId()); - } - } ClientCode newClientCode = buildClientCode(req); clientCodeMap.insert(newClientCode); log.debug("successfully processed, new clientCode id {}", newClientCode.getId()); @@ -233,14 +217,6 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean } } - if (req.getTradingClearingRegistryId() == null && req.getMoneyAccountId() != null) { - TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); - if (tradingClearingRegistry == null) { - return makeErrorResponse(userRequest, CompanyErrors.TradingClearingRegistryNotFound); - } else { - req.setTradingClearingRegistryId(tradingClearingRegistry.getId()); - } - } updateClientCode(clientCode, req); clientCodeMap.update(clientCode); @@ -392,7 +368,17 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean clientCode.setCompanyId(req.getCompanyId()); clientCode.setCode(req.getCode()); - clientCode.setTradingClearingRegistryId(req.getTradingClearingRegistryId()); + + if (req.getMoneyAccountId() != null) { + TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + if (tradingClearingRegistry == null) { + log.warn("TCR not found: CompanyId {}, MoneyAccountId {}, DepoAccountId {}", + req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + } else { + clientCode.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + } + } + clientCode.setMoneyAccountId(req.getMoneyAccountId()); clientCode.setDepoAccountId(req.getDepoAccountId()); clientCode.setStatus(req.getStatus()); @@ -405,6 +391,17 @@ public class ClientCodeService extends QueueConsumer implements InitializingBean clientCode.setCompanyId(req.getCompanyId()); clientCode.setCode(req.getCode()); + + if (req.getMoneyAccountId() != null) { + TradingClearingRegistry tradingClearingRegistry = selectTradingClearingRegistry(req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + if (tradingClearingRegistry == null) { + log.warn("TCR not found: CompanyId {}, MoneyAccountId {}, DepoAccountId {}", + req.getCompanyId(), req.getMoneyAccountId(), req.getDepoAccountId()); + } else { + clientCode.setTradingClearingRegistryId(tradingClearingRegistry.getId()); + } + } + clientCode.setTradingClearingRegistryId(req.getTradingClearingRegistryId()); clientCode.setMoneyAccountId(req.getMoneyAccountId()); clientCode.setDepoAccountId(req.getDepoAccountId()); diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java index 0f34d0778..2599a0ec9 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/ClientCodeServiceTest.java @@ -184,7 +184,7 @@ class ClientCodeServiceTest { predictableClientCode.setCompanyId(COMPANY_ID); // predictableClientCode.setMoneyAccountId(131L); // predictableClientCode.setDepoAccountId(132L); - predictableClientCode.setTradingClearingRegistryId(TCR_ID); +// predictableClientCode.setTradingClearingRegistryId(TCR_ID); //ACT String jsonString = getJsonStringForNew(clientCodeNewRequest, ID); @@ -222,7 +222,7 @@ class ClientCodeServiceTest { predictableClientCode.setCompanyId(COMPANY_ID); // predictableClientCode.setMoneyAccountId(131L); // predictableClientCode.setDepoAccountId(132L); - predictableClientCode.setTradingClearingRegistryId(TCR_ID); +// predictableClientCode.setTradingClearingRegistryId(TCR_ID); //ACT String jsonString = getJsonStringForNew(clientCodeNewRequest, ID); From a83f4f348fe870936bc999567792064f3c7cdcfc Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 4 May 2023 19:06:39 +0300 Subject: [PATCH 08/30] =?UTF-8?q?backend-api=20http://jira.mfd.msk:8088/br?= =?UTF-8?q?owse/CLS-273=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20swagger/json=20=D0=B0=D0=BD=D0=BD=D0=BE=D1=82=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../registry/TradingClearingRegistryBackendGetFields.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/registry/TradingClearingRegistryBackendGetFields.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/registry/TradingClearingRegistryBackendGetFields.java index 60495a336..d4822d731 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/registry/TradingClearingRegistryBackendGetFields.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/registry/TradingClearingRegistryBackendGetFields.java @@ -36,10 +36,12 @@ public class TradingClearingRegistryBackendGetFields { @ApiModelProperty(value = "Наименование статуса", example = "ACTV") private String status; - @JsonProperty("Дата-время создания записи") + @JsonProperty + @ApiModelProperty(value = "Дата-время создания записи") @JsonSerialize(using = InstantSerializer.class) private Instant createdAt; - @JsonProperty("Дата-время изменения записи") + @JsonProperty + @ApiModelProperty(value = "Дата-время изменения записи") @JsonSerialize(using = InstantSerializer.class) private Instant updatedAt; From 71203b08e78906e58ce7d55b7758e19c62da4295 Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 5 May 2023 09:51:10 +0300 Subject: [PATCH 09/30] http://jira.mfd.msk:8088/browse/CLS-271 fix statuses --- .../validation/AccountValidationConfig.java | 27 ++++--- .../BankAccountValidationConfig.java | 3 +- .../ClearingAccountValidationConfig.java | 6 +- .../DepoAccountValidationConfig.java | 4 +- ...adingClearingRegistryValidationConfig.java | 73 ++++++++++++++++++- .../config/validation/ValidationConfig.java | 4 +- .../account/service/AccountService.java | 4 +- .../account/service/BankAccountService.java | 6 +- .../service/ClearingAccountService.java | 12 +-- .../account/service/DepoAccountService.java | 4 +- .../service/InformationAccountService.java | 4 +- .../TradingClearingRegistryService.java | 13 ++++ .../account/service/AccountServiceTest.java | 21 ++++-- .../service/ClearingAccountServiceTest.java | 6 +- .../service/DepoAccountServiceTest.java | 2 +- .../InformationAccountServiceTest.java | 2 +- .../platform/messaging/domain/Consts.java | 1 + 17 files changed, 144 insertions(+), 48 deletions(-) diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java index cb654bc0e..8f9cd76eb 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java @@ -5,18 +5,19 @@ import org.springframework.context.annotation.Configuration; import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.platform.dictionary.AccountTypeDictionary; +import ru.clearing.platform.dictionary.ServiceStatusDictionary; import ru.spcex.clearing.account.errors.AccountError; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; -import ru.spcex.clearing.validation.common.rules.EnumPresentRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; @@ -45,6 +46,7 @@ public class AccountValidationConfig { Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); addImdg.accept(IMDGDistributedNames.Map_Company); addImdg.accept(IMDGDistributedNames.Map_Account); + addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary); addImdg.accept(IMDGDistributedNames.Map_AccountTypeDictionary); return new ValidatorImpl<>(context, IdPresentRule.instance("companyId", @@ -69,12 +71,15 @@ public class AccountValidationConfig { if (accounts.isEmpty()) return null; return AccountError.AccountAlreadyExist; }), - FieldRequiredRule.instance("status", + DictionaryPresentRule.instance("status", CorrespondentAccountNewRequest::getStatus, + IMDGDistributedNames.Map_ServiceStatusDictionary, + ServiceStatusDictionary.class, AccountError.RequiredFieldEmpty, + AccountError.WrongFieldValue, false, statusValue -> { - if (statusValue == null || AccountStatus.ACTIVE.equalsByKey(statusValue)) return null; + if (ServiceStatus.Active.equalsByKey(statusValue.getCode())) return null; return AccountError.WrongFieldValue; }), DictionaryPresentRule.instance("accountType", @@ -127,16 +132,16 @@ public class AccountValidationConfig { error = Objects.equals(company.getId(), correspondentAccountUpdateRequest.getCompanyId()) ? error : AccountError.WrongFieldValue; return error; }), - EnumPresentRule.instance("status", + DictionaryPresentRule.instance("status", CorrespondentAccountUpdateRequest::getStatus, - AccountStatus.values(), - false, - AccountError.WrongFieldValue, - AccountError.RequiredFieldEmpty), + IMDGDistributedNames.Map_ServiceStatusDictionary, + ServiceStatusDictionary.class, + AccountError.RequiredFieldEmpty, + AccountError.WrongFieldValue), DictionaryPresentRule.instance("accountType", CorrespondentAccountUpdateRequest::getAccountType, - IMDGDistributedNames.Map_AccountTypeDictionary, - AccountTypeDictionary.class, + IMDGDistributedNames.Map_ServiceStatusDictionary, + ServiceStatusDictionary.class, AccountError.RequiredFieldEmpty, AccountError.WrongFieldValue, accountType -> { @@ -164,7 +169,7 @@ public class AccountValidationConfig { AccountError.RequiredFieldEmpty, AccountError.AccountNotFound, account -> { - if (AccountStatus.ACTIVE.equalsByKey(account.getStatus())) return null; + if (WorkflowStatus.Active.equalsByKey(account.getStatus())) return null; return AccountError.AccountNotActive; }) ); 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 1c2ca6ab6..c4c350bb4 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 @@ -17,6 +17,7 @@ import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; @@ -62,7 +63,7 @@ public class BankAccountValidationConfig { ); ImdgPredicateBuilder pb = accountImdg.predicateBuilder(); ImdgPredicate accountValuePredicate = pb.equals("account", accountValue); - ImdgPredicate accountStatusPredicate = pb.equals("status", AccountStatus.ACTIVE.getKey()); + ImdgPredicate accountStatusPredicate = pb.equals("status", ServiceStatus.Active.getKey()); ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Bank.getKey()); ImdgPredicate finalPredicate = pb.and(accountValuePredicate, accountStatusPredicate, diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ClearingAccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ClearingAccountValidationConfig.java index cb3c2368e..9c9cb0ba6 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ClearingAccountValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ClearingAccountValidationConfig.java @@ -13,8 +13,8 @@ import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.platform.classes.base.SpcexObjectBase; -import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; @@ -60,7 +60,7 @@ public class ClearingAccountValidationConfig { ); ImdgPredicateBuilder pb = accountImdg.predicateBuilder(); ImdgPredicate accountValuePredicate = pb.equals("account", accountValue); - ImdgPredicate accountStatusPredicate = pb.equals("status", AccountStatus.ACTIVE.getKey()); + ImdgPredicate accountStatusPredicate = pb.equals("status", ServiceStatus.Active.getKey()); ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Clrn.getKey()); ImdgPredicate finalPredicate = pb.and(accountValuePredicate, accountStatusPredicate, @@ -102,7 +102,7 @@ public class ClearingAccountValidationConfig { ); ImdgPredicateBuilder pb = accountImdg.predicateBuilder(); ImdgPredicate accountValuePredicate = pb.equals("account", accountValue); - ImdgPredicate accountStatusPredicate = pb.equals("status", AccountStatus.ACTIVE.getKey()); + ImdgPredicate accountStatusPredicate = pb.equals("status", ServiceStatus.Active.getKey()); ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Clrn.getKey()); ImdgPredicate finalPredicate = pb.and(accountValuePredicate, accountStatusPredicate, diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/DepoAccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/DepoAccountValidationConfig.java index 10277912b..c3bbca5ff 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/DepoAccountValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/DepoAccountValidationConfig.java @@ -10,8 +10,8 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.DepoAccountNewReq import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.platform.classes.base.SpcexObjectBase; -import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; @@ -56,7 +56,7 @@ public class DepoAccountValidationConfig { ); ImdgPredicateBuilder pb = accountImdg.predicateBuilder(); ImdgPredicate accountValuePredicate = pb.equals("account", accountValue); - ImdgPredicate accountStatusPredicate = pb.equals("status", AccountStatus.ACTIVE.getKey()); + ImdgPredicate accountStatusPredicate = pb.equals("status", ServiceStatus.Active.getKey()); ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Clrn.getKey()); ImdgPredicate finalPredicate = pb.and(accountValuePredicate, accountStatusPredicate, diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java index 4cfd24e05..27e0c6581 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.clearing.platform.dictionary.ServiceStatusDictionary; import ru.clearing.platform.dictionary.WorkflowStatusDictionary; import ru.spcex.clearing.account.errors.AccountError; import ru.spcex.clearing.imdg.IMDGDistributedNames; @@ -15,6 +16,7 @@ import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.validation.ImdgValidationContext; @@ -27,6 +29,71 @@ import java.util.function.Function; @Configuration public class TradingClearingRegistryValidationConfig { + @Bean("tradingClearingRegistryAutoNewRequest") + public Function tradingClearingRegistryAutoNewRequestValidator( + Map> imdgForValidation + ) { + return tradingClearingRegistryAutoNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(tradingClearingRegistryAutoNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_Account); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + return new ValidatorImpl<>(context, + IdPresentRule.instance("companyId", + TradingClearingRegistryNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + AccountError.RequiredFieldEmpty, + AccountError.CompanyNotFound), + FieldRequiredRule.instance("moneyAccountId", + TradingClearingRegistryNewRequest::getMoneyAccountId, + AccountError.RequiredFieldEmpty, + moneyAccountId -> { + Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); + Account account = accountImdg.getSingleObjectByID(moneyAccountId); + if (account == null) return AccountError.AccountNotFound; + return null; + }), + FieldRequiredRule.instance("depoAccountId", + TradingClearingRegistryNewRequest::getDepoAccountId, + AccountError.RequiredFieldEmpty, + false, + depoAccountId -> { + Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); + Account account = accountImdg.getSingleObjectByID(depoAccountId); + if (account == null) return AccountError.AccountNotFound; + return null; + }), + DictionaryPresentRule.instance("status", + TradingClearingRegistryNewRequest::getStatus, + IMDGDistributedNames.Map_ServiceStatusDictionary, + ServiceStatusDictionary.class, + AccountError.RequiredFieldEmpty, + AccountError.WrongFieldValue, + false, + statusValue -> { + Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); + Long moneyAccountId = tradingClearingRegistryAutoNewRequest.getMoneyAccountId(); + Long depoAccountId = tradingClearingRegistryAutoNewRequest.getDepoAccountId(); + Account moneyAccount = accountImdg.getSingleObjectByID(moneyAccountId); + Account depoAccount = depoAccountId != null ? accountImdg.getSingleObjectByID(depoAccountId) : null; + if ( + (depoAccount != null && (ServiceStatus.Active.equalsByKey(depoAccount.getStatus()) || ServiceStatus.Reopened.equalsByKey(depoAccount.getStatus()))) && + (ServiceStatus.Active.equalsByKey(moneyAccount.getStatus()) || ServiceStatus.Reopened.equalsByKey(moneyAccount.getStatus())) + ) { + + } + + String statusCode = statusValue.getCode(); + if (WorkflowStatus.Active.equalsByKey(statusCode)) return null; + return AccountError.WrongFieldValue; + }) + ); + }; + } + @Bean("tradingClearingRegistryNewRequest") public Function tradingClearingRegistryNewRequestValidator( Map> imdgForValidation @@ -66,14 +133,14 @@ public class TradingClearingRegistryValidationConfig { }), DictionaryPresentRule.instance("status", TradingClearingRegistryNewRequest::getStatus, - IMDGDistributedNames.Map_WorkflowStatusDictionary, - WorkflowStatusDictionary.class, + IMDGDistributedNames.Map_ServiceStatusDictionary, + ServiceStatusDictionary.class, AccountError.RequiredFieldEmpty, AccountError.WrongFieldValue, false, statusValue -> { String statusCode = statusValue.getCode(); - if (WorkflowStatus.Active.equalsByKey(statusCode)) return null; + if (ServiceStatus.Active.equalsByKey(statusCode)) return null; return AccountError.WrongFieldValue; }) ); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java index 43cbba292..fd41493df 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java @@ -12,7 +12,7 @@ import ru.clearing.classes.statics.data.company.Company; import ru.clearing.platform.dictionary.AccountTypeDictionary; import ru.clearing.platform.dictionary.ClearingAccountTypeDictionary; import ru.clearing.platform.dictionary.CurrencyCodeDictionary; -import ru.clearing.platform.dictionary.WorkflowStatusDictionary; +import ru.clearing.platform.dictionary.ServiceStatusDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.classes.base.SpcexObjectBase; @@ -41,7 +41,7 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_BankAccount, BankAccount.class); addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class); - addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class); return imdg; } diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java index 81df09673..fdc36e84d 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java @@ -28,8 +28,8 @@ import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; -import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.ClearingCategory; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; @@ -173,7 +173,7 @@ public class AccountService extends QueueConsumer implements InitializingBean { CommonDeleteRequest request = userRequest.getRequestPayload(); Account account = accountMap.getSingleObjectByID(request.getId()); - account.setStatus(AccountStatus.BLOCKED.getKey()); + account.setStatus(ServiceStatus.Blocked.getKey()); account.setUpdated(Instant.now()); accountMap.update(account); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java index 1940cc5a9..de0fb0be8 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java @@ -20,8 +20,8 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer; 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.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; @@ -101,7 +101,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea Account account = new Account(); account.setAccount(req.getAccount()); account.setAccountType(AccountType.Bank.getKey()); - account.setStatus(AccountStatus.ACTIVE.getKey()); + account.setStatus(ServiceStatus.Active.getKey()); account.setCompanyId(req.getCompanyId()); account.setCreated(now); account.setUpdated(now); @@ -207,7 +207,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea BankAccount bankAccount = bankAccountMap.getSingleObjectByID(req.getId()); Account account = accountMap.getSingleObjectByID(bankAccount.getAccountId()); - account.setStatus(AccountStatus.BLOCKED.getKey()); + account.setStatus(ServiceStatus.Blocked.getKey()); account.setUpdated(Instant.now()); ImdgTransaction imdgTransaction = imdgProvider.newTransaction(); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java index 03f148353..a4ceddaa6 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java @@ -20,8 +20,8 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.validation.common.ValidationHelper; -import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; @@ -92,7 +92,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin Account account = new Account(); account.setAccount(req.getAccount()); account.setAccountType(AccountType.Clrn.getKey()); - account.setStatus(AccountStatus.ACTIVE.getKey()); + account.setStatus(ServiceStatus.Active.getKey()); account.setCompanyId(req.getCompanyId()); account.setCreated(now); account.setUpdated(now); @@ -137,7 +137,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin ClearingAccountUpdateRequest req = userRequest.getRequestPayload(); ImdgPredicateBuilder pb = accountImdg.predicateBuilder(); ImdgPredicate accountValuePredicate = pb.equals("account", req.getAccount()); - ImdgPredicate accountStatusPredicate = pb.equals("status", AccountStatus.ACTIVE.getKey()); + ImdgPredicate accountStatusPredicate = pb.equals("status", ServiceStatus.Active.getKey()); ImdgPredicate accountTypePredicate = pb.equals("accountType", AccountType.Clrn.getKey()); ImdgPredicate finalPredicate = pb.and(accountValuePredicate, accountStatusPredicate, @@ -156,9 +156,9 @@ public class ClearingAccountService extends QueueConsumer implements Initializin } Integer statusValue = req.getStatus(); - if (statusValue == 0) account.setStatus(AccountStatus.BLOCKED.getKey()); - else if (statusValue == 1) account.setStatus(AccountStatus.ACTIVE.getKey()); - else if (statusValue == 2) account.setStatus(AccountStatus.CLOSE.getKey()); + if (statusValue == 0) account.setStatus(ServiceStatus.Blocked.getKey()); + else if (statusValue == 1) account.setStatus(ServiceStatus.Active.getKey()); + else if (statusValue == 2) account.setStatus(ServiceStatus.Closed.getKey()); account.setUpdated(Instant.now()); accountImdg.update(account); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java index 625e909f5..719820108 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java @@ -16,8 +16,8 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.DepoAccountNewReq import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.validation.common.ValidationHelper; -import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; @@ -74,7 +74,7 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea Account account = new Account(); account.setAccount(req.getAccount()); account.setAccountType(AccountType.Depo.getKey()); - account.setStatus(AccountStatus.ACTIVE.getKey()); + account.setStatus(ServiceStatus.Active.getKey()); account.setCompanyId(req.getCompanyId()); account.setCreated(now); account.setUpdated(now); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java index 2c74b2086..5bb94636b 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java @@ -19,8 +19,8 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.validation.common.ValidationHelper; -import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; @@ -105,7 +105,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali Account account = new Account(); account.setAccount(accountValue); account.setAccountType(AccountType.Info.getKey()); - account.setStatus(AccountStatus.ACTIVE.getKey()); + account.setStatus(ServiceStatus.Active.getKey()); account.setCompanyId(userRequest.getRequestPayload().getCompanyId()); account.setCreated(now); account.setUpdated(now); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java index 43a903066..cec060ea0 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java @@ -74,6 +74,9 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini @Override public void afterPropertiesSet() throws Exception { init(); + callback(TradingClearingRegistryNewRequest.class) + .setConsumer(this::tradingClearingRegistryAutoNew) + .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, callbacks::put); callback(TradingClearingRegistryNewRequest.class) .setConsumer(this::tradingClearingRegistryNew) .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, callbacks::put); @@ -85,6 +88,16 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, callbacks::put); } + public RequestInfoUpdate tradingClearingRegistryAutoNew(BaseRequest userRequest) { + log.debug("TradingClearingRegistryAutoNewRequest received"); + + + + Long id = null; + log.debug("successfully processed, id {}", id); + return null; + } + public RequestInfoUpdate tradingClearingRegistryNew(BaseRequest userRequest) { log.debug("TradingClearingRegistryNewRequest received"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/AccountServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/AccountServiceTest.java index b2d53c3dc..e0e7383b0 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/AccountServiceTest.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/AccountServiceTest.java @@ -19,6 +19,7 @@ import ru.clearing.classes.statics.data.company.ClearingMemberCategory; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.relation.Relation; import ru.clearing.platform.dictionary.AccountTypeDictionary; +import ru.clearing.platform.dictionary.ServiceStatusDictionary; import ru.spcex.clearing.account.config.BeanConfiguration; import ru.spcex.clearing.account.config.HazelcastServiceTestConfiguration; import ru.spcex.clearing.account.config.KafkaConfigTest; @@ -87,6 +88,7 @@ class AccountServiceTest { private Imdg accountTypeDictionaryImdg; private Imdg clearingMemberCategoryImdg; private Imdg relationImdg; + private Imdg serviceStatusDictionaryImdg; @PostConstruct private void init() { @@ -106,6 +108,13 @@ class AccountServiceTest { relationImdg = hazelcastServiceTest.getImdg( IMDGDistributedNames.Map_Relation, Relation.class ); + serviceStatusDictionaryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class + ); + ServiceStatusDictionary serviceStatusDictionary = new ServiceStatusDictionary(); + serviceStatusDictionary.setCode(ServiceStatus.Active.getKey()); + serviceStatusDictionary.setName(ServiceStatus.Active.getKey()); + serviceStatusDictionaryImdg.insert(serviceStatusDictionary); Company company = new Company(); company.setId(companyId); @@ -137,13 +146,13 @@ class AccountServiceTest { correspondentAccountNewRequest.setAccount(uniqueAccount); correspondentAccountNewRequest.setAccountType(AccountType.Corr.getKey()); correspondentAccountNewRequest.setCompanyId(companyId); - correspondentAccountNewRequest.setStatus(AccountStatus.ACTIVE.getKey()); + correspondentAccountNewRequest.setStatus(ServiceStatus.Active.getKey()); Account predictableAccount = new Account(); predictableAccount.setAccount(uniqueAccount); predictableAccount.setAccountType(AccountType.Corr.getKey()); predictableAccount.setCompanyId(companyId); - predictableAccount.setStatus(AccountStatus.ACTIVE.getKey()); + predictableAccount.setStatus(ServiceStatus.Active.getKey()); predictableAccount.setRelationId(relationId); String jsonString = getJsonStringForNew(correspondentAccountNewRequest, 0L); @@ -169,14 +178,14 @@ class AccountServiceTest { Account existAccount = new Account(); existAccount.setAccount(account); existAccount.setAccountType(AccountType.Corr.getKey()); - existAccount.setStatus(AccountStatus.CLOSE.getKey()); + existAccount.setStatus(ServiceStatus.Closed.getKey()); existAccount.setCompanyId(companyId); Long accountId = accountImdg.insert(existAccount); CorrespondentAccountUpdateRequest correspondentAccountUpdateRequest = new CorrespondentAccountUpdateRequest(); correspondentAccountUpdateRequest.setAccount(account); correspondentAccountUpdateRequest.setAccountType(AccountType.Corr.getKey()); - correspondentAccountUpdateRequest.setStatus(AccountStatus.ACTIVE.getKey()); + correspondentAccountUpdateRequest.setStatus(ServiceStatus.Active.getKey()); correspondentAccountUpdateRequest.setCompanyId(companyId); correspondentAccountUpdateRequest.setId(accountId); @@ -204,7 +213,7 @@ class AccountServiceTest { Account existAccount = new Account(); existAccount.setAccount(account); existAccount.setAccountType(AccountType.Corr.getKey()); - existAccount.setStatus(AccountStatus.ACTIVE.getKey()); + existAccount.setStatus(ServiceStatus.Active.getKey()); existAccount.setCompanyId(companyId); Long accountId = accountImdg.insert(existAccount); @@ -224,7 +233,7 @@ class AccountServiceTest { waitingWhenAddedRecordAndCheckIt(0L, producer, producerRecord); Account resultBlock = accountImdg.getSingleObjectByID(accountId); - existAccount.setStatus(AccountStatus.BLOCKED.getKey()); + existAccount.setStatus(ServiceStatus.Blocked.getKey()); existAccount.setUpdated(resultBlock.getUpdated()); ACCOUNT_MATCHER.assertMatch(existAccount, resultBlock); diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/ClearingAccountServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/ClearingAccountServiceTest.java index da67ac384..45509b2c8 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/ClearingAccountServiceTest.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/ClearingAccountServiceTest.java @@ -156,7 +156,7 @@ class ClearingAccountServiceTest { Account predictableAccount = new Account(); predictableAccount.setAccount(ACCOUNT_VALUE); predictableAccount.setAccountType(AccountType.Clrn.getKey()); - predictableAccount.setStatus(AccountStatus.ACTIVE.getKey()); + predictableAccount.setStatus(ServiceStatus.Active.getKey()); predictableAccount.setRelationId(relationId); predictableAccount.setCompanyId(companyId); @@ -182,7 +182,7 @@ class ClearingAccountServiceTest { void clearingAccountUpdate() { Account existAccount = new Account(); existAccount.setAccount(ACCOUNT_VALUE); - existAccount.setStatus(AccountStatus.ACTIVE.getKey()); + existAccount.setStatus(ServiceStatus.Active.getKey()); existAccount.setAccountType(AccountType.Clrn.getKey()); Long accountId = accountImdg.insert(existAccount); @@ -193,7 +193,7 @@ class ClearingAccountServiceTest { Account predictableAccount = new Account(); predictableAccount.setAccount(ACCOUNT_VALUE); - predictableAccount.setStatus(AccountStatus.BLOCKED.getKey()); + predictableAccount.setStatus(ServiceStatus.Blocked.getKey()); predictableAccount.setAccountType(AccountType.Clrn.getKey()); clearingAccountImdg.insert(existClearingAccount); diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/DepoAccountServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/DepoAccountServiceTest.java index 0d6ea0bcb..79dd222f8 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/DepoAccountServiceTest.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/DepoAccountServiceTest.java @@ -155,7 +155,7 @@ class DepoAccountServiceTest { Account predictableAccount = new Account(); predictableAccount.setAccount(ACCOUNT_VALUE); predictableAccount.setAccountType(AccountType.Depo.getKey()); - predictableAccount.setStatus(AccountStatus.ACTIVE.getKey()); + predictableAccount.setStatus(ServiceStatus.Active.getKey()); predictableAccount.setRelationId(relationId); predictableAccount.setCompanyId(companyId); diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/InformationAccountServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/InformationAccountServiceTest.java index 176245ab5..54879a30b 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/InformationAccountServiceTest.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/InformationAccountServiceTest.java @@ -144,7 +144,7 @@ class InformationAccountServiceTest { Account predictableAccount = new Account(); predictableAccount.setAccountType(AccountType.Info.getKey()); - predictableAccount.setStatus(AccountStatus.ACTIVE.getKey()); + predictableAccount.setStatus(ServiceStatus.Active.getKey()); predictableAccount.setRelationId(relationId); predictableAccount.setCompanyId(companyId); diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index c250e2a6e..d6b06bcf7 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -81,6 +81,7 @@ public interface Consts { String DESTINATION_CLIENT_CODE_UPDATE = "client-code-update"; String DESTINATION_CLIENT_CODE_DELETE = "client-code-delete"; + String DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW = "trading-clearing-registry-auto-new"; String DESTINATION_TRADING_CLEARING_REGISTRY_NEW = "trading-clearing-registry-new"; String DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE = "trading-clearing-registry-update"; String DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK = "trading-clearing-registry-block"; From 9d1a3784472a3ac0f7c94fdba53b72bdd1e126cb Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 5 May 2023 10:45:01 +0300 Subject: [PATCH 10/30] http://jira.mfd.msk:8088/browse/CLS-271 TradingClearingRegistryService --- ...adingClearingRegistryValidationConfig.java | 76 ++--------------- .../TradingClearingRegistryService.java | 83 +++++++++++++------ .../platform/messaging/domain/Consts.java | 1 - 3 files changed, 62 insertions(+), 98 deletions(-) diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java index 27e0c6581..b32ebb6e5 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java @@ -6,7 +6,6 @@ import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.platform.dictionary.ServiceStatusDictionary; -import ru.clearing.platform.dictionary.WorkflowStatusDictionary; import ru.spcex.clearing.account.errors.AccountError; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; @@ -17,7 +16,6 @@ import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.enumeration.ServiceStatus; -import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.utils.validation.IValidator; @@ -29,70 +27,6 @@ import java.util.function.Function; @Configuration public class TradingClearingRegistryValidationConfig { - @Bean("tradingClearingRegistryAutoNewRequest") - public Function tradingClearingRegistryAutoNewRequestValidator( - Map> imdgForValidation - ) { - return tradingClearingRegistryAutoNewRequest -> { - ImdgValidationContext context = new ImdgValidationContext<>(); - context.setValidatedObject(tradingClearingRegistryAutoNewRequest); - Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); - addImdg.accept(IMDGDistributedNames.Map_Company); - addImdg.accept(IMDGDistributedNames.Map_Account); - addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); - return new ValidatorImpl<>(context, - IdPresentRule.instance("companyId", - TradingClearingRegistryNewRequest::getCompanyId, - IMDGDistributedNames.Map_Company, - Company.class, - AccountError.RequiredFieldEmpty, - AccountError.CompanyNotFound), - FieldRequiredRule.instance("moneyAccountId", - TradingClearingRegistryNewRequest::getMoneyAccountId, - AccountError.RequiredFieldEmpty, - moneyAccountId -> { - Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); - Account account = accountImdg.getSingleObjectByID(moneyAccountId); - if (account == null) return AccountError.AccountNotFound; - return null; - }), - FieldRequiredRule.instance("depoAccountId", - TradingClearingRegistryNewRequest::getDepoAccountId, - AccountError.RequiredFieldEmpty, - false, - depoAccountId -> { - Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); - Account account = accountImdg.getSingleObjectByID(depoAccountId); - if (account == null) return AccountError.AccountNotFound; - return null; - }), - DictionaryPresentRule.instance("status", - TradingClearingRegistryNewRequest::getStatus, - IMDGDistributedNames.Map_ServiceStatusDictionary, - ServiceStatusDictionary.class, - AccountError.RequiredFieldEmpty, - AccountError.WrongFieldValue, - false, - statusValue -> { - Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); - Long moneyAccountId = tradingClearingRegistryAutoNewRequest.getMoneyAccountId(); - Long depoAccountId = tradingClearingRegistryAutoNewRequest.getDepoAccountId(); - Account moneyAccount = accountImdg.getSingleObjectByID(moneyAccountId); - Account depoAccount = depoAccountId != null ? accountImdg.getSingleObjectByID(depoAccountId) : null; - if ( - (depoAccount != null && (ServiceStatus.Active.equalsByKey(depoAccount.getStatus()) || ServiceStatus.Reopened.equalsByKey(depoAccount.getStatus()))) && - (ServiceStatus.Active.equalsByKey(moneyAccount.getStatus()) || ServiceStatus.Reopened.equalsByKey(moneyAccount.getStatus())) - ) { - - } - - String statusCode = statusValue.getCode(); - if (WorkflowStatus.Active.equalsByKey(statusCode)) return null; - return AccountError.WrongFieldValue; - }) - ); - }; - } @Bean("tradingClearingRegistryNewRequest") public Function tradingClearingRegistryNewRequestValidator( @@ -104,7 +38,7 @@ public class TradingClearingRegistryValidationConfig { Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); addImdg.accept(IMDGDistributedNames.Map_Company); addImdg.accept(IMDGDistributedNames.Map_Account); - addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary); return new ValidatorImpl<>(context, IdPresentRule.instance("companyId", TradingClearingRegistryNewRequest::getCompanyId, @@ -131,6 +65,8 @@ public class TradingClearingRegistryValidationConfig { if (account == null) return AccountError.AccountNotFound; return null; }), + // todo на будущее: нужна ли эта проверка, если при добавлении регистра статус заполняется автоматически + // на основе полей moneyAccountId и depoAccountId, то же касается TradingClearingRegistryNewRequest, нужно ли там поле status DictionaryPresentRule.instance("status", TradingClearingRegistryNewRequest::getStatus, IMDGDistributedNames.Map_ServiceStatusDictionary, @@ -155,7 +91,7 @@ public class TradingClearingRegistryValidationConfig { ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(tradingClearingRegistryUpdateRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); - addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary); addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry); return new ValidatorImpl<>(context, IdPresentRule.instance("id", @@ -166,8 +102,8 @@ public class TradingClearingRegistryValidationConfig { AccountError.TradingClearingRegistryNotFound), DictionaryPresentRule.instance("status", TradingClearingRegistryUpdateRequest::getStatus, - IMDGDistributedNames.Map_WorkflowStatusDictionary, - WorkflowStatusDictionary.class, + IMDGDistributedNames.Map_ServiceStatusDictionary, + ServiceStatusDictionary.class, AccountError.RequiredFieldEmpty, AccountError.WrongFieldValue, false) diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java index cec060ea0..c4855b536 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java @@ -7,10 +7,12 @@ 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.account.Account; import ru.clearing.classes.statics.data.account.ClearingAccount; import ru.clearing.classes.statics.data.account.DepoAccount; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.spcex.clearing.account.errors.AccountError; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -19,15 +21,20 @@ import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingR import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.TradingClearingRegistryPurpose; -import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; +import java.util.Arrays; +import java.util.List; import java.util.function.Function; @Service @@ -40,23 +47,27 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini private final Imdg tradingClearingRegistryImdg; private final Imdg depoAccountImdg; private final Imdg clearingAccountImdg; + private final Imdg accountImdg; private final Imdg companyImdg; private final Function tradingClearingRegistryUpdateRequestValidator; private final Function tradingClearingRegistryNewRequestValidator; private final Function tradingClearingRegistryBlockRequestValidator; + private final IMessageResolver messageResolver; + public TradingClearingRegistryService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, ValidationHelper validationHelper, UserRoleVerification userRoleVerification, + IMessageResolver messageResolver, @Qualifier("tradingClearingRegistryNewRequest") Function tradingClearingRegistryNewRequestValidator, @Qualifier("tradingClearingRegistryUpdateRequest") Function tradingClearingRegistryUpdateRequestValidator, @Qualifier("tradingClearingRegistryBlockRequest") - Function tradingClearingRegistryBlockRequestValidator) { + Function tradingClearingRegistryBlockRequestValidator) { super(kafkaQueue, kafkaProducer); this.validationHelper = validationHelper; this.userRoleVerification = userRoleVerification; @@ -67,16 +78,15 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini this.depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class); this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class); this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); this.tradingClearingRegistryUpdateRequestValidator = tradingClearingRegistryUpdateRequestValidator; this.tradingClearingRegistryBlockRequestValidator = tradingClearingRegistryBlockRequestValidator; + this.messageResolver = messageResolver; } @Override public void afterPropertiesSet() throws Exception { init(); - callback(TradingClearingRegistryNewRequest.class) - .setConsumer(this::tradingClearingRegistryAutoNew) - .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, callbacks::put); callback(TradingClearingRegistryNewRequest.class) .setConsumer(this::tradingClearingRegistryNew) .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, callbacks::put); @@ -88,18 +98,8 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, callbacks::put); } - public RequestInfoUpdate tradingClearingRegistryAutoNew(BaseRequest userRequest) { - log.debug("TradingClearingRegistryAutoNewRequest received"); - - - - Long id = null; - log.debug("successfully processed, id {}", id); - return null; - } - public RequestInfoUpdate tradingClearingRegistryNew(BaseRequest userRequest) { - log.debug("TradingClearingRegistryNewRequest received"); + log.debug("TradingClearingRegistryAutoNewRequest received"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); if (requestInfoUpdate != null) return requestInfoUpdate; @@ -114,18 +114,46 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini tradingClearingRegistry.setCompanyId(req.getCompanyId()); tradingClearingRegistry.setMoneyAccountId(req.getMoneyAccountId()); tradingClearingRegistry.setDepoAaccountId(req.getDepoAccountId()); - tradingClearingRegistry.setStatus(WorkflowStatus.Active.getKey()); - // todo tradingClearingRegistryType из соответствующего параметра очереди но в запросе он не фигурирует - // пока оставил вычисление аналогичное автоматическому добавлению ТКР - String tradingRegistryType; - if (req.getDepoAccountId() != null) { - DepoAccount depoAccount = depoAccountImdg.getSingleObjectByID(req.getDepoAccountId()); - tradingRegistryType = depoAccount.getDepoAccountType(); + DepoAccount depoAccount = req.getDepoAccountId() != null ? depoAccountImdg.getSingleObjectByID(req.getDepoAccountId()) : null; + Account depoAccountMain = depoAccount != null ? accountImdg.getSingleObjectByID(depoAccount.getAccountId()) : null; + + ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(req.getMoneyAccountId()); + Account clearingAccountMain = accountImdg.getSingleObjectByID(clearingAccount.getAccountId()); + + List activeStatuses = Arrays.asList(ServiceStatus.Active.getKey(), ServiceStatus.Reopened.getKey()); + String status = null; + if (depoAccountMain != null) { + if (activeStatuses.contains(depoAccountMain.getStatus()) && activeStatuses.contains(clearingAccountMain.getStatus())) + status = ServiceStatus.Active.getKey(); + if (depoAccountMain.getStatus().equals(ServiceStatus.Blocked.getKey()) || clearingAccountMain.getStatus().equals(ServiceStatus.Blocked.getKey())) + status = ServiceStatus.Blocked.getKey(); + if (depoAccountMain.getStatus().equals(ServiceStatus.Suspended.getKey()) || clearingAccountMain.getStatus().equals(ServiceStatus.Suspended.getKey())) + status = ServiceStatus.Suspended.getKey(); + if (depoAccountMain.getStatus().equals(ServiceStatus.Closed.getKey()) || clearingAccountMain.getStatus().equals(ServiceStatus.Closed.getKey())) + status = ServiceStatus.Closed.getKey(); } else { - ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(req.getMoneyAccountId()); - tradingRegistryType = clearingAccount.getClearingAccountType(); + if (activeStatuses.contains(clearingAccountMain.getStatus())) + status = ServiceStatus.Active.getKey(); + if (clearingAccountMain.getStatus().equals(ServiceStatus.Blocked.getKey())) + status = ServiceStatus.Blocked.getKey(); + if (clearingAccountMain.getStatus().equals(ServiceStatus.Suspended.getKey())) + status = ServiceStatus.Suspended.getKey(); + if (clearingAccountMain.getStatus().equals(ServiceStatus.Closed.getKey())) + status = ServiceStatus.Closed.getKey(); } + if (status == null) { + String errMsg = messageResolver.resolve(new EnumMessage(AccountError.WrongFieldValue, req.getMoneyAccountId())); + return new RequestInfoUpdate() + .setStatus(Status.Error) + .setMessage(errMsg) + .setId(userRequest.getId()); + } + tradingClearingRegistry.setStatus(status); + + String tradingRegistryType; + if (depoAccount != null) tradingRegistryType = depoAccount.getDepoAccountType(); + else tradingRegistryType = clearingAccount.getClearingAccountType(); tradingClearingRegistry.setTradingClearingRegistryType(tradingRegistryType); TradingClearingRegistryPurpose registryPurpose; @@ -134,7 +162,8 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini tradingClearingRegistry.setTradingClearingRegistryPurpose(registryPurpose.getKey()); Company company = companyImdg.getSingleObjectByID(req.getCompanyId()); - String code = company.getClearingCode() + registryPurpose.getKey() + registryPurpose; + String code = "%4s".formatted(company.getClearingCode()).replace(' ', '0'); + code += registryPurpose.getKey(); if (registryPurpose == TradingClearingRegistryPurpose.C) code += tradingRegistryType + id; else code += "AT" + id; tradingClearingRegistry.setCode(code); @@ -182,7 +211,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini CommonDeleteRequest req = userRequest.getRequestPayload(); TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getSingleObjectByID(req.getId()); - tradingClearingRegistry.setStatus(WorkflowStatus.Blocked.getKey()); + tradingClearingRegistry.setStatus(ServiceStatus.Blocked.getKey()); tradingClearingRegistryImdg.update(tradingClearingRegistry); diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index d6b06bcf7..c250e2a6e 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -81,7 +81,6 @@ public interface Consts { String DESTINATION_CLIENT_CODE_UPDATE = "client-code-update"; String DESTINATION_CLIENT_CODE_DELETE = "client-code-delete"; - String DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW = "trading-clearing-registry-auto-new"; String DESTINATION_TRADING_CLEARING_REGISTRY_NEW = "trading-clearing-registry-new"; String DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE = "trading-clearing-registry-update"; String DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK = "trading-clearing-registry-block"; From cdd6a0996fc12d1b88d41a1e5c9a9992b7825bab Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 5 May 2023 11:57:49 +0300 Subject: [PATCH 11/30] =?UTF-8?q?QueueConsumer=20=D1=83=D0=BB=D1=83=D1=87?= =?UTF-8?q?=D1=88=D0=B8=D0=BB=20=D0=BB=D0=BE=D0=B3=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA?= =?UTF-8?q?.=20IMDGMessageResolver=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BD=D0=B0=D0=B4=D1=91=D0=B6=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=B8=20=D0=BF=D1=80=D0=B8=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA?= =?UTF-8?q?=D0=B0=D1=85=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BE=D0=BA.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/services/IMDGMessageResolver.java | 17 +++++++++++------ .../messaging/service/QueueConsumer.java | 5 ++++- 2 files changed, 15 insertions(+), 7 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 97dfbf8cf..3d64121d6 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 @@ -1,5 +1,6 @@ package ru.spcex.clearing.util.services; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.clearing.platform.dictionary.ErrorCodeDictionary; @@ -25,13 +26,17 @@ public class IMDGMessageResolver implements IMessageResolver { @Override public String resolve(EnumMessage errorMessage) { if (errorMessage == null) return "null"; - - ErrorCodeDictionary errorDictionary = errorCodeDictionaryIMDG.getSingleObjectByID(errorMessage.getSubject().getId()); - if (errorDictionary == null) { - log.warn("ERROR_CODE_DICTIONARY not found fo id={}", errorMessage.getSubject().getId()); + try { + ErrorCodeDictionary errorDictionary = errorCodeDictionaryIMDG.getSingleObjectByID(errorMessage.getSubject().getId()); + if (errorDictionary == null) { + log.warn("ERROR_CODE_DICTIONARY not found fo id={}", errorMessage.getSubject().getId()); + return String.format("(%d) args %s", errorMessage.getSubject().getId(), Arrays.toString(errorMessage.getArgs())); + } + String textTemplate = errorDictionary.getName(); + return String.format(textTemplate, errorMessage.getArgs()); + } catch (Exception errFormatting) { // MissingFormatArgumentException + log.warn("Error in message resolver for error {}: {}", errorMessage.getSubject(), ExceptionUtils.getStackTrace(errFormatting)); return String.format("(%d) args %s", errorMessage.getSubject().getId(), Arrays.toString(errorMessage.getArgs())); } - String textTemplate = errorDictionary.getName(); - return String.format(textTemplate, errorMessage.getArgs()); } } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java index 3f7afe713..380250d37 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/service/QueueConsumer.java @@ -83,9 +83,11 @@ public class QueueConsumer implements AutoCloseable { Object o = null; int lastErrors = 0; while (!closed.get()) { + String lastTopic = null; try { ConsumerRecords records = consumer.poll(Duration.of(10, ChronoUnit.SECONDS)); for (ConsumerRecord next : records) { + lastTopic = next.topic(); ConsumerSpecificClass callback = callbacks.get(next.topic()); Class clazz = callback.getClazz(); JavaType payloadType = json.getTypeFactory().constructParametricType(BaseRequest.class, clazz); @@ -99,7 +101,8 @@ public class QueueConsumer implements AutoCloseable { } lastErrors = 0; } catch (Throwable e) { - log.error(ExceptionUtils.getStackTrace(e)); + log.error("Listener {} last topic \"{}\", error: {}", + QueueConsumer.this.getClass().getName(), lastTopic, ExceptionUtils.getStackTrace(e)); if (producer != null && o != null) { sendErrorResponse((BaseRequest) o); } From 1b98981c9f2977513af0682906f31d5774909ab7 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 5 May 2023 12:48:07 +0300 Subject: [PATCH 12/30] =?UTF-8?q?company-service=20http://jira.mfd.msk:808?= =?UTF-8?q?8/browse/CLS-259=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validation/ContactValidationConfig.java | 2 +- .../ProfileDocumentValidationConfig.java | 12 ++++- .../company/service/CompanyInfoService.java | 47 +++++++++++++++++-- .../service/ProfileDocumentService.java | 6 ++- .../service/CompanySymbolServiceTest.java | 9 ++++ 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ContactValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ContactValidationConfig.java index f92635d78..a69e7731c 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ContactValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ContactValidationConfig.java @@ -73,7 +73,7 @@ public class ContactValidationConfig { IMDGDistributedNames.Map_Contact, Contact.class, CompanyErrors.RequiredFieldEmpty, - CompanyErrors.CompanyNotFound, + CompanyErrors.ContactNotFound, contact -> { if (contactUpdateRequest.getContactType() == null) return null; if (!contactUpdateRequest.getContactType().equalsIgnoreCase(contact.getContactType())) { 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 9fe82a927..5449f8f9e 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 @@ -44,7 +44,7 @@ public class ProfileDocumentValidationConfig { Company.class, CompanyErrors.RequiredFieldEmpty, CompanyErrors.CompanyNotFound, - company -> WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled), + company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled), DictionaryPresentRule.instance("documentType", ProfileDocumentNewRequest::getDocumentType, IMDGDistributedNames.Map_DocumentTypeDictionary, @@ -138,7 +138,15 @@ public class ProfileDocumentValidationConfig { IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class, CompanyErrors.RequiredFieldEmpty, - CompanyErrors.RecordNotFound) + CompanyErrors.RecordNotFound, + profileDoc -> { + Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); + Company company = companyImdg.getSingleObjectByID(profileDoc.getCompanyId()); + if (company == null) { + return CompanyErrors.CompanyNotFound; + } + return null; + }) ); }; } diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java index 7dd8ba584..0beb21c0a 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java @@ -22,14 +22,18 @@ 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.ImdgProvider; +import ru.spcex.platform.imdg.api.ImdgTransaction; +import ru.spcex.platform.utils.error.ValidationException; import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; +import java.util.Objects; import java.util.function.Function; @Service public class CompanyInfoService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); + private final ImdgProvider imdgProvider; private final Imdg companyMap; protected final CompanyService companyService; private final RequestHelper requestHelper; @@ -46,6 +50,7 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea Function companyInfoUpdateRequestValidator) { super(kafkaQueue, kafkaProducer); this.companyService = companyService; + this.imdgProvider = imdgProvider; this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.validationHelper = validationHelper; this.userRoleVerification = userRoleVerification; @@ -56,16 +61,16 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea @Override public void afterPropertiesSet() { callback(CompanyInfoUpdateRequest.class) - .setFunction(this::companyInfoUpdate) + .setFunction(request -> requestHelper.requestFunction(this::companyInfoUpdate, request)) .forDestination(Consts.DESTINATION_COMPANY_INFO_UPDATE, callbacks::put); callback(CompanyInfoUpdateRequest.class) - .setFunction(this::companyInfoUpdate) + .setFunction(request -> requestHelper.requestFunction(this::companyInfoUpdate, request)) .forDestination(Consts.DESTINATION_COMPANY_INFO_NEW, callbacks::put); // логика заполнения одинакова с companyInfoUpdate init(); } - public RequestInfoUpdate companyInfoUpdate(BaseRequest companyInfoReq) { + public RequestInfoUpdate companyInfoUpdate(BaseRequest companyInfoReq) throws ValidationException { CompanyInfoUpdateRequest req = companyInfoReq.getRequestPayload(); log.debug("{} received", req.getClass().getSimpleName()); { // Валидация, ValidationException @@ -81,6 +86,7 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea log.trace("Company {} not found", req.getId()); return requestHelper.makeErrorResponse(companyInfoReq, CompanyErrors.CompanyNotFound, companyInfoReq.getId()); } + company.setUpdated(Instant.now()); CompanyInfo companyInfo = company.getProfile(); companyInfo.setCorporationSoleType(req.getCorporationSoleType()); @@ -93,8 +99,39 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea companyInfo.setShortNameEng(req.getShortNameEng()); companyInfo.setFullNameEng(req.getFullNameEng()); - company.setUpdated(Instant.now()); - companyMap.update(company); + company.setShortName(req.getShortName()); + company.setFullName(req.getFullName()); + boolean simpleUpdate = true; + if (req.getWorkflowStatus() != null) { + String prevStatus = company.getWorkflowStatus(); + company.setWorkflowStatus(req.getWorkflowStatus()); + if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { + simpleUpdate = false; + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + companyService.relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + Imdg txCompanyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); + txCompanyMap.update(company); + log.trace("Company {} updated", company.getId()); + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + } else { + log.trace("Status was not changed"); + } + } else { + log.trace("Null new WorkflowStatus"); + } + if (simpleUpdate) { + companyMap.update(company); + log.trace("Company {} updated", company.getId()); + } log.debug("successfully CompanyInfo processed, id {}", companyInfo.getId()); } return null; diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java index 411cfd669..adf51b4ed 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java @@ -174,8 +174,10 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin ProfileDocument profileDocument = profileDocumentMap.getSingleObjectByID(profileDocumentUpdateRequest.getId()); String prevDocType = profileDocument.getDocumentType(); - if (profileDocumentUpdateRequest.getCompanyId() != null) - profileDocument.setCompanyId(profileDocumentUpdateRequest.getCompanyId()); + if (profileDocumentUpdateRequest.getCompanyId() != null && !profileDocumentUpdateRequest.getCompanyId().equals(profileDocument.getCompanyId())) { + log.warn("profileDocumentUpdateRequest[{}] CompanyId {} not match", profileDocumentUpdateRequest.getId(), profileDocumentUpdateRequest.getCompanyId()); + return requestHelper.makeErrorResponse(profileDocumentUpdateRequestBaseRequest, CompanyErrors.WrongFieldValue, "companyId"); + } if (profileDocumentUpdateRequest.getDocumentType() != null) profileDocument.setDocumentType(profileDocumentUpdateRequest.getDocumentType()); diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java index e247fb26a..98383d456 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java @@ -12,6 +12,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; +import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.clearing.platform.dictionary.CompanySymbolDictionary; import ru.spcex.clearing.company.config.BeanConfiguration; @@ -92,6 +93,14 @@ class CompanySymbolServiceTest { cioSymbol.setName(CompanySymbol.CIO.getKey()); companySymbolDictionaryImdg.insert(cioSymbol); } + Imdg companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + { + Company company = new Company(); + company.setId(ID); + company.setShortName("TST"); + company.setWorkflowStatus("ACTV"); + companyImdg.insert(company); + } TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); From 31950816619fb1cd6509733fad20e4b8f71ee283 Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 5 May 2023 13:59:43 +0300 Subject: [PATCH 13/30] http://jira.mfd.msk:8088/browse/CLS-271 TradingClearingRegistryServiceTest --- .../validation/AccountValidationConfig.java | 8 +- .../BankAccountValidationConfig.java | 8 +- ...adingClearingRegistryValidationConfig.java | 29 +- .../config/validation/ValidationConfig.java | 8 +- .../account/service/AccountService.java | 12 +- .../account/service/BankAccountService.java | 14 +- .../TradingClearingRegistryService.java | 19 +- .../TradingClearingRegistryServiceTest.java | 261 ++++++++++++++++++ 8 files changed, 313 insertions(+), 46 deletions(-) create mode 100644 clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java index 8f9cd76eb..f1a5f0293 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java @@ -10,7 +10,7 @@ import ru.spcex.clearing.account.errors.AccountError; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountUpdateRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule; @@ -153,17 +153,17 @@ public class AccountValidationConfig { } @Bean("correspondentAccountBlockRequestValidator") - public Function correspondentAccountBlockRequestValidator( + public Function correspondentAccountBlockRequestValidator( Map> imdgForValidation ) { return correspondentAccountBlockRequest -> { - ImdgValidationContext context = new ImdgValidationContext<>(); + ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(correspondentAccountBlockRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); addImdg.accept(IMDGDistributedNames.Map_Account); return new ValidatorImpl<>(context, IdPresentRule.instance("id", - CommonDeleteRequest::getId, + CommonIdRequest::getId, IMDGDistributedNames.Map_Account, Account.class, AccountError.RequiredFieldEmpty, 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 c4c350bb4..3c6b00d6e 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 @@ -10,7 +10,7 @@ import ru.spcex.clearing.account.errors.AccountError; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountUpdateRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule; @@ -132,18 +132,18 @@ public class BankAccountValidationConfig { } @Bean("bankAccountBlockRequestValidator") - public Function bankAccountBlockRequestValidator( + public Function bankAccountBlockRequestValidator( Map> imdgForValidation ) { return bankAccountBlockRequest -> { - ImdgValidationContext context = new ImdgValidationContext<>(); + ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(bankAccountBlockRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); addImdg.accept(IMDGDistributedNames.Map_BankAccount); addImdg.accept(IMDGDistributedNames.Map_Account); return new ValidatorImpl<>(context, IdPresentRule.instance("id", - CommonDeleteRequest::getId, + CommonIdRequest::getId, IMDGDistributedNames.Map_BankAccount, BankAccount.class, AccountError.RequiredFieldEmpty, diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java index b32ebb6e5..32fb2f34f 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java @@ -2,13 +2,14 @@ package ru.spcex.clearing.account.config.validation; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -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.company.Company; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.platform.dictionary.ServiceStatusDictionary; import ru.spcex.clearing.account.errors.AccountError; import ru.spcex.clearing.imdg.IMDGDistributedNames; -import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; @@ -37,7 +38,8 @@ public class TradingClearingRegistryValidationConfig { context.setValidatedObject(tradingClearingRegistryNewRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); addImdg.accept(IMDGDistributedNames.Map_Company); - addImdg.accept(IMDGDistributedNames.Map_Account); + addImdg.accept(IMDGDistributedNames.Map_ClearingAccount); + addImdg.accept(IMDGDistributedNames.Map_DepoAccount); addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary); return new ValidatorImpl<>(context, IdPresentRule.instance("companyId", @@ -50,9 +52,11 @@ public class TradingClearingRegistryValidationConfig { TradingClearingRegistryNewRequest::getMoneyAccountId, AccountError.RequiredFieldEmpty, moneyAccountId -> { - Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); - Account account = accountImdg.getSingleObjectByID(moneyAccountId); - if (account == null) return AccountError.AccountNotFound; + Imdg clearingAccountImdg = context.obtainMap( + IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class + ); + ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(moneyAccountId); + if (clearingAccount == null) return AccountError.AccountNotFound; return null; }), FieldRequiredRule.instance("depoAccountId", @@ -60,9 +64,10 @@ public class TradingClearingRegistryValidationConfig { AccountError.RequiredFieldEmpty, false, depoAccountId -> { - Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); - Account account = accountImdg.getSingleObjectByID(depoAccountId); - if (account == null) return AccountError.AccountNotFound; + if (depoAccountId == null) return null; + Imdg depoAccountImdg = context.obtainMap(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class); + DepoAccount depoAccount = depoAccountImdg.getSingleObjectByID(depoAccountId); + if (depoAccount == null) return AccountError.AccountNotFound; return null; }), // todo на будущее: нужна ли эта проверка, если при добавлении регистра статус заполняется автоматически @@ -112,17 +117,17 @@ public class TradingClearingRegistryValidationConfig { } @Bean("tradingClearingRegistryBlockRequest") - public Function tradingClearingRegistryBlockRequestValidator( + public Function tradingClearingRegistryBlockRequestValidator( Map> imdgForValidation ) { return tradingClearingRegistryBlockRequest -> { - ImdgValidationContext context = new ImdgValidationContext<>(); + ImdgValidationContext context = new ImdgValidationContext<>(); context.setValidatedObject(tradingClearingRegistryBlockRequest); Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry); return new ValidatorImpl<>(context, IdPresentRule.instance("id", - CommonDeleteRequest::getId, + CommonIdRequest::getId, IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class, AccountError.RequiredFieldEmpty, diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java index fd41493df..6fedb6269 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ValidationConfig.java @@ -3,12 +3,10 @@ package ru.spcex.clearing.account.config.validation; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import ru.clearing.classes.statics.data.account.Account; -import ru.clearing.classes.statics.data.account.BankAccount; -import ru.clearing.classes.statics.data.account.ClearingAccount; -import ru.clearing.classes.statics.data.account.InformationAccount; +import ru.clearing.classes.statics.data.account.*; import ru.clearing.classes.statics.data.company.ClearingMemberCategory; import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.clearing.platform.dictionary.AccountTypeDictionary; import ru.clearing.platform.dictionary.ClearingAccountTypeDictionary; import ru.clearing.platform.dictionary.CurrencyCodeDictionary; @@ -41,7 +39,9 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_BankAccount, BankAccount.class); addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class); + addImdg.accept(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class); addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class); + addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); return imdg; } diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java index fdc36e84d..ff1aeb8b7 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java @@ -21,7 +21,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf0 import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart; import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountSdfToStatementRequestPart; import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; @@ -57,7 +57,7 @@ public class AccountService extends QueueConsumer implements InitializingBean { private final ValidationHelper validationHelper; private final Function accountNewRequestValidator; private final Function accountUpdateRequestValidator; - private final Function accountBlockRequestValidator; + private final Function accountBlockRequestValidator; @Autowired public AccountService(Consumer kafkaQueue, @@ -72,7 +72,7 @@ public class AccountService extends QueueConsumer implements InitializingBean { @Qualifier("correspondentAccountUpdateRequestValidator") Function accountUpdateRequestValidator, @Qualifier("correspondentAccountBlockRequestValidator") - Function accountBlockRequestValidator) { + Function accountBlockRequestValidator) { super(kafkaQueue, kafkaProducer); this.accountMap = imdgProvider.getImdg( IMDGDistributedNames.Map_Account, Account.class @@ -103,7 +103,7 @@ public class AccountService extends QueueConsumer implements InitializingBean { callback(CorrespondentAccountUpdateRequest.class) .setConsumer(this::correspondentAccountUpdate) .forDestination(Consts.DESTINATION_CORRESPONDENT_ACCOUNT_UPDATE, callbacks::put); - callback(CommonDeleteRequest.class) + callback(CommonIdRequest.class) .setConsumer(this::correspondentAccountBlock) .forDestination(Consts.DESTINATION_CORRESPONDENT_ACCOUNT_BLOCK, callbacks::put); init(); @@ -161,7 +161,7 @@ public class AccountService extends QueueConsumer implements InitializingBean { return null; } - public RequestInfoUpdate correspondentAccountBlock(BaseRequest userRequest) { + public RequestInfoUpdate correspondentAccountBlock(BaseRequest userRequest) { log.debug("AccountBlockRequest received"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); @@ -170,7 +170,7 @@ public class AccountService extends QueueConsumer implements InitializingBean { requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, accountBlockRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; - CommonDeleteRequest request = userRequest.getRequestPayload(); + CommonIdRequest request = userRequest.getRequestPayload(); Account account = accountMap.getSingleObjectByID(request.getId()); account.setStatus(ServiceStatus.Blocked.getKey()); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java index de0fb0be8..bff14701c 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java @@ -15,7 +15,7 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountUpdateRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.util.security.UserRoleVerification; @@ -44,7 +44,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea private final Function bankAccountNewRequestValidator; private final Function bankAccountUpdateRequestValidator; - private final Function bankAccountBlockRequestValidator; + private final Function bankAccountBlockRequestValidator; @Autowired public BankAccountService(Consumer kafkaQueue, @@ -58,7 +58,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea @Qualifier("bankAccountUpdateRequestValidator") Function bankAccountUpdateRequestValidator, @Qualifier("bankAccountBlockRequestValidator") - Function bankAccountBlockRequestValidator) { + Function bankAccountBlockRequestValidator) { super(kafkaQueue, kafkaProducer); this.bankAccountMap = imdgProvider.getImdg(IMDGDistributedNames.Map_BankAccount, BankAccount.class); this.accountMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); @@ -79,7 +79,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea callback(BankAccountUpdateRequest.class) .setFunction(this::bankAccountUpdate) .forDestination(Consts.DESTINATION_BANK_ACCOUNT_UPDATE, callbacks::put); - callback(CommonDeleteRequest.class) + callback(CommonIdRequest.class) .setFunction(this::bankAccountBlock) .forDestination(Consts.DESTINATION_BANK_ACCOUNT_BLOCK, callbacks::put); init(); @@ -194,8 +194,8 @@ public class BankAccountService extends QueueConsumer implements InitializingBea return null; } - private RequestInfoUpdate bankAccountBlock(BaseRequest userRequest) { - CommonDeleteRequest req = userRequest.getRequestPayload(); + private RequestInfoUpdate bankAccountBlock(BaseRequest userRequest) { + CommonIdRequest req = userRequest.getRequestPayload(); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); if (requestInfoUpdate != null) return requestInfoUpdate; @@ -203,7 +203,7 @@ public class BankAccountService extends QueueConsumer implements InitializingBea requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, bankAccountBlockRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; - log.debug("CommonDeleteRequest received id = {}", req.getId()); + log.debug("CommonIdRequest received id = {}", req.getId()); BankAccount bankAccount = bankAccountMap.getSingleObjectByID(req.getId()); Account account = accountMap.getSingleObjectByID(bankAccount.getAccountId()); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java index c4855b536..aaafb6972 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java @@ -16,7 +16,7 @@ import ru.spcex.clearing.account.errors.AccountError; 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.common.CommonIdRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; @@ -52,7 +52,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini private final Function tradingClearingRegistryUpdateRequestValidator; private final Function tradingClearingRegistryNewRequestValidator; - private final Function tradingClearingRegistryBlockRequestValidator; + private final Function tradingClearingRegistryBlockRequestValidator; private final IMessageResolver messageResolver; @@ -67,7 +67,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini @Qualifier("tradingClearingRegistryUpdateRequest") Function tradingClearingRegistryUpdateRequestValidator, @Qualifier("tradingClearingRegistryBlockRequest") - Function tradingClearingRegistryBlockRequestValidator) { + Function tradingClearingRegistryBlockRequestValidator) { super(kafkaQueue, kafkaProducer); this.validationHelper = validationHelper; this.userRoleVerification = userRoleVerification; @@ -93,13 +93,13 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini callback(TradingClearingRegistryUpdateRequest.class) .setConsumer(this::tradingClearingRegistryUpdate) .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE, callbacks::put); - callback(CommonDeleteRequest.class) + callback(CommonIdRequest.class) .setConsumer(this::tradingClearingRegistryBlock) .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, callbacks::put); } public RequestInfoUpdate tradingClearingRegistryNew(BaseRequest userRequest) { - log.debug("TradingClearingRegistryAutoNewRequest received"); + log.debug("TradingClearingRegistryNewRequest received"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); if (requestInfoUpdate != null) return requestInfoUpdate; @@ -123,7 +123,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini List activeStatuses = Arrays.asList(ServiceStatus.Active.getKey(), ServiceStatus.Reopened.getKey()); String status = null; - if (depoAccountMain != null) { + if (depoAccountMain != null && depoAccountMain.getStatus() != null) { if (activeStatuses.contains(depoAccountMain.getStatus()) && activeStatuses.contains(clearingAccountMain.getStatus())) status = ServiceStatus.Active.getKey(); if (depoAccountMain.getStatus().equals(ServiceStatus.Blocked.getKey()) || clearingAccountMain.getStatus().equals(ServiceStatus.Blocked.getKey())) @@ -132,7 +132,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini status = ServiceStatus.Suspended.getKey(); if (depoAccountMain.getStatus().equals(ServiceStatus.Closed.getKey()) || clearingAccountMain.getStatus().equals(ServiceStatus.Closed.getKey())) status = ServiceStatus.Closed.getKey(); - } else { + } else if (clearingAccountMain.getStatus() != null) { if (activeStatuses.contains(clearingAccountMain.getStatus())) status = ServiceStatus.Active.getKey(); if (clearingAccountMain.getStatus().equals(ServiceStatus.Blocked.getKey())) @@ -200,7 +200,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini return null; } - public RequestInfoUpdate tradingClearingRegistryBlock(BaseRequest userRequest) { + public RequestInfoUpdate tradingClearingRegistryBlock(BaseRequest userRequest) { log.debug("TradingClearingRegistryBlockRequest received"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); if (requestInfoUpdate != null) return requestInfoUpdate; @@ -208,10 +208,11 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryBlockRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; - CommonDeleteRequest req = userRequest.getRequestPayload(); + CommonIdRequest req = userRequest.getRequestPayload(); TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getSingleObjectByID(req.getId()); tradingClearingRegistry.setStatus(ServiceStatus.Blocked.getKey()); + tradingClearingRegistry.setUpdated(Instant.now()); tradingClearingRegistryImdg.update(tradingClearingRegistry); diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java new file mode 100644 index 000000000..7704cf73b --- /dev/null +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java @@ -0,0 +1,261 @@ +package ru.spcex.clearing.account.service; + +import org.apache.kafka.clients.consumer.MockConsumer; +import org.apache.kafka.clients.producer.MockProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +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.company.Company; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.clearing.platform.dictionary.ServiceStatusDictionary; +import ru.spcex.clearing.account.config.BeanConfiguration; +import ru.spcex.clearing.account.config.HazelcastServiceTestConfiguration; +import ru.spcex.clearing.account.config.KafkaConfigTest; +import ru.spcex.clearing.account.config.validation.TradingClearingRegistryValidationConfig; +import ru.spcex.clearing.account.config.validation.ValidationConfig; +import ru.spcex.clearing.account.utils.MatcherFactory; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +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.registry.TradingClearingRegistryNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest; +import ru.spcex.platform.enumeration.ServiceStatus; +import ru.spcex.platform.enumeration.TradingClearingRegistryPurpose; +import ru.spcex.platform.enumeration.WorkflowStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; + +import javax.annotation.PostConstruct; + +import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.account.utils.TestUtils.*; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + BeanConfiguration.class, + ValidationConfig.class, + TradingClearingRegistryValidationConfig.class, + TradingClearingRegistryService.class, + HazelcastServiceTestConfiguration.class, + KafkaConfigTest.class}) +class TradingClearingRegistryServiceTest { + public static final MatcherFactory.Matcher TRADING_CLEARING_REGISTRY_MATCHER = usingIgnoringFieldsComparator(); + private static final int PARTITION = 0; + private static final String TOPIC_ACCOUNT_NEW = Consts.ACCOUNT_NEW_SDF01; + private static final String account = "123456789123"; + private static final Long companyId = 0L; + private static final Long relationId = 0L; + @Autowired + TradingClearingRegistryService tradingClearingRegistryService; + @Autowired + @Qualifier("hazelcastServiceTest") + private HazelcastService hazelcastServiceTest; + + @Captor + private ArgumentCaptor producerRecord; + @SpyBean + private MockProducer producer; + + private Imdg tradingClearingRegistryImdg; + private Imdg companyImdg; + private Imdg serviceStatusDictionaryImdg; + + private Imdg clearingAccountImdg; + private Long clearingAccountId; + + private Imdg depoAccountImdg; + private Long depoAccountId; + + private Imdg accountImdg; + private Long accountId; + + static boolean oneNewRequestDone = false; + + @PostConstruct + private void init() { + hazelcastServiceTest.waitAvailable(); + tradingClearingRegistryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class + ); + companyImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_Company, Company.class + ); + serviceStatusDictionaryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_ServiceStatusDictionary, ServiceStatusDictionary.class + ); + accountImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_Account, Account.class + ); + clearingAccountImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class + ); + depoAccountImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_DepoAccount, DepoAccount.class + ); + ServiceStatusDictionary serviceStatusDictionary = new ServiceStatusDictionary(); + serviceStatusDictionary.setCode(ServiceStatus.Active.getKey()); + serviceStatusDictionary.setName(ServiceStatus.Active.getKey()); + serviceStatusDictionaryImdg.insert(serviceStatusDictionary); + + Company company = new Company(); + company.setId(companyId); + company.setWorkflowStatus(WorkflowStatus.Active.getKey()); + company.setClearingCode("77"); + companyImdg.insert(company); + + Account account = new Account(); + account.setStatus(ServiceStatus.Active.getKey()); + accountId = accountImdg.insert(account); + + DepoAccount depoAccount = new DepoAccount(); + depoAccount.setAccountId(accountId); + depoAccount.setDepoAccountType("DAT"); + depoAccountId = depoAccountImdg.insert(depoAccount); + + ClearingAccount clearingAccount = new ClearingAccount(); + clearingAccount.setAccountId(accountId); + clearingAccount.setClearingAccountType("CAT"); + clearingAccountId = clearingAccountImdg.insert(clearingAccount); + } + + @Test + void tradingClearingRegistryNew_moneyAccount() { + TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest(); + tradingClearingRegistryNewRequest.setCompanyId(companyId); + tradingClearingRegistryNewRequest.setMoneyAccountId(clearingAccountId); + + TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry(); + predictableTradingClearingRegistry.setCompanyId(companyId); + predictableTradingClearingRegistry.setCode("0077MAT"); + predictableTradingClearingRegistry.setMoneyAccountId(clearingAccountId); + predictableTradingClearingRegistry.setTradingClearingRegistryType("CAT"); + predictableTradingClearingRegistry.setTradingClearingRegistryPurpose(TradingClearingRegistryPurpose.M.getKey()); + predictableTradingClearingRegistry.setStatus(ServiceStatus.Active.getKey()); + + String jsonString = getJsonStringForNew(tradingClearingRegistryNewRequest, 0L); + + addRecordToKafka((MockConsumer) tradingClearingRegistryService.getConsumer(), + Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, + PARTITION + (oneNewRequestDone ? 1 : 0), + 0, + jsonString); + + waitingWhenAddedRecordAndCheckIt(0L, producer, producerRecord); + + TradingClearingRegistry resultNew = tradingClearingRegistryImdg.getAllValues().iterator().next(); + predictableTradingClearingRegistry.setId(resultNew.getId()); + predictableTradingClearingRegistry.setCode(predictableTradingClearingRegistry.getCode() + resultNew.getId()); + predictableTradingClearingRegistry.setUpdated(resultNew.getUpdated()); + predictableTradingClearingRegistry.setCreated(resultNew.getCreated()); + + TRADING_CLEARING_REGISTRY_MATCHER.assertMatch(resultNew, predictableTradingClearingRegistry); + tradingClearingRegistryImdg.delete(resultNew); + + oneNewRequestDone = true; + } + + @Test + void tradingClearingRegistryNew_depoAccount() { + TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest(); + tradingClearingRegistryNewRequest.setCompanyId(companyId); + tradingClearingRegistryNewRequest.setMoneyAccountId(clearingAccountId); + tradingClearingRegistryNewRequest.setDepoAccountId(depoAccountId); + + TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry(); + predictableTradingClearingRegistry.setCompanyId(companyId); + predictableTradingClearingRegistry.setCode("0077CDAT"); + predictableTradingClearingRegistry.setMoneyAccountId(clearingAccountId); + predictableTradingClearingRegistry.setDepoAaccountId(depoAccountId); + predictableTradingClearingRegistry.setTradingClearingRegistryType("DAT"); + predictableTradingClearingRegistry.setTradingClearingRegistryPurpose(TradingClearingRegistryPurpose.C.getKey()); + predictableTradingClearingRegistry.setStatus(ServiceStatus.Active.getKey()); + + String jsonString = getJsonStringForNew(tradingClearingRegistryNewRequest, 0L); + + addRecordToKafka((MockConsumer) tradingClearingRegistryService.getConsumer(), + Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, + PARTITION + (oneNewRequestDone ? 1 : 0), + 0, + jsonString); + + waitingWhenAddedRecordAndCheckIt(0L, producer, producerRecord); + + TradingClearingRegistry resultNew = tradingClearingRegistryImdg.getAllValues().iterator().next(); + predictableTradingClearingRegistry.setId(resultNew.getId()); + predictableTradingClearingRegistry.setCode(predictableTradingClearingRegistry.getCode() + resultNew.getId()); + predictableTradingClearingRegistry.setUpdated(resultNew.getUpdated()); + predictableTradingClearingRegistry.setCreated(resultNew.getCreated()); + + TRADING_CLEARING_REGISTRY_MATCHER.assertMatch(resultNew, predictableTradingClearingRegistry); + tradingClearingRegistryImdg.delete(resultNew); + + oneNewRequestDone = true; + } + + @Test + void tradingClearingRegistryUpdate() { + TradingClearingRegistry existTradingClearingRegistry = new TradingClearingRegistry(); + existTradingClearingRegistry.setStatus(ServiceStatus.Closed.getKey()); + Long registryId = tradingClearingRegistryImdg.insert(existTradingClearingRegistry); + + TradingClearingRegistryUpdateRequest tradingClearingRegistryUpdateRequest = new TradingClearingRegistryUpdateRequest(); + tradingClearingRegistryUpdateRequest.setStatus(ServiceStatus.Active.getKey()); + tradingClearingRegistryUpdateRequest.setId(registryId); + + String jsonString = getJsonStringForUPDATE(tradingClearingRegistryUpdateRequest, 0); + + //ACT + addRecordToKafka((MockConsumer) tradingClearingRegistryService.getConsumer(), + Consts.DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE, + PARTITION, + 0, + jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(0L, producer, producerRecord); + + TradingClearingRegistry resultUpdating = tradingClearingRegistryImdg.getSingleObjectByID(registryId); + existTradingClearingRegistry.setUpdated(resultUpdating.getUpdated()); + existTradingClearingRegistry.setStatus(ServiceStatus.Active.getKey()); + TRADING_CLEARING_REGISTRY_MATCHER.assertMatch(resultUpdating, existTradingClearingRegistry); + tradingClearingRegistryImdg.delete(resultUpdating); + } + + @Test + void tradingClearingRegistryBlock() { + TradingClearingRegistry existTradingClearingRegistry = new TradingClearingRegistry(); + existTradingClearingRegistry.setStatus(ServiceStatus.Closed.getKey()); + Long registryId = tradingClearingRegistryImdg.insert(existTradingClearingRegistry); + + CommonDeleteRequest tradingClearingRegistryDeleteRequest = new CommonDeleteRequest(); + tradingClearingRegistryDeleteRequest.setId(registryId); + + String jsonString = getJsonStringForUPDATE(tradingClearingRegistryDeleteRequest, 0); + + //ACT + addRecordToKafka((MockConsumer) tradingClearingRegistryService.getConsumer(), + Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, + PARTITION, + 0, + jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(0L, producer, producerRecord); + + TradingClearingRegistry resultUpdating = tradingClearingRegistryImdg.getSingleObjectByID(registryId); + existTradingClearingRegistry.setUpdated(resultUpdating.getUpdated()); + existTradingClearingRegistry.setStatus(ServiceStatus.Blocked.getKey()); + TRADING_CLEARING_REGISTRY_MATCHER.assertMatch(resultUpdating, existTradingClearingRegistry); + tradingClearingRegistryImdg.delete(resultUpdating); + } +} \ No newline at end of file From 5938786f842f37c56577c81e16ac6696992267c2 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 5 May 2023 14:30:08 +0300 Subject: [PATCH 14/30] =?UTF-8?q?backend-api=20=D0=BF=D0=BE=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BF=D0=BE=D0=BB=D1=8F=20=D0=B2=20?= =?UTF-8?q?CompanyInfo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../queue/company/CompanyInfoController.java | 14 +- .../company/CompanyInfoBackendGetAll.java | 48 ++++ .../company/CompanyInfoBackendGetFields.java | 224 ++++++++++++++++++ 3 files changed, 277 insertions(+), 9 deletions(-) create mode 100644 clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/company/CompanyInfoBackendGetAll.java create mode 100644 clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/company/CompanyInfoBackendGetFields.java diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyInfoController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyInfoController.java index 6ac88b427..02ef05d01 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyInfoController.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/company/CompanyInfoController.java @@ -14,6 +14,7 @@ import ru.spcex.clearing.backendapi.controller.request.cud.company.CompanyInfoUp import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse; import ru.spcex.clearing.backendapi.controller.response.cud.CudResponse; import ru.spcex.clearing.backendapi.controller.response.entity.CommonGetAllResponse; +import ru.spcex.clearing.backendapi.controller.response.entity.company.CompanyInfoBackendGetAll; import ru.spcex.clearing.backendapi.meta.GetResponseFactory; import ru.spcex.clearing.backendapi.service.IOperator; import ru.spcex.clearing.imdg.IMDGDistributedNames; @@ -53,19 +54,14 @@ public class CompanyInfoController extends AbstractQueueController { } @ApiOperation(value = "get all CompanyInfo's.") - @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CommonGetAllResponse.class)}) + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CompanyInfoBackendGetAll.class)}) @RequestMapping(method = RequestMethod.GET) @ResponseBody - public CommonGetAllResponse getAll() { + public CompanyInfoBackendGetAll getAll() { Collection> all = new ArrayList<>(); Collection companies = companyImdg.getAllValues(); - for (Company company : companies) { - if (company.getProfile() != null && company.getProfile().getId() != null) { // пока возвращает "пустой" CompanyInfo если его нет для Company - all.add(responseFactory.responseFromObject(company.getProfile())); - } - } - CommonGetAllResponse response = new CommonGetAllResponse(); - response.fromEntity(all); + CompanyInfoBackendGetAll response = new CompanyInfoBackendGetAll(); + response.fromEntity(companies); return response; } } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/company/CompanyInfoBackendGetAll.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/company/CompanyInfoBackendGetAll.java new file mode 100644 index 000000000..e134eb83a --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/company/CompanyInfoBackendGetAll.java @@ -0,0 +1,48 @@ +package ru.spcex.clearing.backendapi.controller.response.entity.company; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import ru.clearing.classes.statics.data.company.Company; +import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@ApiModel(description = "Ответ при получении объектов CompanyInfos.") +public class CompanyInfoBackendGetAll extends BasicSpcexResponse { + + @JsonProperty + @ApiModelProperty(value = "Полезная нагрузка") + private CompanyInfoBackendPayload payload = new CompanyInfoBackendPayload(); + + private static class CompanyInfoBackendPayload { + private List items = new ArrayList<>(); + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + } + + public CompanyInfoBackendPayload getPayload() { + return payload; + } + + public void setPayload(CompanyInfoBackendPayload payload) { + this.payload = payload; + } + + public void fromEntity(Collection companys) { + var payload = this.getPayload(); + for (var company : companys) { + var singleItem = CompanyInfoBackendGetFields.fromEntity(company); + payload.getItems().add(singleItem); + } + } + +} \ No newline at end of file diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/company/CompanyInfoBackendGetFields.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/company/CompanyInfoBackendGetFields.java new file mode 100644 index 000000000..4e039a019 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/company/CompanyInfoBackendGetFields.java @@ -0,0 +1,224 @@ +package ru.spcex.clearing.backendapi.controller.response.entity.company; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.profile.CompanyInfo; + +public class CompanyInfoBackendGetFields { + @JsonProperty + @ApiModelProperty(value = "Идентификатор записи") + private Long id; + @JsonProperty + @ApiModelProperty(value = "Идентификатор компании") + private Long companyId; + @JsonProperty + @ApiModelProperty(value = "Код единоличного исполнительного органа") + private String corporationSoleType; + @JsonProperty + @ApiModelProperty(value = "Код юрисдикции") + private String countryCode; + @JsonProperty + @ApiModelProperty(value = "Описание компании") + private String description; + @JsonProperty + @ApiModelProperty(value = "Код признака профессионального участника") + private String professionalSign; + @JsonProperty + @ApiModelProperty(value = "Код вида субъекта") + private String legalKind; + @JsonProperty + @ApiModelProperty(value = "Код типа организации") + private String organizationType; + @JsonProperty + @ApiModelProperty(value = "Код резиденции") + private String residence; + @JsonProperty + @ApiModelProperty(value = "Краткое наименование компании") + private String shortName; + @JsonProperty + @ApiModelProperty(value = "Полное наименование компании") + private String fullName; + @JsonProperty + @ApiModelProperty(value = "Краткое наименование компании на английском") + private String shortNameEng; + @JsonProperty + @ApiModelProperty(value = "Краткое наименование компании на английском") + private String fullNameEng; + @JsonProperty + @ApiModelProperty(value = "Код участника торгов") + private String tradingCode; + @JsonProperty + @ApiModelProperty(value = "Код участника клиринга") + private String clearingCode; + @JsonProperty + @ApiModelProperty(value = "Регистрационный код участника") + private String registrationCode; + @JsonProperty + @ApiModelProperty(value = "Наименование статуса") + private String workflowStatus; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } + + public String getCorporationSoleType() { + return corporationSoleType; + } + + public void setCorporationSoleType(String corporationSoleType) { + this.corporationSoleType = corporationSoleType; + } + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getProfessionalSign() { + return professionalSign; + } + + public void setProfessionalSign(String professionalSign) { + this.professionalSign = professionalSign; + } + + public String getLegalKind() { + return legalKind; + } + + public void setLegalKind(String legalKind) { + this.legalKind = legalKind; + } + + public String getOrganizationType() { + return organizationType; + } + + public void setOrganizationType(String organizationType) { + this.organizationType = organizationType; + } + + public String getResidence() { + return residence; + } + + public void setResidence(String residence) { + this.residence = residence; + } + + public String getShortName() { + return shortName; + } + + public void setShortName(String shortName) { + this.shortName = shortName; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getShortNameEng() { + return shortNameEng; + } + + public void setShortNameEng(String shortNameEng) { + this.shortNameEng = shortNameEng; + } + + public String getFullNameEng() { + return fullNameEng; + } + + public void setFullNameEng(String fullNameEng) { + this.fullNameEng = fullNameEng; + } + + public String getTradingCode() { + return tradingCode; + } + + public void setTradingCode(String tradingCode) { + this.tradingCode = tradingCode; + } + + public String getClearingCode() { + return clearingCode; + } + + public void setClearingCode(String clearingCode) { + this.clearingCode = clearingCode; + } + + public String getRegistrationCode() { + return registrationCode; + } + + public void setRegistrationCode(String registrationCode) { + this.registrationCode = registrationCode; + } + + public String getWorkflowStatus() { + return workflowStatus; + } + + public void setWorkflowStatus(String workflowStatus) { + this.workflowStatus = workflowStatus; + } + + public static CompanyInfoBackendGetFields fromEntity(Company company) { + if (company == null || company.getProfile() == null) { + return null; + } + CompanyInfo info = company.getProfile(); + CompanyInfoBackendGetFields fields = new CompanyInfoBackendGetFields(); + fields.setId(info.getId()); + fields.setCompanyId(info.getCompanyId()); + fields.setCorporationSoleType(info.getCorporationSoleType()); + fields.setCountryCode(info.getCountryCode()); + fields.setDescription(info.getDescription()); + fields.setProfessionalSign(info.getProfessionalSign()); + fields.setLegalKind(info.getLegalKind()); + fields.setOrganizationType(info.getOrganizationType()); + fields.setResidence(info.getResidence()); + fields.setShortNameEng(info.getShortNameEng()); + fields.setFullNameEng(info.getFullNameEng()); + + fields.setShortName(company.getShortName()); + fields.setFullName(company.getFullName()); + fields.setTradingCode(company.getTradingCode()); + fields.setClearingCode(company.getClearingCode()); + fields.setRegistrationCode(company.getRegistrationCode()); + fields.setWorkflowStatus(company.getWorkflowStatus()); + + return fields; + } +} From 2829e50e7e003e492e4473dcbd65639e7251cc07 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 5 May 2023 14:36:33 +0300 Subject: [PATCH 15/30] =?UTF-8?q?company-service=20http://jira.mfd.msk:808?= =?UTF-8?q?8/browse/CLS-284=20=20=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20(?= =?UTF-8?q?=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../company/service/CompanyInfoService.java | 2 +- .../company/service/CompanyService.java | 26 ++++++------ ...lationHelper.java => RelationService.java} | 40 ++++++++++++++++++- .../service/CompanyInfoServiceTest.java | 2 +- .../company/service/CompanyServiceTest.java | 2 +- .../service/CompanySymbolServiceTest.java | 2 +- 6 files changed, 54 insertions(+), 20 deletions(-) rename clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/{RelationHelper.java => RelationService.java} (66%) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java index 0beb21c0a..03d355d49 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java @@ -111,7 +111,7 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea transaction.beginTransaction(); boolean txOk = false; try { - companyService.relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + companyService.relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); Imdg txCompanyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); txCompanyMap.update(company); log.trace("Company {} updated", company.getId()); 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 3444b1243..542916892 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 @@ -29,13 +29,11 @@ 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.enumeration.EnumMessage; -import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.error.ClearingBaseException; import ru.spcex.platform.utils.error.ValidationException; import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; -import java.util.Map; import java.util.Objects; import java.util.function.Function; @@ -56,7 +54,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { protected CompanySymbolService companySymbolService; protected AccountNotificationHelper accountNotification; - protected RelationHelper relationHelper; + protected RelationService relationService; @Autowired public CompanyService(Consumer kafkaQueue, Producer kafkaProducer, @@ -73,7 +71,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { CompanySymbolService companySymbolService, AccountNotificationHelper accountNotification, - RelationHelper relationHelper + RelationService relationService ) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; @@ -89,7 +87,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { this.companySymbolService = companySymbolService; companySymbolService.setCompanyService(this); this.accountNotification = accountNotification; - this.relationHelper = relationHelper; + this.relationService = relationService; companyIMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); } @@ -145,9 +143,9 @@ public class CompanyService extends QueueConsumer implements InitializingBean { companyMap.insert(company); log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", companyNewRequestBaseRequest.getId(), company.getId()); - relationHelper.createNewRelation(transaction, company); + relationService.createNewRelation(transaction, company); if (!(WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()))) { // Block - relationHelper.onChangeWorkflowStatus(transaction, company, null, company.getWorkflowStatus()); + relationService.onChangeWorkflowStatus(transaction, company, null, company.getWorkflowStatus()); } txOk = true; } finally { @@ -180,10 +178,10 @@ public class CompanyService extends QueueConsumer implements InitializingBean { log.trace("Company {} not found", updateRequest.getId()); return requestHelper.makeErrorResponse(companyUpdateRequestBaseRequest, CompanyErrors.CompanyNotFound, updateRequest.getId()); } - if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { - log.trace("Company {} not active: {}", company.getId(), company.getWorkflowStatus()); - return requestHelper.makeErrorResponse(companyUpdateRequestBaseRequest, CompanyErrors.CompanyDisabled, updateRequest.getId()); - } +// if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { +// log.trace("Company {} not active: {}", company.getId(), company.getWorkflowStatus()); +// return requestHelper.makeErrorResponse(companyUpdateRequestBaseRequest, CompanyErrors.CompanyDisabled, updateRequest.getId()); +// } company.setUpdated(Instant.now()); company.setShortName(updateRequest.getShortName()); @@ -199,7 +197,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { if (updateRequest.getWorkflowStatus() != null) { company.setWorkflowStatus(updateRequest.getWorkflowStatus()); if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { - relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); } else { log.trace("Status was not changed"); } @@ -286,7 +284,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { String prevStatus = company.getWorkflowStatus(); company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); - relationHelper.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); log.debug("Update company.id={}", company.getId()); companyMap.update(company); @@ -339,7 +337,7 @@ public class CompanyService extends QueueConsumer implements InitializingBean { company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); - relationHelper.onChangeWorkflowStatusOnlyRelationChange(transaction, company, company.getWorkflowStatus()); + relationService.onChangeWorkflowStatusOnlyRelationChange(transaction, company, company.getWorkflowStatus()); log.debug("Update company.id={}", company.getId()); companyMap.update(company); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationHelper.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java similarity index 66% rename from clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationHelper.java rename to clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java index c68595767..ca0c4349f 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationHelper.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/RelationService.java @@ -1,17 +1,27 @@ package ru.spcex.clearing.company.service; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; +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.company.ProfileDocumentNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUpdateRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.platform.enumeration.ServiceProduct; import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; import ru.spcex.platform.utils.error.ValidationException; @@ -20,15 +30,41 @@ import java.util.Collection; import java.util.Objects; @Service -public class RelationHelper { +public class RelationService extends QueueConsumer implements InitializingBean { protected static final Long SPVB_ID = 1L; // СПВБ protected final Logger log = LoggerFactory.getLogger(getClass()); + protected ImdgProvider imdgProvider; protected AccountNotificationHelper accountNotification; @Autowired - public RelationHelper(AccountNotificationHelper accountNotification) { + public RelationService(Consumer kafkaQueue, + Producer kafkaProducer, + ImdgProvider imdgProvider, + + AccountNotificationHelper accountNotification) { + super(kafkaQueue, kafkaProducer); + this.imdgProvider = imdgProvider; this.accountNotification = accountNotification; + +// this.requestHelper = requestHelper.setLogger(log); + } + + @Override + public void afterPropertiesSet() { +// this.profileDocumentMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); +// this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); +//todo all CLS-284 +// callback(ProfileDocumentNewRequest.class) +// .setFunction(this::profileDocumentNew) +// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_NEW, callbacks::put); +// callback(ProfileDocumentUpdateRequest.class) +// .setFunction(this::profileDocumentUpdate) +// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_UPDATE, callbacks::put); +// callback(CommonDeleteRequest.class) +// .setFunction(this::profileDocumentDelete) +// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_DELETE, callbacks::put); +// init(); } protected void createNewRelation(ImdgTransaction transaction, Company company) { diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java index d823d4ab6..b521fd7e4 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java @@ -50,7 +50,7 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProv ValidationConfig.class, CompanySymbolService.class, AccountNotificationHelper.class, - RelationHelper.class, + RelationService.class, BeanConfiguration.class, KafkaTestConfig.class, diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java index b80446af5..f18f68a84 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java @@ -54,7 +54,7 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProv ValidationConfig.class, CompanySymbolService.class, AccountNotificationHelper.class, - RelationHelper.class, + RelationService.class, CompanySymbolService.class, CompanySymbolValidationConfig.class, diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java index 98383d456..39e77828d 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java @@ -50,7 +50,7 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProv CompanyService.class, CompanyValidationConfig.class, AccountNotificationHelper.class, - RelationHelper.class, + RelationService.class, KafkaTestConfig.class, ImdgTestConfig.class}) From f5e2886ad63bc47372944c56143ea07c5d2b2e1f Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 5 May 2023 15:13:43 +0300 Subject: [PATCH 16/30] http://jira.mfd.msk:8088/browse/CLS-271 TradingClearingRegistryService, fix for informationAccount --- ...adingClearingRegistryValidationConfig.java | 10 ++- .../TradingClearingRegistryService.java | 17 ++++- .../TradingClearingRegistryServiceTest.java | 65 +++++++++++++++++-- 3 files changed, 82 insertions(+), 10 deletions(-) diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java index 32fb2f34f..28d06ed70 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java @@ -4,6 +4,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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.registry.TradingClearingRegistry; import ru.clearing.platform.dictionary.ServiceStatusDictionary; @@ -40,6 +41,7 @@ public class TradingClearingRegistryValidationConfig { addImdg.accept(IMDGDistributedNames.Map_Company); addImdg.accept(IMDGDistributedNames.Map_ClearingAccount); addImdg.accept(IMDGDistributedNames.Map_DepoAccount); + addImdg.accept(IMDGDistributedNames.Map_InformationAccount); addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary); return new ValidatorImpl<>(context, IdPresentRule.instance("companyId", @@ -56,7 +58,13 @@ public class TradingClearingRegistryValidationConfig { IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class ); ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(moneyAccountId); - if (clearingAccount == null) return AccountError.AccountNotFound; + if (clearingAccount == null) { + Imdg informationAccountImdg = context.obtainMap( + IMDGDistributedNames.Map_InformationAccount, InformationAccount.class + ); + InformationAccount infoAccount = informationAccountImdg.getSingleObjectByID(moneyAccountId); + if (infoAccount == null) return AccountError.AccountNotFound; + } return null; }), FieldRequiredRule.instance("depoAccountId", diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java index aaafb6972..9b092effa 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java @@ -10,6 +10,7 @@ import org.springframework.stereotype.Service; 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.registry.TradingClearingRegistry; import ru.spcex.clearing.account.errors.AccountError; @@ -26,6 +27,7 @@ import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.TradingClearingRegistryPurpose; +import ru.spcex.platform.enumeration.TradingClearingRegistryType; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.enumeration.EnumMessage; @@ -47,6 +49,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini private final Imdg tradingClearingRegistryImdg; private final Imdg depoAccountImdg; private final Imdg clearingAccountImdg; + private final Imdg informationAccountImdg; private final Imdg accountImdg; private final Imdg companyImdg; @@ -77,6 +80,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini ); this.depoAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class); this.clearingAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingAccount, ClearingAccount.class); + this.informationAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_InformationAccount, InformationAccount.class); this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); this.tradingClearingRegistryUpdateRequestValidator = tradingClearingRegistryUpdateRequestValidator; @@ -118,8 +122,11 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini DepoAccount depoAccount = req.getDepoAccountId() != null ? depoAccountImdg.getSingleObjectByID(req.getDepoAccountId()) : null; Account depoAccountMain = depoAccount != null ? accountImdg.getSingleObjectByID(depoAccount.getAccountId()) : null; + InformationAccount infoAccount = null; ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(req.getMoneyAccountId()); - Account clearingAccountMain = accountImdg.getSingleObjectByID(clearingAccount.getAccountId()); + if (clearingAccount == null) infoAccount = informationAccountImdg.getSingleObjectByID(req.getMoneyAccountId()); + Long clearingAccountId = clearingAccount != null ? clearingAccount.getAccountId() : infoAccount.getAccountId(); + Account clearingAccountMain = accountImdg.getSingleObjectByID(clearingAccountId); List activeStatuses = Arrays.asList(ServiceStatus.Active.getKey(), ServiceStatus.Reopened.getKey()); String status = null; @@ -152,8 +159,12 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini tradingClearingRegistry.setStatus(status); String tradingRegistryType; - if (depoAccount != null) tradingRegistryType = depoAccount.getDepoAccountType(); - else tradingRegistryType = clearingAccount.getClearingAccountType(); + if (depoAccount != null) { + tradingRegistryType = depoAccount.getDepoAccountType(); + } else { + if (clearingAccount != null) tradingRegistryType = clearingAccount.getClearingAccountType(); + else tradingRegistryType = TradingClearingRegistryType.Owner_A.getKey(); + } tradingClearingRegistry.setTradingClearingRegistryType(tradingRegistryType); TradingClearingRegistryPurpose registryPurpose; diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java index 7704cf73b..4ac339059 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java @@ -15,6 +15,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; 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.registry.TradingClearingRegistry; import ru.clearing.platform.dictionary.ServiceStatusDictionary; @@ -31,6 +32,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingR import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest; import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.TradingClearingRegistryPurpose; +import ru.spcex.platform.enumeration.TradingClearingRegistryType; import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; @@ -76,10 +78,15 @@ class TradingClearingRegistryServiceTest { private Imdg depoAccountImdg; private Long depoAccountId; + private Imdg informationAccountImdg; + private Long infoAccountId; + private Imdg accountImdg; private Long accountId; - static boolean oneNewRequestDone = false; + private Long account2Id; + + static int newRequestCnt = 0; @PostConstruct private void init() { @@ -102,6 +109,9 @@ class TradingClearingRegistryServiceTest { depoAccountImdg = hazelcastServiceTest.getImdg( IMDGDistributedNames.Map_DepoAccount, DepoAccount.class ); + informationAccountImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_InformationAccount, InformationAccount.class + ); ServiceStatusDictionary serviceStatusDictionary = new ServiceStatusDictionary(); serviceStatusDictionary.setCode(ServiceStatus.Active.getKey()); serviceStatusDictionary.setName(ServiceStatus.Active.getKey()); @@ -117,6 +127,8 @@ class TradingClearingRegistryServiceTest { account.setStatus(ServiceStatus.Active.getKey()); accountId = accountImdg.insert(account); + account2Id = accountImdg.insert(account); + DepoAccount depoAccount = new DepoAccount(); depoAccount.setAccountId(accountId); depoAccount.setDepoAccountType("DAT"); @@ -126,10 +138,14 @@ class TradingClearingRegistryServiceTest { clearingAccount.setAccountId(accountId); clearingAccount.setClearingAccountType("CAT"); clearingAccountId = clearingAccountImdg.insert(clearingAccount); + + InformationAccount informationAccount = new InformationAccount(); + informationAccount.setAccountId(account2Id); + infoAccountId = informationAccountImdg.insert(informationAccount); } @Test - void tradingClearingRegistryNew_moneyAccount() { + void tradingClearingRegistryNew_moneyAccount_clearingAccount() { TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest(); tradingClearingRegistryNewRequest.setCompanyId(companyId); tradingClearingRegistryNewRequest.setMoneyAccountId(clearingAccountId); @@ -146,7 +162,7 @@ class TradingClearingRegistryServiceTest { addRecordToKafka((MockConsumer) tradingClearingRegistryService.getConsumer(), Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, - PARTITION + (oneNewRequestDone ? 1 : 0), + newRequestCnt, 0, jsonString); @@ -161,9 +177,46 @@ class TradingClearingRegistryServiceTest { TRADING_CLEARING_REGISTRY_MATCHER.assertMatch(resultNew, predictableTradingClearingRegistry); tradingClearingRegistryImdg.delete(resultNew); - oneNewRequestDone = true; + newRequestCnt++; } + @Test + void tradingClearingRegistryNew_moneyAccount_informationAccount() { + TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest(); + tradingClearingRegistryNewRequest.setCompanyId(companyId); + tradingClearingRegistryNewRequest.setMoneyAccountId(infoAccountId); + + TradingClearingRegistry predictableTradingClearingRegistry = new TradingClearingRegistry(); + predictableTradingClearingRegistry.setCompanyId(companyId); + predictableTradingClearingRegistry.setCode("0077MAT"); + predictableTradingClearingRegistry.setMoneyAccountId(infoAccountId); + predictableTradingClearingRegistry.setTradingClearingRegistryType(TradingClearingRegistryType.Owner_A.getKey()); + predictableTradingClearingRegistry.setTradingClearingRegistryPurpose(TradingClearingRegistryPurpose.M.getKey()); + predictableTradingClearingRegistry.setStatus(ServiceStatus.Active.getKey()); + + String jsonString = getJsonStringForNew(tradingClearingRegistryNewRequest, 0L); + + addRecordToKafka((MockConsumer) tradingClearingRegistryService.getConsumer(), + Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, + newRequestCnt, + 0, + jsonString); + + waitingWhenAddedRecordAndCheckIt(0L, producer, producerRecord); + + TradingClearingRegistry resultNew = tradingClearingRegistryImdg.getAllValues().iterator().next(); + predictableTradingClearingRegistry.setId(resultNew.getId()); + predictableTradingClearingRegistry.setCode(predictableTradingClearingRegistry.getCode() + resultNew.getId()); + predictableTradingClearingRegistry.setUpdated(resultNew.getUpdated()); + predictableTradingClearingRegistry.setCreated(resultNew.getCreated()); + + TRADING_CLEARING_REGISTRY_MATCHER.assertMatch(resultNew, predictableTradingClearingRegistry); + tradingClearingRegistryImdg.delete(resultNew); + + newRequestCnt++; + } + + @Test void tradingClearingRegistryNew_depoAccount() { TradingClearingRegistryNewRequest tradingClearingRegistryNewRequest = new TradingClearingRegistryNewRequest(); @@ -184,7 +237,7 @@ class TradingClearingRegistryServiceTest { addRecordToKafka((MockConsumer) tradingClearingRegistryService.getConsumer(), Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, - PARTITION + (oneNewRequestDone ? 1 : 0), + newRequestCnt, 0, jsonString); @@ -199,7 +252,7 @@ class TradingClearingRegistryServiceTest { TRADING_CLEARING_REGISTRY_MATCHER.assertMatch(resultNew, predictableTradingClearingRegistry); tradingClearingRegistryImdg.delete(resultNew); - oneNewRequestDone = true; + newRequestCnt++; } @Test From c5b80bd3c98c63c8592060232d4f273fd3565cf3 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Fri, 5 May 2023 15:21:22 +0300 Subject: [PATCH 17/30] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-276?= =?UTF-8?q?=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=20=D0=B2=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cud/utilities/STradesImportedRequest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/utilities/STradesImportedRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/utilities/STradesImportedRequest.java index 348527aae..30383c910 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/utilities/STradesImportedRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/utilities/STradesImportedRequest.java @@ -1,4 +1,16 @@ package ru.spcex.clearing.platform.messaging.domain.cud.utilities; +import com.fasterxml.jackson.annotation.JsonProperty; + public class STradesImportedRequest { + @JsonProperty + private Long tradeNum; + + public Long getTradeNum() { + return tradeNum; + } + + public void setTradeNum(Long tradeNum) { + this.tradeNum = tradeNum; + } } From 8238757ca81ce454e23249291ebd58f67fbc29dc Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 5 May 2023 15:33:46 +0300 Subject: [PATCH 18/30] =?UTF-8?q?meta=20http://jira.mfd.msk:8088/browse/CL?= =?UTF-8?q?S-293=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8=D0=BB=20DATA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend-api/src/main/resources/meta/data.xml | 4 ++-- .../db-scripts/src/main/resources/db/DATA.sql | 10 +++++----- 2 files changed, 7 insertions(+), 7 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 f3efd0b8d..e6c737fd9 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/data.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/data.xml @@ -80,7 +80,7 @@ - + @@ -198,7 +198,7 @@ - + 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 20a64eaaa..63716ecd2 100644 --- a/clearing-parent/db-scripts/src/main/resources/db/DATA.sql +++ b/clearing-parent/db-scripts/src/main/resources/db/DATA.sql @@ -1,4 +1,4 @@ --- DB version: 3.5.0.20 +-- DB version: 3.5.0.21 -- DATA version: 3.5.0.4 /* Dictionaries */ @@ -160,7 +160,7 @@ INSERT INTO COMPANY_SYMBOL_DICTIONARY(ID, CODE, NAME, SHORTNAME) values (17, 'RG INSERT INTO COMPANY_SYMBOL_DICTIONARY(ID, CODE, NAME, SHORTNAME) values (18, 'UUID', 'Идентификатор во внешней системе', 'Внешний идентификатор') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME, SHORTNAME = EXCLUDED.SHORTNAME; -INSERT INTO COMPANY_SYMBOL_DICTIONARY(ID, CODE, NAME, SHORTNAME) values (19, 'RDPZ', 'Требуется получение документа о подтверждении открытия депозитного счета', 'Подтверждение депозитного счета') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME, SHORTNAME = EXCLUDED.SHORTNAME; +INSERT INTO COMPANY_SYMBOL_DICTIONARY(ID, CODE, NAME, SHORTNAME) values (19, 'LICM', 'Лицензия на управление инвестиционными фондами, паевыми инвестиционными фондами, негосударственными пенсионными фондами', 'Лицензия на управление фондами') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME, SHORTNAME = EXCLUDED.SHORTNAME; INSERT INTO COMPANY_ROLE_DICTIONARY(ID, CODE, NAME) values (1, 'RPRT', 'Отчетная организация') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; @@ -394,7 +394,7 @@ INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (12, 'CMBA', 'Формиро INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (14, 'GCMR', 'Формирование реестра участников клиринга') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (15, 'GBRR', 'Формирование реестра остатков денежных средств ') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (15, 'GBRR', 'Формирование реестра остатков денежных средств') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (16, 'GORR', 'Формирование реестра распоряжений, направленных расчетной организации') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; @@ -414,9 +414,9 @@ INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (36, 'SPRC', 'Запуск п INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (37, 'SPOC', 'Запуск постклиринга') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (38, 'LIMM', 'Выгрузка в торговую систему остатков секции МКР') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (38, 'LIMM', 'Выгрузка в торговую систему остатков по деньгам') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; -INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (39, 'LIMF', 'Выгрузка в торговую систему остатков Фондовой секции') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; +INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (39, 'LIMS', 'Выгрузка в торговую систему остатков по бумагам') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; INSERT INTO TASK_DICTIONARY(ID, CODE, NAME) values (40, 'LIQU', 'Ликвидационная сессия по обязательтсвам участника') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME; From 654943ec3652e8b611eea20bc2c7f38702c6da69 Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 5 May 2023 18:19:32 +0300 Subject: [PATCH 19/30] http://jira.mfd.msk:8088/browse/CLS-271 --- .../clearing/account/errors/AccountError.java | 3 + .../TradingClearingRegistryService.java | 185 ++++++++++++++++-- 2 files changed, 176 insertions(+), 12 deletions(-) diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java index 7a4b12852..dda968b42 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/errors/AccountError.java @@ -12,6 +12,9 @@ public enum AccountError implements IErrorEnumId { CompanyNotFound(5013L), CompanyNotActive(5014L), InfoAccountAlreadyExist(5015L), + TradingClearingRegistryAlreadyExist(5016L), + DepoAccountNotFound(5017L), + MoneyAccountNotFound(5018L), ClearingCategoryNotFound(5019L), TradingClearingRegistryNotFound(5022L), ; diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java index 9b092effa..2bfd55cf3 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java @@ -12,6 +12,7 @@ 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.company.relation.Relation; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; import ru.spcex.clearing.account.errors.AccountError; import ru.spcex.clearing.imdg.IMDGDistributedNames; @@ -25,18 +26,23 @@ import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; +import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.TradingClearingRegistryPurpose; import ru.spcex.platform.enumeration.TradingClearingRegistryType; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; import java.util.Arrays; +import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.function.Function; @Service @@ -52,6 +58,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini private final Imdg informationAccountImdg; private final Imdg accountImdg; private final Imdg companyImdg; + private final Imdg relationImdg; private final Function tradingClearingRegistryUpdateRequestValidator; private final Function tradingClearingRegistryNewRequestValidator; @@ -83,6 +90,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini this.informationAccountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_InformationAccount, InformationAccount.class); this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); + this.relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); this.tradingClearingRegistryUpdateRequestValidator = tradingClearingRegistryUpdateRequestValidator; this.tradingClearingRegistryBlockRequestValidator = tradingClearingRegistryBlockRequestValidator; this.messageResolver = messageResolver; @@ -102,7 +110,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK, callbacks::put); } - public RequestInfoUpdate tradingClearingRegistryNew(BaseRequest userRequest) { + public RequestInfoUpdate tradingClearingRegistryAutoNew(BaseRequest userRequest) { log.debug("TradingClearingRegistryNewRequest received"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); if (requestInfoUpdate != null) return requestInfoUpdate; @@ -125,28 +133,128 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini InformationAccount infoAccount = null; ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(req.getMoneyAccountId()); if (clearingAccount == null) infoAccount = informationAccountImdg.getSingleObjectByID(req.getMoneyAccountId()); - Long clearingAccountId = clearingAccount != null ? clearingAccount.getAccountId() : infoAccount.getAccountId(); - Account clearingAccountMain = accountImdg.getSingleObjectByID(clearingAccountId); + Long accountId = clearingAccount != null ? clearingAccount.getAccountId() : infoAccount.getAccountId(); + Account accountMain = accountImdg.getSingleObjectByID(accountId); + + + // TODO: WELCOME TO HELL + // Проверка выглядит очень сложно и запутанно, потому что репортеры сами не до конца понимают, какая она должна быть. + // Пока что она соответствует ТЗ, но возможно будет правиться, поэтому расписана без выноса кода в методы и + // прочих методов сокращения кода + Relation relation = relationImdg.getSingleObjectByFieldValues(Map.of("consumerId", req.getCompanyId())); + if (ru.spcex.platform.enumeration.Service.MKR.equalsByKey(relation.getService())) { + TradingClearingRegistry registry = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId())); + if (registry != null) { + String errMsg = messageResolver.resolve( + new EnumMessage(AccountError.TradingClearingRegistryAlreadyExist, + req.getCompanyId(), + registry.getId()) + ); + return new RequestInfoUpdate() + .setMessage(errMsg) + .setStatus(Status.Error) + .setId(userRequest.getId()); + } + DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId())); + if (depoAccountForCheck == null) { + String errMsg = messageResolver.resolve(new EnumMessage(AccountError.DepoAccountNotFound, req.getCompanyId())); + return new RequestInfoUpdate() + .setMessage(errMsg) + .setStatus(Status.Error) + .setId(userRequest.getId()); + } + } else if (ru.spcex.platform.enumeration.Service.FOND.equalsByKey(relation.getService())) { + if (AccountType.Info.equalsByKey(accountMain.getStatus())) { + TradingClearingRegistry registry = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of( + "companyId", req.getCompanyId(), + "tradingClearingRegistryType", TradingClearingRegistryPurpose.M.getKey() + )); + if (registry != null) { + String errMsg = messageResolver.resolve( + new EnumMessage(AccountError.TradingClearingRegistryAlreadyExist, + req.getCompanyId(), + registry.getId()) + ); + return new RequestInfoUpdate() + .setMessage(errMsg) + .setStatus(Status.Error) + .setId(userRequest.getId()); + } + DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId())); + if (depoAccountForCheck == null) { + String errMsg = messageResolver.resolve(new EnumMessage(AccountError.DepoAccountNotFound, req.getCompanyId())); + return new RequestInfoUpdate() + .setMessage(errMsg) + .setStatus(Status.Error) + .setId(userRequest.getId()); + } + } else if (AccountType.Clrn.equalsByKey(accountMain.getStatus())) { + ImdgPredicateBuilder imdgPredicateBuilder = tradingClearingRegistryImdg.predicateBuilder(); + ImdgPredicate predicate = imdgPredicateBuilder.and( + imdgPredicateBuilder.equals("companyId", req.getCompanyId()), + imdgPredicateBuilder.or( + imdgPredicateBuilder.equals("tradingClearingRegistryPurpose", TradingClearingRegistryPurpose.M.getKey()), + imdgPredicateBuilder.equals("tradingClearingRegistryPurpose", TradingClearingRegistryPurpose.C.getKey()) + ) + ); + Collection registry = tradingClearingRegistryImdg.getCollectionObjectsByPredicate(predicate); + if (!registry.isEmpty()) { + String errMsg = messageResolver.resolve( + new EnumMessage(AccountError.TradingClearingRegistryAlreadyExist, + req.getCompanyId(), + registry.iterator().next().getId()) + ); + return new RequestInfoUpdate() + .setMessage(errMsg) + .setStatus(Status.Error) + .setId(userRequest.getId()); + } + DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId())); + if (depoAccountForCheck == null) { + String errMsg = messageResolver.resolve(new EnumMessage(AccountError.DepoAccountNotFound, req.getCompanyId())); + return new RequestInfoUpdate() + .setMessage(errMsg) + .setStatus(Status.Error) + .setId(userRequest.getId()); + } + } else if (AccountType.Depo.equalsByKey(accountMain.getStatus())) { + InformationAccount infoAccountForCheck = informationAccountImdg.getSingleObjectByFieldValues( + Map.of("companyId", req.getCompanyId()) + ); + ClearingAccount clearingAccountForCheck = clearingAccountImdg.getSingleObjectByFieldValues( + Map.of("companyId", req.getCompanyId()) + ); + if (infoAccountForCheck == null && clearingAccountForCheck == null) { + String errMsg = messageResolver.resolve( + new EnumMessage(AccountError.MoneyAccountNotFound, req.getCompanyId()) + ); + return new RequestInfoUpdate() + .setMessage(errMsg) + .setStatus(Status.Error) + .setId(userRequest.getId()); + } + } + } List activeStatuses = Arrays.asList(ServiceStatus.Active.getKey(), ServiceStatus.Reopened.getKey()); String status = null; if (depoAccountMain != null && depoAccountMain.getStatus() != null) { - if (activeStatuses.contains(depoAccountMain.getStatus()) && activeStatuses.contains(clearingAccountMain.getStatus())) + if (activeStatuses.contains(depoAccountMain.getStatus()) && activeStatuses.contains(accountMain.getStatus())) status = ServiceStatus.Active.getKey(); - if (depoAccountMain.getStatus().equals(ServiceStatus.Blocked.getKey()) || clearingAccountMain.getStatus().equals(ServiceStatus.Blocked.getKey())) + if (depoAccountMain.getStatus().equals(ServiceStatus.Blocked.getKey()) || accountMain.getStatus().equals(ServiceStatus.Blocked.getKey())) status = ServiceStatus.Blocked.getKey(); - if (depoAccountMain.getStatus().equals(ServiceStatus.Suspended.getKey()) || clearingAccountMain.getStatus().equals(ServiceStatus.Suspended.getKey())) + if (depoAccountMain.getStatus().equals(ServiceStatus.Suspended.getKey()) || accountMain.getStatus().equals(ServiceStatus.Suspended.getKey())) status = ServiceStatus.Suspended.getKey(); - if (depoAccountMain.getStatus().equals(ServiceStatus.Closed.getKey()) || clearingAccountMain.getStatus().equals(ServiceStatus.Closed.getKey())) + if (depoAccountMain.getStatus().equals(ServiceStatus.Closed.getKey()) || accountMain.getStatus().equals(ServiceStatus.Closed.getKey())) status = ServiceStatus.Closed.getKey(); - } else if (clearingAccountMain.getStatus() != null) { - if (activeStatuses.contains(clearingAccountMain.getStatus())) + } else if (accountMain.getStatus() != null) { + if (activeStatuses.contains(accountMain.getStatus())) status = ServiceStatus.Active.getKey(); - if (clearingAccountMain.getStatus().equals(ServiceStatus.Blocked.getKey())) + if (accountMain.getStatus().equals(ServiceStatus.Blocked.getKey())) status = ServiceStatus.Blocked.getKey(); - if (clearingAccountMain.getStatus().equals(ServiceStatus.Suspended.getKey())) + if (accountMain.getStatus().equals(ServiceStatus.Suspended.getKey())) status = ServiceStatus.Suspended.getKey(); - if (clearingAccountMain.getStatus().equals(ServiceStatus.Closed.getKey())) + if (accountMain.getStatus().equals(ServiceStatus.Closed.getKey())) status = ServiceStatus.Closed.getKey(); } if (status == null) { @@ -189,6 +297,59 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini return null; } + public RequestInfoUpdate tradingClearingRegistryNew(BaseRequest userRequest) { + log.debug("TradingClearingRegistryNewRequest received"); + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + + TradingClearingRegistryNewRequest req = userRequest.getRequestPayload(); + + Long id = tradingClearingRegistryImdg.nextIDSequenceFor(); + TradingClearingRegistry tradingClearingRegistry = new TradingClearingRegistry(); + tradingClearingRegistry.setId(id); + tradingClearingRegistry.setCompanyId(req.getCompanyId()); + tradingClearingRegistry.setMoneyAccountId(req.getMoneyAccountId()); + tradingClearingRegistry.setDepoAaccountId(req.getDepoAccountId()); + + DepoAccount depoAccount = req.getDepoAccountId() != null ? depoAccountImdg.getSingleObjectByID(req.getDepoAccountId()) : null; + ClearingAccount clearingAccount = clearingAccountImdg.getSingleObjectByID(req.getMoneyAccountId()); + + tradingClearingRegistry.setStatus(ServiceStatus.Active.getKey()); + + String tradingRegistryType; + if (depoAccount != null) { + tradingRegistryType = depoAccount.getDepoAccountType(); + } else { + if (clearingAccount != null) tradingRegistryType = clearingAccount.getClearingAccountType(); + else tradingRegistryType = TradingClearingRegistryType.Owner_A.getKey(); + } + tradingClearingRegistry.setTradingClearingRegistryType(tradingRegistryType); + + TradingClearingRegistryPurpose registryPurpose; + if (req.getDepoAccountId() != null) registryPurpose = TradingClearingRegistryPurpose.C; + else registryPurpose = TradingClearingRegistryPurpose.M; + tradingClearingRegistry.setTradingClearingRegistryPurpose(registryPurpose.getKey()); + + Company company = companyImdg.getSingleObjectByID(req.getCompanyId()); + String code = "%4s".formatted(company.getClearingCode()).replace(' ', '0'); + code += registryPurpose.getKey(); + if (registryPurpose == TradingClearingRegistryPurpose.C) code += tradingRegistryType + id; + else code += "AT" + id; + tradingClearingRegistry.setCode(code); + + Instant now = Instant.now(); + tradingClearingRegistry.setCreated(now); + tradingClearingRegistry.setUpdated(now); + + tradingClearingRegistryImdg.insert(tradingClearingRegistry); + + log.debug("successfully processed, id {}", id); + return null; + } + public RequestInfoUpdate tradingClearingRegistryUpdate(BaseRequest userRequest) { log.debug("TradingClearingRegistryUpdateRequest received"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); From 65c235c01c3f4941d0c0febde0b5e4b6f3c50c16 Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 5 May 2023 18:28:32 +0300 Subject: [PATCH 20/30] http://jira.mfd.msk:8088/browse/CLS-265 auto request for TCR new --- .../account/service/ClearingAccountService.java | 12 +++++++++++- .../clearing/account/service/DepoAccountService.java | 12 +++++++++++- .../account/service/InformationAccountService.java | 12 +++++++++++- .../service/TradingClearingRegistryService.java | 6 +++++- .../clearing/platform/messaging/domain/Consts.java | 1 + 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java index a4ceddaa6..8b6779baf 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java @@ -16,9 +16,11 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.ServiceStatus; @@ -38,6 +40,7 @@ import java.util.function.Function; @Service public class ClearingAccountService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); + private final KafkaSender kafkaSender; private final AccountService accountService; private final ValidationHelper validationHelper; private final ImdgProvider imdgProvider; @@ -50,6 +53,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin @Autowired public ClearingAccountService(Consumer kafkaQueue, Producer kafkaResponseQueue, + KafkaSender kafkaSender, AccountService accountService, ValidationHelper validationHelper, ImdgProvider imdgProvider, @@ -59,6 +63,7 @@ public class ClearingAccountService extends QueueConsumer implements Initializin @Qualifier("clearingAccountUpdateRequestValidator") Function clearingAccountUpdateRequestValidator) { super(kafkaQueue, kafkaResponseQueue); + this.kafkaSender = kafkaSender; this.accountService = accountService; this.validationHelper = validationHelper; this.imdgProvider = imdgProvider; @@ -104,10 +109,11 @@ public class ClearingAccountService extends QueueConsumer implements Initializin ImdgTransaction imdgTransaction = imdgProvider.newTransaction(); boolean txOk = false; imdgTransaction.beginTransaction(); + ClearingAccount clearingAccount = null; try { accountId = accountImdg.insert(account); - ClearingAccount clearingAccount = new ClearingAccount(); + clearingAccount = new ClearingAccount(); clearingAccount.setCompanyId(req.getCompanyId()); clearingAccount.setAccountId(accountId); clearingAccount.setClearingAccountType(req.getClearingAccountType()); @@ -116,6 +122,10 @@ public class ClearingAccountService extends QueueConsumer implements Initializin } finally { if (txOk) { imdgTransaction.commitTransaction(); + TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest(); + request.setMoneyAccountId(accountId); + request.setCompanyId(clearingAccount.getCompanyId()); + kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request); log.debug("successfully processed, new clearing account id {}, account id {}", clearingAccountId, accountId); } else { // todo выяснить, что возвращать из метода в этой ситуации diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java index 719820108..f8199ba29 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java @@ -13,8 +13,10 @@ 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.account.DepoAccountNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.ServiceStatus; @@ -30,6 +32,7 @@ import java.util.function.Function; public class DepoAccountService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); + private final KafkaSender kafkaSender; private final ValidationHelper validationHelper; private final ImdgProvider imdgProvider; private final AccountService accountService; @@ -39,12 +42,14 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea public DepoAccountService(Consumer kafkaQueue, Producer kafkaProducer, + KafkaSender kafkaSender, ValidationHelper validationHelper, ImdgProvider imdgProvider, AccountService accountService, @Qualifier("depoAccountNewRequestValidator") Function depoAccountNewRequestValidator) { super(kafkaQueue, kafkaProducer); + this.kafkaSender = kafkaSender; this.validationHelper = validationHelper; this.imdgProvider = imdgProvider; this.accountService = accountService; @@ -86,10 +91,11 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea ImdgTransaction imdgTransaction = imdgProvider.newTransaction(); boolean txOk = false; imdgTransaction.beginTransaction(); + DepoAccount depoAccount = null; try { accountId = accountImdg.insert(account); - DepoAccount depoAccount = new DepoAccount(); + depoAccount = new DepoAccount(); depoAccount.setCompanyId(req.getCompanyId()); depoAccount.setAccountId(accountId); depoAccount.setDepoAccountType(req.getDepoAccountType()); @@ -98,6 +104,10 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea } finally { if (txOk) { imdgTransaction.commitTransaction(); + TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest(); + request.setDepoAccountId(accountId); + request.setCompanyId(depoAccount.getCompanyId()); + kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request); log.debug("successfully processed, new depo account id {}, account id {}", depoAccountId, accountId); } else { // todo выяснить, что возвращать из метода в этой ситуации diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java index 5bb94636b..4b96243ae 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java @@ -15,9 +15,11 @@ 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.account.InformationAccountNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.ServiceStatus; @@ -37,6 +39,7 @@ import java.util.function.Function; @Service public class InformationAccountService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); + private final KafkaSender kafkaSender; private final IMessageResolver messageResolver; private final ImdgProvider imdgProvider; private final ValidationHelper validationHelper; @@ -48,6 +51,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali @Autowired public InformationAccountService(Consumer kafkaQueue, Producer kafkaResponseQueue, + KafkaSender kafkaSender, IMessageResolver messageResolver, ImdgProvider imdgProvider, ValidationHelper validationHelper, @@ -55,6 +59,7 @@ public class InformationAccountService extends QueueConsumer implements Initiali @Qualifier("informationAccountNewRequestValidator") Function infoAccountNewRequestValidator) { super(kafkaQueue, kafkaResponseQueue); + this.kafkaSender = kafkaSender; this.messageResolver = messageResolver; this.imdgProvider = imdgProvider; this.validationHelper = validationHelper; @@ -117,10 +122,11 @@ public class InformationAccountService extends QueueConsumer implements Initiali boolean txOk = false; Long informationAccountId = -1L; Long accountId = -1L; + InformationAccount informationAccount = null; try { accountId = accountImdg.insert(account); - InformationAccount informationAccount = new InformationAccount(); + informationAccount = new InformationAccount(); informationAccount.setId(newId); informationAccount.setAccountId(accountId); informationAccount.setClearingAccountId(anltAccount.getId()); @@ -130,6 +136,10 @@ public class InformationAccountService extends QueueConsumer implements Initiali } finally { if (txOk) { imdgTransaction.commitTransaction(); + TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest(); + request.setMoneyAccountId(informationAccountId); + request.setCompanyId(informationAccount.getCompanyId()); + kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request); log.debug("successfully processed, new information account id {}, new account id {}", informationAccountId, accountId); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java index 2bfd55cf3..5d03d16a6 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java @@ -99,6 +99,9 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini @Override public void afterPropertiesSet() throws Exception { init(); + callback(TradingClearingRegistryNewRequest.class) + .setConsumer(this::tradingClearingRegistryAutoNew) + .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, callbacks::put); callback(TradingClearingRegistryNewRequest.class) .setConsumer(this::tradingClearingRegistryNew) .forDestination(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_NEW, callbacks::put); @@ -140,7 +143,8 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini // TODO: WELCOME TO HELL // Проверка выглядит очень сложно и запутанно, потому что репортеры сами не до конца понимают, какая она должна быть. // Пока что она соответствует ТЗ, но возможно будет правиться, поэтому расписана без выноса кода в методы и - // прочих методов сокращения кода + // прочих методов сокращения кода. В дальнейшем, после тестирования и окончательного выяснения вида проверки, + // её стоит вынести на этап валидации запроса. Relation relation = relationImdg.getSingleObjectByFieldValues(Map.of("consumerId", req.getCompanyId())); if (ru.spcex.platform.enumeration.Service.MKR.equalsByKey(relation.getService())) { TradingClearingRegistry registry = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId())); diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index c250e2a6e..bdc985908 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -82,6 +82,7 @@ public interface Consts { String DESTINATION_CLIENT_CODE_DELETE = "client-code-delete"; String DESTINATION_TRADING_CLEARING_REGISTRY_NEW = "trading-clearing-registry-new"; + String DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW = "trading-clearing-registry-auto-new"; String DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE = "trading-clearing-registry-update"; String DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK = "trading-clearing-registry-block"; From 8d893d74cab3f81b685ca18b03bfd077b5b98002 Mon Sep 17 00:00:00 2001 From: akulikov Date: Fri, 5 May 2023 18:36:14 +0300 Subject: [PATCH 21/30] http://jira.mfd.msk:8088/browse/CLS-265 auto request for TCR new --- .../account/service/TradingClearingRegistryServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java index 4ac339059..8dfb3495e 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/TradingClearingRegistryServiceTest.java @@ -293,7 +293,7 @@ class TradingClearingRegistryServiceTest { CommonDeleteRequest tradingClearingRegistryDeleteRequest = new CommonDeleteRequest(); tradingClearingRegistryDeleteRequest.setId(registryId); - String jsonString = getJsonStringForUPDATE(tradingClearingRegistryDeleteRequest, 0); + String jsonString = getJsonStringForDELETE(tradingClearingRegistryDeleteRequest, 0); //ACT addRecordToKafka((MockConsumer) tradingClearingRegistryService.getConsumer(), From a37fea506195002d72a9cd049178ee4f91005aa7 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Fri, 5 May 2023 20:17:35 +0300 Subject: [PATCH 22/30] =?UTF-8?q?company-service=20http://jira.mfd.msk:808?= =?UTF-8?q?8/browse/CLS-284=20=20=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BB=20=D0=BA=D1=80=D0=BE=D0=BC=D0=B5=20=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=BD=D0=BD=D0=BE=D0=B9=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../validation/RelationValidationConfig.java | 134 +++++++++++ .../config/validation/ValidationConfig.java | 2 + .../clearing/company/error/CompanyErrors.java | 1 + .../company/service/RelationService.java | 206 +++++++++++++++-- .../company/service/RelationServiceTest.java | 214 ++++++++++++++++++ .../platform/messaging/domain/Consts.java | 2 + .../cud/company/RelationNewRequest.java | 46 ++++ 7 files changed, 588 insertions(+), 17 deletions(-) create mode 100644 clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java create mode 100644 clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/RelationServiceTest.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/RelationNewRequest.java diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java new file mode 100644 index 000000000..959f62491 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/RelationValidationConfig.java @@ -0,0 +1,134 @@ +package ru.spcex.clearing.company.config.validation; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +import ru.clearing.platform.dictionary.WorkflowStatusDictionary; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.RelationNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.RelationUpdateRequest; +import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; +import ru.spcex.clearing.validation.common.rules.IdPresentRule; +import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.validation.IValidator; +import ru.spcex.platform.utils.validation.ValidatorImpl; + +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; + +@Configuration +public class RelationValidationConfig { + + @Bean("relationNewRequestValidation") + public Function relationNewRequestValidator( + Map> imdgForValidation + ) { + return relationNewRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(relationNewRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Company); + addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + return new ValidatorImpl<>(context, + IdPresentRule.instance("companyId", + RelationNewRequest::getCompanyId, + IMDGDistributedNames.Map_Company, + Company.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.CompanyNotFound), + DictionaryPresentRule.instance("documentType", + RelationNewRequest::getClearingMemberCategory, + IMDGDistributedNames.Map_ClearingCategoryDictionary, + ClearingCategoryDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue), + DictionaryPresentRule.instance("serviceStatus", + RelationNewRequest::getServiceStatus, + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue) + ); + }; + } + + @Bean("relationUpdateRequestValidation") + public Function relationUpdateRequestValidator( + Map> imdgForValidation + ) { + return relationUpdateRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(relationUpdateRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Relation); + addImdg.accept(IMDGDistributedNames.Map_Company); +// addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary); + addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + RelationUpdateRequest::getId, + IMDGDistributedNames.Map_Relation, + Relation.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.RelationNotFound, + relation -> { + if (relation.getConsumerId() == null) return null; + Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); + Company company = companyImdg.getSingleObjectByID(relation.getConsumerId()); + if (company == null) { + return CompanyErrors.CompanyNotFound; + } else { + return null; + } + }), +// IdPresentRule.instance("companyId", +// RelationUpdateRequest::getCompanyId, +// IMDGDistributedNames.Map_Company, +// Company.class, +// CompanyErrors.RequiredFieldEmpty, +// CompanyErrors.CompanyNotFound), +// DictionaryPresentRule.instance("documentType", +// RelationUpdateRequest::getClearingMemberCategory, +// IMDGDistributedNames.Map_ClearingCategoryDictionary, +// ClearingCategoryDictionary.class, +// CompanyErrors.RequiredFieldEmpty, +// CompanyErrors.WrongFieldValue), + DictionaryPresentRule.instance("serviceStatus", + RelationUpdateRequest::getServiceStatus, + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.WrongFieldValue) + ); + }; + } + + @Bean("relationDeleteRequestValidation") + public Function relationDeleteRequestValidator( + Map> imdgForValidation + ) { + return relationDeleteRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(relationDeleteRequest); + Consumer addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); + addImdg.accept(IMDGDistributedNames.Map_Relation); + return new ValidatorImpl<>(context, + IdPresentRule.instance("id", + CommonDeleteRequest::getId, + IMDGDistributedNames.Map_Relation, + Relation.class, + CompanyErrors.RequiredFieldEmpty, + CompanyErrors.RelationNotFound + ) + ); + }; + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java index cd6671cf1..c586e2fd7 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/validation/ValidationConfig.java @@ -7,6 +7,7 @@ import ru.clearing.classes.statics.data.account.ClientCode; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.clearing.classes.statics.data.company.ClearingMemberCategory; +import ru.clearing.classes.statics.data.company.relation.Relation; import ru.clearing.classes.statics.data.profile.Contact; import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; @@ -37,6 +38,7 @@ public class ValidationConfig { addImdg.accept(IMDGDistributedNames.Map_DocumentTypeDictionary, DocumentTypeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_ContactTypeDictionary, ContactTypeDictionary.class); addImdg.accept(IMDGDistributedNames.Map_Contact, Contact.class); + addImdg.accept(IMDGDistributedNames.Map_Relation, Relation.class); addImdg.accept(IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class); addImdg.accept(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java index 3979ab8b9..a7e4b232d 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java @@ -25,6 +25,7 @@ public enum CompanyErrors implements IErrorEnumId { EditContactType(3021L), // Тип контакта компании %s не может быть изменен. TradingClearingRegistryNotFound(3022L), // ТКР с %s не найден AccountNotFound(3023L), // Счет %s не найден + RelationNotFound(3026L), // Запись о договорных отношениях не найдена ; private final Long id; 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 ca0c4349f..882abff8c 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 @@ -6,28 +6,35 @@ 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.stereotype.Service; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.relation.Relation; -import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.company.util.RequestHelper; 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.company.ProfileDocumentNewRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.*; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +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.enumeration.ServiceProduct; import ru.spcex.platform.enumeration.ServiceStatus; 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 ru.spcex.platform.utils.error.ValidationException; +import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; import java.util.Collection; import java.util.Objects; +import java.util.function.Function; @Service public class RelationService extends QueueConsumer implements InitializingBean { @@ -35,38 +42,203 @@ public class RelationService extends QueueConsumer implements InitializingBean { protected final Logger log = LoggerFactory.getLogger(getClass()); protected ImdgProvider imdgProvider; + protected ImdgId idSequence; + protected Imdg relationMap; + protected Imdg companyMap; protected AccountNotificationHelper accountNotification; + protected UserRoleVerification userRoleVerification; + protected RequestHelper requestHelper; + + protected ValidationHelper validationHelper; + private Function relationNewRequestValidator; + private Function relationUpdateRequestValidator; + private Function relationDeleteRequestValidator; @Autowired public RelationService(Consumer kafkaQueue, Producer kafkaProducer, ImdgProvider imdgProvider, + RequestHelper requestHelper, + + UserRoleVerification userRoleVerification, + ValidationHelper validationHelper, + @Qualifier("relationNewRequestValidation") Function relationNewRequestValidator, + @Qualifier("relationUpdateRequestValidation") Function relationUpdateRequestValidator, + @Qualifier("relationDeleteRequestValidation") Function relationDeleteRequestValidator, AccountNotificationHelper accountNotification) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; + this.idSequence = imdgProvider.getImdgIdGenerator(); this.accountNotification = accountNotification; + this.userRoleVerification = userRoleVerification; -// this.requestHelper = requestHelper.setLogger(log); + this.validationHelper = validationHelper; + this.relationNewRequestValidator = relationNewRequestValidator; + this.relationUpdateRequestValidator = relationUpdateRequestValidator; + this.relationDeleteRequestValidator = relationDeleteRequestValidator; + + relationMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.requestHelper = requestHelper.setLogger(log); } + // --- external API --- @Override public void afterPropertiesSet() { // this.profileDocumentMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); // this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); -//todo all CLS-284 -// callback(ProfileDocumentNewRequest.class) -// .setFunction(this::profileDocumentNew) -// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_NEW, callbacks::put); -// callback(ProfileDocumentUpdateRequest.class) -// .setFunction(this::profileDocumentUpdate) -// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_UPDATE, callbacks::put); -// callback(CommonDeleteRequest.class) -// .setFunction(this::profileDocumentDelete) -// .forDestination(Consts.DESTINATION_PROFILE_DOCUMENT_DELETE, callbacks::put); -// init(); + + callback(RelationNewRequest.class) + .setFunction(this::relationNew) + .forDestination(Consts.DESTINATION_RELATION_NEW, callbacks::put); + callback(RelationUpdateRequest.class) + .setFunction(this::relationUpdate) + .forDestination(Consts.DESTINATION_RELATION_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(this::relationDelete) + .forDestination(Consts.DESTINATION_RELATION_DELETE, callbacks::put); + init(); } + private synchronized RequestInfoUpdate relationNew(BaseRequest relationNewBaseRequest) { + RelationNewRequest req = relationNewBaseRequest.getRequestPayload(); + log.debug("relation-new request received, BaseRequest.id = {}", relationNewBaseRequest.getId()); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(relationNewBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(relationNewBaseRequest, relationNewRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + + + Company company = companyMap.getSingleObjectByID(req.getCompanyId()); + +// if (ClearingCategory.B.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.I.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) +// ) { +// /* +// relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=MKR, +// если запись создана и serviceStatus=CLOS, +// изменить запись в relation согласно описанию с тегом При возобнолвении +// , иначе вернуть ошибку (3024)"Договорные отношения %s в секции МКР уже созданы." +// */ +// } +// if (ClearingCategory.C.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.F.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) +// ) { +// /* +//проверить по relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=FOND, +//если запись создана и serviceStatus=CLOS, изменить запись в relation согласно описанию с тегом При возобнолвении, +// иначе вернуть ошибку (3025)"Договорные отношения %s на фондовой секции уже созданы." */ +// } + Relation relation = new Relation(); + relation.setId(idSequence.nextId()); + relation.setCreated(Instant.now()); + relation.setUpdated(relation.getCreated()); + + relation.setConsumerId(req.getCompanyId()); + relation.setSupplierId(SPVB_ID); // 1 СПВБ + if (req.getServiceStatus() != null) { + relation.setServiceStatus(req.getServiceStatus()); + } else { + log.warn("Request has no status. Set status from company[{}].status={}", company.getId(), company.getWorkflowStatus()); + relation.setServiceStatus(company.getWorkflowStatus()); + } + relation.setService(ru.spcex.platform.enumeration.Service.MKR.getKey()); // MKR + relation.setServiceProduct(ServiceProduct.ZERO.getKey()); + relation.setComment(req.getComment()); + + relationMap.insert(relation); + log.debug("New Relation[{}] created.", relation.getId()); + + return null; + } + + + private synchronized RequestInfoUpdate relationUpdate(BaseRequest relationUpdateBaseRequest) { + RelationUpdateRequest req = relationUpdateBaseRequest.getRequestPayload(); + log.debug("relation-update request received, BaseRequest.id = {}", relationUpdateBaseRequest.getId()); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(relationUpdateBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(relationUpdateBaseRequest, relationUpdateRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + + + //Company company = companyMap.getSingleObjectByID(req.getCompanyId()); +// +// if (ClearingCategory.B.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.I.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) +// ) { +// /* +// relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=MKR, +// если запись создана и serviceStatus=CLOS, +// изменить запись в relation согласно описанию с тегом При возобнолвении +// , иначе вернуть ошибку (3024)"Договорные отношения %s в секции МКР уже созданы." +// */ +// } +// if (ClearingCategory.C.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.F.equalsByKey(req.getClearingMemberCategory()) +// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) +// ) { +// /* +//проверить по relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=FOND, +//если запись создана и serviceStatus=CLOS, изменить запись в relation согласно описанию с тегом При возобнолвении, +// иначе вернуть ошибку (3025)"Договорные отношения %s на фондовой секции уже созданы." */ +// } + + Relation relation = relationMap.getSingleObjectByID(req.getId()); + relation.setUpdated(relation.getCreated()); + + if (req.getServiceStatus() != null) { + relation.setServiceStatus(req.getServiceStatus()); + } else { +// relation.setServiceStatus(company.getStatus()); + } + relation.setComment(req.getComment()); + + relationMap.insert(relation); + log.debug("Update Relation[{}] created.", relation.getId()); + + return null; + } + + + private synchronized RequestInfoUpdate relationDelete(BaseRequest relationDeleteBaseRequest) { + CommonDeleteRequest req = relationDeleteBaseRequest.getRequestPayload(); + log.debug("relation-delete request received, BaseRequest.id = {}", relationDeleteBaseRequest.getId()); + { // Валидация + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(relationDeleteBaseRequest); + if (requestInfoUpdate != null) return requestInfoUpdate; + + requestInfoUpdate = validationHelper.validateTillFirstError(relationDeleteBaseRequest, relationDeleteRequestValidator); + if (requestInfoUpdate != null) return requestInfoUpdate; + } + + + Relation relation = relationMap.getSingleObjectByID(req.getId()); + if (WorkflowStatus.Blocked.equalsByKey(relation.getServiceStatus())) { + log.warn("Relation {} already blocked.", relation.getId()); + } else { + relation.setUpdated(relation.getCreated()); + relation.setServiceStatus(WorkflowStatus.Blocked.getKey()); + + relationMap.insert(relation); + log.debug("Relation[{}] block.", relation.getId()); + } + return null; + } + + + // --- internal API --- + protected void createNewRelation(ImdgTransaction transaction, Company company) { Relation relation = new Relation(); // relation.setId(idSequence.nextId()); @@ -79,7 +251,7 @@ public class RelationService extends QueueConsumer implements InitializingBean { relation.setService(ru.spcex.platform.enumeration.Service.MKR.getKey()); // MKR relation.setServiceProduct(ServiceProduct.ZERO.getKey()); log.debug("New Relation[{}] created.", relation.getId()); - Imdg relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + Imdg relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); relationMap.insert(relation); } @@ -103,7 +275,7 @@ public class RelationService extends QueueConsumer implements InitializingBean { } } - protected void onChangeWorkflowStatusOnlyRelationChange(ImdgTransaction transaction, Company company, String newStatus) throws ValidationException { + protected synchronized void onChangeWorkflowStatusOnlyRelationChange(ImdgTransaction transaction, Company company, String newStatus) throws ValidationException { assert Objects.equals(newStatus, company.getWorkflowStatus()); String query = String.format("consumerId=%s", company.getId()); Imdg relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/RelationServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/RelationServiceTest.java new file mode 100644 index 000000000..8bebb24f7 --- /dev/null +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/RelationServiceTest.java @@ -0,0 +1,214 @@ +package ru.spcex.clearing.company.service; + +import org.apache.kafka.clients.consumer.MockConsumer; +import org.apache.kafka.clients.producer.MockProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.clearing.platform.dictionary.ClearingCategoryDictionary; +import ru.clearing.platform.dictionary.WorkflowStatusDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; +import ru.spcex.clearing.company.config.validation.RelationValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +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.company.RelationNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.RelationUpdateRequest; +import ru.spcex.clearing.test.MatcherFactory; +import ru.spcex.clearing.test.TestUtils; +import ru.spcex.clearing.test.config.ImdgTestConfig; +import ru.spcex.clearing.test.config.KafkaTestConfig; +import ru.spcex.platform.enumeration.ClearingCategory; +import ru.spcex.platform.enumeration.WorkflowStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import javax.annotation.PostConstruct; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.*; +import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID; +import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + BeanConfiguration.class, + ValidationConfig.class, + RelationService.class, + AccountNotificationHelper.class, + RelationValidationConfig.class, + KafkaTestConfig.class, + ImdgTestConfig.class}) +class RelationServiceTest { + + public static final MatcherFactory.Matcher RELATION_MATCHER = usingIgnoringFieldsComparator("created", "updated"); + private static final int PARTITION = 0; + + private static final Long ID = currentID.getAndIncrement(); + @Autowired + RelationService relationService; + @Autowired + @Qualifier("hazelcastServiceTest") + private ImdgProvider hazelcastServiceTest; + private Imdg relationMap; + private Imdg companyMap; + + @Captor + private ArgumentCaptor producerRecord; + @SpyBean + private MockProducer mockProducer; + + private long COMPANY_ID; + + private final long RELATION_ID = ID; + + @PostConstruct + private void init() { + waitAvailableImdgProviderAndAddAdminWithDefaultId(); + this.relationMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + this.companyMap = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + + Company testCompany = new Company(); + testCompany.setWorkflowStatus(WorkflowStatus.Active.getKey()); + COMPANY_ID = companyMap.insert(testCompany); + + Imdg workflowStatusDictionaryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_WorkflowStatusDictionary, + WorkflowStatusDictionary.class + ); + WorkflowStatusDictionary workflowStatusDictionary = new WorkflowStatusDictionary(); + workflowStatusDictionary.setId(1L); + workflowStatusDictionary.setCode(WorkflowStatus.Active.getKey()); + workflowStatusDictionary.setName("active"); + workflowStatusDictionaryImdg.insert(workflowStatusDictionary); + workflowStatusDictionary = new WorkflowStatusDictionary(); + workflowStatusDictionary.setId(2L); + workflowStatusDictionary.setCode(WorkflowStatus.Blocked.getKey()); + workflowStatusDictionary.setName("not active"); + workflowStatusDictionaryImdg.insert(workflowStatusDictionary); + + Imdg clearingCategoryDictionaryImdg = hazelcastServiceTest.getImdg( + IMDGDistributedNames.Map_ClearingCategoryDictionary, + ClearingCategoryDictionary.class + ); + ClearingCategoryDictionary clearingCategoryDictionary = new ClearingCategoryDictionary(); + clearingCategoryDictionary.setId(1L); + clearingCategoryDictionary.setCode(ClearingCategory.I.getKey()); + clearingCategoryDictionary.setName("I"); + clearingCategoryDictionaryImdg.insert(clearingCategoryDictionary); + + TestUtils.FutureRecordMetadata future = spy(TestUtils.FutureRecordMetadata.class); + doReturn(future).when(mockProducer).send(producerRecord.capture()); + } + + + @Test + void newRelation() { + //ARRANGE + RelationNewRequest relationNewRequest = new RelationNewRequest(); + relationNewRequest.setCompanyId(COMPANY_ID); + relationNewRequest.setServiceStatus("ACTV"); + relationNewRequest.setClearingMemberCategory("I"); + relationNewRequest.setComment(null); + + Relation predictableRelation = new Relation(); + predictableRelation.setId(RELATION_ID); + predictableRelation.setConsumerId(relationNewRequest.companyId); + predictableRelation.setService("MKR"); + predictableRelation.setServiceProduct("ZERO"); + predictableRelation.setSupplierId(1L); + predictableRelation.setServiceStatus("ACTV"); + + //ACT + String jsonString = getJsonStringForNew(relationNewRequest, ID); + + addRecordToKafka((MockConsumer) relationService.getConsumer(), Consts.DESTINATION_RELATION_NEW, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + Relation resultNew = relationMap.getSingleObjectBySQL("serviceStatus=ACTV"); // String.format("supplierId = %d", COMPANY_ID)); + predictableRelation.setId(resultNew.getId()); + RELATION_MATCHER.assertMatch(resultNew, predictableRelation); + } + + @Test + void updateRelation() { + //ARRANGE + Relation existsRelation = new Relation(); + existsRelation.setId(ID); + existsRelation.setConsumerId(COMPANY_ID); + existsRelation.setSupplierId(1L); + existsRelation.setComment("Test ONE"); + existsRelation.setServiceStatus("ACTV"); + existsRelation.setServiceProduct("PROD"); + existsRelation.setService("MKR"); + relationMap.insert(existsRelation); + + Relation predictableRelation = new Relation(); + predictableRelation.setId(ID); + predictableRelation.setConsumerId(COMPANY_ID); + predictableRelation.setSupplierId(1L); + predictableRelation.setComment("Another Me - ONE"); + predictableRelation.setServiceStatus("ACTV"); + predictableRelation.setServiceProduct("PROD"); + predictableRelation.setService("MKR"); + + RelationUpdateRequest relationUpdateRequest = new RelationUpdateRequest(); + relationUpdateRequest.setId(RELATION_ID); + relationUpdateRequest.setComment("Another Me - ONE"); + relationUpdateRequest.setServiceStatus("ACTV"); + + //ACT + String jsonString = getJsonStringForUpdate(relationUpdateRequest, ID); + + addRecordToKafka((MockConsumer) relationService.getConsumer(), Consts.DESTINATION_RELATION_UPDATE, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + Relation resultUpdate = relationMap.getSingleObjectBySQL(String.format("id = %d", RELATION_ID)); +// predictableProfileDocument.setId(resultUpdate.getId()); + RELATION_MATCHER.assertMatch(resultUpdate, predictableRelation); + } + + + @Test + void deleteProfileDocument() { + //ARRANGE + Relation existsRelation = new Relation(); + existsRelation.setId(ID); + existsRelation.setConsumerId(COMPANY_ID); + existsRelation.setSupplierId(1L); + existsRelation.setComment("Test ONE"); + existsRelation.setServiceStatus("ACTV"); + existsRelation.setServiceProduct("PROD"); + existsRelation.setService("MKR"); + relationMap.insert(existsRelation); + + CommonDeleteRequest profileDocumentDeleteRequest = new CommonDeleteRequest(); + profileDocumentDeleteRequest.setId(RELATION_ID); + + //ACT + String jsonString = getJsonStringForUpdate(profileDocumentDeleteRequest, ID); + + addRecordToKafka((MockConsumer) relationService.getConsumer(), Consts.DESTINATION_RELATION_DELETE, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenAddedRecordAndCheckIt(ID, mockProducer, producerRecord); + Relation resultUpdate = relationMap.getSingleObjectByID(RELATION_ID); +// Assertions.assertNull(resultUpdate); + assertEquals(WorkflowStatus.Blocked.getKey(), resultUpdate.getServiceStatus()); + } +} \ No newline at end of file diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index c00ea09a8..2d0f0cae6 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -72,7 +72,9 @@ public interface Consts { @Deprecated String ACCOUNT_NEW_SDF01 = "account-new-sdf01"; + String DESTINATION_RELATION_NEW = "relation-new"; String DESTINATION_RELATION_UPDATE = "relation-update"; + String DESTINATION_RELATION_DELETE = "relation-delete"; String DESTINATION_PROFILE_DOCUMENT_NEW = "profile-document-new"; String DESTINATION_PROFILE_DOCUMENT_UPDATE = "profile-document-update"; String DESTINATION_PROFILE_DOCUMENT_DELETE = "profile-document-delete"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/RelationNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/RelationNewRequest.java new file mode 100644 index 000000000..9e630303a --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/company/RelationNewRequest.java @@ -0,0 +1,46 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.company; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class RelationNewRequest { + @JsonProperty + public Long companyId; + @JsonProperty + private String serviceStatus; + @JsonProperty + private String clearingMemberCategory; + @JsonProperty + private String comment; + + public Long getCompanyId() { + return companyId; + } + + public void setCompanyId(Long companyId) { + this.companyId = companyId; + } + + public String getServiceStatus() { + return serviceStatus; + } + + public void setServiceStatus(String serviceStatus) { + this.serviceStatus = serviceStatus; + } + + public String getClearingMemberCategory() { + return clearingMemberCategory; + } + + public void setClearingMemberCategory(String clearingMemberCategory) { + this.clearingMemberCategory = clearingMemberCategory; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } +} From 3d56c0fc6376e8040b23b84631d58178dc783d86 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Tue, 9 May 2023 21:32:01 +0300 Subject: [PATCH 23/30] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-268?= =?UTF-8?q?=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BE?= =?UTF-8?q?=D1=88=D0=B8=D0=B1=D0=BA=D1=83=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81?= =?UTF-8?q?=D0=BA=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...erServiceImdgConfig.java => ImdgConfig.java} | 2 +- .../config/SchedulerServiceConfig.java | 17 +++++++++++++++++ .../clearing/scheduler/service/TaskManager.java | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) rename clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/{SchedulerServiceImdgConfig.java => ImdgConfig.java} (97%) create mode 100644 clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/SchedulerServiceConfig.java diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/SchedulerServiceImdgConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/ImdgConfig.java similarity index 97% rename from clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/SchedulerServiceImdgConfig.java rename to clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/ImdgConfig.java index f9d5da568..69fea82d7 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/SchedulerServiceImdgConfig.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/ImdgConfig.java @@ -10,7 +10,7 @@ import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; @Configuration -public class SchedulerServiceImdgConfig { +public class ImdgConfig { private static ThreadPoolTaskExecutor createThreadPoolTaskExecutor(int maxPoolSz, boolean waitForCompletion) { ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor(); if (maxPoolSz > 2) { diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/SchedulerServiceConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/SchedulerServiceConfig.java new file mode 100644 index 000000000..4e9c619c0 --- /dev/null +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/SchedulerServiceConfig.java @@ -0,0 +1,17 @@ +package ru.spcex.clearing.scheduler.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; + +@Configuration +public class SchedulerServiceConfig { + @Bean(name = "taskScheduler") + public TaskScheduler taskScheduler() { + ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); + threadPoolTaskScheduler.setPoolSize(5); + threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler"); + return threadPoolTaskScheduler; + } +} diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/TaskManager.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/TaskManager.java index 9aed3335e..2f0719507 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/TaskManager.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/service/TaskManager.java @@ -48,7 +48,7 @@ public class TaskManager implements InitializingBean, AutoCloseable { private final ExecutorService outputExecutor; @Autowired - TaskManager(TaskScheduler taskScheduler, + TaskManager(@Qualifier("taskScheduler") TaskScheduler taskScheduler, ImdgProvider imdgProvider, LauncherSender launcherSender, @Qualifier("plannerQueue") BlockingQueue> plannerQueue) { From 84870fb64f5a6dfa52f83998fdffe2cbd61c2960 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 10 May 2023 12:16:41 +0300 Subject: [PATCH 24/30] =?UTF-8?q?company-service=20http://jira.mfd.msk:808?= =?UTF-8?q?8/browse/CLS-284=20=20=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BB.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../clearing/company/error/CompanyErrors.java | 2 + .../company/service/RelationService.java | 126 +++++++++++------- 2 files changed, 78 insertions(+), 50 deletions(-) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java index a7e4b232d..1c5b42c49 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/error/CompanyErrors.java @@ -25,6 +25,8 @@ public enum CompanyErrors implements IErrorEnumId { EditContactType(3021L), // Тип контакта компании %s не может быть изменен. TradingClearingRegistryNotFound(3022L), // ТКР с %s не найден AccountNotFound(3023L), // Счет %s не найден + ClearingMemberCategoryOnMKRAlreadyExist(3024L), // Договорные отношения %s в секции МКР уже созданы. + ClearingMemberCategoryOnFONDAlreadyExist(3025L), // Договорные отношения %s на фондовой секции уже созданы. RelationNotFound(3026L), // Запись о договорных отношениях не найдена ; private final Long id; 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 882abff8c..ab47be9ad 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 @@ -21,6 +21,7 @@ import ru.spcex.clearing.platform.messaging.service.QueueConsumer; 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.enumeration.ClearingCategory; import ru.spcex.platform.enumeration.ServiceProduct; import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.WorkflowStatus; @@ -33,6 +34,7 @@ import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; import java.util.Collection; +import java.util.Map; import java.util.Objects; import java.util.function.Function; @@ -115,38 +117,48 @@ public class RelationService extends QueueConsumer implements InitializingBean { Company company = companyMap.getSingleObjectByID(req.getCompanyId()); -// if (ClearingCategory.B.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.I.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) -// ) { -// /* -// relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=MKR, -// если запись создана и serviceStatus=CLOS, -// изменить запись в relation согласно описанию с тегом При возобнолвении -// , иначе вернуть ошибку (3024)"Договорные отношения %s в секции МКР уже созданы." -// */ -// } -// if (ClearingCategory.C.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.F.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) -// ) { -// /* -//проверить по relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=FOND, -//если запись создана и serviceStatus=CLOS, изменить запись в relation согласно описанию с тегом При возобнолвении, -// иначе вернуть ошибку (3025)"Договорные отношения %s на фондовой секции уже созданы." */ -// } - Relation relation = new Relation(); - relation.setId(idSequence.nextId()); - relation.setCreated(Instant.now()); - relation.setUpdated(relation.getCreated()); + Relation existRelation = searchRelation(req.getClearingMemberCategory(), req.getCompanyId()); + if (existRelation != null && !WorkflowStatus.Blocked.equalsByKey(existRelation.getServiceStatus())) { + CompanyErrors errorType; + if (ru.spcex.platform.enumeration.Service.MKR.equalsByKey(existRelation.getService())) { + errorType = CompanyErrors.ClearingMemberCategoryOnMKRAlreadyExist; + } else if (ru.spcex.platform.enumeration.Service.FOND.equalsByKey(existRelation.getService())) { + errorType = CompanyErrors.ClearingMemberCategoryOnFONDAlreadyExist; + } else { + log.warn("Unknown relation[{}] service={}", existRelation.getId(), existRelation.getService()); + errorType = CompanyErrors.GeneralError; + } + return requestHelper.makeErrorResponse(relationNewBaseRequest, errorType); + } + + Relation relation; + if (existRelation == null) { + relation = new Relation(); + relation.setId(idSequence.nextId()); + relation.setCreated(Instant.now()); + relation.setUpdated(relation.getCreated()); + } else { + log.info("Found exist relation id={}, it will be update.", existRelation.getId()); + relation = existRelation; + relation.setUpdated(Instant.now()); + } relation.setConsumerId(req.getCompanyId()); relation.setSupplierId(SPVB_ID); // 1 СПВБ if (req.getServiceStatus() != null) { relation.setServiceStatus(req.getServiceStatus()); } else { - log.warn("Request has no status. Set status from company[{}].status={}", company.getId(), company.getWorkflowStatus()); - relation.setServiceStatus(company.getWorkflowStatus()); + if (existRelation != null) { + relation.setServiceStatus(ServiceStatus.Reopened.getKey()); + log.debug("Request has no status. Set status by resume: {}", relation.getServiceStatus()); + } else { + String toStatus = WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Active.getKey() : + WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Closed.getKey() : + null; + log.debug("Request has no status. Set status by company[{}].status={}. Relation[{}].serviceSStatus={}", + company.getId(), company.getWorkflowStatus(), toStatus); + relation.setServiceStatus(toStatus); + } } relation.setService(ru.spcex.platform.enumeration.Service.MKR.getKey()); // MKR relation.setServiceProduct(ServiceProduct.ZERO.getKey()); @@ -158,6 +170,27 @@ public class RelationService extends QueueConsumer implements InitializingBean { return null; } + private Relation searchRelation(String clearingMemberCategory, Long consumerId) { + String svc; + if (ClearingCategory.B.equalsByKey(clearingMemberCategory) + || ClearingCategory.I.equalsByKey(clearingMemberCategory) + || ClearingCategory.V.equalsByKey(clearingMemberCategory) + ) { + svc = ru.spcex.platform.enumeration.Service.MKR.getKey(); + } else if (ClearingCategory.C.equalsByKey(clearingMemberCategory) + || ClearingCategory.F.equalsByKey(clearingMemberCategory) + ) { + svc = ru.spcex.platform.enumeration.Service.FOND.getKey(); + } else { + log.warn("Unexpected relation Relation={}", clearingMemberCategory); + return null; + } + Relation existRelation = relationMap.getSingleObjectByFieldValues(Map.of( + "consumerId", consumerId, + "service", svc + )); + return existRelation; + } private synchronized RequestInfoUpdate relationUpdate(BaseRequest relationUpdateBaseRequest) { RelationUpdateRequest req = relationUpdateBaseRequest.getRequestPayload(); @@ -171,37 +204,30 @@ public class RelationService extends QueueConsumer implements InitializingBean { } - //Company company = companyMap.getSingleObjectByID(req.getCompanyId()); -// -// if (ClearingCategory.B.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.I.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) -// ) { -// /* -// relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=MKR, -// если запись создана и serviceStatus=CLOS, -// изменить запись в relation согласно описанию с тегом При возобнолвении -// , иначе вернуть ошибку (3024)"Договорные отношения %s в секции МКР уже созданы." -// */ -// } -// if (ClearingCategory.C.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.F.equalsByKey(req.getClearingMemberCategory()) -// || ClearingCategory.V.equalsByKey(req.getClearingMemberCategory()) -// ) { -// /* -//проверить по relation.consumerId (clearingMemberCategory.companyId=relation.companyId) и service=FOND, -//если запись создана и serviceStatus=CLOS, изменить запись в relation согласно описанию с тегом При возобнолвении, -// иначе вернуть ошибку (3025)"Договорные отношения %s на фондовой секции уже созданы." */ -// } - Relation relation = relationMap.getSingleObjectByID(req.getId()); relation.setUpdated(relation.getCreated()); if (req.getServiceStatus() != null) { + log.debug("To relation {} set serivceStatus=\"{}\" by user request.", relation.getId(), req.getServiceStatus()); relation.setServiceStatus(req.getServiceStatus()); } else { -// relation.setServiceStatus(company.getStatus()); + if (relation.getConsumerId() == null) { + log.warn("Relation[{}]. consumerId was null", relation.getId()); + } + Company company = companyMap.getSingleObjectByID(relation.getConsumerId()); + String toStatus = WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Active.getKey() : + WorkflowStatus.Blocked.equalsByKey(company.getWorkflowStatus()) ? ServiceStatus.Closed.getKey() : + null; + if (ServiceStatus.Active.equalsByKey(toStatus) && ServiceStatus.Closed.equalsByKey(relation.getServiceStatus())) { + relation.setServiceStatus(ServiceStatus.Reopened.getKey()); + log.debug("Set status by resume: {}", relation.getServiceStatus()); + } else { + relation.setServiceStatus(toStatus); + log.debug("Request has no status. Set status by company[{}].status={}. Relation[{}].serviceSStatus={}", + company.getId(), company.getWorkflowStatus(), toStatus, relation.getServiceStatus()); + } } + relation.setComment(req.getComment()); relationMap.insert(relation); From a4d1a618cb1db406dbebfc4796af3c2cfa3dbd4f Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 10 May 2023 12:17:20 +0300 Subject: [PATCH 25/30] =?UTF-8?q?RequestHelper=20=D1=82.=D0=BA.=20=D0=BE?= =?UTF-8?q?=D0=B1=D1=8B=D1=87=D0=BD=D0=BE=20=D0=BE=D1=82=D0=B2=D0=B5=D1=82?= =?UTF-8?q?=20=D1=81=D1=80=D0=B0=D0=B7=D1=83=20=D0=B2=D0=BE=D0=B7=D0=B2?= =?UTF-8?q?=D1=80=D0=B0=D1=89=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20-=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B7=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D1=8C=20=D1=82=D0=B5=D0=BA=D1=81=D1=82=D0=B0=20=D0=BE?= =?UTF-8?q?=D1=82=D0=B2=D0=B5=D1=82=D0=B0=20=D0=B2=20=D0=BB=D0=BE=D0=B3=20?= =?UTF-8?q?info?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/ru/spcex/clearing/company/util/RequestHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java index f134ec949..ac865b66a 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java @@ -74,6 +74,7 @@ public class RequestHelper { public RequestInfoUpdate makeErrorResponse(BaseRequest request, EnumMessage msg) { String errorMsg = msg == null? "" : messageResolver.resolve(msg); + log.info("{}", errorMsg); return new RequestInfoUpdate() .setId(request.getId()) .setStatus(Status.Error) From a60726241202bb6b65d2fe0a0f5336ba0831e1e7 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 10 May 2023 12:27:17 +0300 Subject: [PATCH 26/30] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-284?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spcex/clearing/company/service/CompanyInfoServiceTest.java | 2 ++ .../ru/spcex/clearing/company/service/CompanyServiceTest.java | 3 ++- .../clearing/company/service/CompanySymbolServiceTest.java | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java index b521fd7e4..2735eff4c 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyInfoServiceTest.java @@ -18,6 +18,7 @@ import ru.clearing.platform.dictionary.*; import ru.spcex.clearing.company.config.BeanConfiguration; import ru.spcex.clearing.company.config.validation.CompanySymbolValidationConfig; import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; +import ru.spcex.clearing.company.config.validation.RelationValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; @@ -51,6 +52,7 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProv CompanySymbolService.class, AccountNotificationHelper.class, RelationService.class, + RelationValidationConfig.class, BeanConfiguration.class, KafkaTestConfig.class, diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java index f18f68a84..e6ec57333 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanyServiceTest.java @@ -21,6 +21,7 @@ import ru.clearing.platform.dictionary.WorkflowStatusDictionary; import ru.spcex.clearing.company.config.BeanConfiguration; import ru.spcex.clearing.company.config.validation.CompanySymbolValidationConfig; import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; +import ru.spcex.clearing.company.config.validation.RelationValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.imdg.IMDGDistributedNames; @@ -54,7 +55,7 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProv ValidationConfig.class, CompanySymbolService.class, AccountNotificationHelper.class, - RelationService.class, + RelationService.class, RelationValidationConfig.class, CompanySymbolService.class, CompanySymbolValidationConfig.class, diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java index 39e77828d..f9dee4531 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/CompanySymbolServiceTest.java @@ -18,6 +18,7 @@ import ru.clearing.platform.dictionary.CompanySymbolDictionary; import ru.spcex.clearing.company.config.BeanConfiguration; import ru.spcex.clearing.company.config.validation.CompanySymbolValidationConfig; import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; +import ru.spcex.clearing.company.config.validation.RelationValidationConfig; import ru.spcex.clearing.company.config.validation.ValidationConfig; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; @@ -50,7 +51,7 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProv CompanyService.class, CompanyValidationConfig.class, AccountNotificationHelper.class, - RelationService.class, + RelationService.class, RelationValidationConfig.class, KafkaTestConfig.class, ImdgTestConfig.class}) From 70e73b68aebc537845c2174eefa6cedfe00fad1f Mon Sep 17 00:00:00 2001 From: akulikov Date: Wed, 10 May 2023 13:23:38 +0300 Subject: [PATCH 27/30] fix after review --- .../account/config/validation/AccountValidationConfig.java | 2 +- .../validation/TradingClearingRegistryValidationConfig.java | 2 -- .../ru/spcex/clearing/account/service/BankAccountService.java | 1 - .../spcex/clearing/account/service/ClearingAccountService.java | 1 - .../ru/spcex/clearing/account/service/DepoAccountService.java | 1 - .../clearing/account/service/InformationAccountService.java | 1 - .../account/service/TradingClearingRegistryService.java | 3 ++- 7 files changed, 3 insertions(+), 8 deletions(-) diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java index f1a5f0293..ef68fd75a 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/AccountValidationConfig.java @@ -140,7 +140,7 @@ public class AccountValidationConfig { AccountError.WrongFieldValue), DictionaryPresentRule.instance("accountType", CorrespondentAccountUpdateRequest::getAccountType, - IMDGDistributedNames.Map_ServiceStatusDictionary, + IMDGDistributedNames.Map_AccountTypeDictionary, ServiceStatusDictionary.class, AccountError.RequiredFieldEmpty, AccountError.WrongFieldValue, diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java index 28d06ed70..f936a6925 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/TradingClearingRegistryValidationConfig.java @@ -78,8 +78,6 @@ public class TradingClearingRegistryValidationConfig { if (depoAccount == null) return AccountError.AccountNotFound; return null; }), - // todo на будущее: нужна ли эта проверка, если при добавлении регистра статус заполняется автоматически - // на основе полей moneyAccountId и depoAccountId, то же касается TradingClearingRegistryNewRequest, нужно ли там поле status DictionaryPresentRule.instance("status", TradingClearingRegistryNewRequest::getStatus, IMDGDistributedNames.Map_ServiceStatusDictionary, diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java index bff14701c..1069939db 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/BankAccountService.java @@ -224,7 +224,6 @@ public class BankAccountService extends QueueConsumer implements InitializingBea bankAccount.getId(), account.getId()); } else { - // todo выяснить, что возвращать из метода в этой ситуации log.debug("failed block, bank account id {}, new account id {}", bankAccount.getId(), account.getId()); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java index 8b6779baf..766b1f890 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java @@ -128,7 +128,6 @@ public class ClearingAccountService extends QueueConsumer implements Initializin kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request); log.debug("successfully processed, new clearing account id {}, account id {}", clearingAccountId, accountId); } else { - // todo выяснить, что возвращать из метода в этой ситуации log.debug("failed insert, new clearing account id {}, new account id {} (if id = -1 then insert is failed)", clearingAccountId, accountId); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java index f8199ba29..5495595c2 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/DepoAccountService.java @@ -110,7 +110,6 @@ public class DepoAccountService extends QueueConsumer implements InitializingBea kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request); log.debug("successfully processed, new depo account id {}, account id {}", depoAccountId, accountId); } else { - // todo выяснить, что возвращать из метода в этой ситуации log.debug("failed insert, new depo account id {}, new account id {} (if id = -1 then insert is failed)", depoAccountId, accountId); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java index 4b96243ae..175c058c4 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/InformationAccountService.java @@ -144,7 +144,6 @@ public class InformationAccountService extends QueueConsumer implements Initiali informationAccountId, accountId); } else { - // todo выяснить, что возвращать из метода в этой ситуации log.debug("failed insert, new information account id {}, new account id {} (if id = -1 then insert is failed)", informationAccountId, accountId); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java index 5d03d16a6..0b3c43303 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java @@ -140,7 +140,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini Account accountMain = accountImdg.getSingleObjectByID(accountId); - // TODO: WELCOME TO HELL + // TODO // Проверка выглядит очень сложно и запутанно, потому что репортеры сами не до конца понимают, какая она должна быть. // Пока что она соответствует ТЗ, но возможно будет правиться, поэтому расписана без выноса кода в методы и // прочих методов сокращения кода. В дальнейшем, после тестирования и окончательного выяснения вида проверки, @@ -154,6 +154,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini req.getCompanyId(), registry.getId()) ); + log.error("process failed: {}", errMsg); return new RequestInfoUpdate() .setMessage(errMsg) .setStatus(Status.Error) From 795075a4b6a8e1c6c6c333fc015bf7974a9e4413 Mon Sep 17 00:00:00 2001 From: AKurakin Date: Wed, 10 May 2023 13:33:54 +0300 Subject: [PATCH 28/30] =?UTF-8?q?RequestHelper=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D1=91=D1=81=20=D0=B2=20clearing-validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/services}/RequestHelper.java | 19 +++++++++++++------ .../company/config/BeanConfiguration.java | 4 ++-- .../company/service/CompanyInfoService.java | 2 +- .../service/CompanyRoleSetService.java | 2 +- .../company/service/CompanyService.java | 2 +- .../company/service/CompanySymbolService.java | 2 +- .../service/ProfileDocumentService.java | 3 +-- .../company/service/RelationService.java | 2 +- 8 files changed, 21 insertions(+), 15 deletions(-) rename clearing-parent/{company-service/src/main/java/ru/spcex/clearing/company/util => clearing-validation/src/main/java/ru/spcex/clearing/util/services}/RequestHelper.java (84%) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/RequestHelper.java similarity index 84% rename from clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java rename to clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/RequestHelper.java index ac865b66a..04decd8a7 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/util/RequestHelper.java +++ b/clearing-parent/clearing-validation/src/main/java/ru/spcex/clearing/util/services/RequestHelper.java @@ -1,8 +1,7 @@ -package ru.spcex.clearing.company.util; +package ru.spcex.clearing.util.services; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import ru.spcex.clearing.company.error.CompanyErrors; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.Status; @@ -22,21 +21,28 @@ import java.util.Objects; * callback(CompanyNewRequest.class) * .setFunction( request -> requestHelper.requestFunction(this::createCompany, request)) * .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); + * + * return requestHelper.makeErrorResponse(CompanyError.GeneralError, ...) */ public class RequestHelper { protected Logger log = LoggerFactory.getLogger(getClass()); protected final IMessageResolver messageResolver; + protected final IErrorEnumId generalError; - public RequestHelper(IMessageResolver messageResolver) { + public RequestHelper(IMessageResolver messageResolver, IErrorEnumId generalError) { Objects.requireNonNull(messageResolver); this.messageResolver = messageResolver; + this.generalError = generalError; + Objects.requireNonNull(generalError, "Required generalError enum"); } - public RequestHelper(Logger log, IMessageResolver messageResolver) { + public RequestHelper(Logger log, IMessageResolver messageResolver, IErrorEnumId generalError) { Objects.requireNonNull(log); Objects.requireNonNull(messageResolver); this.log = log; this.messageResolver = messageResolver; + this.generalError = generalError; + Objects.requireNonNull(generalError, "Required generalError enum"); } /** @@ -58,13 +64,14 @@ public class RequestHelper { String message = expectedE.getEnumMsg() == null ? expectedE.getMessage() : messageResolver.resolve(expectedE.getEnumMsg()); + log.info("Response: {}", message); return new RequestInfoUpdate() .setId(userRequest.getId()) .setStatus(Status.Error) .setMessage(message); } catch (Exception unexpectedE) { log.error("Error at {}: {} ", command, ExceptionUtils.getStackTrace(unexpectedE)); - String message = messageResolver.resolve(new EnumMessage(CompanyErrors.GeneralError)); + String message = messageResolver.resolve(new EnumMessage(generalError)); return new RequestInfoUpdate() .setId(userRequest.getId()) .setStatus(Status.Error) @@ -74,7 +81,7 @@ public class RequestHelper { public RequestInfoUpdate makeErrorResponse(BaseRequest request, EnumMessage msg) { String errorMsg = msg == null? "" : messageResolver.resolve(msg); - log.info("{}", errorMsg); + log.info("Response: {}", errorMsg); return new RequestInfoUpdate() .setId(request.getId()) .setStatus(Status.Error) diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/BeanConfiguration.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/BeanConfiguration.java index d6248d708..fd44e1d0e 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/BeanConfiguration.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/config/BeanConfiguration.java @@ -5,7 +5,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.company.util.RequestHelper; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -22,7 +22,7 @@ public class BeanConfiguration { @Bean @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public RequestHelper requestHelper(IMessageResolver messageResolver) { - return new RequestHelper(messageResolver); + return new RequestHelper(messageResolver, CompanyErrors.GeneralError); } @Bean diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java index 03d355d49..c3199aca8 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyInfoService.java @@ -11,7 +11,7 @@ import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.profile.CompanyInfo; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.company.util.RequestHelper; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyRoleSetService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyRoleSetService.java index 2af7a358c..ca4526b9b 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyRoleSetService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanyRoleSetService.java @@ -9,7 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.CompanyRoleSet; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.company.util.RequestHelper; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; 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 542916892..f7182432d 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 @@ -11,7 +11,7 @@ import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.company.util.RequestHelper; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanySymbolService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanySymbolService.java index 85c0469f8..cf534c0ea 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanySymbolService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/CompanySymbolService.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.CompanySymbols; -import ru.spcex.clearing.company.util.RequestHelper; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java index adf51b4ed..30eab291e 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ProfileDocumentService.java @@ -12,7 +12,7 @@ import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.company.util.RequestHelper; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -21,7 +21,6 @@ import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentNe import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; -import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.util.security.UserRoleVerification; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.DocumentTypes; 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 ab47be9ad..d91417af6 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 @@ -11,7 +11,7 @@ import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.relation.Relation; import ru.spcex.clearing.company.error.CompanyErrors; -import ru.spcex.clearing.company.util.RequestHelper; +import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; From 05e879112ac7a545859b25714741077ae8e93db7 Mon Sep 17 00:00:00 2001 From: psemenkov Date: Wed, 10 May 2023 15:03:40 +0300 Subject: [PATCH 29/30] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-268?= =?UTF-8?q?=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=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 --- .../config/validation/ClearingCalendarValidationConfig.java | 2 ++ .../config/validation/PlannerTemplateValidationConfig.java | 6 +++++- .../config/validation/PlannerValidationConfig.java | 1 + .../scheduler/validation/rules/common/EnumPresentRule.java | 2 +- .../ru/spcex/clearing/scheduler/AbstractServiceTest.java | 4 ++-- .../clearing/scheduler/validation/EnumPresentRuleTest.java | 2 +- 6 files changed, 12 insertions(+), 5 deletions(-) diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/ClearingCalendarValidationConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/ClearingCalendarValidationConfig.java index 3d7327714..237040622 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/ClearingCalendarValidationConfig.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/ClearingCalendarValidationConfig.java @@ -43,6 +43,7 @@ public class ClearingCalendarValidationConfig { IMDGDistributedNames.Map_Company, Company.class, ValidationError.CompanyNotFound, + false, company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive), DictionaryPresentRule.instance("dayStatus", ClearingCalendarNewRequest::getDayStatus, @@ -74,6 +75,7 @@ public class ClearingCalendarValidationConfig { IMDGDistributedNames.Map_Company, Company.class, ValidationError.CompanyNotFound, + false, company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive), DictionaryPresentRule.instance("dayStatus", ClearingCalendarUpdateRequest::getDayStatus, diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java index e0390eab6..6f7684118 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java @@ -45,7 +45,9 @@ public class PlannerTemplateValidationConfig { IMDGDistributedNames.Map_TaskDictionary, TaskDictionary.class), TimeNotBeforeRule.instance("taskTime", - PlannerTemplateNewRequest::getTaskTime), + PlannerTemplateNewRequest::getTaskTime, + true, + false), DictionaryPresentRule.instance("taskStatus", PlannerTemplateNewRequest::getTaskStatus, IMDGDistributedNames.Map_TaskStatusDictionary, @@ -55,6 +57,7 @@ public class PlannerTemplateValidationConfig { IMDGDistributedNames.Map_Company, Company.class, ValidationError.CompanyNotFound, + false, company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive), IdPresentRule.instance("securityId", PlannerTemplateNewRequest::getSecurityId, @@ -90,6 +93,7 @@ public class PlannerTemplateValidationConfig { false), TimeNotBeforeRule.instance("taskTime", PlannerTemplateUpdateRequest::getTaskTime, + false, false), DictionaryPresentRule.instance("taskStatus", PlannerTemplateUpdateRequest::getTaskStatus, diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java index c60e0d628..389e7ef97 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java @@ -62,6 +62,7 @@ public class PlannerValidationConfig { IMDGDistributedNames.Map_Company, Company.class, ValidationError.CompanyNotFound, + false, company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : ValidationError.CompanyNotActive), IdPresentRule.instance("securityId", PlannerNewRequest::getSecurityId, diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/EnumPresentRule.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/EnumPresentRule.java index a8ab3cd4f..39e53a19a 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/EnumPresentRule.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/validation/rules/common/EnumPresentRule.java @@ -55,6 +55,6 @@ public record EnumPresentRule(String fieldName, for (E enumValue : enumValues) { if (enumValue.getKey().equals(enumCode)) return empty(); } - return of(ValidationError.WrongEnumValue, fieldName); + return of(ValidationError.WrongDictionaryValue, fieldName); } } diff --git a/clearing-parent/scheduler-service/src/test/java/ru/spcex/clearing/scheduler/AbstractServiceTest.java b/clearing-parent/scheduler-service/src/test/java/ru/spcex/clearing/scheduler/AbstractServiceTest.java index c2a6b2173..51e4f577f 100644 --- a/clearing-parent/scheduler-service/src/test/java/ru/spcex/clearing/scheduler/AbstractServiceTest.java +++ b/clearing-parent/scheduler-service/src/test/java/ru/spcex/clearing/scheduler/AbstractServiceTest.java @@ -19,7 +19,7 @@ import ru.clearing.platform.dictionary.TaskStatusDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.scheduler.config.ErrorResolverConfig; import ru.spcex.clearing.scheduler.config.PlannerQueueConfig; -import ru.spcex.clearing.scheduler.config.SchedulerTestConfig; +import ru.spcex.clearing.scheduler.config.SchedulerServiceConfig; import ru.spcex.clearing.scheduler.config.validation.ClearingCalendarValidationConfig; import ru.spcex.clearing.scheduler.config.validation.PlannerTemplateValidationConfig; import ru.spcex.clearing.scheduler.config.validation.PlannerValidationConfig; @@ -60,7 +60,7 @@ import static ru.spcex.platform.enumeration.Market.mkrs; LauncherService.class, ErrorResolverConfig.class, PlannerQueueConfig.class, - SchedulerTestConfig.class, + SchedulerServiceConfig.class, ImdgTestConfig.class, KafkaTestConfig.class}) public abstract class AbstractServiceTest { diff --git a/clearing-parent/scheduler-service/src/test/java/ru/spcex/clearing/scheduler/validation/EnumPresentRuleTest.java b/clearing-parent/scheduler-service/src/test/java/ru/spcex/clearing/scheduler/validation/EnumPresentRuleTest.java index 5d039d6aa..cfc803a26 100644 --- a/clearing-parent/scheduler-service/src/test/java/ru/spcex/clearing/scheduler/validation/EnumPresentRuleTest.java +++ b/clearing-parent/scheduler-service/src/test/java/ru/spcex/clearing/scheduler/validation/EnumPresentRuleTest.java @@ -85,7 +85,7 @@ class EnumPresentRuleTest extends AbstractServiceTest { setter.accept(record, "BAD_VALUE"); enumMessages = strictValidator.validateAll(); assertEquals(1, enumMessages.size()); - assertEquals(ValidationError.WrongEnumValue, enumMessages.iterator().next().getSubject()); + assertEquals(ValidationError.WrongDictionaryValue, enumMessages.iterator().next().getSubject()); } } \ No newline at end of file From d023d289b0c3bce5920d941c005145ecdf19dfbf Mon Sep 17 00:00:00 2001 From: psemenkov Date: Wed, 10 May 2023 15:34:51 +0300 Subject: [PATCH 30/30] =?UTF-8?q?http://jira.mfd.msk:8088/browse/CLS-268?= =?UTF-8?q?=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=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 --- .../config/validation/PlannerTemplateValidationConfig.java | 1 + .../scheduler/config/validation/PlannerValidationConfig.java | 1 + 2 files changed, 2 insertions(+) diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java index 6f7684118..77adaefcc 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerTemplateValidationConfig.java @@ -64,6 +64,7 @@ public class PlannerTemplateValidationConfig { IMDGDistributedNames.Map_Security, Security.class, ValidationError.SecurityNotFound, + false, security -> WorkflowStatus.Active.equalsByKey(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive) ); }; diff --git a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java index 389e7ef97..fa6e186af 100644 --- a/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java +++ b/clearing-parent/scheduler-service/src/main/java/ru/spcex/clearing/scheduler/config/validation/PlannerValidationConfig.java @@ -69,6 +69,7 @@ public class PlannerValidationConfig { IMDGDistributedNames.Map_Security, Security.class, ValidationError.SecurityNotFound, + false, security -> WorkflowStatus.Active.equalsByKey(security.getWorkflowStatus()) ? null : ValidationError.SecurityNotActive) ); };