diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClearingMemberCategoryService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClearingMemberCategoryService.java index 5d0a3825e..4e341dc79 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClearingMemberCategoryService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/ClearingMemberCategoryService.java @@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import ru.clearing.classes.statics.data.company.ClearingMemberCategory; import ru.clearing.classes.statics.data.company.Company; +import ru.spcex.clearing.company.service.v2.facade.CompanyServiceFacade; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -43,7 +44,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init private final Function clearingMemberCategoryDeleteRequestValidator; private final ValidationHelper validationHelper; private final UserRoleVerification userRoleVerification; - private final CompanyService companyService; + private final CompanyServiceFacade companyService; @Autowired public ClearingMemberCategoryService(Consumer kafkaQueue, @@ -54,7 +55,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init @Qualifier("clearingMemberCategoryNewRequestValidator") Function clearingMemberCategoryNewRequestValidator, @Qualifier("clearingMemberCategoryUpdateRequestValidator") Function clearingMemberCategoryUpdateRequestValidator, @Qualifier("clearingMemberCategoryDeleteRequestValidator") Function clearingMemberCategoryDeleteRequestValidator, - CompanyService companyService) { + CompanyServiceFacade companyService) { super(kafkaQueue, kafkaProducer); this.clearingMemberCategoryMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); this.companyMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); @@ -82,7 +83,7 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init init(); } - protected RequestInfoUpdate clearingMemberCategoryNew(BaseRequest userRequest) { + public RequestInfoUpdate clearingMemberCategoryNew(BaseRequest userRequest) { log.debug("ClearingMemberCategoryNewRequest received {}", userRequest.getId()); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); 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 ccdd7723e..887232ba7 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 @@ -12,6 +12,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.service.v2.facade.CompanyServiceFacade; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -36,7 +37,7 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea private final Logger log = LoggerFactory.getLogger(getClass()); private final ImdgProvider imdgProvider; private final Imdg companyMap; - protected final CompanyService companyService; + protected final CompanyServiceFacade companyService; private final RequestHelper requestHelper; private final ValidationHelper validationHelper; final Function companyInfoUpdateRequestValidator; @@ -44,7 +45,7 @@ public class CompanyInfoService extends QueueConsumer implements InitializingBea @Autowired public CompanyInfoService(Consumer kafkaQueue, Producer kafkaProducer, - ImdgProvider imdgProvider, CompanyService companyService, + ImdgProvider imdgProvider, CompanyServiceFacade companyService, RequestHelper requestHelper, ValidationHelper validationHelper, UserRoleVerification userRoleVerification, @Qualifier("CompanyInfoUpdateRequestValidator") 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 62a0d4987..2408f2896 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 @@ -42,6 +42,7 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Function; +@Deprecated @Service public class CompanyService extends QueueConsumer implements InitializingBean { @@ -94,22 +95,22 @@ public class CompanyService extends QueueConsumer implements InitializingBean { @Override public void afterPropertiesSet() { - callback(CommonDeleteRequest.class) - .setFunction(request -> requestHelper.requestFunction(this::deleteCompany, request)) - .forDestination(Consts.DESTINATION_COMPANY_DELETE, callbacks::put); - callback(CommonDeleteRequest.class) - .setFunction(request -> requestHelper.requestFunction(this::blockCompanyAfterDocument, request)) - .forDestination(Consts.DESTINATION_COMPANY_BLOCK, callbacks::put); - callback(CompanyNewRequest.class) - .setFunction(request -> requestHelper.requestFunction(this::processBaseRequest, request)) - .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); - callback(CompanyNewRequest.class) - .setFunction(request -> requestHelper.requestFunction(this::processBaseRequest, request)) - .forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put); - callback(AccountTerminationRequest.class) - .setFunction(request -> requestHelper.requestFunction(this::finishCompanyTermination, request)) - .forDestination(Consts.ACCOUNT_TERMINATION_STEP2, callbacks::put); - init(); +// callback(CommonDeleteRequest.class) +// .setFunction(request -> requestHelper.requestFunction(this::deleteCompany, request)) +// .forDestination(Consts.DESTINATION_COMPANY_DELETE, callbacks::put); +// callback(CommonDeleteRequest.class) +// .setFunction(request -> requestHelper.requestFunction(this::blockCompanyAfterDocument, request)) +// .forDestination(Consts.DESTINATION_COMPANY_BLOCK, callbacks::put); +// callback(CompanyNewRequest.class) +// .setFunction(request -> requestHelper.requestFunction(this::processBaseRequest, request)) +// .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); +// callback(CompanyNewRequest.class) +// .setFunction(request -> requestHelper.requestFunction(this::processBaseRequest, request)) +// .forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put); +// callback(AccountTerminationRequest.class) +// .setFunction(request -> requestHelper.requestFunction(this::finishCompanyTermination, request)) +// .forDestination(Consts.ACCOUNT_TERMINATION_STEP2, callbacks::put); +// init(); } private RequestInfoUpdate processBaseRequest(BaseRequest request) throws ValidationException { diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/MultiCompanyService.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/MultiCompanyService.java index 22dc30751..911dee586 100644 --- a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/MultiCompanyService.java +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/MultiCompanyService.java @@ -41,6 +41,7 @@ import java.util.stream.Stream; /** * Обрабатывает MultiCompanyRequest и распределяет сложный объект по... */ +@Deprecated @Service public class MultiCompanyService extends QueueConsumer implements InitializingBean { @@ -107,10 +108,10 @@ public class MultiCompanyService @Override public void afterPropertiesSet() { - callback(CompanyGatewayRequest.class) - .setFunction(request -> requestHelper.requestFunction(this::processMultiRequest, request)) - .forDestination(Consts.DESTINATION_COMPANY_GATEWAY_REQUEST, callbacks::put); - init(); +// callback(CompanyGatewayRequest.class) +// .setFunction(request -> requestHelper.requestFunction(this::processMultiRequest, request)) +// .forDestination(Consts.DESTINATION_COMPANY_GATEWAY_REQUEST, callbacks::put); +// init(); } private synchronized RequestInfoUpdate processMultiRequest(BaseRequest baseRequest) { 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 8a548c097..bf601f285 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,6 +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.service.v2.facade.CompanyServiceFacade; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -37,7 +38,7 @@ import java.util.function.Function; @Service public class ProfileDocumentService extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); - private final CompanyService companyService; + private final CompanyServiceFacade companyService; private final Function profileDocumentNewRequestValidator; private final Function profileDocumentUpdateRequestValidator; private final Function profileDocumentDeleteRequestValidator; @@ -62,7 +63,7 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin IMessageResolver messageResolver, RequestHelper requestHelper, AccountNotificationHelper accountNotificationHelper, - CompanyService companyService) { + CompanyServiceFacade companyService) { super(kafkaQueue, kafkaProducer); this.imdgProvider = imdgProvider; this.accountNotificationHelper = accountNotificationHelper; @@ -94,7 +95,7 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin } @NonNull - protected RequestInfoUpdate profileDocumentNew(BaseRequest profileDocumentNewRequestBaseRequest) { + public RequestInfoUpdate profileDocumentNew(BaseRequest profileDocumentNewRequestBaseRequest) { log.trace("Start processing ProfileDocumentNewRequest!"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(profileDocumentNewRequestBaseRequest); @@ -168,7 +169,7 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin } - protected RequestInfoUpdate profileDocumentUpdate(BaseRequest profileDocumentUpdateRequestBaseRequest) { + public RequestInfoUpdate profileDocumentUpdate(BaseRequest profileDocumentUpdateRequestBaseRequest) { log.trace("Start processing ProfileDocumentUpdateRequest!"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(profileDocumentUpdateRequestBaseRequest); 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 4d9056990..6055d2d11 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 @@ -642,7 +642,7 @@ public class RelationService extends QueueConsumer implements InitializingBean { } } - protected void cancelAllRelationForCompany(ImdgTransaction transaction, Long companyId) { + public void cancelAllRelationForCompany(ImdgTransaction transaction, Long companyId) { Objects.requireNonNull(companyId, "companyId"); Imdg relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); Collection relations = relationMap.getCollectionObjectsByFieldValues(Map.of("consumerId", companyId)); @@ -689,7 +689,7 @@ public class RelationService extends QueueConsumer implements InitializingBean { } } - protected synchronized void onChangeWorkflowStatusOnlyRelationChange(ImdgTransaction transaction, Company company, String newStatus) throws ValidationException { + public 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/main/java/ru/spcex/clearing/company/service/v2/facade/CompanyServiceFacade.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/facade/CompanyServiceFacade.java new file mode 100644 index 000000000..24818eca0 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/facade/CompanyServiceFacade.java @@ -0,0 +1,253 @@ +package ru.spcex.clearing.company.service.v2.facade; + +import java.time.Instant; +import java.util.Objects; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.profile.CompanyInfo; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.company.service.RelationService; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountTerminationRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +import ru.spcex.platform.enumeration.CompanySymbol; +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.enumeration.EnumMessage; +import ru.spcex.platform.utils.error.ValidationException; + +@Service +public class CompanyServiceFacade { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final ImdgProvider imdgProvider; + private final ImdgId idSequence; + private final Imdg companyIMap; + public RelationService relationService; + + public CompanyServiceFacade(ImdgProvider imdgProvider, + RelationService relationService) { + this.imdgProvider = imdgProvider; + this.idSequence = imdgProvider.getImdgIdGenerator(); + this.relationService = relationService; + + this.companyIMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + } + + public synchronized Long create(CompanyNewRequest companyNewRequest) throws ValidationException { + log.debug("creating new company"); + Instant now = Instant.now(); + Company company = new Company(); + company.setId(idSequence.nextId()); + company.setCreated(now); + company.setUpdated(now); + company.setShortName(companyNewRequest.getShortName()); + company.setFullName(companyNewRequest.getFullName()); + company.setTradingCode(companyNewRequest.getTradingCode()); + company.setClearingCode(companyNewRequest.getClearingCode()); + company.setRegistrationCode(companyNewRequest.getRegistrationCode()); + if (companyNewRequest.getWorkflowStatus() != null) { + company.setWorkflowStatus(companyNewRequest.getWorkflowStatus()); + } else { + company.setWorkflowStatus(WorkflowStatus.Active.getKey()); + } + if (company.getProfile() == null) + company.setProfile(new CompanyInfo()); + CompanyInfo ci = company.getProfile(); + ci.setId(company.getId()); + ci.setCompanyId(company.getId()); + + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + if (companyNewRequest.getCompanySymbol() != null) { + CompanySymbols newSymbol = new CompanySymbols(); + newSymbol.setId(idSequence.nextId()); + newSymbol.setCompanyId(company.getId()); + newSymbol.setCompanySymbol(companyNewRequest.getCompanySymbol()); + newSymbol.setCompanySymbolValue(companyNewRequest.getCompanySymbolValue()); + log.debug("Created new companySymbols.id={} for company {}", newSymbol.getId(), company.getId()); + Imdg companySymbolsImdg = transaction.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + companySymbolsImdg.insert(newSymbol); + log.debug("Creating companySymbols with id: {} by company.id: {} done", newSymbol.getId(), company.getId()); + updateCompanyBySymbol(company, newSymbol, false); + } + companyIMap.insert(company); + log.debug("company-new request processed, BaseRequest.id = {}, company.id={}", + companyNewRequest.getId(), company.getId()); + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + return company.getId(); + } + + public synchronized void update(CompanyNewRequest updateRequest) throws ValidationException { + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + Company company = companyIMap.getSingleObjectByID(updateRequest.getId()); + if (company == null) { + log.trace("Company {} not found", updateRequest.getId()); + throw new ValidationException(new EnumMessage(CompanyErrors.CompanyNotFound)); + } +// 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()); + if (StringUtils.isNotEmpty(updateRequest.getShortName())) + company.setShortName(updateRequest.getShortName()); + if (StringUtils.isNotEmpty(updateRequest.getFullName())) + company.setFullName(updateRequest.getFullName()); + + if (updateRequest.getCompanySymbol() != null || updateRequest.getCompanySymbolValue() != null) { + log.trace("Request field CompanySymbol, CompanySymbolValue ignore for update company request."); + } + + String prevStatus = company.getWorkflowStatus(); + if (updateRequest.getWorkflowStatus() != null) { + company.setWorkflowStatus(updateRequest.getWorkflowStatus()); + if (!Objects.equals(prevStatus, company.getWorkflowStatus())) { + relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + } else { + log.trace("Status was not changed"); + } + } else { + log.trace("Null new WorkflowStatus"); + } + companyIMap.update(company); + txOk = true; + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + } + + public synchronized CompanyErrors delete(BaseRequest companyBlockRequestBaseRequest) { + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + Company company = companyIMap.getSingleObjectByID(companyBlockRequestBaseRequest.getRequestPayload().getId()); + if (company == null) { + return CompanyErrors.CompanyNotFound; + } + + company.setUpdated(Instant.now()); + + String prevStatus = company.getWorkflowStatus(); + company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); + + relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus()); + log.debug("Update company.id={}", company.getId()); + companyIMap.update(company); + + txOk = true; + } catch (ValidationException e) { + throw new RuntimeException(e); + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + + return null; + } + + public synchronized CompanyErrors blockCompany(BaseRequest companyBlockRequestBaseRequest) { + Company company = companyIMap.getSingleObjectByID(companyBlockRequestBaseRequest.getRequestPayload().getId()); + if (company == null) { + return CompanyErrors.CompanyNotFound; + } + if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) { + return CompanyErrors.CompanyDisabled; + } + + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + boolean txOk = false; + try { + Imdg companyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class); + + company.setUpdated(Instant.now()); + company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); + + relationService.onChangeWorkflowStatusOnlyRelationChange(transaction, company, company.getWorkflowStatus()); + log.debug("Update company.id={}", company.getId()); + companyMap.update(company); + + txOk = true; + } catch (ValidationException e) { + throw new RuntimeException(e); + } finally { + if (txOk) + transaction.commitTransaction(); + else + transaction.rollbackTransaction(); + } + + return null; + } + + public synchronized CompanyErrors terminateAccount(BaseRequest accountTerminationRequestBaseRequest) { + log.debug("Finish block company {}", accountTerminationRequestBaseRequest.getRequestPayload().getCompanyId()); + ImdgTransaction tx = imdgProvider.newTransaction(); + boolean txOk = false; + tx.beginTransaction(); + try { + Company company = companyIMap.getSingleObjectByID(accountTerminationRequestBaseRequest.getRequestPayload().getCompanyId()); + if (company == null) { + log.warn("Company {} not found", accountTerminationRequestBaseRequest.getRequestPayload().getCompanyId()); + //return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyNotFound); + } + if (WorkflowStatus.Blocked.equalsByKey(Objects.requireNonNull(company).getWorkflowStatus())) { + log.info("Company {} already blocked", company.getId()); + //return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyDisabled); + } else { + company.setWorkflowStatus(WorkflowStatus.Blocked.getKey()); + company.setUpdated(Instant.now()); + companyIMap.update(company); + } + + relationService.cancelAllRelationForCompany(tx, accountTerminationRequestBaseRequest.getRequestPayload().getCompanyId()); + txOk = true; + } finally { + if (txOk) tx.commitTransaction(); + else tx.rollbackTransaction(); + } + + return null; + } + + private void updateCompanyBySymbol(Company company, CompanySymbols companySymbol, boolean shouldBeDeleted) { + assert company.getId().equals(companySymbol.getCompanyId()); + String setUpValue = shouldBeDeleted ? "" : companySymbol.getCompanySymbolValue(); + if (CompanySymbol.TRDC.equalsByKey(companySymbol.getCompanySymbol())) { + company.setTradingCode(setUpValue); + } + if (CompanySymbol.CLRC.equalsByKey(companySymbol.getCompanySymbol())) { + company.setClearingCode(setUpValue); + } + if (CompanySymbol.RGRC.equalsByKey(companySymbol.getCompanySymbol())) { + company.setRegistrationCode(setUpValue); + } + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/facade/MultiCompanyServiceFacade.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/facade/MultiCompanyServiceFacade.java new file mode 100644 index 000000000..35d1c786d --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/facade/MultiCompanyServiceFacade.java @@ -0,0 +1,426 @@ +package ru.spcex.clearing.company.service.v2.facade; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.BiFunction; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.company.ClearingMemberCategory; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.profile.Contact; +import ru.clearing.classes.statics.data.profile.ProfileDocument; +import ru.spcex.clearing.company.service.ClearingMemberCategoryService; +import ru.spcex.clearing.company.service.CompanyInfoService; +import ru.spcex.clearing.company.service.CompanySymbolService; +import ru.spcex.clearing.company.service.ContactService; +import ru.spcex.clearing.company.service.ProfileDocumentService; +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.cud.account.ClientCodeNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyGatewayRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactUpdateRequest; +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.RequestInfoUpdate; +import ru.spcex.platform.enumeration.CompanySymbol; +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.enumeration.IEnumKey; +import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.error.ValidationException; +import ru.spcex.platform.utils.log.ExceptionUtils; +import ru.spcex.platform.utils.text.TextUtil; + +@Service +public class MultiCompanyServiceFacade { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final CompanyServiceFacade companyServiceFacade; + private final CompanyInfoService companyInfoService; + private final ProfileDocumentService profileDocumentService; + private final CompanySymbolService companySymbolService; + private final ContactService contactService; + private final ClearingMemberCategoryService clearingMemberCategoryService; + private final IMessageResolver messageResolver; + + private final ImdgProvider imdgProvider; + final Imdg companySymbolsImdg; + final Imdg profileDocumentImdg; + final Imdg contactImdg; + final Imdg clearingMemberCategoryImdg; + + public MultiCompanyServiceFacade(ImdgProvider imdgProvider, + CompanyServiceFacade companyServiceFacade, + CompanyInfoService companyInfoService, + ProfileDocumentService profileDocumentService, + CompanySymbolService companySymbolService, + ContactService contactService, + ClearingMemberCategoryService clearingMemberCategoryService, + IMessageResolver messageResolver) { + this.imdgProvider = imdgProvider; + this.companyServiceFacade = companyServiceFacade; + this.companyInfoService = companyInfoService; + this.profileDocumentService = profileDocumentService; + this.companySymbolService = companySymbolService; + this.contactService = contactService; + this.clearingMemberCategoryService = clearingMemberCategoryService; + this.messageResolver = messageResolver; + + companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + profileDocumentImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); + contactImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Contact, Contact.class); + clearingMemberCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); + } + + public synchronized boolean createUpdateMultiCompany(BaseRequest baseRequest) { + ImdgTransaction transaction = imdgProvider.newTransaction(); + transaction.beginTransaction(); + + CompanyGatewayRequest req = baseRequest.getRequestPayload(); + Long companyId = getCompanyIdForCompanySymbols(req.getUuid(), req.getCompany(), req.getCompanySymbols()); + + try { + req.setCompanySymbols( + Stream.concat(req.getCompanySymbols().stream(), additionalSymbols(req.getCompany())).collect(Collectors.toList()) + ); + + log.debug("For request {} (uuid {}) company {}.", baseRequest.getId(), req.getUuid(), companyId == null ? "not found" : ("found, id=" + companyId)); + + if (companyId == null) { + companyId = companyServiceFacade.create(req.getCompany()); + log.debug("The companyId={}", companyId); + fillCompanyId(req, companyId); + } else { + fillCompanyId(req, companyId); + companyServiceFacade.update(req.getCompany()); + } + + RequestInfoUpdate replyI = new RequestInfoUpdate(); + if (req.getCompanyInfo() != null) { + log.trace("For company {} do update CompanyInfo", companyId); + replyI = companyInfoService.companyInfoUpdate(wrapRequest(baseRequest, req.getCompanyInfo(), null)); + validateReply(companyId, "CompanyInfo", replyI); + } + replyI = createUpdateProfileDocument(baseRequest, replyI, companyId); + replyI = createUpdateCompanySymbol(baseRequest, replyI, companyId); + replyI = createUpdateContract(baseRequest, replyI, companyId); + createUpdateClearingMemberCategory(baseRequest, replyI, companyId); + + log.debug("Create or update sendNewClientCode for company {}", companyId); + return true; + } catch (ValidationException vex) { + log.error("For gateway request.id={}, companyId={} error validate: {}", baseRequest.getId(), companyId, messageResolver.resolve(vex.getEnumMsg())); + log.trace("For companyId={} error validation: {}", companyId, ExceptionUtils.getStackTrace(vex)); + } + return false; + } + + private RequestInfoUpdate createUpdateProfileDocument(BaseRequest baseRequest, RequestInfoUpdate requestInfoUpdate, Long companyId) { + for (ProfileDocumentNewRequest partRequest : baseRequest.getRequestPayload().getProfileDocuments()) { + ProfileDocument existDocument = findCompanyDocument(partRequest); + if (existDocument == null) { + log.trace("For company[{}] do new profileDocument", companyId); + requestInfoUpdate = profileDocumentService.profileDocumentNew(wrapRequest(baseRequest, partRequest, ActionType.NEW)); + validateReply(companyId, "profileDocumentNew", requestInfoUpdate); + } else { + log.trace("For company[{}] do update profileDocument[{}]", companyId, existDocument.getId()); + ProfileDocumentUpdateRequest partUpdateRequest = createUpdateRequest(existDocument, partRequest); + requestInfoUpdate = profileDocumentService.profileDocumentUpdate(wrapRequest(baseRequest, partUpdateRequest, ActionType.UPDATE)); + validateReply(companyId, "profileDocumentUpdate", requestInfoUpdate); + } + } + + return requestInfoUpdate; + } + + private RequestInfoUpdate createUpdateCompanySymbol(BaseRequest baseRequest, RequestInfoUpdate requestInfoUpdate, Long companyId) throws ValidationException { + for (CompanySymbolNewRequest partRequest : baseRequest.getRequestPayload().getCompanySymbols()) { + CompanySymbols existSymbol = findCompanySymbols(partRequest); + if (existSymbol == null) { + log.trace("For company[{}] do new companySymbol", companyId); + Long id = companySymbolService.create(partRequest); + } else { + log.trace("For company[{}] do update companySymbol[{}]", companyId, existSymbol.getId()); + CompanySymbolUpdateRequest partUpdateRequest = createUpdateRequest(existSymbol, partRequest); + requestInfoUpdate = companySymbolService.companySymbolUpdate(wrapRequest(baseRequest, partUpdateRequest, ActionType.UPDATE)); + validateReply(companyId, "companySymbolUpdate", requestInfoUpdate); + } + } + + return requestInfoUpdate; + } + + private RequestInfoUpdate createUpdateContract(BaseRequest baseRequest, RequestInfoUpdate requestInfoUpdate, Long companyId) { + for (ContactNewRequest partRequest : baseRequest.getRequestPayload().getContacts()) { + Contact existContact = findContact(partRequest); + if (existContact == null) { + log.trace("For company[{}] do new contact", companyId); + requestInfoUpdate = contactService.contactNew(wrapRequest(baseRequest, partRequest, ActionType.NEW)); + validateReply(companyId, "contactNew", requestInfoUpdate); + } else { + log.trace("For company[{}] do update contact[{}]", companyId, existContact.getId()); + ContactUpdateRequest partUpdateRequest = createUpdateRequest(existContact, partRequest); + requestInfoUpdate = contactService.contactUpdate(wrapRequest(baseRequest, partUpdateRequest, ActionType.UPDATE)); + validateReply(companyId, "contactUpdate", requestInfoUpdate); + } + } + + return requestInfoUpdate; + } + + private RequestInfoUpdate createUpdateClearingMemberCategory(BaseRequest baseRequest, RequestInfoUpdate requestInfoUpdate, Long companyId) { + for (ClearingMemberCategoryNewRequest partRequest : baseRequest.getRequestPayload().getCategories()) { + ClearingMemberCategory existCategory = findCategory(partRequest); + if (existCategory == null) { + log.trace("For company[{}] do new category", companyId); + requestInfoUpdate = clearingMemberCategoryService.clearingMemberCategoryNew(wrapRequest(baseRequest, partRequest, ActionType.NEW)); + validateReply(companyId, "contactNew", requestInfoUpdate); + } else { + log.trace("For company[{}] do update category[{}]", companyId, existCategory.getId()); + ClearingMemberCategoryUpdateRequest partUpdateRequest = createUpdateRequest(existCategory, partRequest); + requestInfoUpdate = clearingMemberCategoryService.clearingMemberCategoryUpdate(wrapRequest(baseRequest, partUpdateRequest, ActionType.UPDATE)); + validateReply(companyId, "categoryUpdate", requestInfoUpdate); + } + } + + return requestInfoUpdate; + } + + private Stream additionalSymbols(CompanyNewRequest companyNewReq) { + BiFunction> symbolCreation = (companySymbol, companySymbolValue) -> { + if (companySymbolValue == null || TextUtil.isEmpty(companySymbolValue)) { + return Optional.empty(); + } + CompanySymbolNewRequest companySymbolNewRequest = new CompanySymbolNewRequest(); + companySymbolNewRequest.setCompanySymbol(companySymbol); + companySymbolNewRequest.setCompanySymbolValue(companySymbolValue); + return Optional.of(companySymbolNewRequest); + }; + return Stream.of(symbolCreation.apply(CompanySymbol.TRDC.getKey(), companyNewReq.getTradingCode()), + symbolCreation.apply(CompanySymbol.CLRC.getKey(), companyNewReq.getClearingCode()), + symbolCreation.apply(CompanySymbol.INTC.getKey(), companyNewReq.getInitiatorCode()), + symbolCreation.apply(CompanySymbol.RGRC.getKey(), companyNewReq.getRegistrationCode())) + .filter(Optional::isPresent) + .map(Optional::get); + } + + private void validateReply(Long companyId, String process, RequestInfoUpdate replyI) { + if (replyI != null && replyI.getMessage() != null) { + log.warn("Error process {} for companyId={}: {}", process, companyId, replyI.getMessage()); + } + } + + public ProfileDocument findCompanyDocument(ProfileDocumentNewRequest partRequest) { + Map> query = new HashMap<>(); + query.put("companyId", partRequest.getCompanyId()); + query.put("documentType", partRequest.getDocumentType()); + query.put("issueDate", partRequest.getIssueDate()); // может быть null + Collection allDoc = profileDocumentImdg.getCollectionObjectsByFieldValues(query); + if (allDoc.isEmpty()) + return null; + if (allDoc.size() > 1) + log.warn("Fount {} ProfileDocument by: {}", allDoc.size(), query); + return allDoc.iterator().next(); + } + + public CompanySymbols findCompanySymbols(CompanySymbolNewRequest partRequest) { + Map> query = new HashMap<>(); + query.put("companyId", partRequest.getCompanyId()); + query.put("companySymbol", partRequest.getCompanySymbol()); + Collection allCS = companySymbolsImdg.getCollectionObjectsByFieldValues(query); + if (allCS.isEmpty()) + return null; + if (allCS.size() > 1) + log.warn("Fount {} CompanySymbols by: {}", allCS.size(), query); + return allCS.iterator().next(); + } + + public Contact findContact(ContactNewRequest partRequest) { + Map> query = new HashMap<>(); + query.put("companyId", partRequest.getCompanyId()); + query.put("contactType", partRequest.getContactType()); + Collection allCS = contactImdg.getCollectionObjectsByFieldValues(query); + if (allCS.isEmpty()) + return null; + if (allCS.size() > 1) + log.warn("Fount {} Contact by: {}", allCS.size(), query); + return allCS.iterator().next(); + } + + private ClearingMemberCategory findCategory(ClearingMemberCategoryNewRequest partRequest) { + Map> query = new HashMap<>(); + query.put("companyId", partRequest.getCompanyId()); + query.put("clearingMemberCategory", partRequest.getClearingMemberCategory()); + Collection allCS = clearingMemberCategoryImdg.getCollectionObjectsByFieldValues(query); + if (allCS.isEmpty()) + return null; + if (allCS.size() > 1) + log.warn("Fount {} ClearingMemberCategory by: {}", allCS.size(), query); + return allCS.iterator().next(); + } + + private ProfileDocumentUpdateRequest createUpdateRequest(ProfileDocument existDocument, ProfileDocumentNewRequest partRequest) { + ProfileDocumentUpdateRequest r = new ProfileDocumentUpdateRequest(); + r.setId(existDocument.getId()); + r.setCompanyId(partRequest.getCompanyId()); + r.setDocumentType(partRequest.getDocumentType()); + r.setIssueDate(partRequest.getIssueDate()); + r.setIssuePlace(partRequest.getIssuePlace()); + r.setIssuer(partRequest.getIssuer()); + r.setIssuerCode(partRequest.getIssuerCode()); + r.setName(partRequest.getName()); + r.setNumber(partRequest.getNumber()); + r.setPlace(partRequest.getPlace()); + r.setValidFromDate(partRequest.getValidFromDate()); + r.setValidToDate(partRequest.getValidToDate()); + r.setLink(partRequest.getLink()); + return r; + } + + private CompanySymbolUpdateRequest createUpdateRequest(CompanySymbols existSymbol, CompanySymbolNewRequest partRequest) { + CompanySymbolUpdateRequest r = new CompanySymbolUpdateRequest(); + r.setId(existSymbol.getId()); + r.setCompanyId(partRequest.getCompanyId()); + r.setCompanySymbol(partRequest.getCompanySymbol()); + r.setCompanySymbolValue(partRequest.getCompanySymbolValue()); + return r; + } + + private ContactUpdateRequest createUpdateRequest(Contact existContact, ContactNewRequest partRequest) { + ContactUpdateRequest r = new ContactUpdateRequest(); + r.setId(existContact.getId()); + r.setContactType(partRequest.getContactType()); + r.setContactValue(partRequest.getContactValue()); + return r; + } + + private ClearingMemberCategoryUpdateRequest createUpdateRequest(ClearingMemberCategory existCategory, ClearingMemberCategoryNewRequest partRequest) { + ClearingMemberCategoryUpdateRequest r = new ClearingMemberCategoryUpdateRequest(); + r.setId(existCategory.getId()); + r.setClearingMemberCategory(partRequest.getClearingMemberCategory()); + return r; + } + + public Long getCompanyIdForCompanySymbols(String uuid, CompanyNewRequest cnr, Collection companySymbols) { + CompanySymbols companySymbol = null; + if (StringUtils.isNotEmpty(uuid)) { + log.trace("Search company by companySymbol uuid={}", uuid); + Collection companySymbolsFromImdg = companySymbolsImdg.getCollectionObjectsByFieldValues( + Map.of( + "companySymbol", CompanySymbol.UUID.getKey(), + "companySymbolValue", uuid + ) + ); + if (!companySymbolsFromImdg.isEmpty()) { + companySymbol = companySymbolsFromImdg.iterator().next(); + if (companySymbolsFromImdg.size() > 1) { + log.warn("For UUID found > 1 company_symbols, use first (id = {})", companySymbol.getId()); + } + } + } + if (companySymbol == null && StringUtils.isNotEmpty(cnr.getCompanySymbolValue()) + && IEnumKey.contains(cnr.getCompanySymbol(), CompanySymbol.UUID, CompanySymbol.INN, CompanySymbol.CIO)) { // вероятно там будет только UUID + { + String companySymbolType = cnr.getCompanySymbol(); + log.debug("Company not found by UUID=\"{}\", try find by {}={}", + uuid, companySymbolType, cnr.getCompanySymbolValue()); + log.trace("Search company by companySymbol {}={}", companySymbolType, cnr.getCompanySymbolValue()); + Collection companySymbolsFromImdg = companySymbolsImdg.getCollectionObjectsByFieldValues( + Map.of( + "companySymbol", companySymbolType, + "companySymbolValue", cnr.getCompanySymbolValue() + ) + ); + if (!companySymbolsFromImdg.isEmpty()) { + companySymbol = companySymbolsFromImdg.iterator().next(); + if (companySymbolsFromImdg.size() > 1) { + log.warn("For {} found > 1 company_symbols, use first (id = {})", companySymbolType, cnr.getCompanySymbolValue()); + } + } + } + } + if (companySymbol == null && companySymbols != null) { + for (CompanySymbolNewRequest cSymbolReq : companySymbols) { + if (IEnumKey.contains(cSymbolReq.getCompanySymbol(), CompanySymbol.INN, CompanySymbol.CIO)) { + String companySymbolType = cSymbolReq.getCompanySymbol(); + log.debug("Company not found by UUID=\"{}\", try find by {}", uuid, companySymbolType); + log.trace("Search company by companySymbol {}={}", companySymbolType, cSymbolReq.getCompanySymbolValue()); + Collection companySymbolsFromImdg = companySymbolsImdg.getCollectionObjectsByFieldValues( + Map.of( + "companySymbol", companySymbolType, + "companySymbolValue", cSymbolReq.getCompanySymbolValue() + ) + ); + if (!companySymbolsFromImdg.isEmpty()) { + companySymbol = companySymbolsFromImdg.iterator().next(); + if (companySymbolsFromImdg.size() > 1) { + log.warn("For {} found > 1 company_symbols, use first (id = {})", companySymbolType, cSymbolReq.getCompanySymbolValue()); + } + break; + } + } + } + } + + if (companySymbol != null) + return companySymbol.getCompanyId(); + else + return null; + } + + private BaseRequest wrapRequest(BaseRequest template, T payload, ActionType action) { + BaseRequest r = new BaseRequest<>(); + r.setId(template.getId()); + if (action == null) { + r.setActionType(template.getActionType()); + } else { + r.setActionType(action); + } + r.setUserId(template.getUserId()); + r.setCorrelationId(template.getCorrelationId()); + r.setRequestPayload(payload); + return r; + } + + public void fillCompanyId(CompanyGatewayRequest req, Long companyId) { + if (req.getCompany() != null) { + req.getCompany().setId(companyId); + } + if (req.getCompanyInfo() != null) { + req.getCompanyInfo().setId(companyId); + } + if (req.getCompanySymbols() == null) req.setCompanySymbols(new ArrayList<>()); + if (req.getClientCodes() == null) req.setClientCodes(new ArrayList<>()); + if (req.getProfileDocuments() == null) req.setProfileDocuments(new ArrayList<>()); + if (req.getContacts() == null) req.setContacts(new ArrayList<>()); + for (CompanySymbolNewRequest cs : req.getCompanySymbols()) { + cs.setCompanyId(companyId); + } + for (ClientCodeNewRequest cc : req.getClientCodes()) { + cc.setCompanyId(companyId); + } + for (ProfileDocumentNewRequest pd : req.getProfileDocuments()) { + pd.setCompanyId(companyId); + } + for (ContactNewRequest c : req.getContacts()) { + c.setCompanyId(companyId); + } + for (ClearingMemberCategoryNewRequest c : req.getCategories()) { + c.setCompanyId(companyId); + } + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/listeners/CompanyServiceListener.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/listeners/CompanyServiceListener.java new file mode 100644 index 000000000..7927ef042 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/listeners/CompanyServiceListener.java @@ -0,0 +1,124 @@ +package ru.spcex.clearing.company.service.v2.listeners; + +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.stereotype.Service; +import ru.spcex.clearing.company.error.CompanyErrors; +import ru.spcex.clearing.company.service.v2.facade.CompanyServiceFacade; +import ru.spcex.clearing.company.service.v2.validators.CompanyServiceValidator; +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.sdf01.AccountTerminationRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.util.services.RequestHelper; +import ru.spcex.platform.utils.error.ValidationException; + +@Service +public class CompanyServiceListener extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final CompanyServiceFacade companyServiceFacade; + private final CompanyServiceValidator companyServiceValidator; + private final RequestHelper requestHelper; + + public CompanyServiceListener(Consumer kafkaQueue, + Producer kafkaResponseQueue, + CompanyServiceFacade companyServiceFacade, + CompanyServiceValidator companyServiceValidator, + RequestHelper requestHelper) { + super(kafkaQueue, kafkaResponseQueue); + this.companyServiceFacade = companyServiceFacade; + this.companyServiceValidator = companyServiceValidator; + this.requestHelper = requestHelper; + } + + @Override + public void afterPropertiesSet() throws Exception { + callback(CompanyNewRequest.class) + .setFunction(request -> requestHelper.requestFunction(this::processBaseRequest, request)) + .forDestination(Consts.DESTINATION_COMPANY_NEW, callbacks::put); + callback(CompanyNewRequest.class) + .setFunction(request -> requestHelper.requestFunction(this::processBaseRequest, request)) + .forDestination(Consts.DESTINATION_COMPANY_UPDATE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(request -> requestHelper.requestFunction(this::processDeleteRequest, request)) + .forDestination(Consts.DESTINATION_COMPANY_DELETE, callbacks::put); + callback(CommonDeleteRequest.class) + .setFunction(request -> requestHelper.requestFunction(this::processCompanyBlock, request)) + .forDestination(Consts.DESTINATION_COMPANY_BLOCK, callbacks::put); + callback(AccountTerminationRequest.class) + .setFunction(request -> requestHelper.requestFunction(this::processAccountTermination, request)) + .forDestination(Consts.ACCOUNT_TERMINATION_STEP2, callbacks::put); + init(); + } + + private RequestInfoUpdate processBaseRequest(BaseRequest request) throws ValidationException { + RequestInfoUpdate requestInfoUpdate = companyServiceValidator.baseRequestValidation(request); + if (requestInfoUpdate != null) { + return requestInfoUpdate; + } + ActionType actionType = request.getActionType(); + switch (actionType) { + case NEW -> { + companyServiceValidator.createRequestValidation((CompanyNewRequest) request.getRequestPayload()); + companyServiceFacade.create((CompanyNewRequest) request.getRequestPayload()); + } + case UPDATE -> { + companyServiceValidator.updateRequestValidation((CompanyNewRequest) request.getRequestPayload()); + companyServiceFacade.update((CompanyNewRequest) request.getRequestPayload()); + } + } + return requestInfoUpdate; + } + + private synchronized RequestInfoUpdate processDeleteRequest(BaseRequest companyBlockRequestBaseRequest) throws ValidationException { + log.debug("CommonDeleteRequest (block request) received id = {}", companyBlockRequestBaseRequest.getRequestPayload().getId()); + RequestInfoUpdate requestInfoUpdate = companyServiceValidator.deleteRequestValidation(companyBlockRequestBaseRequest); + if (requestInfoUpdate != null) { + return requestInfoUpdate; + } + + CompanyErrors result = companyServiceFacade.delete(companyBlockRequestBaseRequest); + if (result.equals(CompanyErrors.CompanyNotFound)) { + log.warn("Company {} not found", companyBlockRequestBaseRequest.getRequestPayload().getId()); + return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyNotFound, companyBlockRequestBaseRequest.getRequestPayload().getId()); + } + + return null; + } + + private synchronized RequestInfoUpdate processCompanyBlock(BaseRequest companyBlockRequestBaseRequest) throws ValidationException { + log.debug("CommonDeleteRequest (block request) received id = {}", companyBlockRequestBaseRequest.getRequestPayload().getId()); + RequestInfoUpdate requestInfoUpdate = companyServiceValidator.baseRequestValidation(companyBlockRequestBaseRequest); + if (requestInfoUpdate != null) { + return requestInfoUpdate; + } + + CompanyErrors result = companyServiceFacade.blockCompany(companyBlockRequestBaseRequest); + if (result.equals(CompanyErrors.CompanyNotFound)) { + log.warn("Company {} not found", companyBlockRequestBaseRequest.getRequestPayload().getId()); + return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyNotFound); + } else if (result.equals(CompanyErrors.CompanyDisabled)) { + log.info("Company {} already blocked", companyBlockRequestBaseRequest.getRequestPayload().getId()); + return requestHelper.makeErrorResponse(companyBlockRequestBaseRequest, CompanyErrors.CompanyDisabled, companyBlockRequestBaseRequest.getRequestPayload().getId()); + } + + return null; + } + + private synchronized RequestInfoUpdate processAccountTermination(BaseRequest accountTerminationRequestBaseRequest) throws ValidationException { + log.debug("AccountTerminationRequest (block request) received id = {}", accountTerminationRequestBaseRequest.getId()); + RequestInfoUpdate requestInfoUpdate = companyServiceValidator.baseRequestValidation(accountTerminationRequestBaseRequest); + if (requestInfoUpdate != null) { + return requestInfoUpdate; + } + companyServiceFacade.terminateAccount(accountTerminationRequestBaseRequest); + return null; + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/listeners/MultiCompanyServiceListener.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/listeners/MultiCompanyServiceListener.java new file mode 100644 index 000000000..3dc2522b5 --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/listeners/MultiCompanyServiceListener.java @@ -0,0 +1,65 @@ +package ru.spcex.clearing.company.service.v2.listeners; + +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.stereotype.Service; +import ru.spcex.clearing.company.service.AccountNotificationHelper; +import ru.spcex.clearing.company.service.v2.facade.MultiCompanyServiceFacade; +import ru.spcex.clearing.company.service.v2.validators.MultiCompanyServiceValidator; +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.company.CompanyGatewayRequest; +import ru.spcex.clearing.platform.messaging.service.QueueConsumer; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.util.services.RequestHelper; + +@Service +public class MultiCompanyServiceListener extends QueueConsumer implements InitializingBean { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final MultiCompanyServiceFacade multiCompanyServiceFacade; + private final MultiCompanyServiceValidator multiCompanyServiceValidator; + private final RequestHelper requestHelper; + private final AccountNotificationHelper accountNotificationHelper; + + public MultiCompanyServiceListener(Consumer kafkaQueue, + Producer kafkaResponseQueue, + MultiCompanyServiceFacade multiCompanyServiceFacade, + MultiCompanyServiceValidator multiCompanyServiceValidator, + RequestHelper requestHelper, + AccountNotificationHelper accountNotificationHelper) { + super(kafkaQueue, kafkaResponseQueue); + this.multiCompanyServiceFacade = multiCompanyServiceFacade; + this.multiCompanyServiceValidator = multiCompanyServiceValidator; + this.requestHelper = requestHelper; + this.accountNotificationHelper = accountNotificationHelper; + } + + @Override + public void afterPropertiesSet() throws Exception { + callback(CompanyGatewayRequest.class) + .setFunction(request -> requestHelper.requestFunction(this::processMultiRequest, request)) + .forDestination(Consts.DESTINATION_COMPANY_GATEWAY_REQUEST, callbacks::put); + init(); + } + + private synchronized RequestInfoUpdate processMultiRequest(BaseRequest baseRequest) { + log.debug("company-batch-new request received, BaseRequest.id = {}", baseRequest.getId()); + RequestInfoUpdate requestInfoUpdate = multiCompanyServiceValidator.baseRequestValidation(baseRequest); + if (requestInfoUpdate != null) { + return requestInfoUpdate; + } + + boolean result = multiCompanyServiceFacade.createUpdateMultiCompany(baseRequest); + if (result) { + for (ClientCodeNewRequest partRequest : baseRequest.getRequestPayload().getClientCodes()) { + accountNotificationHelper.clientCodeNew(partRequest); // Consts.DESTINATION_CLIENT_CODE_NEW Consts.DESTINATION_CLIENT_CODE_UPDATE + } + } + + return null; + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/validators/CompanyServiceValidator.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/validators/CompanyServiceValidator.java new file mode 100644 index 000000000..8d961627f --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/validators/CompanyServiceValidator.java @@ -0,0 +1,69 @@ +package ru.spcex.clearing.company.service.v2.validators; + +import java.util.Optional; +import java.util.function.Function; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +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.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.error.ValidationException; +import ru.spcex.platform.utils.validation.IValidator; + +@Service +public class CompanyServiceValidator { + private final ValidationHelper validationHelper; + private final Function companyNewRequestValidator; + private final Function companyUpdateRequestValidator; + private final Function companyDeleteRequestValidator; + protected UserRoleVerification userRoleVerification; + + public CompanyServiceValidator(ValidationHelper validationHelper, + @Qualifier("companyNewRequestValidator") + Function companyNewRequestValidator, + @Qualifier("companyUpdateRequestValidator") + Function companyUpdateRequestValidator, + @Qualifier("CompanyDeleteRequestValidator") + Function companyDeleteRequestValidator, + UserRoleVerification userRoleVerification) { + this.validationHelper = validationHelper; + this.companyNewRequestValidator = companyNewRequestValidator; + this.companyUpdateRequestValidator = companyUpdateRequestValidator; + this.companyDeleteRequestValidator = companyDeleteRequestValidator; + this.userRoleVerification = userRoleVerification; + } + + public RequestInfoUpdate baseRequestValidation(BaseRequest request) { + return userRoleVerification.validateRoleAndGetResult(request); + } + + public void createRequestValidation(CompanyNewRequest companyNewRequest) throws ValidationException { + IValidator validator = companyNewRequestValidator.apply(companyNewRequest); + Optional error = validator.tillFirstError(); + if (error.isPresent()) { + throw new ValidationException(error.get()); + } + } + + public void updateRequestValidation(CompanyNewRequest updateRequest) throws ValidationException { + IValidator validator = companyUpdateRequestValidator.apply(updateRequest); + Optional error = validator.tillFirstError(); + if (error.isPresent()) { + throw new ValidationException(error.get()); + } + } + + public RequestInfoUpdate deleteRequestValidation(BaseRequest companyBlockRequestBaseRequest) { + RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyBlockRequestBaseRequest); + if (requestInfoUpdate != null) { + return requestInfoUpdate; + } + + requestInfoUpdate = validationHelper.validateTillFirstError(companyBlockRequestBaseRequest, companyDeleteRequestValidator); + return requestInfoUpdate; + } +} diff --git a/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/validators/MultiCompanyServiceValidator.java b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/validators/MultiCompanyServiceValidator.java new file mode 100644 index 000000000..a1c63b57d --- /dev/null +++ b/clearing-parent/company-service/src/main/java/ru/spcex/clearing/company/service/v2/validators/MultiCompanyServiceValidator.java @@ -0,0 +1,19 @@ +package ru.spcex.clearing.company.service.v2.validators; + +import org.springframework.stereotype.Service; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; +import ru.spcex.clearing.util.security.UserRoleVerification; + +@Service +public class MultiCompanyServiceValidator { + protected UserRoleVerification userRoleVerification; + + public MultiCompanyServiceValidator(UserRoleVerification userRoleVerification) { + this.userRoleVerification = userRoleVerification; + } + + public RequestInfoUpdate baseRequestValidation(BaseRequest request) { + return userRoleVerification.validateRoleAndGetResult(request); + } +} 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 bb8a4bccc..02ea80e91 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 @@ -41,6 +41,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; +@Deprecated @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { CompanyService.class, diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/MultiCompanyServiceTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/MultiCompanyServiceTest.java index 67bd1f7f9..fb00ec215 100644 --- a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/MultiCompanyServiceTest.java +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/MultiCompanyServiceTest.java @@ -32,6 +32,7 @@ import java.util.List; import static org.junit.jupiter.api.Assertions.*; import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId; +@Deprecated @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { MultiCompanyService.class, diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/v2/CompanyServiceListenerTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/v2/CompanyServiceListenerTest.java new file mode 100644 index 000000000..32e0fc420 --- /dev/null +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/v2/CompanyServiceListenerTest.java @@ -0,0 +1,230 @@ +package ru.spcex.clearing.company.service.v2; + +import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator; +import static ru.spcex.clearing.test.TestUtils.addRecordToKafka; +import static ru.spcex.clearing.test.TestUtils.getJsonStringForDelete; +import static ru.spcex.clearing.test.TestUtils.getJsonStringForNew; +import static ru.spcex.clearing.test.TestUtils.waitingSendAndCheckRecord; +import static ru.spcex.clearing.test.TestUtils.waitingWhenTryAddRecordAndCheckError; +import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId; + +import java.util.Arrays; +import java.util.Map; +import javax.annotation.PostConstruct; +import org.apache.kafka.clients.consumer.MockConsumer; +import org.apache.kafka.clients.producer.Producer; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import ru.clearing.classes.statics.data.company.ClearingMemberCategory; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.platform.dictionary.CompanySymbolDictionary; +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.company.service.AccountNotificationHelper; +import ru.spcex.clearing.company.service.CompanyService; +import ru.spcex.clearing.company.service.CompanySymbolService; +import ru.spcex.clearing.company.service.RelationService; +import ru.spcex.clearing.company.service.v2.facade.CompanyServiceFacade; +import ru.spcex.clearing.company.service.v2.listeners.CompanyServiceListener; +import ru.spcex.clearing.company.service.v2.validators.CompanyServiceValidator; +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.CompanyNewRequest; +import ru.spcex.clearing.test.MatcherFactory; +import ru.spcex.clearing.test.config.ImdgTestConfig; +import ru.spcex.clearing.test.config.KafkaTestConfig; +import ru.spcex.platform.enumeration.CompanySymbol; +import ru.spcex.platform.enumeration.WorkflowStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + CompanyServiceListener.class, + CompanyServiceFacade.class, + CompanyServiceValidator.class, + CompanyValidationConfig.class, + ValidationConfig.class, + AccountNotificationHelper.class, + RelationService.class, + RelationValidationConfig.class, + + CompanySymbolService.class, + CompanySymbolValidationConfig.class, + + KafkaTestConfig.class, + ImdgTestConfig.class, + BeanConfiguration.class}) +public class CompanyServiceListenerTest { + public static final MatcherFactory.Matcher COMPANY_MATCHER = usingIgnoringFieldsComparator(); + private static final int PARTITION = 0; + private static final String TOPIC_COMPANY_DELETE = Consts.DESTINATION_COMPANY_DELETE; + + @Autowired + CompanyServiceListener companyServiceListener; + @Autowired + @Qualifier("hazelcastServiceTest") + private ImdgProvider hazelcastServiceTest; + private Imdg companyImdg; + private Imdg companySymbolsImdg; + private Imdg workflowStatusDictionaryImdg; + + @Autowired + @Qualifier("mockProducer") + protected Producer mockProducer; + + @PostConstruct + private void init() { + waitAvailableImdgProviderAndAddAdminWithDefaultId(); + companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + companySymbolsImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + + workflowStatusDictionaryImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class); + WorkflowStatusDictionary ws1 = new WorkflowStatusDictionary(); + ws1.setId(1L); + ws1.setCode(WorkflowStatus.Active.getKey()); + ws1.setName("Active"); + workflowStatusDictionaryImdg.insert(ws1); + WorkflowStatusDictionary ws2 = new WorkflowStatusDictionary(); + ws2.setId(2L); + ws2.setCode(WorkflowStatus.Blocked.getKey()); + ws2.setName("Blocked"); + workflowStatusDictionaryImdg.insert(ws2); + + Imdg companySymbolDictionaryImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanySymbolDictionary, CompanySymbolDictionary.class); + { + CompanySymbolDictionary cSymbol = new CompanySymbolDictionary(); + cSymbol.setId(11L); + cSymbol.setCode(CompanySymbol.CLRC.getKey()); + cSymbol.setName(CompanySymbol.CLRC.getKey()); + cSymbol.setShortname(" CLRC key"); + companySymbolDictionaryImdg.insert(cSymbol); + CompanySymbolDictionary cioSymbol = new CompanySymbolDictionary(); + cioSymbol.setId(22L); + cioSymbol.setCode(CompanySymbol.CIO.getKey()); + cioSymbol.setName(CompanySymbol.CIO.getKey()); + companySymbolDictionaryImdg.insert(cioSymbol); + } + } + + /** + * {@link CompanyService#deleteCompany(BaseRequest)}
+ * Тест проверяет удаление сущности {@link Company} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CommonDeleteRequest}:
+ * {@link CommonDeleteRequest#id} - Идентификатор записи
+ */ + @Test + void deleteCompany() throws InterruptedException { + //ARRANGE + final Long ID = 101L; + Company existsCompany = new Company(); + existsCompany.setId(ID); + existsCompany.setWorkflowStatus(WorkflowStatus.Active.getKey()); + companyImdg.insert(existsCompany); + + CommonDeleteRequest commonDeleteRequest = new CommonDeleteRequest(); + commonDeleteRequest.setId(ID); + + //ACT + String jsonString = getJsonStringForDelete(commonDeleteRequest, ID); + addRecordToKafka((MockConsumer) companyServiceListener.getConsumer(), TOPIC_COMPANY_DELETE, PARTITION, 0, jsonString); + + //ASSERT + waitingSendAndCheckRecord(ID, mockProducer); + + //Company resultDeleting = companyImdg.getSingleObjectByID(ID); + Company resultDeleting = companyImdg.getFirstObjectBySQL("id=" + ID); + Assertions.assertEquals(WorkflowStatus.Blocked.getKey(), resultDeleting.getWorkflowStatus()); + + { + // Hazelcast 3.12.4 возможно имеет ошибку с NearCache (https://github.com/hazelcast/hazelcast/issues/16577) и её устранили в версии 3.12.7+. + // метод устранения проблемы: вместо return map.get(paramLong); использовать return map.getEntryView(paramLong).getValue(); + Company resultDeletingDirectGet = companyImdg.getSingleObjectByID(ID); + if (!resultDeleting.getWorkflowStatus().equals(resultDeletingDirectGet.getWorkflowStatus())) { + System.out.println("WARNING: Hazelcast error: WorkflowStatus " + resultDeletingDirectGet.getWorkflowStatus() + " and " + resultDeleting.getWorkflowStatus() + " together!"); + } + } + } + + + /** + * {@link CompanyService#createCompany(BaseRequest)}
+ * Тест проверяет удаление сущности {@link Company} в Hazelcast при передаче из Apache Kafka.
+ * Входной запрос {@link CommonDeleteRequest}:
+ * {@link CommonDeleteRequest#id} - Идентификатор записи
+ */ + @Test + void newCompany() throws InterruptedException { + //ARRANGE + final Long ID = 102L; + final String DESTINATION_COMPANY_NEW = Consts.DESTINATION_COMPANY_NEW; + companyImdg.size(); + + CompanyNewRequest companyNewRequest = new CompanyNewRequest(); +// companyNewRequest.setId(ID); + companyNewRequest.setCompanySymbol(CompanySymbol.CLRC.getKey()); + companyNewRequest.setCompanySymbolValue("CLR-symbol ipo"); + companyNewRequest.setShortName("ClrIPO"); + companyNewRequest.setFullName("Clearing IPO"); + companyNewRequest.setWorkflowStatus(WorkflowStatus.Active.getKey()); + + //ACT + String jsonString = getJsonStringForNew(companyNewRequest, ID); + addRecordToKafka((MockConsumer) companyServiceListener.getConsumer(), DESTINATION_COMPANY_NEW, PARTITION, 0, jsonString); + + //ASSERT + waitingSendAndCheckRecord(ID, mockProducer); + + Company resultNew = companyImdg.getFirstObjectByFieldValues(Map.of("ShortName", "ClrIPO")); + Assertions.assertNotNull(resultNew); + Assertions.assertEquals("ClrIPO", resultNew.getShortName()); + Assertions.assertEquals(WorkflowStatus.Active.getKey(), resultNew.getWorkflowStatus()); + } + + @Test + void newExistCompanySymbolCompanyRequest() { + final Long ID = 102L; + final String DESTINATION_COMPANY_NEW = Consts.DESTINATION_COMPANY_NEW; + companyImdg.size(); + + CompanySymbols existCompanySymbols = new CompanySymbols(); + existCompanySymbols.setCompanyId(ID); + existCompanySymbols.setCompanySymbol(CompanySymbol.CIO.getKey()); + existCompanySymbols.setCompanySymbolValue("test_value"); + companySymbolsImdg.insert(existCompanySymbols); + + CompanyNewRequest companyNewRequest = new CompanyNewRequest(); +// companyNewRequest.setId(ID); + companyNewRequest.setCompanySymbol(CompanySymbol.CIO.getKey()); + companyNewRequest.setCompanySymbolValue("test_value"); + companyNewRequest.setShortName("ClrIPO"); + companyNewRequest.setFullName("Clearing IPO"); + companyNewRequest.setWorkflowStatus(WorkflowStatus.Active.getKey()); + + //ACT + String jsonString = getJsonStringForNew(companyNewRequest, ID); + addRecordToKafka((MockConsumer) companyServiceListener.getConsumer(), DESTINATION_COMPANY_NEW, PARTITION, 0, jsonString); + + //ASSERT + waitingWhenTryAddRecordAndCheckError(ID, + mockProducer, + String.valueOf(CompanyErrors.CompanyWithCompanySymbolAlreadyExist.getId()), + Arrays.asList("CIO", "test_value")); + + Company resultNew = companyImdg.getFirstObjectByFieldValues(Map.of("ShortName", "ClrIPO")); + Assertions.assertNull(resultNew); + } +} diff --git a/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/v2/MultiCompanyServiceListenerTest.java b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/v2/MultiCompanyServiceListenerTest.java new file mode 100644 index 000000000..6610d6749 --- /dev/null +++ b/clearing-parent/company-service/src/test/java/ru/spcex/clearing/company/service/v2/MultiCompanyServiceListenerTest.java @@ -0,0 +1,247 @@ +package ru.spcex.clearing.company.service.v2; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProviderAndAddAdminWithDefaultId; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.PostConstruct; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +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.classes.statics.data.profile.Contact; +import ru.clearing.classes.statics.data.profile.ProfileDocument; +import ru.clearing.platform.dictionary.CompanySymbolDictionary; +import ru.spcex.clearing.company.config.BeanConfiguration; +import ru.spcex.clearing.company.config.validation.ClearingMemberCategoryValidationConfig; +import ru.spcex.clearing.company.config.validation.CompanySymbolValidationConfig; +import ru.spcex.clearing.company.config.validation.CompanyValidationConfig; +import ru.spcex.clearing.company.config.validation.ContactValidationConfig; +import ru.spcex.clearing.company.config.validation.ProfileDocumentValidationConfig; +import ru.spcex.clearing.company.config.validation.RelationValidationConfig; +import ru.spcex.clearing.company.config.validation.ValidationConfig; +import ru.spcex.clearing.company.service.AccountNotificationHelper; +import ru.spcex.clearing.company.service.ClearingMemberCategoryService; +import ru.spcex.clearing.company.service.CompanyInfoService; +import ru.spcex.clearing.company.service.CompanySymbolService; +import ru.spcex.clearing.company.service.ContactService; +import ru.spcex.clearing.company.service.ProfileDocumentService; +import ru.spcex.clearing.company.service.RelationService; +import ru.spcex.clearing.company.service.v2.facade.CompanyServiceFacade; +import ru.spcex.clearing.company.service.v2.facade.MultiCompanyServiceFacade; +import ru.spcex.clearing.company.service.v2.listeners.CompanyServiceListener; +import ru.spcex.clearing.company.service.v2.listeners.MultiCompanyServiceListener; +import ru.spcex.clearing.company.service.v2.validators.CompanyServiceValidator; +import ru.spcex.clearing.company.service.v2.validators.MultiCompanyServiceValidator; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyGatewayRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyInfoUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanyNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.CompanySymbolNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ContactNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.company.ProfileDocumentNewRequest; +import ru.spcex.clearing.test.config.ImdgTestConfig; +import ru.spcex.clearing.test.config.KafkaTestConfig; +import ru.spcex.platform.enumeration.CompanySymbol; +import ru.spcex.platform.enumeration.ContactTypes; +import ru.spcex.platform.enumeration.DocumentTypes; +import ru.spcex.platform.enumeration.WorkflowStatus; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { + MultiCompanyServiceListener.class, + MultiCompanyServiceFacade.class, + MultiCompanyServiceValidator.class, + + CompanyServiceListener.class, + CompanyServiceFacade.class, + CompanyServiceValidator.class, + CompanyValidationConfig.class, + ValidationConfig.class, + CompanySymbolService.class, + AccountNotificationHelper.class, + RelationService.class, + RelationValidationConfig.class, + + CompanySymbolService.class, + CompanySymbolValidationConfig.class, + CompanyInfoService.class, + ProfileDocumentService.class, + ProfileDocumentValidationConfig.class, + ContactService.class, + ContactValidationConfig.class, + ClearingMemberCategoryService.class, + ClearingMemberCategoryValidationConfig.class, + + KafkaTestConfig.class, + ImdgTestConfig.class, + BeanConfiguration.class}) +public class MultiCompanyServiceListenerTest { + final Long COMPANY_ID = 123L; + + @Autowired + protected MultiCompanyServiceListener multiCompanyServiceListener; + @Autowired + protected MultiCompanyServiceFacade multiCompanyServiceFacade; + + @Autowired + @Qualifier("hazelcastServiceTest") + private ImdgProvider hazelcastServiceTest; + + @PostConstruct + private void init() { + waitAvailableImdgProviderAndAddAdminWithDefaultId(); + Imdg companyImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Company, Company.class); + Imdg companySymbolsImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + + Company company = new Company(); + company.setId(COMPANY_ID); + company.setWorkflowStatus(WorkflowStatus.Active.getKey()); + company.setFullName("Test company prime"); + companyImdg.insert(company); + + + Imdg companySymbolDictionaryImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_CompanySymbolDictionary, CompanySymbolDictionary.class); + { + CompanySymbolDictionary cSymbol = new CompanySymbolDictionary(); + cSymbol.setId(11L); + cSymbol.setCode(CompanySymbol.CLRC.getKey()); + cSymbol.setName(CompanySymbol.CLRC.getKey()); + cSymbol.setShortname(" CLRC key"); + companySymbolDictionaryImdg.insert(cSymbol); + CompanySymbolDictionary cioSymbol = new CompanySymbolDictionary(); + cioSymbol.setId(22L); + cioSymbol.setCode(CompanySymbol.CIO.getKey()); + cioSymbol.setName(CompanySymbol.CIO.getKey()); + companySymbolDictionaryImdg.insert(cioSymbol); + } + + Imdg contactImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Contact, Contact.class); + Contact contact = new Contact(); + contact.setId(100L); + contact.setCompanyId(company.getId()); + contact.setContactType(ContactTypes.adrs.getKey()); + contact.setContactValue("UAR, st.Uarus, anystreet st., house 1"); + contactImdg.insert(contact); + + CompanySymbols companySymbol = new CompanySymbols(); + companySymbol.setId(222L); + companySymbol.setCompanyId(company.getId()); + companySymbol.setCompanySymbol(CompanySymbol.INN.getKey()); + companySymbol.setCompanySymbolValue("INN-VALUE"); + companySymbolsImdg.insert(companySymbol); + + Imdg profileDocumentImdg = hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); + ProfileDocument doc = new ProfileDocument(); + doc.setId(10002L); + doc.setCompanyId(COMPANY_ID); + doc.setDocumentType(DocumentTypes.form.getKey()); + doc.setIssueDate(LocalDate.now()); // тест может показать ложное срабатывание в 00:00:00.001 + profileDocumentImdg.insert(doc); + } + + @Test + void findCompanyDocument() { + ProfileDocumentNewRequest req = new ProfileDocumentNewRequest(); + req.setCompanyId(COMPANY_ID); + req.setDocumentType(DocumentTypes.form.getKey()); + req.setIssueDate(LocalDate.now()); + ProfileDocument doc = multiCompanyServiceFacade.findCompanyDocument(req); + assertNotNull(doc); + } + + @Test + void findCompanySymbols() { + CompanySymbolNewRequest req = new CompanySymbolNewRequest(); + req.setCompanyId(COMPANY_ID); + req.setCompanySymbol(CompanySymbol.CLRC.getKey()); + req.setCompanySymbolValue("CL-VALUE-2"); + assertNull(multiCompanyServiceFacade.findCompanySymbols(req)); + + req.setCompanySymbol(CompanySymbol.INN.getKey()); + req.setCompanySymbolValue("INN-VALUE"); + CompanySymbols symbol = multiCompanyServiceFacade.findCompanySymbols(req); + assertNotNull(symbol); + assertEquals("INN-VALUE", symbol.getCompanySymbolValue()); + } + + @Test + void findContact() { + ContactNewRequest req = new ContactNewRequest(); + req.setCompanyId(COMPANY_ID); + req.setContactType(ContactTypes.adrs.getKey()); + req.setContactValue("UAR, st.Uarus, anystreet st., house 2"); + Contact contact = multiCompanyServiceFacade.findContact(req); + assertNotNull(contact); + assertNotEquals(req.getContactValue(), contact.getContactValue()); + } + + @Test + void getCompanyIdForCompanySymbols() { + CompanyNewRequest req = new CompanyNewRequest(); + req.setCompanySymbol(CompanySymbol.CLRC.getKey()); + req.setCompanySymbolValue("CL-VALUE"); + assertNull(multiCompanyServiceFacade.getCompanyIdForCompanySymbols("SAMPLE-NO-uuid", req, null)); + + req.setCompanySymbolValue("INN-VALUE"); + assertNull(multiCompanyServiceFacade.getCompanyIdForCompanySymbols("SAMPLE-NO-uuid", req, null)); + req.setCompanySymbol(CompanySymbol.INN.getKey()); + assertEquals(COMPANY_ID, multiCompanyServiceFacade.getCompanyIdForCompanySymbols("SAMPLE-NO-uuid", req, null)); + req.setCompanySymbol(null); + req.setCompanySymbolValue(null); + assertNull(multiCompanyServiceFacade.getCompanyIdForCompanySymbols(null, req, null)); + List csReq=new ArrayList<>(); + assertNull(multiCompanyServiceFacade.getCompanyIdForCompanySymbols(null, req, null)); + assertNull(multiCompanyServiceFacade.getCompanyIdForCompanySymbols(null, req, csReq)); + { + CompanySymbolNewRequest cs=new CompanySymbolNewRequest(); + cs.setCompanySymbol(CompanySymbol.CLRC.getKey()); + cs.setCompanySymbolValue("INN-VALUE"); + csReq.add(cs); + } + assertNull(multiCompanyServiceFacade.getCompanyIdForCompanySymbols(null, req, csReq)); + { + CompanySymbolNewRequest cs=new CompanySymbolNewRequest(); + cs.setCompanySymbol(CompanySymbol.INN.getKey()); + cs.setCompanySymbolValue("INN-VALUE"); + csReq.add(cs); + } + assertEquals(COMPANY_ID, multiCompanyServiceFacade.getCompanyIdForCompanySymbols(null, req, csReq)); + } + + @Test + void fillCompanyId() { + { + CompanyGatewayRequest testReq = new CompanyGatewayRequest(); + testReq.setCompany(new CompanyNewRequest()); + testReq.setProfileDocuments(null); + testReq.setCompanySymbols(null); + testReq.setContacts(null); + testReq.setClientCodes(null); + multiCompanyServiceFacade.fillCompanyId(testReq, COMPANY_ID); + assertEquals(COMPANY_ID, testReq.getCompany().getId()); + assertNotNull(testReq.getProfileDocuments()); + assertNotNull(testReq.getCompanySymbols()); + assertNotNull(testReq.getContacts()); + assertNotNull(testReq.getClientCodes()); + } + { + CompanyGatewayRequest testReq = new CompanyGatewayRequest(); + testReq.setCompany(new CompanyNewRequest()); + testReq.setCompanyInfo(new CompanyInfoUpdateRequest()); + multiCompanyServiceFacade.fillCompanyId(testReq, COMPANY_ID); + assertEquals(COMPANY_ID, testReq.getCompany().getId()); + } + } +}